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 #13

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
39 changes: 24 additions & 15 deletions src/CompileTimeComputation/src/CompileTimeComputationGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,24 +66,33 @@ public static void Execute(SourceProductionContext context, (ImmutableArray<Fiel
var constDeclaration =
HeaderTemplate.Render(new { Filename = filename }) +
$$$"""
namespace {{{fieldSymbol.ContainingType.ContainingNamespace.ToDisplayString()}}};

{{{fieldSymbol.ContainingType.DeclaredAccessibility.ToString().ToLower().Replace("or", " ").Replace("and", " ")}}} {{{(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(nameof(String), InvariantCultureIgnoreCase) ? "\"" : "")}}}{{{funcResult}}}{{{(fieldSymbol.Name.Equals(nameof(String), InvariantCultureIgnoreCase) ? "\"" : "")}}};
namespace {{{fieldSymbol.ContainingType.ContainingNamespace.ToDisplayString() }
}};

{ { { fieldSymbol.ContainingType.DeclaredAccessibility.ToString().ToLower().Replace("or", " ").Replace("and", " ")} } }
{ { { (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(nameof(String), InvariantCultureIgnoreCase) ? "\"" : "")} } }
{ { { funcResult} } }
{ { { (fieldSymbol.Name.Equals(nameof(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()));
}
}
}
}
23 changes: 13 additions & 10 deletions src/CompileTimeComputation/src/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,19 @@ public static class Constants

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

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

public string Name { get; }
}
""";
}
80 changes: 41 additions & 39 deletions src/Extensions/MemberSymbolExtensions/MemberSymbolExtenisons.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,52 +35,54 @@ public static object InvokeStaticMethod(this IMethodSymbol methodSymbol, Compila
$$"""
using System;

public static class {{programClassName}}
{
public static object Run() => {{methodSymbol.ContainingType.ToDisplayString()}}.{{methodSymbol.Name}}({{Join(", ", arguments.Select(arg => $"{(arg is string ? "\"" : "")}{arg}{(arg is string ? "\"" : "")}"))}});
}
""";
public static class {{programClassName
}
}
{
public static object Run() => { { methodSymbol.ContainingType.ToDisplayString()} }.{ { methodSymbol.Name} } ({ { Join(", ", arguments.Select(arg => $"{(arg is string ? "\"" : "")}{arg}{(arg is string ? "\"" : "")}"))} });
}
""";
return AddToCompilatonAndCallRun(compilation, program, programClassName);
}

public static object GetStaticPropertyValue(this IPropertySymbol propertySymbol, Compilation compilation)
{
if (!propertySymbol.IsStatic || propertySymbol.DeclaredAccessibility != Accessibility.Public)
{
throw new InvalidOperationException($"The property {propertySymbol.ToDisplayString()} must be public and static.");
}
var programClassName = $"Program_{guid.NewGuid().ToByteArray().ToHexString()}";
var program =
public static object GetStaticPropertyValue(this IPropertySymbol propertySymbol, Compilation compilation)
{
if (!propertySymbol.IsStatic || propertySymbol.DeclaredAccessibility != Accessibility.Public)
{
throw new InvalidOperationException($"The property {propertySymbol.ToDisplayString()} must be public and static.");
}
var programClassName = $"Program_{guid.NewGuid().ToByteArray().ToHexString()}";
var program =
$$"""
using System;

public static class {{programClassName}}
{
public static object Run() => {{propertySymbol.ContainingType.ToDisplayString()}}.{{propertySymbol.Name}};
}
""";
public static class {{ programClassName}}
{
public static object Run() => { { propertySymbol.ContainingType.ToDisplayString()} }.{ { propertySymbol.Name} };
}
""";
return AddToCompilatonAndCallRun(compilation, program, programClassName);
}

private static object AddToCompilatonAndCallRun(Compilation compilation, string cSharpCode, string programClassName)
{
compilation = compilation.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(cSharpCode, compilation.SyntaxTrees.First().Options));
return EmitAndCallRun(compilation, programClassName, cSharpCode);
}
private static object EmitAndCallRun(Compilation compilation, string programClassName, string? extraInfo = "")
{
using var asmStream = new MemoryStream();
var emitResult = compilation.Emit(asmStream, options: new EmitOptions(false, debugInformationFormat: DebugInformationFormat.Embedded));
if (!emitResult.Success)
{
var errorDiagnostic = emitResult.Diagnostics.FirstOrDefault(diag => diag.Severity == DiagnosticSeverity.Error);
throw new CompilationException($"{programClassName}: {errorDiagnostic?.GetMessage()}{(!IsNullOrEmpty(extraInfo) ? ", *" : "")}{extraInfo?.Replace("\n", " ").Replace("\r", " ")}{(!IsNullOrEmpty(extraInfo) ? "*" : "")}");
}
asmStream.Flush();
var asm = Assembly.Load(asmStream.GetBuffer());
var programClass = Find(asm.GetExportedTypes(), t => t.Name == programClassName);
var runMethod = programClass.GetMethod("Run");
return runMethod.Invoke(null, null);
}
private static object AddToCompilatonAndCallRun(Compilation compilation, string cSharpCode, string programClassName)
{
compilation = compilation.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(cSharpCode, compilation.SyntaxTrees.First().Options));
return EmitAndCallRun(compilation, programClassName, cSharpCode);
}

private static object EmitAndCallRun(Compilation compilation, string programClassName, string? extraInfo = "")
{
using var asmStream = new MemoryStream();
var emitResult = compilation.Emit(asmStream, options: new EmitOptions(false, debugInformationFormat: DebugInformationFormat.Embedded));
if (!emitResult.Success)
{
var errorDiagnostic = emitResult.Diagnostics.FirstOrDefault(diag => diag.Severity == DiagnosticSeverity.Error);
throw new CompilationException($"{programClassName}: {errorDiagnostic?.GetMessage()}{(!IsNullOrEmpty(extraInfo) ? ", *" : "")}{extraInfo?.Replace("\n", " ").Replace("\r", " ")}{(!IsNullOrEmpty(extraInfo) ? "*" : "")}");
}
asmStream.Flush();
var asm = Assembly.Load(asmStream.GetBuffer());
var programClass = Find(asm.GetExportedTypes(), t => t.Name == programClassName);
var runMethod = programClass.GetMethod("Run");
return runMethod.Invoke(null, null);
}
}