Skip to content
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

[Binding SG] Removed deprecated InterceptsLocationAttribute #27145

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 6 additions & 11 deletions src/Controls/src/BindingSourceGen/BindingCodeWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,11 @@ namespace System.Runtime.CompilerServices
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute : Attribute
{
public InterceptsLocationAttribute(string filePath, int line, int column)
public InterceptsLocationAttribute(int version, string data)
{
FilePath = filePath;
Line = line;
Column = column;
_ = version;
_ = data;
}

public string FilePath { get; }
public int Line { get; }
public int Column { get; }
}
}

Expand Down Expand Up @@ -177,7 +172,7 @@ public BindingInterceptorCodeBuilder(int indent = 0)
public void AppendSetBindingInterceptor(uint id, BindingInvocationDescription binding)
{
AppendLine(GeneratedCodeAttribute);
AppendInterceptorAttribute(binding.Location);
AppendInterceptorAttribute(binding.InterceptableLocation);
AppendMethodName(binding, id);
if (binding.SourceType.IsGenericParameter && binding.PropertyType.IsGenericParameter)
{
Expand Down Expand Up @@ -310,9 +305,9 @@ private void AppendMethodName(BindingInvocationDescription binding, uint id)
});
}

private void AppendInterceptorAttribute(InterceptorLocation location)
private void AppendInterceptorAttribute(InterceptableLocationRecord location)
{
AppendLine($"[InterceptsLocationAttribute(@\"{location.FilePath}\", {location.Line}, {location.Column})]");
AppendLine($"[InterceptsLocationAttribute({location.Version}, @\"{location.Data}\")]");
}

private void AppendSetterAction(BindingInvocationDescription binding, uint id, string sourceVariableName = "source", string valueVariableName = "value")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
namespace Microsoft.Maui.Controls.BindingSourceGen;

public sealed record BindingInvocationDescription(
InterceptorLocation Location,
InterceptableLocationRecord InterceptableLocation,
SimpleLocation SimpleLocation,
TypeDescription SourceType,
TypeDescription PropertyType,
EquatableArray<IPathPart> Path,
SetterOptions SetterOptions,
bool NullableContextEnabled,
InterceptedMethodType MethodType);


public sealed record InterceptableLocationRecord(int Version, string Data);

public sealed record SourceCodeLocation(string FilePath, TextSpan TextSpan, LinePositionSpan LineSpan)
{
public static SourceCodeLocation? CreateFrom(Location location)
Expand All @@ -24,13 +28,13 @@ public Location ToLocation()
return Location.Create(FilePath, TextSpan, LineSpan);
}

public InterceptorLocation ToInterceptorLocation()
public SimpleLocation ToSimpleLocation()
{
return new InterceptorLocation(FilePath, LineSpan.Start.Line + 1, LineSpan.Start.Character + 1);
return new SimpleLocation(FilePath, LineSpan.Start.Line + 1, LineSpan.Start.Character + 1);
}
}

public sealed record InterceptorLocation(string FilePath, int Line, int Column);
public sealed record SimpleLocation(string FilePath, int Line, int Column);

public sealed record TypeDescription(
string GlobalName,
Expand Down
16 changes: 12 additions & 4 deletions src/Controls/src/BindingSourceGen/BindingSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context)

context.RegisterImplementationSourceOutput(bindings, (spc, binding) =>
{
var fileName = $"{binding.Location.FilePath}-GeneratedBindingInterceptors-{binding.Location.Line}-{binding.Location.Column}.g.cs";
var location = binding.SimpleLocation;
var fileName = $"{location.FilePath}-GeneratedBindingInterceptors-{location.Line}-{location.Column}.g.cs";
var sanitizedFileName = fileName.Replace('/', '-').Replace('\\', '-').Replace(':', '-');
var code = BindingCodeWriter.GenerateBinding(binding, (uint)Math.Abs(binding.Location.GetHashCode()));
var code = BindingCodeWriter.GenerateBinding(binding, (uint)Math.Abs(location.GetHashCode()));
spc.AddSource(sanitizedFileName, code);
});
}
Expand Down Expand Up @@ -83,8 +84,14 @@ private static Result<BindingInvocationDescription> GetBindingForGeneration(Gene
return Result<BindingInvocationDescription>.Failure(interceptedMethodTypeResult.Diagnostics);
}

#pragma warning disable RSEXPERIMENTAL002
var interceptableLocation = context.SemanticModel.GetInterceptableLocation(invocation, t);
#pragma warning restore RSEXPERIMENTAL002

var sourceCodeLocation = SourceCodeLocation.CreateFrom(method.Name.GetLocation());
if (sourceCodeLocation == null)


if (interceptableLocation == null || sourceCodeLocation == null)
{
return Result<BindingInvocationDescription>.Failure(DiagnosticsFactory.UnableToResolvePath(invocation.GetLocation()));
}
Expand Down Expand Up @@ -115,7 +122,8 @@ private static Result<BindingInvocationDescription> GetBindingForGeneration(Gene
}

