Skip to content

Commit

Permalink
Merge pull request #5 from naminodarie/feature/analyzer
Browse files Browse the repository at this point in the history
v1.0.2
  • Loading branch information
kzrnm authored Dec 5, 2020
2 parents cafb444 + c11515b commit cabd670
Show file tree
Hide file tree
Showing 39 changed files with 3,041 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ env:
DOTNET_NOLOGO: true
NUGET_XMLDOC_MODE: skip
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
WORKFLOW_VERSION_PROJ: Source/AtCoderLibrary/AtCoderLibrary.csproj
WORKFLOW_VERSION_PROJ: Directory.Build.props
WORKFLOW_BUILD_SLN: AtCoderLibrary.sln
GIT_COMMIT: ${{ github.sha }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Install dotnet-format
run: dotnet tool install --global dotnet-format
- name: Format
run: dotnet format ${{ env.WORKFLOW_BUILD_SLN }} --check --dry-run
run: dotnet format ${{ env.WORKFLOW_BUILD_SLN }} --check
test:
runs-on: ubuntu-latest
steps:
Expand Down
14 changes: 14 additions & 0 deletions AtCoderLibrary.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C9D4DB37-1705-454C-B223-B73CB823335D}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtCoderLibrary.Test", "Test\AtCoderLibrary.Test\AtCoderLibrary.Test.csproj", "{D0662927-8142-43D2-ABA9-C1977107F0ED}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{573A3DC6-BEB2-4E3A-8EB3-E4CB88F3C8F1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtCoderAnalyzer", "Source\AtCoderAnalyzer\AtCoderAnalyzer.csproj", "{1557AA29-1069-43ED-8552-791248C9E31C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtCoderAnalyzer.Test", "Test\AtCoderAnalyzer.Test\AtCoderAnalyzer.Test.csproj", "{522A1037-5060-4CBA-A4A3-99624FAD732E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -28,12 +33,21 @@ Global
{D0662927-8142-43D2-ABA9-C1977107F0ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0662927-8142-43D2-ABA9-C1977107F0ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0662927-8142-43D2-ABA9-C1977107F0ED}.Release|Any CPU.Build.0 = Release|Any CPU
{1557AA29-1069-43ED-8552-791248C9E31C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1557AA29-1069-43ED-8552-791248C9E31C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1557AA29-1069-43ED-8552-791248C9E31C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1557AA29-1069-43ED-8552-791248C9E31C}.Release|Any CPU.Build.0 = Release|Any CPU
{522A1037-5060-4CBA-A4A3-99624FAD732E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{522A1037-5060-4CBA-A4A3-99624FAD732E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{522A1037-5060-4CBA-A4A3-99624FAD732E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{522A1037-5060-4CBA-A4A3-99624FAD732E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D0662927-8142-43D2-ABA9-C1977107F0ED} = {573A3DC6-BEB2-4E3A-8EB3-E4CB88F3C8F1}
{522A1037-5060-4CBA-A4A3-99624FAD732E} = {573A3DC6-BEB2-4E3A-8EB3-E4CB88F3C8F1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3DF2A5DC-C174-486C-A24B-1F08FAA0D4F5}
Expand Down
19 changes: 19 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project>

<PropertyGroup>
<Authors>naminodarie</Authors>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/naminodarie/ac-library-csharp</PackageProjectUrl>
<RepositoryUrl>https://github.com/naminodarie/ac-library-csharp</RepositoryUrl>

<Version>1.0.2</Version>
<AssemblyVersion>1.0.2.101</AssemblyVersion>
<RepositoryCommit Condition="'$(GIT_COMMIT)' != ''">$(GIT_COMMIT)</RepositoryCommit>

<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)key.snk</AssemblyOriginatorKeyFile>

<PackageOutputPath>$(MSBuildThisFileDirectory)bin\Packages\$(Configuration)\</PackageOutputPath>
</PropertyGroup>

</Project>
11 changes: 11 additions & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
</configuration>
8 changes: 7 additions & 1 deletion README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ README languages: [Japanese](README.ja.md)
- [Status](#status)
- [Getting started](#getting-started)
- [Installation](#installation)
- [Install analyzer(optional)](#install-analyzeroptional)
- [output combinded source code](#output-combinded-source-code)
- [License](#license)

Expand All @@ -35,6 +36,12 @@ README languages: [Japanese](README.ja.md)
Install-Package ac-library-csharp
```

### Install analyzer(optional)

```
Install-Package AtCoderAnalyzer
```

### output combinded source code

提出用にソースコードを結合したファイルを出力する方式です。
Expand All @@ -43,7 +50,6 @@ SourceExpander はソースジェネレーターを使用するライブラリ

```
Install-Package SourceExpander
Install-Package ac-library-csharp
```

`/home/any_directory/ac-library-csharp/Sample/SampleProject/Program.cs`を実行すると, `SourceExpander.Expander.Expand()``/home/any_directory/ac-library-csharp/Sample/SampleProject/Combined.csx` が出力されます。
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ README languages: [Japanese](README.ja.md)
- [Status](#status)
- [Getting started](#getting-started)
- [Installation](#installation)
- [Install analyzer(optional)](#install-analyzeroptional)
- [output combinded source code](#output-combinded-source-code)
- [License](#license)

Expand All @@ -35,6 +36,12 @@ C# port of [AtCoder Library](https://github.com/atcoder/ac-library/)
Install-Package ac-library-csharp
```

### Install analyzer(optional)

```
Install-Package AtCoderAnalyzer
```

### output combinded source code

Output combinded source code for submitting.
Expand All @@ -43,7 +50,6 @@ Require **.NET 5 SDK** or **Visual Studio 16.8** or later because SourceExpander

```
Install-Package SourceExpander
Install-Package ac-library-csharp
```

When you run `/home/any_directory/ac-library-csharp/Sample/SampleProject/Program.cs`, `SourceExpander.Expander.Expand()` creates `/home/any_directory/ac-library-csharp/Sample/SampleProject/Combined.csx`
Expand Down
12 changes: 12 additions & 0 deletions Sample/Sample.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ VisualStudioVersion = 16.0.30523.141
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleProject", "SampleProject\SampleProject.csproj", "{6077D1BD-7B49-4611-AF49-0E01E462C956}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtCoderLibrary", "..\Source\AtCoderLibrary\AtCoderLibrary.csproj", "{75EDB69F-2582-4251-8709-E0BB934336C4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtCoderAnalyzer", "..\Source\AtCoderAnalyzer\AtCoderAnalyzer.csproj", "{4101D5BE-4FC7-467E-BCAD-0C6BD57B3485}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +19,14 @@ Global
{6077D1BD-7B49-4611-AF49-0E01E462C956}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6077D1BD-7B49-4611-AF49-0E01E462C956}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6077D1BD-7B49-4611-AF49-0E01E462C956}.Release|Any CPU.Build.0 = Release|Any CPU
{75EDB69F-2582-4251-8709-E0BB934336C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75EDB69F-2582-4251-8709-E0BB934336C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75EDB69F-2582-4251-8709-E0BB934336C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75EDB69F-2582-4251-8709-E0BB934336C4}.Release|Any CPU.Build.0 = Release|Any CPU
{4101D5BE-4FC7-467E-BCAD-0C6BD57B3485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4101D5BE-4FC7-467E-BCAD-0C6BD57B3485}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4101D5BE-4FC7-467E-BCAD-0C6BD57B3485}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4101D5BE-4FC7-467E-BCAD-0C6BD57B3485}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
18 changes: 17 additions & 1 deletion Sample/SampleProject/SampleProject.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,24 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ac-library-csharp" Version="1.0.1" />
<PackageReference Include="SourceExpander" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="ac-library-csharp" Version="1.0.2" />
<PackageReference Include="AtCoderAnalyzer" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<!--
<ItemGroup>
<ProjectReference Include="..\..\Source\AtCoderLibrary\AtCoderLibrary.csproj" />
<ProjectReference Include="..\..\Source\AtCoderAnalyzer\AtCoderAnalyzer.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Analyzer</OutputItemType>
</ProjectReference>
</ItemGroup>
-->
</Project>
70 changes: 70 additions & 0 deletions Source/AtCoderAnalyzer/AC0001_AC0002_IntToLongAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Immutable;
using AtCoderAnalyzer.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;

namespace AtCoderAnalyzer
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class AC0001_AC0002_IntToLongAnalyzer : DiagnosticAnalyzer
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
=> ImmutableArray.Create(
DiagnosticDescriptors.AC0001_MultiplyOverflowInt32,
DiagnosticDescriptors.AC0002_LeftShiftOverflowInt32);

public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(
GeneratedCodeAnalysisFlags.Analyze |
GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.EnableConcurrentExecution();

context.RegisterSyntaxNodeAction(AnalyzeIntToLongSyntaxNode,
SyntaxKind.LeftShiftExpression, SyntaxKind.MultiplyExpression);
}

private void AnalyzeIntToLongSyntaxNode(SyntaxNodeAnalysisContext context)
{
var semanticModel = context.SemanticModel;
var node = context.Node;

var typeInfo = semanticModel.GetTypeInfo(node, cancellationToken: context.CancellationToken);
if (typeInfo.Type.SpecialType != SpecialType.System_Int32)
return;

DiagnosticDescriptor descriptor = node.Kind() switch
{
SyntaxKind.MultiplyExpression => DiagnosticDescriptors.AC0001_MultiplyOverflowInt32,
SyntaxKind.LeftShiftExpression => DiagnosticDescriptors.AC0002_LeftShiftOverflowInt32,
_ => throw new InvalidOperationException(),
};

for (; node is not null; node = GetParent(node))
{
if (semanticModel.GetTypeInfo(node, cancellationToken: context.CancellationToken)
.ConvertedType.SpecialType == SpecialType.System_Int64)
{
var diagnostic = Diagnostic.Create(
descriptor,
context.Node.GetLocation(),
context.Node.ToString());

context.ReportDiagnostic(diagnostic);
return;
}
}

static SyntaxNode GetParent(SyntaxNode node)
{
var parent = node.Parent;
if (parent is BinaryExpressionSyntax or ParenthesizedExpressionSyntax)
return parent;
return null;
}
}
}
}
68 changes: 68 additions & 0 deletions Source/AtCoderAnalyzer/AC0001_AC0002_IntToLongCodeFixProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AtCoderAnalyzer.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace AtCoderAnalyzer
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AC0001_AC0002_IntToLongCodeFixProvider)), Shared]
public class AC0001_AC0002_IntToLongCodeFixProvider : CodeFixProvider
{
private const string title = "Cast int to long";
public override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(
DiagnosticDescriptors.AC0001_MultiplyOverflowInt32.Id,
DiagnosticDescriptors.AC0002_LeftShiftOverflowInt32.Id);

public sealed override FixAllProvider GetFixAllProvider()
=> WellKnownFixAllProviders.BatchFixer;

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
if (await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false)
is not CompilationUnitSyntax root)
return;
var diagnostic = context.Diagnostics[0];
var diagnosticSpan = diagnostic.Location.SourceSpan;

var node = root.FindNode(diagnosticSpan);
foreach (var nn in node.ChildNodes().Prepend(node))
{
if (nn is BinaryExpressionSyntax b)
{
switch (b.Kind())
{
case SyntaxKind.LeftShiftExpression:
case SyntaxKind.MultiplyExpression:
var action = CodeAction.Create(title: title,
createChangedDocument: c => CastLong(context.Document, b, c),
equivalenceKey: title);
context.RegisterCodeFix(action, diagnostic);
return;
}
}
}
}
private async Task<Document> CastLong(Document document, BinaryExpressionSyntax syntax, CancellationToken cancellationToken)
{
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
while (syntax.Left is BinaryExpressionSyntax nx)
syntax = nx;

if (syntax.Left is LiteralExpressionSyntax lx && lx.Token.Value is int num)
{
var longEx = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal((long)num));
return document.WithSyntaxRoot(root.ReplaceNode(syntax.Left, longEx));
}
var castEx = SyntaxFactory.CastExpression(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.LongKeyword)), syntax.Left);
return document.WithSyntaxRoot(root.ReplaceNode(syntax.Left, castEx));
}
}
}
Loading

0 comments on commit cabd670

Please sign in to comment.