未验证 提交 2330b4be 编写于 作者: J Jeremy Koritzinsky 提交者: GitHub

Make DllImportGenerator emit a GeneratedCodeAttribute on our stubs (#65868)

上级 defd20c1
......@@ -268,6 +268,9 @@
<type fullname="System.Runtime.InteropServices.GeneratedDllImportAttribute">
<attribute internal="RemoveAttributeInstances" />
</type>
<type fullname="System.CodeDom.Compiler.GeneratedCodeAttribute">
<attribute internal="RemoveAttributeInstances" />
</type>
<!-- The following attributes are generated by the compiler, so they could be in any assembly -->
......
......@@ -42,6 +42,10 @@ public static bool AreCompilationSettingsEqual(StubEnvironment env1, StubEnviron
internal sealed class DllImportStubContext : IEquatable<DllImportStubContext>
{
private static readonly string GeneratorName = typeof(DllImportGenerator).Assembly.GetName().Name;
private static readonly string GeneratorVersion = typeof(DllImportGenerator).Assembly.GetName().Version.ToString();
// We don't need the warnings around not setting the various
// non-nullable fields/properties on this type in the constructor
// since we always use a property initializer.
......@@ -123,18 +127,31 @@ public IEnumerable<ParameterSyntax> StubParameters
ImmutableArray<AttributeListSyntax>.Builder additionalAttrs = ImmutableArray.CreateBuilder<AttributeListSyntax>();
// Define additional attributes for the stub definition.
if (env.TargetFramework != TargetFramework.Unknown)
{
// Define additional attributes for the stub definition.
additionalAttrs.Add(
AttributeList(
SingletonSeparatedList(
Attribute(ParseName(TypeNames.System_CodeDom_Compiler_GeneratedCodeAttribute),
AttributeArgumentList(
SeparatedList(
new[]
{
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(GeneratorName))),
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(GeneratorVersion)))
}))))));
}
if (env.TargetFrameworkVersion >= new Version(5, 0) && !MethodIsSkipLocalsInit(env, method))
{
additionalAttrs.Add(
AttributeList(
SeparatedList(new[]
{
SingletonSeparatedList(
// Adding the skip locals init indiscriminately since the source generator is
// targeted at non-blittable method signatures which typically will contain locals
// in the generated code.
Attribute(ParseName(TypeNames.System_Runtime_CompilerServices_SkipLocalsInitAttribute))
})));
Attribute(ParseName(TypeNames.System_Runtime_CompilerServices_SkipLocalsInitAttribute)))));
}
return new DllImportStubContext()
......
......@@ -67,5 +67,7 @@ public static string MarshalEx(InteropGenerationOptions options)
public const string DefaultDllImportSearchPathsAttribute = "System.Runtime.InteropServices.DefaultDllImportSearchPathsAttribute";
public const string DllImportSearchPath = "System.Runtime.InteropServices.DllImportSearchPath";
public const string System_CodeDom_Compiler_GeneratedCodeAttribute = "System.CodeDom.Compiler.GeneratedCodeAttribute";
}
}
......@@ -64,6 +64,57 @@ partial class C
Assert.DoesNotContain(stubMethod.GetAttributes(), attr => attr.AttributeClass!.ToDisplayString() == typeof(SkipLocalsInitAttribute).FullName);
}
[ConditionalFact]
public async Task GeneratedCodeAdded()
{
string source = @"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly:DisableRuntimeMarshalling]
partial class C
{
[GeneratedDllImportAttribute(""DoesNotExist"")]
public static partial S Method();
}
[NativeMarshalling(typeof(Native))]
struct S
{
}
struct Native
{
public Native(S s) { }
public S ToManaged() { return default; }
}";
Compilation comp = await TestUtils.CreateCompilation(source);
Compilation newComp = TestUtils.RunGenerators(comp, out _, new Microsoft.Interop.DllImportGenerator());
ITypeSymbol c = newComp.GetTypeByMetadataName("C")!;
IMethodSymbol stubMethod = c.GetMembers().OfType<IMethodSymbol>().Single(m => m.Name == "Method");
Assert.Contains(stubMethod.GetAttributes(), attr => attr.AttributeClass!.ToDisplayString() == typeof(System.CodeDom.Compiler.GeneratedCodeAttribute).FullName);
}
[ConditionalFact]
public async Task GeneratedCodeNotAddedOnForwardingStub()
{
string source = @"
using System.Runtime.InteropServices;
partial class C
{
[GeneratedDllImportAttribute(""DoesNotExist"")]
public static partial void Method();
}";
Compilation comp = await TestUtils.CreateCompilation(source);
Compilation newComp = TestUtils.RunGenerators(comp, out _, new Microsoft.Interop.DllImportGenerator());
ITypeSymbol c = newComp.GetTypeByMetadataName("C")!;
IMethodSymbol stubMethod = c.GetMembers().OfType<IMethodSymbol>().Single(m => m.Name == "Method");
Assert.DoesNotContain(stubMethod.GetAttributes(), attr => attr.AttributeClass!.ToDisplayString() == typeof(System.CodeDom.Compiler.GeneratedCodeAttribute).FullName);
}
public static IEnumerable<object[]> GetDownlevelTargetFrameworks()
{
yield return new object[] { TestTargetFramework.Net, true };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册