-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
support for method invocation ref & out modifiers (ex. TryParse("one"…
…, out int one)) support for tuple deconstruction (including nested kinds) var (x,y) = (1,2) & (var x, var y) = (1,2) & (var x, (var a, var b)) = (1,(2,3)) implicit array initializers new []{1,2,3} entirely new lst model for dealing with using statements (similar to java's try-with-resources) new Rewrite.Analyzers project that takes uses native .net code generation for all enums such asCsSpace, CsRightPadded, CsContainer, CsLeftPadded . code is contributed at compile time rather then design time, so no autogenerated files need to be checked in nor generator rerun explicitly - it's called automatically as part of build. It also generates a ToString() overload for all LST types to produce output from printer major improvement to c# project parser, nearly tripling its parsing speed by adding some parallel processing when using local printer, tests can now run in parallel vastly speeding up their execution (entire test suite now executes in under 5 seconds)
- Loading branch information
Showing
105 changed files
with
3,687 additions
and
826 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<SolutionConfiguration> | ||
<Settings> | ||
<AllowParallelTestExecution>False</AllowParallelTestExecution> | ||
<EnableRDI>True</EnableRDI> | ||
<RdiConfigured>True</RdiConfigured> | ||
<SolutionConfigured>True</SolutionConfigured> | ||
</Settings> | ||
</SolutionConfiguration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rewrite.Analyzers", "Rewrite.Analyzers.csproj", "{A9BDECE3-D39F-48AE-A94E-B546887F5EC2}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rewrite.CSharp", "..\Rewrite.CSharp\Rewrite.CSharp.csproj", "{E18B9AF4-A15B-4A68-AD48-6F4795DAFA38}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{A9BDECE3-D39F-48AE-A94E-B546887F5EC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{A9BDECE3-D39F-48AE-A94E-B546887F5EC2}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{A9BDECE3-D39F-48AE-A94E-B546887F5EC2}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{A9BDECE3-D39F-48AE-A94E-B546887F5EC2}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{E18B9AF4-A15B-4A68-AD48-6F4795DAFA38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{E18B9AF4-A15B-4A68-AD48-6F4795DAFA38}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{E18B9AF4-A15B-4A68-AD48-6F4795DAFA38}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
using System.Text; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.Text; | ||
|
||
namespace Rewrite.Analyzers; | ||
|
||
[Generator] | ||
public class EnumGenerator : ISourceGenerator | ||
{ | ||
public void Initialize(GeneratorInitializationContext context) | ||
{ | ||
context.RegisterForSyntaxNotifications(() => new SyntaxScanner()); | ||
} | ||
|
||
public void Execute(GeneratorExecutionContext context) | ||
{ | ||
var scanner = (SyntaxScanner)context.SyntaxReceiver!; | ||
|
||
scanner.CsRightPaddedEnumValues.UnionWith(scanner.CsContainerEnumValues); | ||
scanner.CsSpaceEnumValues.UnionWith(scanner.CsContainerEnumValues); | ||
scanner.CsSpaceEnumValues.UnionWith(scanner.CsRightPaddedEnumValues); | ||
scanner.CsSpaceEnumValues.UnionWith(scanner.CsLeftPaddedEnumValues); | ||
// scanner.CsLeftPaddedEnumValues.UnionWith(scanner.CsContainerEnumValues); | ||
var csContainerSrc = $$""" | ||
namespace Rewrite.RewriteCSharp.Tree; | ||
public interface CsContainer | ||
{ | ||
public record Location(CsSpace.Location BeforeLocation, CsRightPadded.Location ElementLocation) | ||
{ | ||
{{ scanner.CsContainerEnumValues.Render(enumValue => $$""" | ||
public static readonly Location {{enumValue}} = new(CsSpace.Location.{{enumValue}}, CsRightPadded.Location.{{enumValue}}); | ||
""", "\n").Ident(2) }} | ||
} | ||
} | ||
"""; | ||
var csSpaceSrc = $$""" | ||
namespace Rewrite.RewriteCSharp.Tree; | ||
public interface CsSpace | ||
{ | ||
public record Location | ||
{ | ||
{{ scanner.CsSpaceEnumValues.Render(enumValue => $$""" | ||
public static readonly Location {{enumValue}} = new(); | ||
""", "\n").Ident(2) }} | ||
} | ||
} | ||
"""; | ||
|
||
var csRightPaddedSrc = $$""" | ||
namespace Rewrite.RewriteCSharp.Tree; | ||
public interface CsRightPadded | ||
{ | ||
public record Location(CsSpace.Location AfterLocation) | ||
{ | ||
{{ scanner.CsRightPaddedEnumValues.Render(enumValue => $$""" | ||
public static readonly Location {{enumValue}} = new (CsSpace.Location.{{enumValue}}); | ||
""", "\n").Ident(2) }} | ||
} | ||
} | ||
"""; | ||
|
||
var csLeftPaddedSrc = $$""" | ||
namespace Rewrite.RewriteCSharp.Tree; | ||
public interface CsLeftPadded | ||
{ | ||
public record Location(CsSpace.Location BeforeLocation) | ||
{ | ||
{{ scanner.CsLeftPaddedEnumValues.Render(enumValue => $$""" | ||
public static readonly Location {{enumValue}} = new (CsSpace.Location.{{enumValue}}); | ||
""", "\n").Ident(2) }} | ||
} | ||
} | ||
"""; | ||
if(scanner.CsContainerEnumValues.Count > 0) | ||
context.AddSource("CsContainer.gs", SourceText.From(csContainerSrc, Encoding.UTF8)); | ||
if(scanner.CsRightPaddedEnumValues.Count > 0) | ||
context.AddSource("CsRightPadded.gs", SourceText.From(csRightPaddedSrc, Encoding.UTF8)); | ||
if(scanner.CsLeftPaddedEnumValues.Count > 0) | ||
context.AddSource("CsLeftPadded.gs", SourceText.From(csLeftPaddedSrc, Encoding.UTF8)); | ||
if(scanner.CsSpaceEnumValues.Count > 0) | ||
context.AddSource("CsSpace.gs", SourceText.From(csSpaceSrc, Encoding.UTF8)); | ||
} | ||
public class SyntaxScanner : ISyntaxReceiver | ||
{ | ||
public HashSet<string> CsContainerEnumValues { get; } = new(); | ||
public HashSet<string> CsRightPaddedEnumValues { get; } = new(); | ||
public HashSet<string> CsLeftPaddedEnumValues { get; } = new(); | ||
public HashSet<string> CsSpaceEnumValues { get; } = new(); | ||
public string? AssemblyFileVersion { get; set; } | ||
|
||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode) | ||
{ | ||
if (syntaxNode is MemberAccessExpressionSyntax | ||
{ | ||
Expression: MemberAccessExpressionSyntax | ||
{ | ||
Expression: IdentifierNameSyntax { Identifier.Text: "CsContainer" }, | ||
Name: IdentifierNameSyntax { Identifier.Text: "Location" }, | ||
} | ||
} csContainerLocation) | ||
{ | ||
|
||
CsContainerEnumValues.Add(csContainerLocation.Name.Identifier.Text); | ||
} | ||
|
||
if (syntaxNode is MemberAccessExpressionSyntax | ||
{ | ||
Expression: MemberAccessExpressionSyntax | ||
{ | ||
Expression: IdentifierNameSyntax { Identifier.Text: "CsRightPadded" }, | ||
Name: IdentifierNameSyntax { Identifier.Text: "Location" }, | ||
} | ||
} csRightPaddedLocation) | ||
{ | ||
|
||
CsRightPaddedEnumValues.Add(csRightPaddedLocation.Name.Identifier.Text); | ||
} | ||
if (syntaxNode is MemberAccessExpressionSyntax | ||
{ | ||
Expression: MemberAccessExpressionSyntax | ||
{ | ||
Expression: IdentifierNameSyntax { Identifier.Text: "CsLeftPadded" }, | ||
Name: IdentifierNameSyntax { Identifier.Text: "Location" }, | ||
} | ||
} csLeftPaddedLocation) | ||
{ | ||
|
||
CsLeftPaddedEnumValues.Add(csLeftPaddedLocation.Name.Identifier.Text); | ||
} | ||
if (syntaxNode is MemberAccessExpressionSyntax | ||
{ | ||
Expression: MemberAccessExpressionSyntax | ||
{ | ||
Expression: IdentifierNameSyntax { Identifier.Text: "CsSpace" }, | ||
Name: IdentifierNameSyntax { Identifier.Text: "Location" }, | ||
} | ||
} csSpaceLocation) | ||
{ | ||
|
||
CsSpaceEnumValues.Add(csSpaceLocation.Name.Identifier.Text); | ||
} | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace Rewrite.Analyzers; | ||
|
||
public static class Extensions | ||
{ | ||
public static bool InheritsFrom(this INamedTypeSymbol symbol, string type) | ||
{ | ||
var current = symbol.BaseType; | ||
while (current != null) | ||
{ | ||
if (current.Name == type) | ||
return true; | ||
current = current.BaseType; | ||
} | ||
return false; | ||
} | ||
public static string Ident(this object source, int identLevels) | ||
{ | ||
var lines = source.ToString().TrimStart(' ').Split('\n'); | ||
var ident = new string(' ', identLevels * 4); | ||
return string.Join("\n", lines.Select((x, i) => $"""{ (i > 0 ? ident : "") }{x}""")); | ||
} | ||
|
||
public static string Render<T>(this IEnumerable<T> source, Func<T, string> template, string separator = "", string openToken = "", string closeToken = "", bool renderEmpty = true) | ||
{ | ||
if (!renderEmpty && source.Count() == 0) | ||
return ""; | ||
return $"{openToken}{string.Join(separator, source.Select(template))}{closeToken}"; | ||
} | ||
|
||
public static string Render<T>(this IEnumerable<T> source, Func<T, int, string> template, string separator = "") | ||
{ | ||
return string.Join(separator, source.Select(template)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using System.Text; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.Text; | ||
|
||
namespace Rewrite.Analyzers; | ||
|
||
[Generator] | ||
public class LstToGenerator : ISourceGenerator | ||
{ | ||
public void Initialize(GeneratorInitializationContext context) | ||
{ | ||
context.RegisterForSyntaxNotifications(() => new SyntaxScanner()); | ||
} | ||
|
||
public void Execute(GeneratorExecutionContext context) | ||
{ | ||
var scanner = (SyntaxScanner)context.SyntaxReceiver!; | ||
string GetSrc(List<ClassDeclarationSyntax> classes, string parent) | ||
{ | ||
var ns = parent == "J" ? "RewriteJava" : "RewriteCSharp"; | ||
return $$""" | ||
using Rewrite.Core; | ||
using Rewrite.RewriteJava.Tree; | ||
namespace Rewrite.{{ns}}.Tree | ||
{ | ||
public partial interface {{parent}} | ||
{ | ||
{{ classes.Render(c => $$""" | ||
partial class {{c.Identifier}}{{c.TypeParameterList?.Parameters.Render(p => p.Identifier.Text, ",", "<", ">", renderEmpty: false)}} | ||
{ | ||
public override string? ToString() => Core.Tree.ToString(this) ?? base.ToString(); | ||
} | ||
""", "\n").Ident(2) }} | ||
} | ||
} | ||
"""; | ||
} | ||
if(scanner.CsClasses.Count > 0) | ||
context.AddSource("CsLstToString.gs", SourceText.From(GetSrc(scanner.CsClasses.Values.ToList(), "Cs"), Encoding.UTF8)); | ||
if(scanner.JClasses.Count > 0) | ||
context.AddSource("JLstToString.gs", SourceText.From(GetSrc(scanner.JClasses.Values.ToList(), "J"), Encoding.UTF8)); | ||
|
||
} | ||
public class SyntaxScanner : ISyntaxReceiver | ||
{ | ||
public Dictionary<string, ClassDeclarationSyntax> CsClasses { get; } = new(); | ||
public Dictionary<string, ClassDeclarationSyntax> JClasses { get; } = new(); | ||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode) | ||
{ | ||
if (syntaxNode is ClassDeclarationSyntax | ||
{ | ||
Parent: InterfaceDeclarationSyntax | ||
{ | ||
Identifier.Text: "Cs" or "J" , | ||
} parent | ||
} classDeclaration) | ||
{ | ||
if (parent.Identifier.Text == "J") | ||
JClasses[classDeclaration.Identifier.Text] = classDeclaration; | ||
else | ||
CsClasses[classDeclaration.Identifier.Text] = classDeclaration; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/launchsettings.json", | ||
"profiles": { | ||
"Generators": { | ||
"commandName": "DebugRoslynComponent", | ||
"targetProject": "../Rewrite.CSharp/Rewrite.CSharp.csproj" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules> | ||
<IncludeBuildOutput>false</IncludeBuildOutput> <!-- disable convention based nuget creation - we're controlling it fully manually --> | ||
<NoWarn>NU5128</NoWarn> | ||
<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" > | ||
<PrivateAssets>all</PrivateAssets> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
</PackageReference> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" PrivateAssets="all"/> | ||
<PackageReference Include="YamlDotNet" Version="16.0.0" GeneratePathProperty="true" PrivateAssets="all" /> | ||
|
||
</ItemGroup> | ||
<Target Name="GetDependencyTargetPaths"> | ||
<ItemGroup> | ||
<!-- <TargetPathWithTargetPlatformMoniker Include="$(PKGYamlDotNet)\lib\netstandard2.0\YamlDotNet.dll" IncludeRuntimeDependency="false" />--> | ||
</ItemGroup> | ||
</Target> | ||
<ItemGroup> | ||
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" /> | ||
<!-- <None Include="$(PKGYamlDotNet)\lib\netstandard2.0\YamlDotNet.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />--> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.