Skip to content

Commit

Permalink
Merge pull request #119 from Cysharp/incremental-incremental
Browse files Browse the repository at this point in the history
True Incremental Generator
  • Loading branch information
neuecc authored Jun 12, 2024
2 parents b188553 + addfba1 commit fe2877e
Show file tree
Hide file tree
Showing 27 changed files with 1,532 additions and 200 deletions.
4 changes: 2 additions & 2 deletions ConsoleAppFramework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleAppFramework.Generat
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NativeAot", "sandbox\NativeAot\NativeAot.csproj", "{EC1A3299-6597-4AD2-92DE-EDF309875A97}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppFramework.Abstractions", "src\ConsoleAppFramework.Abstractions\ConsoleAppFramework.Abstractions.csproj", "{855B0D28-DC69-470B-B3D9-481EE52737AA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleAppFramework.Abstractions", "src\ConsoleAppFramework.Abstractions\ConsoleAppFramework.Abstractions.csproj", "{855B0D28-DC69-470B-B3D9-481EE52737AA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilterShareProject", "sandbox\FilterShareProject\FilterShareProject.csproj", "{2A1E8ED1-CEB9-47CB-8497-A0C4F5A8F025}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterShareProject", "sandbox\FilterShareProject\FilterShareProject.csproj", "{2A1E8ED1-CEB9-47CB-8497-A0C4F5A8F025}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
1 change: 1 addition & 0 deletions sandbox/CliFrameworkBenchmark/CliFrameworkBenchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<nullable>annotations</nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPackable>false</IsPackable>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions sandbox/FilterShareProject/FilterShareProject.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 2 additions & 0 deletions sandbox/GeneratorSandbox/GeneratorSandbox.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
<IsPackable>false</IsPackable>

<DefineConstants>USE_EXTERNAL_CONSOLEAPP_ABSTRACTIONS</DefineConstants>

<Configurations>Debug;Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand Down
20 changes: 10 additions & 10 deletions sandbox/GeneratorSandbox/Program.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using ConsoleAppFramework;
using ConsoleAppFramework;

var app = ConsoleApp.Create();

app.Add("aaa", () =>
{
});


args = ["show", "--aaa", "a", "value", "10.2"];

var app = ConsoleApp.Create();
app.Add<Test>();
app.Run(args);

public class Test
app.Add("aabcdefg", int (int x, string y) =>
{
public void Show(string aaa, [Range(0, 1)] double value) => ConsoleApp.Log($"{value}");
}
return default!;
});

app.Run(args);
1 change: 1 addition & 0 deletions sandbox/NativeAot/NativeAot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

<PublishAot>true</PublishAot>
<IsAotCompatible>true</IsAotCompatible>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand Down
7 changes: 6 additions & 1 deletion sandbox/NativeAot/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
using ConsoleAppFramework;

ConsoleApp.Run(args, (int x, int y) => Console.WriteLine(x + y));

var app = ConsoleApp.Create();

//ConsoleApp.Run(args, (int x, int y) => Console.WriteLine(x + y));

app.Run(args);
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<!-- NuGet -->
<PackageId>ConsoleAppFramework.Abstractions</PackageId>
<Description>ConsoleAppFramework external abstractions library.</Description>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>

<ItemGroup>
Expand Down
45 changes: 17 additions & 28 deletions src/ConsoleAppFramework/Command.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using Microsoft.CodeAnalysis;
using System;
using System.Data.Common;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;

namespace ConsoleAppFramework;
Expand All @@ -24,16 +19,16 @@ public record class Command
{
public required bool IsAsync { get; init; } // Task or Task<int>
public required bool IsVoid { get; init; } // void or int

public bool IsRootCommand => Name == "";
public required string Name { get; init; }

public required CommandParameter[] Parameters { get; init; }
public required EquatableArray<CommandParameter> Parameters { get; init; }
public required string Description { get; init; }
public required MethodKind MethodKind { get; init; }
public required DelegateBuildType DelegateBuildType { get; init; }
public CommandMethodInfo? CommandMethodInfo { get; set; } // can set...!
public required FilterInfo[] Filters { get; init; }
public required EquatableArray<FilterInfo> Filters { get; init; }
public bool HasFilter => Filters.Length != 0;

public string? BuildDelegateSignature(out string? delegateType)
Expand Down Expand Up @@ -148,15 +143,16 @@ public string BuildDelegateType(string delegateName)

public record class CommandParameter
{
public required ITypeSymbol Type { get; init; }
public required Location Location { get; init; }
public required EquatableTypeSymbol Type { get; init; }
public required IgnoreEquality<Location> Location { get; init; }
public required IgnoreEquality<WellKnownTypes> WellKnownTypes { get; init; }
public required bool IsNullableReference { get; init; }
public required bool IsParams { get; init; }
public required string Name { get; init; }
public required string OriginalParameterName { get; init; }
public required bool HasDefaultValue { get; init; }
public object? DefaultValue { get; init; }
public required ITypeSymbol? CustomParserType { get; init; }
public required EquatableTypeSymbol? CustomParserType { get; init; }
public required bool IsFromServices { get; init; }
public required bool IsConsoleAppContext { get; init; }
public required bool IsCancellationToken { get; init; }
Expand All @@ -165,15 +161,15 @@ public record class CommandParameter
public required bool HasValidation { get; init; }
public required int ArgumentIndex { get; init; } // -1 is not Argument, other than marked as [Argument]
public bool IsArgument => ArgumentIndex != -1;
public required string[] Aliases { get; init; }
public required EquatableArray<string> Aliases { get; init; }
public required string Description { get; init; }
public bool RequireCheckArgumentParsed => !(HasDefaultValue || IsParams || IsFlag);

// increment = false when passed from [Argument]
public string BuildParseMethod(int argCount, string argumentName, WellKnownTypes wellKnownTypes, bool increment)
public string BuildParseMethod(int argCount, string argumentName, bool increment)
{
var incrementIndex = increment ? "!TryIncrementIndex(ref i, args.Length) || " : "";
return Core(Type, false);
return Core(Type.TypeSymbol, false);

string Core(ITypeSymbol type, bool nullable)
{
Expand Down Expand Up @@ -207,7 +203,7 @@ string Core(ITypeSymbol type, bool nullable)
{
return $"arg{argCount} = args[i];";
}

case SpecialType.System_Boolean:
return $"arg{argCount} = true;"; // bool is true flag
case SpecialType.System_Char:
Expand Down Expand Up @@ -242,7 +238,7 @@ string Core(ITypeSymbol type, bool nullable)
if (type.TypeKind == TypeKind.Array)
{
var elementType = (type as IArrayTypeSymbol)!.ElementType;
var parsable = wellKnownTypes.ISpanParsable;
var parsable = WellKnownTypes.Value.ISpanParsable;
if (parsable != null) // has parsable
{
if (elementType.AllInterfaces.Any(x => x.EqualsUnconstructedGenericType(parsable)))
Expand All @@ -254,12 +250,12 @@ string Core(ITypeSymbol type, bool nullable)
}

// System.DateTimeOffset, System.Guid, System.Version
tryParseKnownPrimitive = wellKnownTypes.HasTryParse(type);
tryParseKnownPrimitive = WellKnownTypes.Value.HasTryParse(type);

if (!tryParseKnownPrimitive)
{
// ISpanParsable<T> (BigInteger, Complex, Half, Int128, etc...)
var parsable = wellKnownTypes.ISpanParsable;
var parsable = WellKnownTypes.Value.ISpanParsable;
if (parsable != null) // has parsable
{
tryParseIParsable = type.AllInterfaces.Any(x => x.EqualsUnconstructedGenericType(parsable));
Expand Down Expand Up @@ -316,13 +312,6 @@ public string DefaultValueToString(bool castValue = true, bool enumIncludeTypeNa
return $"({Type.ToFullyQualifiedFormatDisplayString()}){DefaultValue}";
}

public string? GetEnumSymbolName(object value)
{
var symbol = Type.GetMembers().OfType<IFieldSymbol>().FirstOrDefault(x => x.ConstantValue == value);
if (symbol == null) return "";
return symbol.Name;
}

public string ToTypeDisplayString()
{
var t = Type.ToFullyQualifiedFormatDisplayString();
Expand Down Expand Up @@ -359,7 +348,7 @@ public record class CommandMethodInfo
{
public required string TypeFullName { get; init; }
public required string MethodName { get; init; }
public required ITypeSymbol[] ConstructorParameterTypes { get; init; }
public required EquatableArray<EquatableTypeSymbol> ConstructorParameterTypes { get; init; }
public required bool IsIDisposable { get; init; }
public required bool IsIAsyncDisposable { get; init; }

Expand All @@ -378,7 +367,7 @@ public string BuildNew()
public record class FilterInfo
{
public required string TypeFullName { get; init; }
public required ITypeSymbol[] ConstructorParameterTypes { get; init; }
public required EquatableArray<EquatableTypeSymbol> ConstructorParameterTypes { get; init; }

FilterInfo()
{
Expand All @@ -400,7 +389,7 @@ public record class FilterInfo
var filter = new FilterInfo
{
TypeFullName = type.ToFullyQualifiedFormatDisplayString(),
ConstructorParameterTypes = publicConstructors[0].Parameters.Select(x => x.Type).ToArray()
ConstructorParameterTypes = publicConstructors[0].Parameters.Select(x => new EquatableTypeSymbol(x.Type)).ToArray()
};

return filter;
Expand Down
8 changes: 6 additions & 2 deletions src/ConsoleAppFramework/ConsoleAppFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<IncludeSymbols>false</IncludeSymbols>
<DevelopmentDependency>true</DevelopmentDependency>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>

<!-- NuGet -->
<PackageId>ConsoleAppFramework</PackageId>
<Description>Zero Dependency, Zero Overhead, Zero Reflection, Zero Allocation, AOT Safe CLI Framework powered by C# Source Generator.</Description>
<Configurations>Debug;Release</Configurations>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" />
<!-- Roslyn for .NET 8 / C# 12 -->
<!-- https://learn.microsoft.com/en-us/visualstudio/extensibility/roslyn-version-support -->
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
<PackageReference Include="PolySharp" Version="1.14.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading

0 comments on commit fe2877e

Please sign in to comment.