Skip to content

Commit

Permalink
Generator changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpar committed Jun 8, 2022
1 parent 3cc587e commit 909709a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,15 @@ public partial class RegexGenerator
private const string RegexGeneratorAttributeName = "System.Text.RegularExpressions.RegexGeneratorAttribute";

private static bool IsSyntaxTargetForGeneration(SyntaxNode node, CancellationToken cancellationToken) =>
// We don't have a semantic model here, so the best we can do is say whether there are any attributes.
node is MethodDeclarationSyntax { AttributeLists: { Count: > 0 } };

private static bool IsSemanticTargetForGeneration(SemanticModel semanticModel, MethodDeclarationSyntax methodDeclarationSyntax, CancellationToken cancellationToken)
{
foreach (AttributeListSyntax attributeListSyntax in methodDeclarationSyntax.AttributeLists)
{
foreach (AttributeSyntax attributeSyntax in attributeListSyntax.Attributes)
{
if (semanticModel.GetSymbolInfo(attributeSyntax, cancellationToken).Symbol is IMethodSymbol attributeSymbol &&
attributeSymbol.ContainingType.ToDisplayString() == RegexGeneratorAttributeName)
{
return true;
}
}
}

return false;
}
node is MethodDeclarationSyntax;

// Returns null if nothing to do, Diagnostic if there's an error to report, or RegexType if the type was analyzed successfully.
private static object? GetSemanticTargetForGeneration(GeneratorSyntaxContext context, CancellationToken cancellationToken)
private static object? GetSemanticTargetForGeneration(GeneratorAttributeSyntaxContext context, CancellationToken cancellationToken)
{
var methodSyntax = (MethodDeclarationSyntax)context.Node;
Debug.Assert(!context.Attributes.IsDefaultOrEmpty);
var methodSyntax = (MethodDeclarationSyntax)context.TargetNode;
SemanticModel sm = context.SemanticModel;

if (!IsSemanticTargetForGeneration(sm, methodSyntax, cancellationToken))
{
return null;
}

Compilation compilation = sm.Compilation;
INamedTypeSymbol? regexSymbol = compilation.GetBestTypeByMetadataName(RegexName);
INamedTypeSymbol? regexGeneratorAttributeSymbol = compilation.GetBestTypeByMetadataName(RegexGeneratorAttributeName);
Expand All @@ -69,23 +47,17 @@ private static bool IsSemanticTargetForGeneration(SemanticModel semanticModel, M
return null;

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Jun 9, 2022

Member

nit: this syntaqctic check could move into IsSyntaxTargetForGeneration instead.

}

IMethodSymbol? regexMethodSymbol = sm.GetDeclaredSymbol(methodSyntax, cancellationToken) as IMethodSymbol;
IMethodSymbol? regexMethodSymbol = context.TargetSymbol as IMethodSymbol;

This comment has been minimized.

Copy link
@CyrusNajmabadi

CyrusNajmabadi Jun 9, 2022

Member

nit. this shoudl never happen. we can consider asserting this in the code.

if (regexMethodSymbol is null)
{
return null;
}

ImmutableArray<AttributeData>? boundAttributes = regexMethodSymbol.GetAttributes();
if (boundAttributes is null || boundAttributes.Value.Length == 0)
{
return null;
}

bool attributeFound = false;
string? pattern = null;
int? options = null;
int? matchTimeout = null;
foreach (AttributeData attributeData in boundAttributes)
foreach (AttributeData attributeData in context.Attributes)
{
if (!SymbolEqualityComparer.Default.Equals(attributeData.AttributeClass, regexGeneratorAttributeSymbol))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
// - (RegexMethod regexMethod, string runnerFactoryImplementation, Dictionary<string, string[]> requiredHelpers) in the case of valid regex
// - (RegexMethod regexMethod, string reason, Diagnostic diagnostic) in the case of a limited-support regex
IncrementalValueProvider<ImmutableArray<object>> codeOrDiagnostics =
context.SyntaxProvider

// Find all MethodDeclarationSyntax nodes attributed with RegexGenerator and gather the required information.
.CreateSyntaxProvider(IsSyntaxTargetForGeneration, GetSemanticTargetForGeneration)
context
.ForAttributeWithMetadataName(
RegexName,
IsSyntaxTargetForGeneration,
GetSemanticTargetForGeneration)
.Where(static m => m is not null)

// Generate the RunnerFactory for each regex, if possible. This is where the bulk of the implementation occurs.
Expand Down

0 comments on commit 909709a

Please sign in to comment.