var binding = new BindingInvocationDescription(
Location: sourceCodeLocation.ToInterceptorLocation(),
InterceptableLocation: new InterceptableLocationRecord(interceptableLocation.Version, interceptableLocation.Data),
SimpleLocation: sourceCodeLocation.ToSimpleLocation(),
SourceType: lambdaParamTypeResult.Value.CreateTypeDescription(enabledNullable),
PropertyType: lambdaReturnTypeResult.Value.CreateTypeDescription(enabledNullable),
Path: new EquatableArray<IPathPart>([.. pathParseResult.Value]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
</ItemGroup>

Expand All @@ -29,4 +29,4 @@
</ItemGroup>
<Copy SourceFiles="@(_CopyItems)" DestinationFolder="$(_MauiBuildTasksLocation)" ContinueOnError="true" Retries="0" />
</Target>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ internal static void BindingsAreEqual(BindingInvocationDescription expectedBindi
AssertNoDiagnostics(codeGeneratorResult);
Assert.NotNull(codeGeneratorResult.Binding);

//TODO: Change arrays to custom collections implementing IEquatable
// Skip interceptable location
Assert.Equal(expectedBinding.SimpleLocation, codeGeneratorResult.Binding.SimpleLocation);
Assert.Equal(expectedBinding.SourceType, codeGeneratorResult.Binding.SourceType);
Assert.Equal(expectedBinding.PropertyType, codeGeneratorResult.Binding.PropertyType);
Assert.Equal(expectedBinding.Path, codeGeneratorResult.Binding.Path);
Assert.Equal(expectedBinding, codeGeneratorResult.Binding);
Assert.Equal(expectedBinding.SetterOptions, codeGeneratorResult.Binding.SetterOptions);
Assert.Equal(expectedBinding.NullableContextEnabled, codeGeneratorResult.Binding.NullableContextEnabled);
Assert.Equal(expectedBinding.MethodType, codeGeneratorResult.Binding.MethodType);

}

private static IEnumerable<string> SplitCode(string code)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ private static bool ShouldUseSetter(BindingMode mode)
public void BuildsWholeBinding()
{
var code = BindingCodeWriter.GenerateBinding(new BindingInvocationDescription(
Location: new InterceptorLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30),
InterceptableLocation: new InterceptableLocationRecord(Version: 1, Data: "serializedData"),
SimpleLocation: new SimpleLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30),
SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
PropertyType: new TypeDescription("global::MyNamespace.MyPropertyClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
Path: new EquatableArray<IPathPart>([
Expand Down Expand Up @@ -83,16 +84,11 @@ namespace System.Runtime.CompilerServices
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute : Attribute
{
public InterceptsLocationAttribute(string filePath, int line, int column)
public InterceptsLocationAttribute(int version, string data)
{
FilePath = filePath;
Line = line;
Column = column;
_ = version;
_ = data;
}

public string FilePath { get; }
public int Line { get; }
public int Column { get; }
}
}

Expand All @@ -107,7 +103,7 @@ internal static partial class GeneratedBindingInterceptors
{

{{BindingCodeWriter.GeneratedCodeAttribute}}
[InterceptsLocationAttribute(@"Path\To\Program.cs", 20, 30)]
[InterceptsLocationAttribute(1, @"serializedData")]
public static void SetBinding1(
this BindableObject bindableObject,
BindableProperty bindableProperty,
Expand Down Expand Up @@ -164,8 +160,8 @@ public void CorrectlyFormatsSimpleBinding()
{
var codeBuilder = new BindingCodeWriter.BindingInterceptorCodeBuilder();
codeBuilder.AppendSetBindingInterceptor(id: 1, new BindingInvocationDescription(
Location: new InterceptorLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30),
SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
InterceptableLocation: new InterceptableLocationRecord(Version: 1, Data: "serializedData"),
SimpleLocation: new SimpleLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30), SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
PropertyType: new TypeDescription("global::MyNamespace.MyPropertyClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
Path: new EquatableArray<IPathPart>([
new MemberAccess("A"),
Expand All @@ -180,7 +176,7 @@ public void CorrectlyFormatsSimpleBinding()
AssertExtensions.CodeIsEqual(
$$"""
{{BindingCodeWriter.GeneratedCodeAttribute}}
[InterceptsLocationAttribute(@"Path\To\Program.cs", 20, 30)]
[InterceptsLocationAttribute(1, @"serializedData")]
public static void SetBinding1(
this BindableObject bindableObject,
BindableProperty bindableProperty,
Expand Down Expand Up @@ -236,8 +232,8 @@ public void CorrectlyFormatsBindingWithoutAnyNullablesInPath()
{
var codeBuilder = new BindingCodeWriter.BindingInterceptorCodeBuilder();
codeBuilder.AppendSetBindingInterceptor(id: 1, new BindingInvocationDescription(
Location: new InterceptorLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30),
SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
InterceptableLocation: new InterceptableLocationRecord(Version: 1, Data: "serializedData"),
SimpleLocation: new SimpleLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30), SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
PropertyType: new TypeDescription("global::MyNamespace.MyPropertyClass", IsValueType: false, IsNullable: false, IsGenericParameter: false),
Path: new EquatableArray<IPathPart>([
new MemberAccess("A"),
Expand All @@ -252,7 +248,7 @@ public void CorrectlyFormatsBindingWithoutAnyNullablesInPath()
AssertExtensions.CodeIsEqual(
$$"""
{{BindingCodeWriter.GeneratedCodeAttribute}}
[InterceptsLocationAttribute(@"Path\To\Program.cs", 20, 30)]
[InterceptsLocationAttribute(1, @"serializedData")]
public static void SetBinding1(
this BindableObject bindableObject,
BindableProperty bindableProperty,
Expand Down Expand Up @@ -304,8 +300,8 @@ public void CorrectlyFormatsBindingWithoutSetter()
{
var codeBuilder = new BindingCodeWriter.BindingInterceptorCodeBuilder();
codeBuilder.AppendSetBindingInterceptor(id: 1, new BindingInvocationDescription(
Location: new InterceptorLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30),
SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsNullable: false, IsGenericParameter: false, IsValueType: false),
InterceptableLocation: new InterceptableLocationRecord(Version: 1, Data: "serializedData"),
SimpleLocation: new SimpleLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30), SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsNullable: false, IsGenericParameter: false, IsValueType: false),
PropertyType: new TypeDescription("global::MyNamespace.MyPropertyClass", IsNullable: false, IsGenericParameter: false, IsValueType: false),
Path: new EquatableArray<IPathPart>([
new MemberAccess("A"),
Expand All @@ -320,7 +316,7 @@ public void CorrectlyFormatsBindingWithoutSetter()
AssertExtensions.CodeIsEqual(
$$"""
{{BindingCodeWriter.GeneratedCodeAttribute}}
[InterceptsLocationAttribute(@"Path\To\Program.cs", 20, 30)]
[InterceptsLocationAttribute(1, @"serializedData")]
public static void SetBinding1(
this BindableObject bindableObject,
BindableProperty bindableProperty,
Expand Down Expand Up @@ -369,8 +365,8 @@ public void CorrectlyFormatsBindingWithIndexers()
{
var codeBuilder = new BindingCodeWriter.BindingInterceptorCodeBuilder();
codeBuilder.AppendSetBindingInterceptor(id: 1, new BindingInvocationDescription(
Location: new InterceptorLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30),
SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsNullable: false, IsGenericParameter: false),
InterceptableLocation: new InterceptableLocationRecord(Version: 1, Data: "serializedData"),
SimpleLocation: new SimpleLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30), SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsNullable: false, IsGenericParameter: false),
PropertyType: new TypeDescription("global::MyNamespace.MyPropertyClass", IsNullable: true, IsGenericParameter: false),
Path: new EquatableArray<IPathPart>([
new IndexAccess("Item", 12),
Expand All @@ -385,7 +381,7 @@ public void CorrectlyFormatsBindingWithIndexers()
AssertExtensions.CodeIsEqual(
$$"""
{{BindingCodeWriter.GeneratedCodeAttribute}}
[InterceptsLocationAttribute(@"Path\To\Program.cs", 20, 30)]
[InterceptsLocationAttribute(1, @"serializedData")]
public static void SetBinding1(
this BindableObject bindableObject,
BindableProperty bindableProperty,
Expand Down Expand Up @@ -448,8 +444,8 @@ public void CorrectlyFormatsBindingWithCasts()
{
var codeBuilder = new BindingCodeWriter.BindingInterceptorCodeBuilder();
codeBuilder.AppendSetBindingInterceptor(id: 1, new BindingInvocationDescription(
Location: new InterceptorLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30),
SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsNullable: false, IsGenericParameter: false),
InterceptableLocation: new InterceptableLocationRecord(Version: 1, Data: "serializedData"),
SimpleLocation: new SimpleLocation(FilePath: @"Path\To\Program.cs", Line: 20, Column: 30), SourceType: new TypeDescription("global::MyNamespace.MySourceClass", IsNullable: false, IsGenericParameter: false),
PropertyType: new TypeDescription("global::MyNamespace.MyPropertyClass", IsNullable: false, IsGenericParameter: false),
Path: new EquatableArray<IPathPart>([
new MemberAccess("A"),
Expand All @@ -469,7 +465,7 @@ public void CorrectlyFormatsBindingWithCasts()
AssertExtensions.CodeIsEqual(
$$"""
{{BindingCodeWriter.GeneratedCodeAttribute}}
[InterceptsLocationAttribute(@"Path\To\Program.cs", 20, 30)]
[InterceptsLocationAttribute(1, @"serializedData")]
public static void SetBinding1(
this BindableObject bindableObject,
BindableProperty bindableProperty,
Expand Down
Loading
Loading