Skip to content

Commit

Permalink
Strip trivia from tokens. (#88856)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
jkoritzinsky committed Jul 14, 2023
1 parent 45db21d commit 1deac17
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(

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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(

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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M

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<FunctionPointerUnmanagedCallingConventionSyntax> callConv = VirtualMethodPointerStubGenerator.GenerateCallConvSyntaxFromAttributes(
suppressGCTransitionAttribute,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M

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<FunctionPointerUnmanagedCallingConventionSyntax> callConv = VirtualMethodPointerStubGenerator.GenerateCallConvSyntaxFromAttributes(suppressGCTransitionAttribute, unmanagedCallConvAttribute, defaultCallingConventions: ImmutableArray<FunctionPointerUnmanagedCallingConventionSyntax>.Empty);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(

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<AttributeSyntax> additionalAttributes = GenerateSyntaxForForwardedAttributes(suppressGCTransitionAttribute, unmanagedCallConvAttribute, defaultDllImportSearchPathsAttribute);
return new IncrementalStubGenerationContext(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,18 @@

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<ContainingSyntax>
{
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)
Expand Down Expand Up @@ -42,8 +52,12 @@ private static ImmutableArray<ContainingSyntax> GetContainingTypes(MemberDeclara
ImmutableArray<ContainingSyntax>.Builder containingTypeInfoBuilder = ImmutableArray.CreateBuilder<ContainingSyntax>();
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -558,69 +558,45 @@ public static IEnumerable<object[]> ByValueMarshalAttributeOnValueTypes()

// [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.
var outAttributeNotSupportedOnValueParameters = new DiagnosticResult(GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails)
.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
} };

Expand Down Expand Up @@ -688,12 +664,12 @@ public static IEnumerable<object[]> ByValueMarshalAttributeOnReferenceTypes()
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)
Expand All @@ -704,21 +680,21 @@ public static IEnumerable<object[]> ByValueMarshalAttributeOnReferenceTypes()
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
Expand Down Expand Up @@ -774,11 +750,10 @@ public static IEnumerable<object[]> ByValueMarshalAttributeOnPinnedMarshalledTyp
.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)),
Expand All @@ -793,13 +768,13 @@ public static IEnumerable<object[]> ByValueMarshalAttributeOnPinnedMarshalledTyp
"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
Expand All @@ -811,12 +786,12 @@ public static IEnumerable<object[]> ByValueMarshalAttributeOnPinnedMarshalledTyp
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 }
};

Expand Down Expand Up @@ -847,7 +822,7 @@ public async Task VerifyByValueMarshallingAttributeUsage(string id, string sourc
{
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);
Expand Down

0 comments on commit 1deac17

Please sign in to comment.