Skip to content

Commit

Permalink
Merge pull request #69 from hadashiA/ku/incremental-source-generator
Browse files Browse the repository at this point in the history
Add incremental source generator
  • Loading branch information
hadashiA authored Dec 11, 2023
2 parents 77b9ea1 + 92fd8c0 commit 3cc4ec8
Show file tree
Hide file tree
Showing 45 changed files with 3,194 additions and 160 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
default: false
type: boolean
jobs:
nuget-publish:
build-dotnet:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
Expand All @@ -20,11 +20,12 @@ jobs:
- uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
8.0.x
- run: dotnet build -c Release
- run: dotnet test -c Release --no-build
- run: dotnet pack -c Release --no-build -o ./publish
- run: rm ./publish/VYaml.Benchmark.*
- run: |
rm ./publish/VYaml.Benchmark.*
- uses: actions/upload-artifact@v3
with:
name: nuget
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ jobs:
- uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
8.0.x
- run: dotnet build -c Debug
- run: dotnet test -c Debug --no-build
2 changes: 1 addition & 1 deletion VYaml.SourceGenerator.Roslyn3/CodeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace VYaml.SourceGenerator;

public class CodeWriter
class CodeWriter
{
readonly struct IndentScope : IDisposable
{
Expand Down
6 changes: 3 additions & 3 deletions VYaml.SourceGenerator.Roslyn3/DiagnosticDescriptors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ static class DiagnosticDescriptors

public static readonly DiagnosticDescriptor YamlMemberPropertyMustHaveSetter = new(
id: "VYAML004",
title: "A yaml serializable property with must have setter.",
messageFormat: "The VYaml serializable object '{0}' property '{1}' must have setter.",
title: "A yaml serializable property with must have setter",
messageFormat: "The VYaml serializable object '{0}' property '{1}' must have setter",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor YamlMemberFieldCannotBeReadonly = new(
id: "VYAML005",
title: "A yaml serializable field cannot be readonly",
messageFormat: "The VYaml serializable object '{0}' field '{1}' cannot be readonly.",
messageFormat: "The VYaml serializable object '{0}' field '{1}' cannot be readonly",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);
Expand Down
2 changes: 1 addition & 1 deletion VYaml.SourceGenerator.Roslyn3/ReferenceSymbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace VYaml.SourceGenerator;

public class ReferenceSymbols
class ReferenceSymbols
{
public static ReferenceSymbols? Create(Compilation compilation)
{
Expand Down
3 changes: 1 addition & 2 deletions VYaml.SourceGenerator.Roslyn3/SyntaxContextReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@ or RecordDeclarationSyntax
classDeclarations.Add(typeSyntax);
}
}
}
}
} }
}
25 changes: 7 additions & 18 deletions VYaml.SourceGenerator.Roslyn3/VYaml.SourceGenerator.Roslyn3.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>12</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>VYaml.SourceGenerator</RootNamespace>

<AnalyzerLanguage>cs</AnalyzerLanguage>
<IncludeBuildOutput>false</IncludeBuildOutput>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<DevelopmentDependency>true</DevelopmentDependency>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackBuildOutputs</TargetsForTfmSpecificContentInPackage>
<LangVersion>11</LangVersion>
<RootNamespace>VYaml.SourceGenerator</RootNamespace>
<IsRoslynComponent>true</IsRoslynComponent>

<PackageTags>yaml</PackageTags>
<Description>Code generator for VYaml</Description>
</PropertyGroup>
Expand All @@ -24,19 +25,7 @@
</PackageReference>
</ItemGroup>

<!-- Copy files for Unity -->
<PropertyGroup>
<DestinationRoot>$(MSBuildProjectDirectory)\..\VYaml.Unity\Assets\VYaml\Runtime</DestinationRoot>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="$(Configuration) == 'Release'">
<Copy SourceFiles="$(TargetPath)" DestinationFiles="$(DestinationRoot)\$(TargetFileName)" SkipUnchangedFiles="true" />
</Target>

<!-- for nuget publish -->
<Target Name="PackBuildOutputs" DependsOnTargets="SatelliteDllsProjectOutputGroup;DebugSymbolsProjectOutputGroup">
<ItemGroup>
<TfmSpecificPackageFile Include="$(TargetDir)\*.dll" PackagePath="analyzers\dotnet\cs" />
<TfmSpecificPackageFile Include="@(SatelliteDllsProjectOutputGroupOutput->'%(FinalOutputPath)')" PackagePath="analyzers\dotnet\cs\%(SatelliteDllsProjectOutputGroupOutput.Culture)\" />
</ItemGroup>
</Target>
<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
</Project>
121 changes: 121 additions & 0 deletions VYaml.SourceGenerator/CodeWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using System;
using System.Text;

namespace VYaml.SourceGenerator;

