From 1deac177b2b63d1122225f5a53a0780fd99ed12b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 13 Jul 2023 19:10:18 -0700 Subject: [PATCH] Strip trivia from tokens. (#88856) * Strip trivia from tokens. Fixes #88798 * Move the trivia stripping into ContainingSyntax record constructor * Make ContainingSyntax a regular struct with a primary constructor instead of a record struct. * Fix #88867 * Suppress compiler diagnostics based on the linked issue. --- .../gen/JSImportGenerator/JSExportGenerator.cs | 2 +- .../gen/JSImportGenerator/JSImportGenerator.cs | 2 +- .../ComInterfaceGenerator/ComInterfaceGenerator.cs | 2 +- .../VtableIndexStubGenerator.cs | 2 +- .../LibraryImportGenerator.cs | 2 +- .../ContainingSyntaxContext.cs | 20 ++++++-- .../CompileFails.cs | 53 ++++++---------------- 7 files changed, 36 insertions(+), 47 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportGenerator.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportGenerator.cs index cf64774..b0bfeef 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportGenerator.cs @@ -206,7 +206,7 @@ namespace Microsoft.Interop.JavaScript var containingTypeContext = new ContainingSyntaxContext(originalSyntax); - var methodSyntaxTemplate = new ContainingSyntax(originalSyntax.Modifiers.StripTriviaFromTokens(), SyntaxKind.MethodDeclaration, originalSyntax.Identifier, originalSyntax.TypeParameterList); + var methodSyntaxTemplate = new ContainingSyntax(originalSyntax.Modifiers, SyntaxKind.MethodDeclaration, originalSyntax.Identifier, originalSyntax.TypeParameterList); return new IncrementalStubGenerationContext( signatureContext, diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSImportGenerator.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSImportGenerator.cs index 99bdb63..87d0484 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSImportGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSImportGenerator.cs @@ -194,7 +194,7 @@ namespace Microsoft.Interop.JavaScript var containingTypeContext = new ContainingSyntaxContext(originalSyntax); - var methodSyntaxTemplate = new ContainingSyntax(originalSyntax.Modifiers.StripTriviaFromTokens(), SyntaxKind.MethodDeclaration, originalSyntax.Identifier, originalSyntax.TypeParameterList); + var methodSyntaxTemplate = new ContainingSyntax(originalSyntax.Modifiers, SyntaxKind.MethodDeclaration, originalSyntax.Identifier, originalSyntax.TypeParameterList); return new IncrementalStubGenerationContext( signatureContext, containingTypeContext, diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs index ddaff90..e1cc737 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs @@ -307,7 +307,7 @@ namespace Microsoft.Interop var containingSyntaxContext = new ContainingSyntaxContext(syntax); - var methodSyntaxTemplate = new ContainingSyntax(syntax.Modifiers.StripAccessibilityModifiers().StripTriviaFromTokens(), SyntaxKind.MethodDeclaration, syntax.Identifier, syntax.TypeParameterList); + var methodSyntaxTemplate = new ContainingSyntax(syntax.Modifiers.StripAccessibilityModifiers(), SyntaxKind.MethodDeclaration, syntax.Identifier, syntax.TypeParameterList); ImmutableArray callConv = VirtualMethodPointerStubGenerator.GenerateCallConvSyntaxFromAttributes( suppressGCTransitionAttribute, diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs index dea2aca..e5faa6f 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs @@ -278,7 +278,7 @@ namespace Microsoft.Interop var containingSyntaxContext = new ContainingSyntaxContext(syntax); - var methodSyntaxTemplate = new ContainingSyntax(syntax.Modifiers.StripAccessibilityModifiers().StripTriviaFromTokens(), SyntaxKind.MethodDeclaration, syntax.Identifier, syntax.TypeParameterList); + var methodSyntaxTemplate = new ContainingSyntax(syntax.Modifiers.StripAccessibilityModifiers(), SyntaxKind.MethodDeclaration, syntax.Identifier, syntax.TypeParameterList); ImmutableArray callConv = VirtualMethodPointerStubGenerator.GenerateCallConvSyntaxFromAttributes(suppressGCTransitionAttribute, unmanagedCallConvAttribute, defaultCallingConventions: ImmutableArray.Empty); diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs index 2d61f23..fcd915e 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.cs @@ -288,7 +288,7 @@ namespace Microsoft.Interop var containingTypeContext = new ContainingSyntaxContext(originalSyntax); - var methodSyntaxTemplate = new ContainingSyntax(originalSyntax.Modifiers.StripTriviaFromTokens(), SyntaxKind.MethodDeclaration, originalSyntax.Identifier, originalSyntax.TypeParameterList); + var methodSyntaxTemplate = new ContainingSyntax(originalSyntax.Modifiers, SyntaxKind.MethodDeclaration, originalSyntax.Identifier, originalSyntax.TypeParameterList); List additionalAttributes = GenerateSyntaxForForwardedAttributes(suppressGCTransitionAttribute, unmanagedCallConvAttribute, defaultDllImportSearchPathsAttribute); return new IncrementalStubGenerationContext( diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs index 5902831..1ac5eff 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs @@ -12,8 +12,18 @@ using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Microsoft.Interop { - public readonly record struct ContainingSyntax(SyntaxTokenList Modifiers, SyntaxKind TypeKind, SyntaxToken Identifier, TypeParameterListSyntax? TypeParameters) + public readonly struct ContainingSyntax(SyntaxTokenList modifiers, SyntaxKind typeKind, SyntaxToken identifier, TypeParameterListSyntax? typeParameters) : IEquatable { + public SyntaxTokenList Modifiers { get; init; } = modifiers.StripTriviaFromTokens(); + + public SyntaxToken Identifier { get; init; } = identifier.WithoutTrivia(); + + public SyntaxKind TypeKind { get; init; } = typeKind; + + public TypeParameterListSyntax? TypeParameters { get; init; } = typeParameters; + + public override bool Equals(object obj) => obj is ContainingSyntax other && Equals(other); + public bool Equals(ContainingSyntax other) { return Modifiers.SequenceEqual(other.Modifiers, SyntaxEquivalentComparer.Instance) @@ -42,8 +52,12 @@ namespace Microsoft.Interop ImmutableArray.Builder containingTypeInfoBuilder = ImmutableArray.CreateBuilder(); for (SyntaxNode? parent = memberDeclaration.Parent; parent is TypeDeclarationSyntax typeDeclaration; parent = parent.Parent) { - containingTypeInfoBuilder.Add(new ContainingSyntax(typeDeclaration.Modifiers.StripTriviaFromTokens(), typeDeclaration.Kind(), typeDeclaration.Identifier.WithoutTrivia(), - typeDeclaration.TypeParameterList)); + containingTypeInfoBuilder.Add( + new ContainingSyntax( + typeDeclaration.Modifiers, + typeDeclaration.Kind(), + typeDeclaration.Identifier, + typeDeclaration.TypeParameterList)); } return containingTypeInfoBuilder.ToImmutable(); diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs index b2a3c6a..c4e5f9b 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs @@ -558,20 +558,12 @@ namespace ComInterfaceGenerator.Unit.Tests // [In] is default for all non-pinned marshalled types yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute, "int", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic, - //https://github.com/dotnet/runtime/issues/88540 inAttributeIsDefaultDiagnostic } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute, "byte", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic, - //https://github.com/dotnet/runtime/issues/88540 inAttributeIsDefaultDiagnostic } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + "[MarshalAs(UnmanagedType.U4)]", "bool", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic, - //https://github.com/dotnet/runtime/issues/88540 inAttributeIsDefaultDiagnostic } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + "[MarshalAs(UnmanagedType.U2)]", "char", paramNameWithLocation), new DiagnosticResult[] { - inAttributeIsDefaultDiagnostic, - //https://github.com/dotnet/runtime/issues/88540 inAttributeIsDefaultDiagnostic } }; // [Out] is not allowed on value types passed by value - there is no indirection for the callee to make visible modifications. @@ -579,48 +571,32 @@ namespace ComInterfaceGenerator.Unit.Tests .WithLocation(0) .WithArguments(SR.OutAttributeNotSupportedOnByValueParameters, paramName); yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute, "int", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 outAttributeNotSupportedOnValueParameters } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute, "IntStruct", paramNameWithLocation) + CodeSnippets.IntStructAndMarshaller, new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 - outAttributeNotSupportedOnValueParameters, + outAttributeNotSupportedOnValueParameters } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute + "[MarshalAs(UnmanagedType.U4)]", "bool", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 outAttributeNotSupportedOnValueParameters } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute, "[MarshalAs(UnmanagedType.U2)] char", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 outAttributeNotSupportedOnValueParameters } }; // [In,Out] should only warn for Out attribute yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute+outAttribute, "int", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 outAttributeNotSupportedOnValueParameters } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute+outAttribute, "IntStruct", paramNameWithLocation) + CodeSnippets.IntStructAndMarshaller, new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 - outAttributeNotSupportedOnValueParameters, + outAttributeNotSupportedOnValueParameters } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute + "[MarshalAs(UnmanagedType.U4)]", "bool", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 outAttributeNotSupportedOnValueParameters } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute, "[MarshalAs(UnmanagedType.U2)] char", paramNameWithLocation), new DiagnosticResult[] { - outAttributeNotSupportedOnValueParameters, - //https://github.com/dotnet/runtime/issues/88540 outAttributeNotSupportedOnValueParameters } }; @@ -688,12 +664,12 @@ namespace ComInterfaceGenerator.Unit.Tests yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute, "string", paramNameWithLocation, (StringMarshalling.Utf8, null)), - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic, inAttributeIsDefaultDiagnostic } + new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute, "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic, inAttributeIsDefaultDiagnostic } + new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } }; var outNotAllowedOnRefTypes = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails) @@ -704,21 +680,21 @@ namespace ComInterfaceGenerator.Unit.Tests yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute, "string", paramNameWithLocation, (StringMarshalling.Utf8, null)), - new DiagnosticResult[] { outNotAllowedOnRefTypes, outNotAllowedOnRefTypes } + new DiagnosticResult[] { outNotAllowedOnRefTypes } }; // [Out] warns on by value reference types yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(outAttribute, "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { outNotAllowedOnRefTypes, outNotAllowedOnRefTypes } + new DiagnosticResult[] { outNotAllowedOnRefTypes } }; // [In,Out] is fine on classes yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute, "IntClass", paramNameWithLocation) + CodeSnippets.IntClassAndMarshaller, - new DiagnosticResult[] { outNotAllowedOnRefTypes, outNotAllowedOnRefTypes } + new DiagnosticResult[] { outNotAllowedOnRefTypes } }; // All refkinds are okay on classes and strings @@ -774,11 +750,10 @@ namespace ComInterfaceGenerator.Unit.Tests .WithLocation(0) .WithArguments(SR.InAttributeOnlyNotSupportedOnPinnedParameters, paramName); yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + constElementCount, "int[]", paramNameWithLocation), new DiagnosticResult[] { - inAttributeNotSupportedOnPinnedParameter, - //https://github.com/dotnet/runtime/issues/88540 inAttributeNotSupportedOnPinnedParameter }}; - // new issue before merge: char generated code doesn't seem to work well with [In, Out] + // blittable arrays don't support [In] only. Different diagnostics are issued because we can pin in one direction (managed->unmanaged) + // but not the other direction. yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + constElementCount, "char[]", paramNameWithLocation, (StringMarshalling.Utf16, null)), @@ -793,13 +768,13 @@ namespace ComInterfaceGenerator.Unit.Tests "bool[]", paramNameWithLocation, (StringMarshalling.Utf16, null)), - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic, inAttributeIsDefaultDiagnostic} + new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } }; // Overriding marshalling with a custom marshaller makes it not pinned yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute, "[MarshalUsing(typeof(IntMarshaller), ElementIndirectionDepth = 1), MarshalUsing(ConstantElementCount = 10)]int[]", paramNameWithLocation) + CodeSnippets.IntMarshaller, - new DiagnosticResult[] { inAttributeIsDefaultDiagnostic, inAttributeIsDefaultDiagnostic} + new DiagnosticResult[] { inAttributeIsDefaultDiagnostic } }; // [In, Out] is default @@ -811,12 +786,12 @@ namespace ComInterfaceGenerator.Unit.Tests yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute + constElementCount, "int[]", paramNameWithLocation), - new DiagnosticResult[] { inOutAttributeIsDefaultDiagnostic, inOutAttributeIsDefaultDiagnostic} + new DiagnosticResult[] { inOutAttributeIsDefaultDiagnostic } }; yield return new object[] { ID(), codeSnippets.ByValueMarshallingOfType(inAttribute + outAttribute + constElementCount, "char[]", paramNameWithLocation, (StringMarshalling.Utf16, null)), - //https://github.com/dotnet/runtime/issues/88540 + //https://github.com/dotnet/runtime/issues/88708 new DiagnosticResult[] { inOutAttributeIsDefaultDiagnostic } }; @@ -847,7 +822,7 @@ namespace ComInterfaceGenerator.Unit.Tests { TestCode = source, TestBehaviors = TestBehaviors.SkipGeneratedSourcesCheck, - // Our fallback mechanism for invalid code for unmanaged->managed stubs sometimes generates invalid code. + // https://github.com/dotnet/runtime/issues/88708 CompilerDiagnostics = diagnostics.Length != 0 ? CompilerDiagnostics.None : CompilerDiagnostics.Errors, }; test.ExpectedDiagnostics.AddRange(diagnostics); -- 2.7.4