Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -76,7 +75,7 @@ public override void Initialize(AnalysisContext context)
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#if !ROSLYN_4_11_0_OR_GREATER

using System.Collections.Immutable;
using System.Linq;
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
Expand Down Expand Up @@ -44,11 +45,11 @@ public override void Initialize(AnalysisContext context)
}

// If the property has [ObservableProperty], emit an error in all cases
if (propertySymbol.TryGetAttributeWithType(observablePropertySymbol, out AttributeData? observablePropertyAttribute))
if (propertySymbol.HasAttributeWithType(observablePropertySymbol))
{
context.ReportDiagnostic(Diagnostic.Create(
UnsupportedRoslynVersionForObservablePartialPropertySupport,
observablePropertyAttribute.GetLocation(),
propertySymbol.Locations.FirstOrDefault(),
propertySymbol.ContainingType,
propertySymbol));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#if ROSLYN_4_11_0_OR_GREATER

using System.Collections.Immutable;
using System.Linq;
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
Expand Down Expand Up @@ -57,7 +58,7 @@ public override void Initialize(AnalysisContext context)
}

// Check that we are in fact using [ObservableProperty]
if (!fieldSymbol.TryGetAttributeWithType(observablePropertySymbol, out AttributeData? observablePropertyAttribute))
if (!fieldSymbol.HasAttributeWithType(observablePropertySymbol))
{
return;
}
Expand All @@ -74,7 +75,7 @@ public override void Initialize(AnalysisContext context)
// Emit the diagnostic for this field to suggest changing to a partial property instead
context.ReportDiagnostic(Diagnostic.Create(
UseObservablePropertyOnPartialProperty,
observablePropertyAttribute.GetLocation(),
fieldSymbol.Locations.FirstOrDefault(),
ImmutableDictionary.Create<string, string?>()
.Add(FieldReferenceForObservablePropertyFieldAnalyzer.FieldNameKey, fieldSymbol.Name)
.Add(FieldReferenceForObservablePropertyFieldAnalyzer.PropertyNameKey, ObservablePropertyGenerator.Execute.GetGeneratedPropertyName(fieldSymbol)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -79,7 +78,7 @@ public override void Initialize(AnalysisContext context)
{
context.ReportDiagnostic(Diagnostic.Create(
GeneratorAttributeNamesToDiagnosticsMap[attributeClass.Name],
context.Symbol.Locations.FirstOrDefault(),
context.Symbol.GetLocationFromAttributeDataOrDefault(attribute),
context.Symbol));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public override void Initialize(AnalysisContext context)
{
context.ReportDiagnostic(Diagnostic.Create(
WinRTGeneratedBindableCustomPropertyWithBaseObservablePropertyOnField,
generatedBindableCustomPropertyAttribute.GetLocation(),
typeSymbol.GetLocationFromAttributeDataOrDefault(generatedBindableCustomPropertyAttribute),
typeSymbol,
fieldSymbol.ContainingType,
fieldSymbol.Name));
Expand All @@ -76,7 +76,7 @@ public override void Initialize(AnalysisContext context)
{
context.ReportDiagnostic(Diagnostic.Create(
WinRTGeneratedBindableCustomPropertyWithBaseRelayCommand,
generatedBindableCustomPropertyAttribute.GetLocation(),
typeSymbol.GetLocationFromAttributeDataOrDefault(generatedBindableCustomPropertyAttribute),
typeSymbol,
methodSymbol));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#if ROSLYN_4_11_0_OR_GREATER

using System.Collections.Immutable;
using System.Linq;
using CommunityToolkit.Mvvm.SourceGenerators.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
Expand Down Expand Up @@ -50,11 +51,11 @@ public override void Initialize(AnalysisContext context)
}

// Emit a diagnostic if the field is using the [ObservableProperty] attribute
if (fieldSymbol.TryGetAttributeWithType(observablePropertySymbol, out AttributeData? observablePropertyAttribute))
if (fieldSymbol.HasAttributeWithType(observablePropertySymbol))
{
context.ReportDiagnostic(Diagnostic.Create(
WinRTObservablePropertyOnFieldsIsNotAotCompatible,
observablePropertyAttribute.GetLocation(),
fieldSymbol.Locations.FirstOrDefault(),
ImmutableDictionary.Create<string, string?>()
.Add(FieldReferenceForObservablePropertyFieldAnalyzer.FieldNameKey, fieldSymbol.Name)
.Add(FieldReferenceForObservablePropertyFieldAnalyzer.PropertyNameKey, ObservablePropertyGenerator.Execute.GetGeneratedPropertyName(fieldSymbol)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public override void Initialize(AnalysisContext context)
{
context.ReportDiagnostic(Diagnostic.Create(
WinRTRelayCommandIsNotGeneratedBindableCustomPropertyCompatible,
relayCommandAttribute.GetLocation(),
methodSymbol.GetLocationFromAttributeDataOrDefault(relayCommandAttribute),
methodSymbol));
}
}, SymbolKind.Method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,31 @@ public static bool CanBeAccessedFrom(this ISymbol symbol, IAssemblySymbol assemb
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ namespace MyApp
{
public partial class SampleViewModel : ObservableObject
{
[{|MVVMTK0044:ObservableProperty|}]
public string Bar { get; set; }
[ObservableProperty]
public string {|MVVMTK0044:Bar|} { get; set; }
}
}
""";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ namespace MyApp
{
public partial class SampleViewModel : ObservableObject
{
[{|MVVMTK0042:ObservableProperty|}]
private string name;
[ObservableProperty]
private string {|MVVMTK0042:name|};
}
}
""";
Expand Down Expand Up @@ -371,8 +371,8 @@ namespace MyApp
{
public partial class SampleViewModel : ObservableObject
{
[{|MVVMTK0045:ObservableProperty|}]
private string name;
[ObservableProperty]
private string {|MVVMTK0045:name|};
}
}
""";
Expand Down Expand Up @@ -415,8 +415,8 @@ namespace MyApp
{
public partial class SampleViewModel : ObservableObject
{
[{|MVVMTK0045:ObservableProperty|}]
private string name;
[ObservableProperty]
private string {|MVVMTK0045:name|};
}
}
""";
Expand All @@ -437,8 +437,8 @@ namespace MyApp
{
public partial class SampleViewModel : ObservableObject
{
[{|MVVMTK0045:ObservableProperty|}]
private string name;
[ObservableProperty]
private string {|MVVMTK0045:name|};
}
}
""";
Expand All @@ -459,8 +459,8 @@ namespace MyApp
{
public partial class SampleViewModel : ObservableObject
{
[{|MVVMTK0045:ObservableProperty|}]
private string name;
[ObservableProperty]
private string {|MVVMTK0045:name|};
}
}

Expand All @@ -486,8 +486,8 @@ namespace MyApp
{
public partial class SampleViewModel : ObservableObject
{
[{|MVVMTK0045:ObservableProperty|}]
private string name;
[ObservableProperty]
private string {|MVVMTK0045:name|};
}
}

Expand Down Expand Up @@ -585,8 +585,8 @@ public async Task WinRTGeneratedBindableCustomPropertyWithBasesMemberAnalyzer_Ta

namespace MyApp
{
[{|MVVMTK0047:GeneratedBindableCustomProperty|}]
public partial class SampleViewModel : BaseViewModel
[GeneratedBindableCustomProperty]
public partial class {|MVVMTK0047:SampleViewModel|} : BaseViewModel
{
}

Expand Down Expand Up @@ -620,8 +620,8 @@ public async Task WinRTGeneratedBindableCustomPropertyWithBasesMemberAnalyzer_Ta

namespace MyApp
{
[{|MVVMTK0048:GeneratedBindableCustomProperty|}]
public partial class SampleViewModel : BaseViewModel
[GeneratedBindableCustomProperty]
public partial class {|MVVMTK0048:SampleViewModel|} : BaseViewModel
{
}

Expand Down
Loading