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

Fix StringMarshalling error message and actually copy attributes from methods to shadows #86731

Merged
merged 4 commits into from
May 26, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static MarshallingGeneratorFactoryKey<(TargetFramework, Version)> CreateG
// If we're in a "supported" scenario, then emit a diagnostic as our final fallback.
generatorFactory = new UnsupportedMarshallingFactory();

generatorFactory = new NoMarshallingInfoErrorMarshallingFactory(generatorFactory);
generatorFactory = new NoMarshallingInfoErrorMarshallingFactory(generatorFactory, TypeNames.GeneratedComInterfaceAttribute_ShortName);

// The presence of System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute is tied to TFM,
// so we use TFM in the generator factory key instead of the Compilation as the compilation changes on every keystroke.
Expand All @@ -27,15 +27,15 @@ public static MarshallingGeneratorFactoryKey<(TargetFramework, Version)> CreateG

// Since the char type can go into the P/Invoke signature here, we can only use it when
// runtime marshalling is disabled.
generatorFactory = new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: runtimeMarshallingDisabled);
generatorFactory = new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: runtimeMarshallingDisabled, TypeNames.GeneratedComInterfaceAttribute_ShortName);

InteropGenerationOptions interopGenerationOptions = new(UseMarshalType: true);
generatorFactory = new MarshalAsMarshallingGeneratorFactory(interopGenerationOptions, generatorFactory);

IMarshallingGeneratorFactory elementFactory = new AttributedMarshallingModelGeneratorFactory(
// Since the char type in an array will not be part of the P/Invoke signature, we can
// use the regular blittable marshaller in all cases.
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true),
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true, TypeNames.GeneratedComInterfaceAttribute_ShortName),
new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, MarshalMode.ElementIn, MarshalMode.ElementRef, MarshalMode.ElementOut));
// We don't need to include the later generator factories for collection elements
// as the later generator factories only apply to parameters.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ private MethodDeclarationSyntax GenerateShadow()
var forwarder = new Forwarder();
return MethodDeclaration(GenerationContext.SignatureContext.StubReturnType, MethodInfo.MethodName)
.WithModifiers(TokenList(Token(SyntaxKind.NewKeyword)))
.WithAttributeLists(List(GenerationContext.SignatureContext.AdditionalAttributes.Concat(MethodInfo.Attributes.Select(a => a.GenerateAttributeList()))))
.WithParameterList(ParameterList(SeparatedList(GenerationContext.SignatureContext.StubParameters)))
.WithExpressionBody(
ArrowExpressionClause(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
Expand All @@ -16,7 +17,8 @@ namespace Microsoft.Interop
/// </summary>
internal sealed record ComMethodInfo(
MethodDeclarationSyntax Syntax,
string MethodName)
string MethodName,
SequenceEqualImmutableArray<AttributeInfo> Attributes)
{
/// <summary>
/// Returns a list of tuples of ComMethodInfo, IMethodSymbol, and Diagnostic. If ComMethodInfo is null, Diagnostic will not be null, and vice versa.
Expand Down Expand Up @@ -108,7 +110,14 @@ private static (ComMethodInfo?, IMethodSymbol, Diagnostic?) CalculateMethodInfo(
{
return (null, method, diag);
}
var comMethodInfo = new ComMethodInfo(comMethodDeclaringSyntax, method.Name);

var attributes = method.GetAttributes();
var attributeInfos = ImmutableArray.CreateBuilder<AttributeInfo>(attributes.Length);
foreach (var attr in attributes)
{
attributeInfos.Add(AttributeInfo.From(attr));
}
var comMethodInfo = new ComMethodInfo(comMethodDeclaringSyntax, method.Name, attributeInfos.MoveToImmutable().ToSequenceEqual());
return (comMethodInfo, method, null);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static MarshallingGeneratorFactoryKey<(TargetFramework, Version)> CreateG
// If we're in a "supported" scenario, then emit a diagnostic as our final fallback.
generatorFactory = new UnsupportedMarshallingFactory();

generatorFactory = new NoMarshallingInfoErrorMarshallingFactory(generatorFactory);
generatorFactory = new NoMarshallingInfoErrorMarshallingFactory(generatorFactory, TypeNames.VirtualMethodIndexAttribute_ShortName);

// The presence of System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute is tied to TFM,
// so we use TFM in the generator factory key instead of the Compilation as the compilation changes on every keystroke.
Expand All @@ -27,15 +27,15 @@ public static MarshallingGeneratorFactoryKey<(TargetFramework, Version)> CreateG

// Since the char type can go into the P/Invoke signature here, we can only use it when
// runtime marshalling is disabled.
generatorFactory = new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: runtimeMarshallingDisabled);
generatorFactory = new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: runtimeMarshallingDisabled, TypeNames.VirtualMethodIndexAttribute_ShortName);

InteropGenerationOptions interopGenerationOptions = new(UseMarshalType: true);
generatorFactory = new MarshalAsMarshallingGeneratorFactory(interopGenerationOptions, generatorFactory);

IMarshallingGeneratorFactory elementFactory = new AttributedMarshallingModelGeneratorFactory(
// Since the char type in an array will not be part of the P/Invoke signature, we can
// use the regular blittable marshaller in all cases.
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true),
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true, TypeNames.VirtualMethodIndexAttribute_ShortName),
new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, MarshalMode.ElementIn, MarshalMode.ElementRef, MarshalMode.ElementOut));
// We don't need to include the later generator factories for collection elements
// as the later generator factories only apply to parameters.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static MarshallingGeneratorFactoryKey<(TargetFramework, Version, LibraryI
generatorFactory = new UnsupportedMarshallingFactory();
}

