Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add incremental source generator #69

Merged
merged 5 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading