-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from ufcpp/roslyn_3_9_0
Roslyn 3 9 0
- Loading branch information
Showing
8 changed files
with
230 additions
and
174 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"profiles": { | ||
"StringLiteralGenerator": { | ||
"commandName": "DebugRoslynComponent", | ||
"targetProject": "..\\..\\samples\\StringLiteralSample\\StringLiteralSample.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
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,26 @@ | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace StringLiteralGenerator; | ||
|
||
public partial class Utf8StringLiteralGenerator | ||
{ | ||
private record struct TypeInfo(string? Namespace, string Name) | ||
{ | ||
public TypeInfo(INamedTypeSymbol t) | ||
: this(GetNamespace(t), t.Name) | ||
{ } | ||
|
||
private static string? GetNamespace(INamedTypeSymbol t) | ||
{ | ||
var x = t.ContainingNamespace; | ||
return string.IsNullOrEmpty(x.Name) ? null : x.ToDisplayString(); | ||
} | ||
} | ||
|
||
private record struct MethodInfo(string Name, Accessibility Accessibility, string Text) | ||
{ | ||
public MethodInfo(IMethodSymbol m, string text) | ||
: this(m.Name, m.DeclaredAccessibility, text) | ||
{ } | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
src/StringLiteralGenerator/Utf8StringLiteralGenerator.Emitter.cs
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,84 @@ | ||
using Microsoft.CodeAnalysis; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace StringLiteralGenerator; | ||
|
||
public partial class Utf8StringLiteralGenerator : ISourceGenerator | ||
{ | ||
private static string GetFilename(TypeInfo type, StringBuilder buffer) | ||
{ | ||
buffer.Clear(); | ||
|
||
if (type.Namespace is { } ns) | ||
{ | ||
buffer.Append(ns.Replace('.', '_')); | ||
buffer.Append('_'); | ||
} | ||
buffer.Append(type.Name); | ||
buffer.Append("_utf8literal.cs"); | ||
|
||
return buffer.ToString(); | ||
} | ||
|
||
private static string Generate(TypeInfo type, IEnumerable<MethodInfo> methods, StringBuilder buffer) | ||
{ | ||
var (ns, name) = type; | ||
|
||
buffer.Clear(); | ||
buffer.AppendLine("// <auto-generated />"); | ||
|
||
if (ns is not null) | ||
{ | ||
buffer.Append(@"namespace "); | ||
buffer.Append(ns); | ||
buffer.Append(@" | ||
{ | ||
"); | ||
} | ||
buffer.Append(@"partial class "); | ||
buffer.Append(name); | ||
buffer.Append(@" | ||
{ | ||
"); | ||
foreach (var (methodName, accessibility, value) in methods) | ||
{ | ||
buffer.Append(" "); | ||
buffer.Append(AccessibilityText(accessibility)); | ||
buffer.Append(" static partial System.ReadOnlySpan<byte> "); | ||
buffer.Append(methodName); | ||
buffer.Append("() => new byte[] {"); | ||
|
||
foreach (var b in Encoding.UTF8.GetBytes(value)) | ||
{ | ||
buffer.Append(b); | ||
buffer.Append(", "); | ||
} | ||
|
||
buffer.Append(@"}; | ||
"); | ||
} | ||
|
||
buffer.Append(@"} | ||
"); | ||
if (ns is not null) | ||
{ | ||
buffer.Append(@"} | ||
"); | ||
} | ||
|
||
return buffer.ToString(); | ||
} | ||
|
||
private static string AccessibilityText(Accessibility accessibility) => accessibility switch | ||
{ | ||
Accessibility.Public => "public", | ||
Accessibility.Protected => "protected", | ||
Accessibility.Private => "private", | ||
Accessibility.Internal => "internal", | ||
Accessibility.ProtectedOrInternal => "protected internal", | ||
Accessibility.ProtectedAndInternal => "private protected", | ||
_ => throw new InvalidOperationException(), | ||
}; | ||
} |
26 changes: 26 additions & 0 deletions
26
src/StringLiteralGenerator/Utf8StringLiteralGenerator.Init.cs
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,26 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.Text; | ||
using System.Text; | ||
|
||
namespace StringLiteralGenerator; | ||
|
||
public partial class Utf8StringLiteralGenerator : ISourceGenerator | ||
{ | ||
private const string attributeText = @"// <auto-generated /> | ||
using System; | ||
namespace StringLiteral | ||
{ | ||
[System.Diagnostics.Conditional(""COMPILE_TIME_ONLY"")] | ||
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] | ||
sealed class Utf8Attribute : Attribute | ||
{ | ||
public Utf8Attribute(string s) { } | ||
} | ||
} | ||
"; | ||
|
||
private static void AddAttribute(GeneratorPostInitializationContext context) | ||
{ | ||
context.AddSource("Utf8Attribute", SourceText.From(attributeText, Encoding.UTF8)); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/StringLiteralGenerator/Utf8StringLiteralGenerator.Parser.cs
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,43 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
namespace StringLiteralGenerator; | ||
|
||
public partial class Utf8StringLiteralGenerator : ISourceGenerator | ||
{ | ||
private const string attributeName = "StringLiteral.Utf8Attribute"; | ||
|
||
private static bool IsStaticPartial(MemberDeclarationSyntax m) | ||
{ | ||
bool isStatic = false; | ||
bool isPartial = false; | ||
foreach (var mod in m.Modifiers) | ||
{ | ||
isStatic |= mod.Text == "static"; | ||
isPartial |= mod.Text == "partial"; | ||
} | ||
return isStatic && isPartial; | ||
} | ||
|
||
static bool ReturnsString(IMethodSymbol methodSymbol) | ||
{ | ||
return methodSymbol.ReturnType is INamedTypeSymbol s | ||
&& s.ToDisplayString() == "System.ReadOnlySpan<byte>"; | ||
} | ||
|
||
static string? GetUtf8Attribute(IMethodSymbol methodSymbol) | ||
{ | ||
foreach (var a in methodSymbol.GetAttributes()) | ||
{ | ||
if (a.AttributeClass?.ToDisplayString() == attributeName) | ||
{ | ||
var args = a.ConstructorArguments; | ||
if (args.Length != 1) continue; | ||
|
||
if (args[0].Value is string value) return value; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
Oops, something went wrong.