generatorFactory = new NoMarshallingInfoErrorMarshallingFactory(generatorFactory);
generatorFactory = new NoMarshallingInfoErrorMarshallingFactory(generatorFactory, TypeNames.LibraryImportAttribute_ShortName);

// The presence of System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute is tied to TFM,
// so we use TFM in the generator factory key instead of the Compilation as the compilation changes on every keystroke.
Expand All @@ -43,15 +43,15 @@ public static MarshallingGeneratorFactoryKey<(TargetFramework, Version, LibraryI

// Since the char type can go into the P/Invoke signature here, we can only use it when
// runtime marshalling is disabled.
generatorFactory = new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: runtimeMarshallingDisabled);
generatorFactory = new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: runtimeMarshallingDisabled, TypeNames.LibraryImportAttribute_ShortName);

InteropGenerationOptions interopGenerationOptions = new(options.UseMarshalType);
generatorFactory = new MarshalAsMarshallingGeneratorFactory(interopGenerationOptions, generatorFactory);

IMarshallingGeneratorFactory elementFactory = new AttributedMarshallingModelGeneratorFactory(
// Since the char type in an array will not be part of the P/Invoke signature, we can
// use the regular blittable marshaller in all cases.
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true),
new CharMarshallingGeneratorFactory(generatorFactory, useBlittableMarshallerForUtf16: true, TypeNames.GeneratedComInterfaceAttribute_ShortName),
jtschuster marked this conversation as resolved.
Show resolved Hide resolved
new AttributedMarshallingModelOptions(runtimeMarshallingDisabled, MarshalMode.ElementIn, MarshalMode.ElementRef, MarshalMode.ElementOut));
// We don't need to include the later generator factories for collection elements
// as the later generator factories only apply to parameters.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ public sealed class CharMarshallingGeneratorFactory : IMarshallingGeneratorFacto

private readonly IMarshallingGeneratorFactory _inner;
private readonly bool _useBlittableMarshallerForUtf16;
private readonly string _stringMarshallingAttributeProvider;

public CharMarshallingGeneratorFactory(IMarshallingGeneratorFactory inner, bool useBlittableMarshallerForUtf16)
public CharMarshallingGeneratorFactory(IMarshallingGeneratorFactory inner, bool useBlittableMarshallerForUtf16, string stringMarshallingAttributeProvider)
{
_inner = inner;
_useBlittableMarshallerForUtf16 = useBlittableMarshallerForUtf16;
_stringMarshallingAttributeProvider = stringMarshallingAttributeProvider;
}

public IMarshallingGenerator Create(TypePositionInfo info, StubCodeContext context)
Expand All @@ -41,7 +43,7 @@ private IMarshallingGenerator CreateCharMarshaller(TypePositionInfo info, StubCo
// [Compat] Require explicit marshalling information.
throw new MarshallingNotSupportedException(info, context)
{
NotSupportedDetails = SR.MarshallingStringOrCharAsUndefinedNotSupported
NotSupportedDetails = string.Format(SR.MarshallingStringOrCharAsUndefinedNotSupported, _stringMarshallingAttributeProvider)
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public sealed class NoMarshallingInfoErrorMarshallingFactory : IMarshallingGener
return _inner.Create(info, context);
}

public NoMarshallingInfoErrorMarshallingFactory(IMarshallingGeneratorFactory inner)
: this(inner, DefaultTypeToErrorMessageMap)
public NoMarshallingInfoErrorMarshallingFactory(IMarshallingGeneratorFactory inner, string stringMarshallingAttribute)
: this(inner, DefaultTypeToErrorMessageMap(stringMarshallingAttribute))
{
}

Expand All @@ -40,10 +40,10 @@ private NoMarshallingInfoErrorMarshallingFactory(IMarshallingGeneratorFactory in

public ImmutableDictionary<ManagedTypeInfo, string> CustomTypeToErrorMessageMap { get; }

private static ImmutableDictionary<ManagedTypeInfo, string> DefaultTypeToErrorMessageMap { get; } =
ImmutableDictionary.CreateRange(new Dictionary<ManagedTypeInfo, string>
private static ImmutableDictionary<ManagedTypeInfo, string> DefaultTypeToErrorMessageMap(string stringMarshallingAttribute)
=> ImmutableDictionary.CreateRange(new Dictionary<ManagedTypeInfo, string>
{
{ SpecialTypeInfo.String, SR.MarshallingStringOrCharAsUndefinedNotSupported },
{ SpecialTypeInfo.String, string.Format(SR.MarshallingStringOrCharAsUndefinedNotSupported, stringMarshallingAttribute) },
{ SpecialTypeInfo.Boolean, SR.MarshallingBoolAsUndefinedNotSupported },
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
<value>Marshalling char with 'StringMarshalling.{0}' is not supported. Instead, manually convert the char type to the desired byte representation and pass to the source-generated P/Invoke.</value>
</data>
<data name="MarshallingStringOrCharAsUndefinedNotSupported" xml:space="preserve">
<value>Marshalling string or char without explicit marshalling information is not supported. Specify 'LibraryImportAttribute.StringMarshalling', 'LibraryImportAttribute.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</value>
<value>Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</value>
</data>
<data name="SafeHandleByRefMustBeConcrete" xml:space="preserve">
<value>An abstract type derived from 'SafeHandle' cannot be marshalled by reference. The provided type must be concrete.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<note />
</trans-unit>
<trans-unit id="MarshallingStringOrCharAsUndefinedNotSupported">
<source>Marshalling string or char without explicit marshalling information is not supported. Specify 'LibraryImportAttribute.StringMarshalling', 'LibraryImportAttribute.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="translated">Zařazování řetězce nebo znaku bez explicitních informací o zařazování se nepodporuje. Zadejte LibraryImportAttribute.StringMarshalling, LibraryImportAttribute.StringMarshallingCustomType, MarshalUsingAttribute nebo MarshalAsAttribute.</target>
<source>Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="new">Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RuntimeMarshallingMustBeDisabled">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<note />
</trans-unit>
<trans-unit id="MarshallingStringOrCharAsUndefinedNotSupported">
<source>Marshalling string or char without explicit marshalling information is not supported. Specify 'LibraryImportAttribute.StringMarshalling', 'LibraryImportAttribute.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="translated">Das Marshalling von Zeichenfolgen oder Zeichen ohne explizite Marshalling-Informationen wird nicht unterstützt. Geben Sie „LibraryImportAttribute.StringMarshalling“, „LibraryImportAttribute.StringMarshallingCustomType“, „MarshalUsingAttribute“ oder „MarshalAsAttribute“ an.</target>
<source>Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="new">Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RuntimeMarshallingMustBeDisabled">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<note />
</trans-unit>
<trans-unit id="MarshallingStringOrCharAsUndefinedNotSupported">
<source>Marshalling string or char without explicit marshalling information is not supported. Specify 'LibraryImportAttribute.StringMarshalling', 'LibraryImportAttribute.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="translated">No se admite la serialización de cadenas o caracteres sin información de serialización explícita. Especifique \"LibraryImportAttribute.StringMars slaing\", \"LibraryImportAttribute.StringMars slaingCustomType\", \"MarshalUsingAttribute\" o \"MarshalAsAttribute\".</target>
<source>Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="new">Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RuntimeMarshallingMustBeDisabled">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<note />
</trans-unit>
<trans-unit id="MarshallingStringOrCharAsUndefinedNotSupported">
<source>Marshalling string or char without explicit marshalling information is not supported. Specify 'LibraryImportAttribute.StringMarshalling', 'LibraryImportAttribute.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="translated">Le marshaling de chaîne ou de char sans informations de marshaling explicites n’est pas pris en charge. Spécifiez « LibraryImportAttribute.StringMars streaming », « LibraryImportAttribute.StringMars streamingCustomType », « MarshalUsingAttribute » ou « MarshalAsAttribute ».</target>
<source>Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="new">Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RuntimeMarshallingMustBeDisabled">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
<note />
</trans-unit>
<trans-unit id="MarshallingStringOrCharAsUndefinedNotSupported">
<source>Marshalling string or char without explicit marshalling information is not supported. Specify 'LibraryImportAttribute.StringMarshalling', 'LibraryImportAttribute.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="translated">Il marshalling di stringa o carattere senza informazioni di marshalling esplicite non è supportato. Specificare 'LibraryImportAttribute.StringMarshalling', 'LibraryImportAttribute.StringMarshallingCustomType', 'MarshalUsingAttribute' o 'MarshalAsAttribute'.</target>
<source>Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</source>
<target state="new">Marshalling string or char without explicit marshalling information is not supported. Specify '{0}.StringMarshalling', '{0}.StringMarshallingCustomType', 'MarshalUsingAttribute' or 'MarshalAsAttribute'.</target>
<note />
</trans-unit>
<trans-unit id="RuntimeMarshallingMustBeDisabled">
Expand Down