class CodeWriter
{
readonly struct IndentScope : IDisposable
{
readonly CodeWriter source;

public IndentScope(CodeWriter source, string? startLine = null)
{
this.source = source;
source.AppendLine(startLine);
source.IncreaseIndent();
}

public void Dispose()
{
source.DecreaseIndent();
}
}

readonly struct BlockScope : IDisposable
{
readonly CodeWriter source;

public BlockScope(CodeWriter source, string? startLine = null)
{
this.source = source;
source.AppendLine(startLine);
source.BeginBlock();
}

public void Dispose()
{
source.EndBlock();
}
}

readonly StringBuilder buffer = new();
int indentLevel;

public void Append(string value, bool indent = true)
{
if (indent)
{
buffer.Append($"{new string(' ', indentLevel * 4)} {value}");
}
else
{
buffer.Append(value);
}
}

public void AppendLine(string? value = null, bool indent = true)
{
if (string.IsNullOrEmpty(value))
{
buffer.AppendLine();
}
else if (indent)
{
buffer.AppendLine($"{new string(' ', indentLevel * 4)} {value}");
}
else
{
buffer.AppendLine(value);
}
}

public void AppendByteArrayString(byte[] bytes)
{
buffer.Append("{ ");
var first = true;
foreach (var x in bytes)
{
if (!first)
{
buffer.Append(", ");
}
buffer.Append(x);
first = false;
}
buffer.Append(" }");
}

public override string ToString() => buffer.ToString();

public IDisposable BeginIndentScope(string? startLine = null) => new IndentScope(this, startLine);
public IDisposable BeginBlockScope(string? startLine = null) => new BlockScope(this, startLine);

public void IncreaseIndent()
{
indentLevel++;
}

public void DecreaseIndent()
{
if (indentLevel > 0)
indentLevel--;
}

public void BeginBlock()
{
AppendLine("{");
IncreaseIndent();
}

public void EndBlock()
{
DecreaseIndent();
AppendLine("}");
}

public void Clear()
{
buffer.Clear();
}
}
130 changes: 130 additions & 0 deletions VYaml.SourceGenerator/DiagnosticDescriptors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#pragma warning disable RS2008

using Microsoft.CodeAnalysis;

namespace VYaml.SourceGenerator;

static class DiagnosticDescriptors
{
const string Category = "VYaml.SourceGenerator";

public static readonly DiagnosticDescriptor UnexpectedErrorDescriptor = new(
id: "VYAML001",
title: "Unexpected error during source code generation",
messageFormat: "Unexpected error occurred during source code code generation: {0}",
category: "Usage",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor MustBePartial = new(
id: "VYAML002",
title: "VYaml serializable type declaration must be partial",
messageFormat: "The VYaml serializable type declaration '{0}' must be partial",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor NestedNotAllow = new(
id: "VYAML003",
title: "VYaml serializable type must not be nested type",
messageFormat: "The VYaml serializable object '{0}' must be not nested type",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor YamlMemberPropertyMustHaveSetter = new(
id: "VYAML004",
title: "A yaml serializable property with must have setter",
messageFormat: "The VYaml serializable object '{0}' property '{1}' must have setter",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor YamlMemberFieldCannotBeReadonly = new(
id: "VYAML005",
title: "A yaml serializable field cannot be readonly",
messageFormat: "The VYaml serializable object '{0}' field '{1}' cannot be readonly",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor AbstractMustUnion = new(
id: "VYAML006",
title: "abstract/interface type of `[YamlObject]` must annotate with Union",
messageFormat: "abstract/interface type of `[YamlObject]` '{0}' must annotate with Union",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor ConcreteTypeCantBeUnion = new(
id: "VYAML007",
title: "Concrete type can't be union",
messageFormat: "The object that has `[YamlObject]` '{0}' can be Union, only allow abstract or interface",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor UnionTagDuplicate = new(
id: "VYAML008",
title: "Union tag is duplicate",
messageFormat: "The object that has `[YamlObject]` '{0}' union tag value is duplicate",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor UnionMemberTypeNotImplementBaseType = new(
id: "VYAML009",
title: "Union member not implement union interface",
messageFormat: "The object '{0}' union member '{1}' not implment union interface",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor UnionMemberTypeNotDerivedBaseType = new(
id: "VYAML010",
title: "Union member not dervided union base type",
messageFormat: "The object '{0}' union member '{1}' not derived union type",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor UnionMemberNotAllowStruct = new(
id: "VYAML011",
title: "Union member can't be struct",
messageFormat: "The object '{0}' union member '{1}' can't be member, not allows struct",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor UnionMemberMustBeYamlObject = new(
id: "VYAML012",
title: "Union member must be YamlObject",
messageFormat: "The object '{0}' union member '{1}' must be [YamlObject]",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor MultipleConstructorAttribute = new(
id: "VYAML013",
title: "[YamlConstructor] exists in multiple constructors",
messageFormat: "Mupltiple [YamlConstructor] exists in '{0}' but allows only single ctor",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor MultipleConstructorWithoutAttribute = new(
id: "VYAML014",
title: "Require [YamlConstructor] when exists multiple constructors",
messageFormat: "The Yaml object '{0}' must annotate with [YamlConstructor] when exists multiple constructors",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static readonly DiagnosticDescriptor ConstructorHasNoMatchedParameter = new(
id: "VYAML0015",
title: "VYaml's constructor has no matched parameter",
messageFormat: "The VYaml object '{0}' constructor's parameter '{1}' must match a serialized member name(case-insensitive)",
category: Category,
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);
}
Loading

0 comments on commit 3cc4ec8

Please sign in to comment.