diff --git a/src/ZLogger.Generator/Shims/CSharpSyntaxHelper.cs b/src/ZLogger.Generator/Shims/CSharpSyntaxHelper.cs deleted file mode 100644 index fb076462..00000000 --- a/src/ZLogger.Generator/Shims/CSharpSyntaxHelper.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/Common/src/Roslyn/CSharpSyntaxHelper.cs - -using System.Collections.Generic; -using System.Diagnostics; - -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions -{ - internal sealed class CSharpSyntaxHelper : AbstractSyntaxHelper - { - public static readonly ISyntaxHelper Instance = new CSharpSyntaxHelper(); - - private CSharpSyntaxHelper() - { - } - - public override bool IsCaseSensitive - => true; - - public override bool IsValidIdentifier(string name) - => SyntaxFacts.IsValidIdentifier(name); - - public override bool IsAnyNamespaceBlock(SyntaxNode node) - => node is BaseNamespaceDeclarationSyntax; - - public override bool IsAttribute(SyntaxNode node) - => node is AttributeSyntax; - - public override SyntaxNode GetNameOfAttribute(SyntaxNode node) - => ((AttributeSyntax)node).Name; - - public override bool IsAttributeList(SyntaxNode node) - => node is AttributeListSyntax; - - public override void AddAttributeTargets(SyntaxNode node, ref ValueListBuilder targets) - { - var attributeList = (AttributeListSyntax)node; - var container = attributeList.Parent; - Debug.Assert(container != null); - - // For fields/events, the attribute applies to all the variables declared. - if (container is FieldDeclarationSyntax field) - { - foreach (var variable in field.Declaration.Variables) - targets.Append(variable); - } - else if (container is EventFieldDeclarationSyntax ev) - { - foreach (var variable in ev.Declaration.Variables) - targets.Append(variable); - } - else - { - targets.Append(container); - } - } - - public override SeparatedSyntaxList GetAttributesOfAttributeList(SyntaxNode node) - => ((AttributeListSyntax)node).Attributes; - - public override bool IsLambdaExpression(SyntaxNode node) - => node is LambdaExpressionSyntax; - - public override SyntaxToken GetUnqualifiedIdentifierOfName(SyntaxNode node) - => ((NameSyntax)node).GetUnqualifiedName().Identifier; - - public override void AddAliases(SyntaxNode node, ref ValueListBuilder<(string aliasName, string symbolName)> aliases, bool global) - { - if (node is CompilationUnitSyntax compilationUnit) - { - AddAliases(compilationUnit.Usings, ref aliases, global); - } - else if (node is BaseNamespaceDeclarationSyntax namespaceDeclaration) - { - AddAliases(namespaceDeclaration.Usings, ref aliases, global); - } - else - { - Debug.Fail("This should not be reachable. Caller already checked we had a compilation unit or namespace."); - } - } - - private static void AddAliases(SyntaxList usings, ref ValueListBuilder<(string aliasName, string symbolName)> aliases, bool global) - { - foreach (var usingDirective in usings) - { - if (usingDirective.Alias is null) - continue; - - if (global != usingDirective.GlobalKeyword.Kind() is SyntaxKind.GlobalKeyword) - continue; - - var aliasName = usingDirective.Alias.Name.Identifier.ValueText; - var symbolName = usingDirective.Name.GetUnqualifiedName().Identifier.ValueText; - aliases.Append((aliasName, symbolName)); - } - } - - public override void AddAliases(CompilationOptions compilation, ref ValueListBuilder<(string aliasName, string symbolName)> aliases) - { - // C# doesn't have global aliases at the compilation level. - return; - } - - public override bool ContainsGlobalAliases(SyntaxNode root) - { - // Global usings can only exist at the compilation-unit level, so no need to dive any deeper than that. - var compilationUnit = (CompilationUnitSyntax)root; - - foreach (var directive in compilationUnit.Usings) - { - if (directive.GlobalKeyword.IsKind(SyntaxKind.GlobalKeyword) && - directive.Alias != null) - { - return true; - } - } - - return false; - } - } -} \ No newline at end of file diff --git a/src/ZLogger.Generator/Shims/CompilationExtensions.cs b/src/ZLogger.Generator/Shims/CompilationExtensions.cs deleted file mode 100644 index 9cc3ef8a..00000000 --- a/src/ZLogger.Generator/Shims/CompilationExtensions.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/Common/src/Roslyn/GetBestTypeByMetadataName.cs - -using System; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions -{ - internal static class RoslynExtensions - { - // Copied from: https://github.com/dotnet/roslyn/blob/main/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/CompilationExtensions.cs - /// - /// Gets a type by its metadata name to use for code analysis within a . This method - /// attempts to find the "best" symbol to use for code analysis, which is the symbol matching the first of the - /// following rules. - /// - /// - /// - /// If only one type with the given name is found within the compilation and its referenced assemblies, that - /// type is returned regardless of accessibility. - /// - /// - /// If the current defines the symbol, that symbol is returned. - /// - /// - /// If exactly one referenced assembly defines the symbol in a manner that makes it visible to the current - /// , that symbol is returned. - /// - /// - /// Otherwise, this method returns . - /// - /// - /// - /// The to consider for analysis. - /// The fully-qualified metadata type name to find. - /// The symbol to use for code analysis; otherwise, . - public static INamedTypeSymbol? GetBestTypeByMetadataName(this Compilation compilation, string fullyQualifiedMetadataName) - { - // Try to get the unique type with this name, ignoring accessibility - var type = compilation.GetTypeByMetadataName(fullyQualifiedMetadataName); - - // Otherwise, try to get the unique type with this name originally defined in 'compilation' - type ??= compilation.Assembly.GetTypeByMetadataName(fullyQualifiedMetadataName); - - // Otherwise, try to get the unique accessible type with this name from a reference - if (type is null) - { - foreach (var module in compilation.Assembly.Modules) - { - foreach (var referencedAssembly in module.ReferencedAssemblySymbols) - { - var currentType = referencedAssembly.GetTypeByMetadataName(fullyQualifiedMetadataName); - if (currentType is null) - continue; - - switch (currentType.GetResultantVisibility()) - { - case SymbolVisibility.Public: - case SymbolVisibility.Internal when referencedAssembly.GivesAccessTo(compilation.Assembly): - break; - - default: - continue; - } - - if (type is object) - { - // Multiple visible types with the same metadata name are present - return null; - } - - type = currentType; - } - } - } - - return type; - } - - /// - /// A thin wrapper over , - /// but taking the type itself rather than the fully-qualified metadata type name. - /// - /// The to consider for analysis. - /// The type to find. - /// - public static INamedTypeSymbol? GetBestTypeByMetadataName(this Compilation compilation, Type type) => - type.IsArray || type.FullName is null - ? throw new ArgumentException("The input type must correspond to a named type symbol.") - : GetBestTypeByMetadataName(compilation, type.FullName); - - // copied from https://github.com/dotnet/roslyn/blob/main/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ISymbolExtensions.cs - private static SymbolVisibility GetResultantVisibility(this ISymbol symbol) - { - // Start by assuming it's visible. - SymbolVisibility visibility = SymbolVisibility.Public; - - switch (symbol.Kind) - { - case SymbolKind.Alias: - // Aliases are uber private. They're only visible in the same file that they - // were declared in. - return SymbolVisibility.Private; - - case SymbolKind.Parameter: - // Parameters are only as visible as their containing symbol - return GetResultantVisibility(symbol.ContainingSymbol); - - case SymbolKind.TypeParameter: - // Type Parameters are private. - return SymbolVisibility.Private; - } - - while (symbol != null && symbol.Kind != SymbolKind.Namespace) - { - switch (symbol.DeclaredAccessibility) - { - // If we see anything private, then the symbol is private. - case Accessibility.NotApplicable: - case Accessibility.Private: - return SymbolVisibility.Private; - - // If we see anything internal, then knock it down from public to - // internal. - case Accessibility.Internal: - case Accessibility.ProtectedAndInternal: - visibility = SymbolVisibility.Internal; - break; - - // For anything else (Public, Protected, ProtectedOrInternal), the - // symbol stays at the level we've gotten so far. - } - - symbol = symbol.ContainingSymbol; - } - - return visibility; - } - - // Copied from: https://github.com/dotnet/roslyn/blob/main/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolVisibility.cs -#pragma warning disable CA1027 // Mark enums with FlagsAttribute - private enum SymbolVisibility -#pragma warning restore CA1027 // Mark enums with FlagsAttribute - { - Public = 0, - Internal = 1, - Private = 2, - Friend = Internal, - } - - internal static bool HasAttributeSuffix(this string name, bool isCaseSensitive) - { - const string AttributeSuffix = "Attribute"; - - var comparison = isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; - return name.Length > AttributeSuffix.Length && name.EndsWith(AttributeSuffix, comparison); - } - - public static ImmutableArray ToImmutableArray(this ReadOnlySpan span) - { - switch (span.Length) - { - case 0: return ImmutableArray.Empty; - case 1: return ImmutableArray.Create(span[0]); - case 2: return ImmutableArray.Create(span[0], span[1]); - case 3: return ImmutableArray.Create(span[0], span[1], span[2]); - case 4: return ImmutableArray.Create(span[0], span[1], span[2], span[3]); - default: - var builder = ImmutableArray.CreateBuilder(span.Length); - foreach (var item in span) - builder.Add(item); - - return builder.MoveToImmutable(); - } - } - - public static SimpleNameSyntax GetUnqualifiedName(this NameSyntax name) - => name switch - { - AliasQualifiedNameSyntax alias => alias.Name, - QualifiedNameSyntax qualified => qualified.Right, - SimpleNameSyntax simple => simple, - _ => throw new InvalidOperationException("Unreachable"), - }; - } -} \ No newline at end of file diff --git a/src/ZLogger.Generator/Shims/GlobalAliases.cs b/src/ZLogger.Generator/Shims/GlobalAliases.cs deleted file mode 100644 index 6fa3476e..00000000 --- a/src/ZLogger.Generator/Shims/GlobalAliases.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/Common/src/Roslyn/GlobalAliases.cs - -using System; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis.PooledObjects; -using Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions; - -/// -/// Simple wrapper class around an immutable array so we can have the value-semantics needed for the incremental -/// generator to know when a change actually happened and it should run later transform stages. -/// -internal sealed class GlobalAliases : IEquatable -{ - public static readonly GlobalAliases Empty = new(ImmutableArray<(string aliasName, string symbolName)>.Empty); - - public readonly ImmutableArray<(string aliasName, string symbolName)> AliasAndSymbolNames; - - private int _hashCode; - - private GlobalAliases(ImmutableArray<(string aliasName, string symbolName)> aliasAndSymbolNames) - { - AliasAndSymbolNames = aliasAndSymbolNames; - } - - public static GlobalAliases Create(ImmutableArray<(string aliasName, string symbolName)> aliasAndSymbolNames) - { - return aliasAndSymbolNames.IsEmpty ? Empty : new GlobalAliases(aliasAndSymbolNames); - } - - public static GlobalAliases Concat(GlobalAliases ga1, GlobalAliases ga2) - { - if (ga1.AliasAndSymbolNames.Length == 0) - return ga2; - - if (ga2.AliasAndSymbolNames.Length == 0) - return ga1; - - return new(ga1.AliasAndSymbolNames.AddRange(ga2.AliasAndSymbolNames)); - } - - public override int GetHashCode() - { - if (_hashCode == 0) - { - var hashCode = 0; - foreach (var tuple in this.AliasAndSymbolNames) - hashCode = Hash.Combine(tuple.GetHashCode(), hashCode); - - _hashCode = hashCode == 0 ? 1 : hashCode; - } - - return _hashCode; - } - - public override bool Equals(object? obj) - => this.Equals(obj as GlobalAliases); - - public bool Equals(GlobalAliases? aliases) - { - if (aliases is null) - return false; - - if (ReferenceEquals(this, aliases)) - return true; - - if (this.AliasAndSymbolNames == aliases.AliasAndSymbolNames) - return true; - - return this.AliasAndSymbolNames.AsSpan().SequenceEqual(aliases.AliasAndSymbolNames.AsSpan()); - } -} diff --git a/src/ZLogger.Generator/Shims/Hash.cs b/src/ZLogger.Generator/Shims/Hash.cs deleted file mode 100644 index 4dd887ac..00000000 --- a/src/ZLogger.Generator/Shims/Hash.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/Roslyn/Hash.cs - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; - -namespace Roslyn.Utilities -{ - internal static class Hash - { - /// - /// This is how VB Anonymous Types combine hash values for fields. - /// - internal static int Combine(int newKey, int currentKey) - { - return unchecked((currentKey * (int)0xA5555529) + newKey); - } - - // The rest of this file was removed as they were not currently needed in the polyfill of SyntaxValueProvider.ForAttributeWithMetadataName. - // If that changes, they should be added back as necessary. - } -} diff --git a/src/ZLogger.Generator/Shims/ISyntaxHelper.cs b/src/ZLogger.Generator/Shims/ISyntaxHelper.cs deleted file mode 100644 index 76a97045..00000000 --- a/src/ZLogger.Generator/Shims/ISyntaxHelper.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/Common/src/Roslyn/ISyntaxHelper.cs - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; - -using Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions -{ - internal interface ISyntaxHelper - { - bool IsCaseSensitive { get; } - - bool IsValidIdentifier(string name); - - bool IsAnyNamespaceBlock(SyntaxNode node); - - bool IsAttributeList(SyntaxNode node); - SeparatedSyntaxList GetAttributesOfAttributeList(SyntaxNode node); - - void AddAttributeTargets(SyntaxNode node, ref ValueListBuilder targets); - - bool IsAttribute(SyntaxNode node); - SyntaxNode GetNameOfAttribute(SyntaxNode node); - - bool IsLambdaExpression(SyntaxNode node); - - SyntaxToken GetUnqualifiedIdentifierOfName(SyntaxNode node); - - /// - /// must be a compilation unit or namespace block. - /// - void AddAliases(SyntaxNode node, ref ValueListBuilder<(string aliasName, string symbolName)> aliases, bool global); - void AddAliases(CompilationOptions options, ref ValueListBuilder<(string aliasName, string symbolName)> aliases); - - bool ContainsGlobalAliases(SyntaxNode root); - } - - internal abstract class AbstractSyntaxHelper : ISyntaxHelper - { - public abstract bool IsCaseSensitive { get; } - - public abstract bool IsValidIdentifier(string name); - - public abstract SyntaxToken GetUnqualifiedIdentifierOfName(SyntaxNode name); - - public abstract bool IsAnyNamespaceBlock(SyntaxNode node); - - public abstract bool IsAttribute(SyntaxNode node); - public abstract SyntaxNode GetNameOfAttribute(SyntaxNode node); - - public abstract bool IsAttributeList(SyntaxNode node); - public abstract SeparatedSyntaxList GetAttributesOfAttributeList(SyntaxNode node); - public abstract void AddAttributeTargets(SyntaxNode node, ref ValueListBuilder targets); - - public abstract bool IsLambdaExpression(SyntaxNode node); - - public abstract void AddAliases(SyntaxNode node, ref ValueListBuilder<(string aliasName, string symbolName)> aliases, bool global); - public abstract void AddAliases(CompilationOptions options, ref ValueListBuilder<(string aliasName, string symbolName)> aliases); - - public abstract bool ContainsGlobalAliases(SyntaxNode root); - } -} diff --git a/src/ZLogger.Generator/Shims/ImmutableArrayValueComparer.cs b/src/ZLogger.Generator/Shims/ImmutableArrayValueComparer.cs deleted file mode 100644 index c03764c4..00000000 --- a/src/ZLogger.Generator/Shims/ImmutableArrayValueComparer.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/Common/src/Roslyn/SyntaxValueProvider.ImmutableArrayValueComparer.cs - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions; - -internal static partial class SyntaxValueProviderExtensions -{ - private sealed class ImmutableArrayValueComparer : IEqualityComparer> - { - public static readonly IEqualityComparer> Instance = new ImmutableArrayValueComparer(); - - public bool Equals(ImmutableArray x, ImmutableArray y) - => x.SequenceEqual(y, EqualityComparer.Default); - - public int GetHashCode(ImmutableArray obj) - { - var hashCode = 0; - foreach (var value in obj) - hashCode = Hash.Combine(hashCode, EqualityComparer.Default.GetHashCode(value!)); - - return hashCode; - } - } -} \ No newline at end of file diff --git a/src/ZLogger.Generator/Shims/SyntaxValueProvider_ForAttributeWithMetadataName.cs b/src/ZLogger.Generator/Shims/SyntaxValueProvider_ForAttributeWithMetadataName.cs deleted file mode 100644 index 0da2d9b9..00000000 --- a/src/ZLogger.Generator/Shims/SyntaxValueProvider_ForAttributeWithMetadataName.cs +++ /dev/null @@ -1,203 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/Common/src/Roslyn/SyntaxValueProvider_ForAttributeWithMetadataName.cs - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -using System.Threading; - -using Microsoft.CodeAnalysis; - -using Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions; - -internal readonly struct GeneratorAttributeSyntaxContext -{ - /// - /// The syntax node the attribute is attached to. For example, with [CLSCompliant] class C { } this would - /// the class declaration node. - /// - public SyntaxNode TargetNode { get; } - - /// - /// The symbol that the attribute is attached to. For example, with [CLSCompliant] class C { } this would be - /// the for "C". - /// - public ISymbol TargetSymbol { get; } - - /// - /// Semantic model for the file that is contained within. - /// - public SemanticModel SemanticModel { get; } - - /// - /// s for any matching attributes on . Always non-empty. All - /// these attributes will have an whose fully qualified name metadata - /// name matches the name requested in . - /// - /// To get the entire list of attributes, use on . - /// - /// - public ImmutableArray Attributes { get; } - - internal GeneratorAttributeSyntaxContext( - SyntaxNode targetNode, - ISymbol targetSymbol, - SemanticModel semanticModel, - ImmutableArray attributes) - { - TargetNode = targetNode; - TargetSymbol = targetSymbol; - SemanticModel = semanticModel; - Attributes = attributes; - } -} - -internal static partial class SyntaxValueProviderExtensions -{ -#if false - - // Deviation from roslyn. We do not support attributes that are nested or generic. That's ok as that's not a - // scenario that ever arises in our generators. - - private static readonly char[] s_nestedTypeNameSeparators = new char[] { '+' }; - - private static readonly SymbolDisplayFormat s_metadataDisplayFormat = - SymbolDisplayFormat.QualifiedNameArityFormat.AddCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.UsePlusForNestedTypes); - -#endif - - /// - /// Creates an that can provide a transform over all s if that node has an attribute on it that binds to a with the - /// same fully-qualified metadata as the provided . should be the fully-qualified, metadata name of the attribute, including the - /// Attribute suffix. For example "System.CLSCompliantAttribute for . - /// - /// A function that determines if the given attribute target () should be transformed. Nodes that do not pass this - /// predicate will not have their attributes looked at at all. - /// A function that performs the transform. This will only be passed nodes that return for and which have a matching whose - /// has the same fully qualified, metadata name as . - public static IncrementalValuesProvider ForAttributeWithMetadataName( - this SyntaxValueProvider @this, - IncrementalGeneratorInitializationContext context, - string fullyQualifiedMetadataName, - Func predicate, - Func transform) - { -#if false - - // Deviation from roslyn. We do not support attributes that are nested or generic. That's ok as that's not a - // scenario that ever arises in our generators. - - var metadataName = fullyQualifiedMetadataName.Contains('+') - ? MetadataTypeName.FromFullName(fullyQualifiedMetadataName.Split(s_nestedTypeNameSeparators).Last()) - : MetadataTypeName.FromFullName(fullyQualifiedMetadataName); - - var nodesWithAttributesMatchingSimpleName = @this.ForAttributeWithSimpleName(context, metadataName.UnmangledTypeName, predicate); - -#else - - var lastDotIndex = fullyQualifiedMetadataName.LastIndexOf('.'); - Debug.Assert(lastDotIndex > 0); - var unmangledTypeName = fullyQualifiedMetadataName.Substring(lastDotIndex + 1); - - var nodesWithAttributesMatchingSimpleName = @this.ForAttributeWithSimpleName(context, unmangledTypeName, predicate); - -#endif - - var compilationAndGroupedNodesProvider = nodesWithAttributesMatchingSimpleName - .Combine(context.CompilationProvider) - /*.WithTrackingName("compilationAndGroupedNodes_ForAttributeWithMetadataName")*/; - - var syntaxHelper = CSharpSyntaxHelper.Instance; - var finalProvider = compilationAndGroupedNodesProvider.SelectMany((tuple, cancellationToken) => - { - var ((syntaxTree, syntaxNodes), compilation) = tuple; - Debug.Assert(syntaxNodes.All(n => n.SyntaxTree == syntaxTree)); - - using var result = new ValueListBuilder(Span.Empty); - if (!syntaxNodes.IsEmpty) - { - var semanticModel = compilation.GetSemanticModel(syntaxTree); - - foreach (var targetNode in syntaxNodes) - { - cancellationToken.ThrowIfCancellationRequested(); - - var targetSymbol = - targetNode is ICompilationUnitSyntax compilationUnit ? semanticModel.Compilation.Assembly : - syntaxHelper.IsLambdaExpression(targetNode) ? semanticModel.GetSymbolInfo(targetNode, cancellationToken).Symbol : - semanticModel.GetDeclaredSymbol(targetNode, cancellationToken); - if (targetSymbol is null) - continue; - - var attributes = getMatchingAttributes(targetNode, targetSymbol, fullyQualifiedMetadataName); - if (attributes.Length > 0) - { - result.Append(transform( - new GeneratorAttributeSyntaxContext(targetNode, targetSymbol, semanticModel, attributes), - cancellationToken)); - } - } - } - - return result.AsSpan().ToImmutableArray(); - })/*.WithTrackingName("result_ForAttributeWithMetadataName")*/; - - return finalProvider; - - static ImmutableArray getMatchingAttributes( - SyntaxNode attributeTarget, - ISymbol symbol, - string fullyQualifiedMetadataName) - { - var targetSyntaxTree = attributeTarget.SyntaxTree; - var result = new ValueListBuilder(Span.Empty); - - try - { - addMatchingAttributes(ref result, symbol.GetAttributes()); - addMatchingAttributes(ref result, (symbol as IMethodSymbol)?.GetReturnTypeAttributes()); - - if (symbol is IAssemblySymbol assemblySymbol) - { - foreach (var module in assemblySymbol.Modules) - addMatchingAttributes(ref result, module.GetAttributes()); - } - - return result.AsSpan().ToImmutableArray(); - } - finally - { - result.Dispose(); - } - - void addMatchingAttributes( - ref ValueListBuilder result, - ImmutableArray? attributes) - { - if (!attributes.HasValue) - return; - - foreach (var attribute in attributes.Value) - { - if (attribute.ApplicationSyntaxReference?.SyntaxTree == targetSyntaxTree && - attribute.AttributeClass?.ToDisplayString(/*s_metadataDisplayFormat*/) == fullyQualifiedMetadataName) - { - result.Append(attribute); - } - } - } - } - } -} diff --git a/src/ZLogger.Generator/Shims/SyntaxValueProvider_ForAttributeWithSimpleName.cs b/src/ZLogger.Generator/Shims/SyntaxValueProvider_ForAttributeWithSimpleName.cs deleted file mode 100644 index 193f8dd4..00000000 --- a/src/ZLogger.Generator/Shims/SyntaxValueProvider_ForAttributeWithSimpleName.cs +++ /dev/null @@ -1,455 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/Common/src/Roslyn/SyntaxValueProvider_ForAttributeWithSimpleName.cs - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Diagnostics; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading; - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Aliases = System.Collections.Generic.ValueListBuilder<(string aliasName, string symbolName)>; - -namespace Microsoft.CodeAnalysis.DotnetRuntime.Extensions; - -internal static partial class SyntaxValueProviderExtensions -{ - // Normal class as Runtime does not seem to support records currently. - - /// - /// Information computed about a particular tree. Cached so we don't repeatedly recompute this important - /// information each time the incremental pipeline is rerun. - /// - private sealed class SyntaxTreeInfo : IEquatable - { - public readonly SyntaxTree Tree; - public readonly bool ContainsGlobalAliases; - public readonly bool ContainsAttributeList; - - public SyntaxTreeInfo(SyntaxTree tree, bool containsGlobalAliases, bool containsAttributeList) - { - Tree = tree; - ContainsGlobalAliases = containsGlobalAliases; - ContainsAttributeList = containsAttributeList; - } - - public bool Equals(SyntaxTreeInfo? other) - => Tree == other?.Tree; - - public override bool Equals(object? obj) - => this.Equals(obj as SyntaxTreeInfo); - - public override int GetHashCode() - => Tree.GetHashCode(); - } - - /// - /// Caching of syntax-tree to the info we've computed about it. Used because compilations will have thousands of - /// trees, and the incremental pipeline will get called back for *all* of them each time a compilation changes. We - /// do not want to continually recompute this data over and over again each time that happens given that normally - /// only one tree will be different. We also do not want to create an IncrementalValuesProvider that yield this - /// information as that will mean we have a node in the tree that scales with the number of *all syntax trees*, not - /// the number of *relevant syntax trees*. This can lead to huge memory churn keeping track of a high number of - /// trees, most of which are not going to be relevant. - /// - private static readonly ConditionalWeakTable s_treeToInfo = new ConditionalWeakTable(); - -#if false - // Not used in runtime. Pooling is not a pattern here, and we use ValueListBuilder instead. - - private static readonly ObjectPool> s_stackPool = new(static () => new()); -#endif - - /// - /// Returns all syntax nodes of that match if that node has an attribute on it that - /// could possibly bind to the provided . should be the - /// simple, non-qualified, name of the attribute, including the Attribute suffix, and not containing any - /// generics, containing types, or namespaces. For example CLSCompliantAttribute for . - /// This provider understands (Import in Visual Basic) aliases and will find - /// matches even when the attribute references an alias name. For example, given: - /// - /// using XAttribute = System.CLSCompliantAttribute; - /// [X] - /// class C { } - /// - /// Then - /// context.SyntaxProvider.CreateSyntaxProviderForAttribute(nameof(CLSCompliantAttribute), (node, c) => node is ClassDeclarationSyntax) - /// will find the C class. - /// - /// - /// Note: a 'Values'-provider of arrays are returned. Each array provides all the matching nodes from a single . - /// - public static IncrementalValuesProvider<(SyntaxTree tree, ImmutableArray matches)> ForAttributeWithSimpleName( - this SyntaxValueProvider @this, - IncrementalGeneratorInitializationContext context, - string simpleName, - Func predicate) - { - var syntaxHelper = CSharpSyntaxHelper.Instance; - - // Create a provider over all the syntax trees in the compilation. This is better than CreateSyntaxProvider as - // using SyntaxTrees is purely syntax and will not update the incremental node for a tree when another tree is - // changed. CreateSyntaxProvider will have to rerun all incremental nodes since it passes along the - // SemanticModel, and that model is updated whenever any tree changes (since it is tied to the compilation). - var syntaxTreesProvider = context.CompilationProvider - .SelectMany((compilation, cancellationToken) => compilation.SyntaxTrees - .Select(tree => GetTreeInfo(tree, syntaxHelper, cancellationToken)) - .Where(info => info.ContainsGlobalAliases || info.ContainsAttributeList)) - /*.WithTrackingName("compilationUnit_ForAttribute")*/; - - // Create a provider that provides (and updates) the global aliases for any particular file when it is edited. - var individualFileGlobalAliasesProvider = syntaxTreesProvider - .Where(info => info.ContainsGlobalAliases) - .Select((info, cancellationToken) => getGlobalAliasesInCompilationUnit(info.Tree.GetRoot(cancellationToken))) - /*.WithTrackingName("individualFileGlobalAliases_ForAttribute")*/; - - // Create an aggregated view of all global aliases across all files. This should only update when an individual - // file changes its global aliases or a file is added / removed from the compilation - var collectedGlobalAliasesProvider = individualFileGlobalAliasesProvider - .Collect() - .WithComparer(ImmutableArrayValueComparer.Instance) - /*.WithTrackingName("collectedGlobalAliases_ForAttribute")*/; - - var allUpGlobalAliasesProvider = collectedGlobalAliasesProvider - .Select(static (arrays, _) => GlobalAliases.Create(arrays.SelectMany(a => a.AliasAndSymbolNames).ToImmutableArray())) - /*.WithTrackingName("allUpGlobalAliases_ForAttribute")*/; - -#if false - - // C# does not support global aliases from compilation options. So we can just ignore this part. - - // Regenerate our data if the compilation options changed. VB can supply global aliases with compilation options, - // so we have to reanalyze everything if those changed. - var compilationGlobalAliases = _context.CompilationOptionsProvider.Select( - (o, _) => - { - var aliases = Aliases.GetInstance(); - syntaxHelper.AddAliases(o, aliases); - return GlobalAliases.Create(aliases.ToImmutableAndFree()); - }).WithTrackingName("compilationGlobalAliases_ForAttribute"); - - allUpGlobalAliasesProvider = allUpGlobalAliasesProvider - .Combine(compilationGlobalAliases) - .Select((tuple, _) => GlobalAliases.Concat(tuple.Left, tuple.Right)) - .WithTrackingName("allUpIncludingCompilationGlobalAliases_ForAttribute"); - -#endif - - // Combine the two providers so that we reanalyze every file if the global aliases change, or we reanalyze a - // particular file when it's compilation unit changes. - var syntaxTreeAndGlobalAliasesProvider = syntaxTreesProvider - .Where(info => info.ContainsAttributeList) - .Combine(allUpGlobalAliasesProvider) - /*.WithTrackingName("compilationUnitAndGlobalAliases_ForAttribute")*/; - - // For each pair of compilation unit + global aliases, walk the compilation unit - var result = syntaxTreeAndGlobalAliasesProvider - .Select((tuple, c) => (tuple.Left.Tree, GetMatchingNodes(syntaxHelper, tuple.Right, tuple.Left.Tree, simpleName, predicate, c))) - .Where(tuple => tuple.Item2.Length > 0) - /*.WithTrackingName("result_ForAttribute")*/; - - return result; - - static GlobalAliases getGlobalAliasesInCompilationUnit( - SyntaxNode compilationUnit) - { - Debug.Assert(compilationUnit is ICompilationUnitSyntax); - var globalAliases = new Aliases(Span<(string aliasName, string symbolName)>.Empty); - - CSharpSyntaxHelper.Instance.AddAliases(compilationUnit, ref globalAliases, global: true); - - return GlobalAliases.Create(globalAliases.AsSpan().ToImmutableArray()); - } - } - - private static SyntaxTreeInfo GetTreeInfo( - SyntaxTree tree, ISyntaxHelper syntaxHelper, CancellationToken cancellationToken) - { - // prevent captures for the case where the item is in the tree. - return s_treeToInfo.TryGetValue(tree, out var info) - ? info - : computeTreeInfo(); - - SyntaxTreeInfo computeTreeInfo() - { - var root = tree.GetRoot(cancellationToken); - var containsGlobalAliases = syntaxHelper.ContainsGlobalAliases(root); - var containsAttributeList = ContainsAttributeList(root); - - var info = new SyntaxTreeInfo(tree, containsGlobalAliases, containsAttributeList); - return s_treeToInfo.GetValue(tree, _ => info); - } - } - - private static ImmutableArray GetMatchingNodes( - ISyntaxHelper syntaxHelper, - GlobalAliases globalAliases, - SyntaxTree syntaxTree, - string name, - Func predicate, - CancellationToken cancellationToken) - { - var compilationUnit = syntaxTree.GetRoot(cancellationToken); - Debug.Assert(compilationUnit is ICompilationUnitSyntax); - - var isCaseSensitive = syntaxHelper.IsCaseSensitive; - var comparison = isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; - - // As we walk down the compilation unit and nested namespaces, we may encounter additional using aliases local - // to this file. Keep track of them so we can determine if they would allow an attribute in code to bind to the - // attribute being searched for. - var localAliases = new Aliases(Span<(string, string)>.Empty); - var nameHasAttributeSuffix = name.HasAttributeSuffix(isCaseSensitive); - - // Used to ensure that as we recurse through alias names to see if they could bind to attributeName that we - // don't get into cycles. - - var seenNames = new ValueListBuilder(Span.Empty); - var results = new ValueListBuilder(Span.Empty); - var attributeTargets = new ValueListBuilder(Span.Empty); - - try - { - processCompilationUnit(compilationUnit, ref localAliases, ref seenNames, ref results, ref attributeTargets); - - if (results.Length == 0) - return ImmutableArray.Empty; - - return results.AsSpan().ToArray().Distinct().ToImmutableArray(); - } - finally - { - attributeTargets.Dispose(); - results.Dispose(); - seenNames.Dispose(); - } - - void processCompilationUnit( - SyntaxNode compilationUnit, - ref Aliases localAliases, - ref ValueListBuilder seenNames, - ref ValueListBuilder results, - ref ValueListBuilder attributeTargets) - { - cancellationToken.ThrowIfCancellationRequested(); - - syntaxHelper.AddAliases(compilationUnit, ref localAliases, global: false); - - processCompilationOrNamespaceMembers(compilationUnit, ref localAliases, ref seenNames, ref results, ref attributeTargets); - } - - void processCompilationOrNamespaceMembers( - SyntaxNode node, - ref Aliases localAliases, - ref ValueListBuilder seenNames, - ref ValueListBuilder results, - ref ValueListBuilder attributeTargets) - { - cancellationToken.ThrowIfCancellationRequested(); - - foreach (var child in node.ChildNodesAndTokens()) - { - if (child.IsNode) - { - var childNode = child.AsNode()!; - if (syntaxHelper.IsAnyNamespaceBlock(childNode)) - processNamespaceBlock(childNode, ref localAliases, ref seenNames, ref results, ref attributeTargets); - else - processMember(childNode, ref localAliases, ref seenNames, ref results, ref attributeTargets); - } - } - } - - void processNamespaceBlock( - SyntaxNode namespaceBlock, - ref Aliases localAliases, - ref ValueListBuilder seenNames, - ref ValueListBuilder results, - ref ValueListBuilder attributeTargets) - { - cancellationToken.ThrowIfCancellationRequested(); - - var localAliasCount = localAliases.Length; - syntaxHelper.AddAliases(namespaceBlock, ref localAliases, global: false); - - processCompilationOrNamespaceMembers( - namespaceBlock, ref localAliases, ref seenNames, ref results, ref attributeTargets); - - // after recursing into this namespace, dump any local aliases we added from this namespace decl itself. - localAliases.Length = localAliasCount; - } - - void processMember( - SyntaxNode member, - ref Aliases localAliases, - ref ValueListBuilder seenNames, - ref ValueListBuilder results, - ref ValueListBuilder attributeTargets) - { - cancellationToken.ThrowIfCancellationRequested(); - - // nodes can be arbitrarily deep. Use an explicit stack over recursion to prevent a stack-overflow. - var nodeStack = new ValueListBuilder(Span.Empty); - nodeStack.Append(member); - - try - { - while (nodeStack.Length > 0) - { - var node = nodeStack.Pop(); - - if (syntaxHelper.IsAttributeList(node)) - { - foreach (var attribute in syntaxHelper.GetAttributesOfAttributeList(node)) - { - // Have to lookup both with the name in the attribute, as well as adding the 'Attribute' suffix. - // e.g. if there is [X] then we have to lookup with X and with XAttribute. - var simpleAttributeName = syntaxHelper.GetUnqualifiedIdentifierOfName( - syntaxHelper.GetNameOfAttribute(attribute)).ValueText; - if (matchesAttributeName(ref localAliases, ref seenNames, simpleAttributeName, withAttributeSuffix: false) || - matchesAttributeName(ref localAliases, ref seenNames, simpleAttributeName, withAttributeSuffix: true)) - { - attributeTargets.Length = 0; - syntaxHelper.AddAttributeTargets(node, ref attributeTargets); - - foreach (var target in attributeTargets.AsSpan()) - { - if (predicate(target, cancellationToken)) - results.Append(target); - } - - break; - } - } - - // attributes can't have attributes inside of them. so no need to recurse when we're done. - } - else - { - // For any other node, just keep recursing deeper to see if we can find an attribute. Note: we cannot - // terminate the search anywhere as attributes may be found on things like local functions, and that - // means having to dive deep into statements and expressions. - var childNodesAndTokens = node.ChildNodesAndTokens(); - - // Avoid performance issue in ChildSyntaxList when iterating the child list in reverse - // (see https://github.com/dotnet/roslyn/issues/66475) by iterating forward first to - // ensure child nodes are realized. - foreach (var childNode in childNodesAndTokens) - { - } - - foreach (var child in childNodesAndTokens.Reverse()) - { - if (child.IsNode) - nodeStack.Append(child.AsNode()!); - } - } - - } - } - finally - { - nodeStack.Dispose(); - } - } - - // Checks if `name` is equal to `matchAgainst`. if `withAttributeSuffix` is true, then - // will check if `name` + "Attribute" is equal to `matchAgainst` - bool matchesName(string name, string matchAgainst, bool withAttributeSuffix) - { - if (withAttributeSuffix) - { - return name.Length + "Attribute".Length == matchAgainst.Length && - matchAgainst.HasAttributeSuffix(isCaseSensitive) && - matchAgainst.StartsWith(name, comparison); - } - else - { - return name.Equals(matchAgainst, comparison); - } - } - - bool matchesAttributeName( - ref Aliases localAliases, - ref ValueListBuilder seenNames, - string currentAttributeName, - bool withAttributeSuffix) - { - // If the names match, we're done. - if (withAttributeSuffix) - { - if (nameHasAttributeSuffix && - matchesName(currentAttributeName, name, withAttributeSuffix)) - { - return true; - } - } - else - { - if (matchesName(currentAttributeName, name, withAttributeSuffix: false)) - return true; - } - - // Otherwise, keep searching through aliases. Check that this is the first time seeing this name so we - // don't infinite recurse in error code where aliases reference each other. - // - // note: as we recurse up the aliases, we do not want to add the attribute suffix anymore. aliases must - // reference the actual real name of the symbol they are aliasing. - foreach (var seenName in seenNames.AsSpan()) - { - if (seenName == currentAttributeName) - return false; - } - - seenNames.Append(currentAttributeName); - - foreach (var (aliasName, symbolName) in localAliases.AsSpan()) - { - // see if user wrote `[SomeAlias]`. If so, if we find a `using SomeAlias = ...` recurse using the - // ... name portion to see if it might bind to the attr name the caller is searching for. - if (matchesName(currentAttributeName, aliasName, withAttributeSuffix) && - matchesAttributeName(ref localAliases, ref seenNames, symbolName, withAttributeSuffix: false)) - { - return true; - } - } - - foreach (var (aliasName, symbolName) in globalAliases.AliasAndSymbolNames) - { - if (matchesName(currentAttributeName, aliasName, withAttributeSuffix) && - matchesAttributeName(ref localAliases, ref seenNames, symbolName, withAttributeSuffix: false)) - { - return true; - } - } - - seenNames.Pop(); - return false; - } - } - - private static bool ContainsAttributeList(SyntaxNode node) - { - if (node.IsKind(SyntaxKind.AttributeList)) - return true; - - foreach (SyntaxNodeOrToken child in node.ChildNodesAndTokens()) - { - if (child.IsToken) - continue; - - SyntaxNode? childNode = child.AsNode()!; - if (ContainsAttributeList(childNode)) - return true; - } - - return false; - } -} diff --git a/src/ZLogger.Generator/Shims/ValueListHelper.cs b/src/ZLogger.Generator/Shims/ValueListHelper.cs deleted file mode 100644 index 1c4dc11a..00000000 --- a/src/ZLogger.Generator/Shims/ValueListHelper.cs +++ /dev/null @@ -1,213 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// Copied from https://github.com/dotnet/runtime/blob/1473deaa50785b956edd7d078e68c0581c1b4d95/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ValueListBuilder.cs - -using System.Buffers; -using System.Diagnostics; -using System.Runtime.CompilerServices; - -namespace System.Collections.Generic -{ - internal ref partial struct ValueListBuilder - { - private Span _span; - private T[]? _arrayFromPool; - private int _pos; - - public ValueListBuilder(Span initialSpan) - { - _span = initialSpan; - _arrayFromPool = null; - _pos = 0; - } - - public int Length - { - get => _pos; - set - { - Debug.Assert(value >= 0); - Debug.Assert(value <= _span.Length); - _pos = value; - } - } - - public ref T this[int index] - { - get - { - Debug.Assert(index < _pos); - return ref _span[index]; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(T item) - { - int pos = _pos; - - // Workaround for https://github.com/dotnet/runtime/issues/72004 - Span span = _span; - if ((uint)pos < (uint)span.Length) - { - span[pos] = item; - _pos = pos + 1; - } - else - { - AddWithResize(item); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Append(scoped ReadOnlySpan source) - { - int pos = _pos; - Span span = _span; - if (source.Length == 1 && (uint)pos < (uint)span.Length) - { - span[pos] = source[0]; - _pos = pos + 1; - } - else - { - AppendMultiChar(source); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private void AppendMultiChar(scoped ReadOnlySpan source) - { - if ((uint)(_pos + source.Length) > (uint)_span.Length) - { - Grow(_span.Length - _pos + source.Length); - } - - source.CopyTo(_span.Slice(_pos)); - _pos += source.Length; - } - - public void Insert(int index, scoped ReadOnlySpan source) - { - Debug.Assert(index >= 0 && index <= _pos); - - if ((uint)(_pos + source.Length) > (uint)_span.Length) - { - Grow(source.Length); - } - - _span.Slice(0, _pos).CopyTo(_span.Slice(source.Length)); - source.CopyTo(_span); - _pos += source.Length; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span AppendSpan(int length) - { - Debug.Assert(length >= 0); - - int pos = _pos; - Span span = _span; - if ((ulong)(uint)pos + (ulong)(uint)length <= (ulong)(uint)span.Length) // same guard condition as in Span.Slice on 64-bit - { - _pos = pos + length; - return span.Slice(pos, length); - } - else - { - return AppendSpanWithGrow(length); - } - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private Span AppendSpanWithGrow(int length) - { - int pos = _pos; - Grow(_span.Length - pos + length); - _pos += length; - return _span.Slice(pos, length); - } - - // Hide uncommon path - [MethodImpl(MethodImplOptions.NoInlining)] - private void AddWithResize(T item) - { - Debug.Assert(_pos == _span.Length); - int pos = _pos; - Grow(1); - _span[pos] = item; - _pos = pos + 1; - } - - public ReadOnlySpan AsSpan() - { - return _span.Slice(0, _pos); - } - - public bool TryCopyTo(Span destination, out int itemsWritten) - { - if (_span.Slice(0, _pos).TryCopyTo(destination)) - { - itemsWritten = _pos; - return true; - } - - itemsWritten = 0; - return false; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T Pop() - { - _pos--; - return _span[_pos]; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() - { - T[]? toReturn = _arrayFromPool; - if (toReturn != null) - { - _arrayFromPool = null; - ArrayPool.Shared.Return(toReturn); - } - } - - // Note that consuming implementations depend on the list only growing if it's absolutely - // required. If the list is already large enough to hold the additional items be added, - // it must not grow. The list is used in a number of places where the reference is checked - // and it's expected to match the initial reference provided to the constructor if that - // span was sufficiently large. - private void Grow(int additionalCapacityRequired = 1) - { - const int ArrayMaxLength = 0x7FFFFFC7; // same as Array.MaxLength - - // Double the size of the span. If it's currently empty, default to size 4, - // although it'll be increased in Rent to the pool's minimum bucket size. - int nextCapacity = Math.Max(_span.Length != 0 ? _span.Length * 2 : 4, _span.Length + additionalCapacityRequired); - - // If the computed doubled capacity exceeds the possible length of an array, then we - // want to downgrade to either the maximum array length if that's large enough to hold - // an additional item, or the current length + 1 if it's larger than the max length, in - // which case it'll result in an OOM when calling Rent below. In the exceedingly rare - // case where _span.Length is already int.MaxValue (in which case it couldn't be a managed - // array), just use that same value again and let it OOM in Rent as well. - if ((uint)nextCapacity > ArrayMaxLength) - { - nextCapacity = Math.Max(Math.Max(_span.Length + 1, ArrayMaxLength), _span.Length); - } - - T[] array = ArrayPool.Shared.Rent(nextCapacity); - _span.CopyTo(array); - - T[]? toReturn = _arrayFromPool; - _span = _arrayFromPool = array; - if (toReturn != null) - { - ArrayPool.Shared.Return(toReturn); - } - } - } -} \ No newline at end of file diff --git a/src/ZLogger.Generator/ZLoggerGenerator.Parser.cs b/src/ZLogger.Generator/ZLoggerGenerator.Parser.cs index 12c841c7..5c536741 100644 --- a/src/ZLogger.Generator/ZLoggerGenerator.Parser.cs +++ b/src/ZLogger.Generator/ZLoggerGenerator.Parser.cs @@ -2,8 +2,6 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Immutable; -using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; -using GeneratorAttributeSyntaxContext = Microsoft.CodeAnalysis.DotnetRuntime.Extensions.GeneratorAttributeSyntaxContext; namespace ZLogger.Generator; diff --git a/src/ZLogger.Generator/ZLoggerGenerator.cs b/src/ZLogger.Generator/ZLoggerGenerator.cs index d03e98bd..ba2fe4c0 100644 --- a/src/ZLogger.Generator/ZLoggerGenerator.cs +++ b/src/ZLogger.Generator/ZLoggerGenerator.cs @@ -1,8 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Collections.Immutable; -using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; -using GeneratorAttributeSyntaxContext = Microsoft.CodeAnalysis.DotnetRuntime.Extensions.GeneratorAttributeSyntaxContext; namespace ZLogger.Generator; @@ -14,7 +12,6 @@ public partial class ZLoggerGenerator : IIncrementalGenerator public void Initialize(IncrementalGeneratorInitializationContext context) { var source = context.SyntaxProvider.ForAttributeWithMetadataName( - context, "ZLogger.ZLoggerMessageAttribute", static (node, token) => node is MethodDeclarationSyntax, static (context, token) => context);