-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Polyfill the incremental generator ForAttributeWithMetadataName from roslyn. #70911
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
Changes from 1 commit
6e03dca
539b248
e8f0a8e
1c0fbf2
b533f26
c1a76b1
2ef0717
1f35a7e
f5d8137
be4ef0f
2babd86
1cdc428
cfce553
fd9a27e
e2613b6
a0e9d88
91672fe
86de769
cc933a2
8a5a8d0
4eb00d1
59cdea7
e7a1f3e
20d62a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,58 +1,30 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using Microsoft.CodeAnalysis; | ||
| using Microsoft.CodeAnalysis.CSharp; | ||
| using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
| using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; | ||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using System.Collections.Immutable; | ||
| using System.Diagnostics; | ||
| using System.Globalization; | ||
| using System.Linq; | ||
| using System.Threading; | ||
|
|
||
| using Microsoft.CodeAnalysis; | ||
| using Microsoft.CodeAnalysis.CSharp; | ||
| using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
| using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; | ||
|
|
||
| namespace System.Text.RegularExpressions.Generator | ||
| { | ||
| public partial class RegexGenerator | ||
| { | ||
| private const string RegexName = "System.Text.RegularExpressions.Regex"; | ||
| 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) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no more costly binding of every attribute in the world, as well as a costly ToDisplayString on all of them. |
||
| { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| // 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; | ||
| 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); | ||
|
|
@@ -69,7 +41,7 @@ private static bool IsSemanticTargetForGeneration(SemanticModel semanticModel, M | |
| return null; | ||
| } | ||
|
|
||
| IMethodSymbol? regexMethodSymbol = sm.GetDeclaredSymbol(methodSyntax, cancellationToken) as IMethodSymbol; | ||
| IMethodSymbol regexMethodSymbol = context.TargetSymbol as IMethodSymbol; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i considered doing a direct cast here to IMethodSybmol (since that is an invariant of roslyn given that we only examine MethodDeclarationSytnax). However, i wanted to preserve semantics here, including the high paranoia that this might not always be the same. |
||
| if (regexMethodSymbol is null) | ||
| { | ||
| return null; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is hte change to the actual generator to use the new API.