mirror of
https://github.com/CommunityToolkit/dotnet.git
synced 2026-10-18 13:11:13 +08:00
Improve logic to find target symbol locations
This commit is contained in:
+1
-2
@@ -4,7 +4,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
@@ -76,7 +75,7 @@ public sealed class UnsupportedCSharpLanguageVersionAnalyzer : DiagnosticAnalyze
|
||||
typeSymbols.TryGetValue(attributeName, out INamedTypeSymbol? attributeSymbol) &&
|
||||
SymbolEqualityComparer.Default.Equals(attributeClass, attributeSymbol))
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, context.Symbol.Locations.FirstOrDefault()));
|
||||
context.ReportDiagnostic(Diagnostic.Create(UnsupportedCSharpLanguageVersionError, context.Symbol.GetLocationFromAttributeDataOrDefault(attribute)));
|
||||
|
||||
// If we created a diagnostic for this symbol, we can stop. Even if there's multiple attributes, no need for repeated errors
|
||||
return;
|
||||
|
||||
+1
-2
@@ -4,7 +4,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
@@ -79,7 +78,7 @@ public sealed class WinRTClassUsingNotifyPropertyChangedAttributesAnalyzer : Dia
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
GeneratorAttributeNamesToDiagnosticsMap[attributeClass.Name],
|
||||
context.Symbol.Locations.FirstOrDefault(),
|
||||
context.Symbol.GetLocationFromAttributeDataOrDefault(attribute),
|
||||
context.Symbol));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -6,7 +6,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
@@ -56,7 +55,7 @@ public sealed class WinRTGeneratedBindableCustomPropertyWithBasesMemberAnalyzer
|
||||
}
|
||||
|
||||
// We only care about it if it's using [GeneratedBindableCustomProperty]
|
||||
if (!typeSymbol.HasAttributeWithType(generatedBindableCustomPropertySymbol))
|
||||
if (!typeSymbol.TryGetAttributeWithType(generatedBindableCustomPropertySymbol, out AttributeData? generatedBindableCustomPropertyAttribute))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -66,7 +65,7 @@ public sealed class WinRTGeneratedBindableCustomPropertyWithBasesMemberAnalyzer
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
WinRTGeneratedBindableCustomPropertyWithBaseObservablePropertyOnField,
|
||||
typeSymbol.Locations.FirstOrDefault(),
|
||||
typeSymbol.GetLocationFromAttributeDataOrDefault(generatedBindableCustomPropertyAttribute),
|
||||
typeSymbol,
|
||||
fieldSymbol.ContainingType,
|
||||
fieldSymbol.Name));
|
||||
@@ -77,7 +76,7 @@ public sealed class WinRTGeneratedBindableCustomPropertyWithBasesMemberAnalyzer
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
WinRTGeneratedBindableCustomPropertyWithBaseRelayCommand,
|
||||
typeSymbol.Locations.FirstOrDefault(),
|
||||
typeSymbol.GetLocationFromAttributeDataOrDefault(generatedBindableCustomPropertyAttribute),
|
||||
typeSymbol,
|
||||
methodSymbol));
|
||||
}
|
||||
|
||||
+2
-3
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
@@ -50,7 +49,7 @@ public sealed class WinRTRelayCommandIsNotGeneratedBindableCustomPropertyCompati
|
||||
}
|
||||
|
||||
// If the method is not using [RelayCommand], we can skip it
|
||||
if (!methodSymbol.HasAttributeWithType(relayCommandSymbol))
|
||||
if (!methodSymbol.TryGetAttributeWithType(relayCommandSymbol, out AttributeData? relayCommandAttribute))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -60,7 +59,7 @@ public sealed class WinRTRelayCommandIsNotGeneratedBindableCustomPropertyCompati
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
WinRTRelayCommandIsNotGeneratedBindableCustomPropertyCompatible,
|
||||
methodSymbol.Locations.FirstOrDefault(),
|
||||
methodSymbol.GetLocationFromAttributeDataOrDefault(relayCommandAttribute),
|
||||
methodSymbol));
|
||||
}
|
||||
}, SymbolKind.Method);
|
||||
|
||||
@@ -175,4 +175,31 @@ internal static class ISymbolExtensions
|
||||
accessibility == Accessibility.Public ||
|
||||
accessibility == Accessibility.Internal && symbol.ContainingAssembly.GivesAccessTo(assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the location of a given symbol that is in the same syntax tree of a specified attribute, or the first one.
|
||||
/// </summary>
|
||||
/// <param name="symbol">The input <see cref="ISymbol"/> instance to check.</param>
|
||||
/// <param name="attributeData">The target <see cref="AttributeData"/> instance.</param>
|
||||
/// <returns>The best <see cref="Location"/> match.</returns>
|
||||
public static Location? GetLocationFromAttributeDataOrDefault(this ISymbol symbol, AttributeData attributeData)
|
||||
{
|
||||
Location? firstLocation = null;
|
||||
|
||||
// Get the syntax tree where the attribute application is located. We use
|
||||
// it to try to find the symbol location that belongs to the same file.
|
||||
SyntaxTree? attributeTree = attributeData.ApplicationSyntaxReference?.SyntaxTree;
|
||||
|
||||
foreach (Location location in symbol.Locations)
|
||||
{
|
||||
if (location.SourceTree == attributeTree)
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
firstLocation ??= location;
|
||||
}
|
||||
|
||||
return firstLocation;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user