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

format code with dotnet-format #11

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
131 changes: 71 additions & 60 deletions src/CompileTimeComputation/src/CompileTimeComputationGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,79 +63,90 @@ public static void Execute(SourceProductionContext context, (ImmutableArray<Fiel
var constDeclaration =
HeaderTemplate.Render(new { Filename = filename }) +
$$$"""
namespace {{{fieldSymbol.ContainingType.ContainingNamespace.ToDisplayString()}}};

public {{{(fieldSymbol.ContainingType.IsStatic ? "static" : "")}}} partial {{{(fieldSymbol.ContainingType.IsRecord ? "record" : "")}}} {{{(fieldSymbol.ContainingType.TypeKind == TypeKind.Class ? "class" : fieldSymbol.ContainingType.TypeKind == TypeKind.Struct ? "struct" : $"#error Wrong data structure type: {fieldSymbol.ContainingType.TypeKind}")}}} {{{fieldSymbol.ContainingType.Name}}}
{
public const {{{fieldSymbol.ToDisplayString()}}} {{{name}}} = {{{(fieldType.Name.Equals("string", InvariantCultureIgnoreCase) ? "\"" : "")}}} {{{funcResult}}} {{{(fieldSymbol.Name.Equals("string", InvariantCultureIgnoreCase) ? "\"" : "")}}};
namespace {{{fieldSymbol.ContainingType.ContainingNamespace.ToDisplayString() }
}};

public
{ { { (fieldSymbol.ContainingType.IsStatic ? "static" : "")} } }
partial
{ { { (fieldSymbol.ContainingType.IsRecord ? "record" : "")} } }
{ { { (fieldSymbol.ContainingType.TypeKind == TypeKind.Class ? "class" : fieldSymbol.ContainingType.TypeKind == TypeKind.Struct ? "struct" : $"#error Wrong data structure type: {fieldSymbol.ContainingType.TypeKind}")} } }
{ { { fieldSymbol.ContainingType.Name} } }
{
public const { { { fieldSymbol.ToDisplayString()} } }
{ { { name} } } = { { { (fieldType.Name.Equals("string", InvariantCultureIgnoreCase) ? "\"" : "")} } }
{ { { funcResult} } }
{ { { (fieldSymbol.Name.Equals("string", InvariantCultureIgnoreCase) ? "\"" : "")} } };
}
""";

// Add the class and const variable declarations to the compilation
context.AddSource(filename, constDeclaration);
}
else
{
context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor("CTCG002", "Error generatimg compile-time computed constant: must be const-able",
Format(CTCG002ErrorMessage, fieldSymbolDisplay),
"CTCG002: Field must be const-able", DiagnosticSeverity.Error, true),
fieldSymbol.Locations.FirstOrDefault()));

// Add the class and const variable declarations to the compilation
context.AddSource(filename, constDeclaration);
}
else
{
context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor("CTCG002", "Error generatimg compile-time computed constant: must be const-able",
Format(CTCG002ErrorMessage, fieldSymbolDisplay),
"CTCG002: Field must be const-able", DiagnosticSeverity.Error, true),
fieldSymbol.Locations.FirstOrDefault()));
}
}
}

private static object CompileAndRunFunc(SourceProductionContext context, Compilation compilation, INamedTypeSymbol returnType, IFieldSymbol fieldSymbol)
{
try
{
var programClassName = $"Program_{guid.NewGuid().ToString().Substring(0, 4)}";
var code =
$$$"""
private static object CompileAndRunFunc(SourceProductionContext context, Compilation compilation, INamedTypeSymbol returnType, IFieldSymbol fieldSymbol)
{
try
{
var programClassName = $"Program_{guid.NewGuid().ToString().Substring(0, 4)}";
var code =
$$$"""
using System;
public class {{{programClassName}}}
public class {{ { programClassName} }}
{
public static {{{returnType.ToDisplayString()}}} Run()
{
return {{{fieldSymbol.ContainingType.ToDisplayString()}}}.{{{fieldSymbol.Name}}}.Compute();
}
public static
{ { { returnType.ToDisplayString()} } }
Run()
{
return { { { fieldSymbol.ContainingType.ToDisplayString()} } }.{ { { fieldSymbol.Name} } }.Compute();
}
}
""";

var parseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview);
var syntaxTree = CSharpSyntaxTree.ParseText(code, parseOptions);
compilation = compilation.AddSyntaxTrees(syntaxTree)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
using var peStream = new MemoryStream();
using var pdbSream = new MemoryStream();
var assembly = compilation.Emit(peStream, pdbSream, options: new EmitOptions(false, DebugInformationFormat.Pdb, tolerateErrors: true, includePrivateMembers: true, pdbChecksumAlgorithm: HashAlgorithmName.SHA512), cancellationToken: default);
if (assembly.Success)
{
peStream.Flush();
var dynamicAssembly = Assembly.Load(peStream.GetBuffer());
var programType = dynamicAssembly.GetType(programClassName);
var methodInfo = programType.GetMethod("Run");
return methodInfo.Invoke(null, null);
}
else
{
foreach (var diagnostic in assembly.Diagnostics)
{
context.ReportDiagnostic(diagnostic);
}
}
var parseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview);
var syntaxTree = CSharpSyntaxTree.ParseText(code, parseOptions);

compilation = compilation.AddSyntaxTrees(syntaxTree)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));

using var peStream = new MemoryStream();
using var pdbSream = new MemoryStream();
var assembly = compilation.Emit(peStream, pdbSream, options: new EmitOptions(false, DebugInformationFormat.Pdb, tolerateErrors: true, includePrivateMembers: true, pdbChecksumAlgorithm: HashAlgorithmName.SHA512), cancellationToken: default);
if (assembly.Success)
{
peStream.Flush();

var dynamicAssembly = Assembly.Load(peStream.GetBuffer());
var programType = dynamicAssembly.GetType(programClassName);
var methodInfo = programType.GetMethod("Run");

return methodInfo.Invoke(null, null);
}
else
{
foreach (var diagnostic in assembly.Diagnostics)
{
context.ReportDiagnostic(diagnostic);
}
}
}
catch (Exception ex)
{
RegisterPostInitializationOutput(ctx => ctx.AddSource("error.g.cs", $@"/*
catch (Exception ex)
{
RegisterPostInitializationOutput(ctx => ctx.AddSource("error.g.cs", $@"/*
{ex.GetType()}: {ex.Message}
{ex.StackTrace}
*/"));
}
return "NO RESULT";
*/"));
}
return "NO RESULT";
}
}
25 changes: 14 additions & 11 deletions src/CompileTimeComputation/src/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,20 @@ public static class Constants

public const string CompileTimeComputationClassDeclaration =
$$$"""
{{{GeneratedCodeAttributes}}}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
public sealed class {{{CompileTimeComputationOfT}}} : Attribute
{
public {{{CompileTimeComputation}}}(string name)
{
Name = name;
}


public string Name { get; }
{{{GeneratedCodeAttributes
}
}}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
public sealed class {{ { CompileTimeComputationOfT} }} : Attribute
{
public
{ { { CompileTimeComputation} } } (string name)
{
Name = name;
}


public string Name { get; }
}
""";
}