提交 28f41128 编写于 作者: A AlekseyTs

Apply ComVisible attribute to embedded value types.

Fixes #16177.
上级 84e6e7e5
......@@ -206,13 +206,6 @@ protected override IEnumerable<CSharpAttributeData> GetCustomAttributesToEmit(Mo
return UnderlyingNamedType.GetCustomAttributesToEmit(compilationState);
}
protected override CSharpAttributeData CreateCompilerGeneratedAttribute()
{
Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
var compilation = TypeManager.ModuleBeingBuilt.Compilation;
return compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor);
}
protected override CSharpAttributeData CreateTypeIdentifierAttribute(bool hasGuid, SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
{
var member = hasGuid ?
......
......@@ -565,5 +565,22 @@ protected override EmbeddedType GetEmbeddedTypeForMember(Symbol member, SyntaxNo
{
return underlyingParameters.SelectAsArray((p, c) => new EmbeddedParameter(c, p), containingPropertyOrMethod);
}
protected override CSharpAttributeData CreateCompilerGeneratedAttribute()
{
Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
var compilation = ModuleBeingBuilt.Compilation;
return compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor);
}
protected override CSharpAttributeData CreateComVisibleAttribute()
{
var compilation = ModuleBeingBuilt.Compilation;
return compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_InteropServices_ComVisibleAttribute__ctor,
ImmutableArray.Create(new TypedConstant(compilation.GetSpecialType(SpecialType.System_Boolean),
TypedConstantKind.Primitive,
value:true)),
isOptionalUse:true);
}
}
}
......@@ -306,10 +306,14 @@ internal static Symbol GetRuntimeMember(NamedTypeSymbol declaringType, ref Membe
/// If the well-known member does not exist in the compilation then no attribute
/// will be synthesized.
/// </param>
/// <param name="isOptionalUse">
/// Indicates if this particular attribute application should be considered optional.
/// </param>
internal SynthesizedAttributeData TrySynthesizeAttribute(
WellKnownMember constructor,
ImmutableArray<TypedConstant> arguments = default(ImmutableArray<TypedConstant>),
ImmutableArray<KeyValuePair<WellKnownMember, TypedConstant>> namedArguments = default(ImmutableArray<KeyValuePair<WellKnownMember, TypedConstant>>))
ImmutableArray<KeyValuePair<WellKnownMember, TypedConstant>> namedArguments = default(ImmutableArray<KeyValuePair<WellKnownMember, TypedConstant>>),
bool isOptionalUse = false)
{
DiagnosticInfo diagnosticInfo;
var ctorSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(this, constructor, out diagnosticInfo, isOptional: true);
......@@ -317,7 +321,7 @@ internal static Symbol GetRuntimeMember(NamedTypeSymbol declaringType, ref Membe
if ((object)ctorSymbol == null)
{
// if this assert fails, UseSiteErrors for "member" have not been checked before emitting ...
Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(constructor));
Debug.Assert(isOptionalUse || WellKnownMembers.IsSynthesizedAttributeOptional(constructor));
return null;
}
......
......@@ -1201,9 +1201,10 @@ public void M6(ITest26 x)
Assert.Equal(TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, test2.Flags);
attributes = test2.GetAttributes();
Assert.Equal(2, attributes.Length);
Assert.Equal(3, attributes.Length);
Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes[0].ToString());
Assert.Equal(@"System.Runtime.InteropServices.TypeIdentifierAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"", ""Test2"")", attributes[1].ToString());
Assert.Equal("System.Runtime.InteropServices.ComVisibleAttribute(true)", attributes[2].ToString());
var itest3 = module.GlobalNamespace.GetTypeMembers("ITest3").Single();
Assert.Equal(TypeKind.Interface, itest3.TypeKind);
......@@ -1261,9 +1262,10 @@ public void M6(ITest26 x)
Assert.Equal(TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass, test9.Flags);
attributes = test9.GetAttributes();
Assert.Equal(2, attributes.Length);
Assert.Equal(3, attributes.Length);
Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes[0].ToString());
Assert.Equal(@"System.Runtime.InteropServices.TypeIdentifierAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"", ""Test9"")", attributes[1].ToString());
Assert.Equal("System.Runtime.InteropServices.ComVisibleAttribute(true)", attributes[2].ToString());
var fieldToEmit = test9.GetFieldsToEmit().ToArray().AsImmutableOrNull();
Assert.Equal(3, fieldToEmit.Length);
......
......@@ -68,7 +68,6 @@ protected CommonEmbeddedType(TEmbeddedTypesManager typeManager, TNamedTypeSymbol
protected abstract bool IsSealed { get; }
protected abstract TypeLayout? GetTypeLayoutIfStruct();
protected abstract System.Runtime.InteropServices.CharSet StringFormat { get; }
protected abstract TAttributeData CreateCompilerGeneratedAttribute();
protected abstract TAttributeData CreateTypeIdentifierAttribute(bool hasGuid, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics);
protected abstract void EmbedDefaultMembers(string defaultMember, TSyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics);
protected abstract IEnumerable<TAttributeData> GetCustomAttributesToEmit(TModuleCompilationState compilationState);
......@@ -85,7 +84,7 @@ private ImmutableArray<TAttributeData> GetAttributes(TModuleCompilationState com
// Put the CompilerGenerated attribute on the NoPIA types we define so that
// static analysis tools (e.g. fxcop) know that they can be skipped
builder.AddOptional(CreateCompilerGeneratedAttribute());
builder.AddOptional(TypeManager.CreateCompilerGeneratedAttribute());
// Copy some of the attributes.
......@@ -204,6 +203,11 @@ private ImmutableArray<TAttributeData> GetAttributes(TModuleCompilationState com
builder.AddOptional(CreateTypeIdentifierAttribute(hasGuid && IsInterface, syntaxNodeOpt, diagnostics));
if (UnderlyingNamedType.IsValueType)
{
builder.AddOptional(TypeManager.CreateComVisibleAttribute());
}
return builder.ToImmutableAndFree();
}
......
......@@ -155,6 +155,8 @@ internal bool IsTargetAttribute(TSymbol underlyingSymbol, TAttributeData attrDat
protected abstract void OnGetTypesCompleted(ImmutableArray<TEmbeddedType> types, DiagnosticBag diagnostics);
protected abstract void ReportNameCollisionBetweenEmbeddedTypes(TEmbeddedType typeA, TEmbeddedType typeB, DiagnosticBag diagnostics);
protected abstract void ReportNameCollisionWithAlreadyDeclaredType(TEmbeddedType type, DiagnosticBag diagnostics);
protected abstract TAttributeData CreateCompilerGeneratedAttribute();
protected abstract TAttributeData CreateComVisibleAttribute();
private sealed class TypeComparer : IComparer<TEmbeddedType>
{
......
......@@ -158,12 +158,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit.NoPia
Return UnderlyingNamedType.GetCustomAttributesToEmit(compilationState)
End Function
Protected Overrides Function CreateCompilerGeneratedAttribute() As VisualBasicAttributeData
Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor))
Dim compilation = TypeManager.ModuleBeingBuilt.Compilation
Return compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)
End Function
Protected Overrides Function CreateTypeIdentifierAttribute(hasGuid As Boolean, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag) As VisualBasicAttributeData
Dim member = If(hasGuid,
WellKnownMember.System_Runtime_InteropServices_TypeIdentifierAttribute__ctor,
......
......@@ -488,6 +488,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit.NoPia
Return underlyingParameters.SelectAsArray(Function(parameter, container) New EmbeddedParameter(container, parameter), containingPropertyOrMethod)
End Function
Protected Overrides Function CreateCompilerGeneratedAttribute() As VisualBasicAttributeData
Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor))
Dim compilation = ModuleBeingBuilt.Compilation
Return compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)
End Function
Protected Overrides Function CreateComVisibleAttribute() As VisualBasicAttributeData
Dim compilation = ModuleBeingBuilt.Compilation
Return compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_InteropServices_ComVisibleAttribute__ctor,
ImmutableArray.Create(New TypedConstant(compilation.GetSpecialType(SpecialType.System_Boolean),
TypedConstantKind.Primitive,
value:=True)),
isOptionalUse:=True)
End Function
End Class
End Namespace
......@@ -136,15 +136,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' If the well-known member does Not exist in the compilation then no attribute
''' will be synthesized.
''' </param>
''' <param name="isOptionalUse">
''' Indicates if this particular attribute application should be considered optional.
''' </param>
Friend Function TrySynthesizeAttribute(
constructor As WellKnownMember,
Optional arguments As ImmutableArray(Of TypedConstant) = Nothing,
Optional namedArguments As ImmutableArray(Of KeyValuePair(Of WellKnownMember, TypedConstant)) = Nothing) As SynthesizedAttributeData
Optional namedArguments As ImmutableArray(Of KeyValuePair(Of WellKnownMember, TypedConstant)) = Nothing,
Optional isOptionalUse As Boolean = False
) As SynthesizedAttributeData
Dim constructorSymbol = TryCast(GetWellKnownTypeMember(constructor), MethodSymbol)
If constructorSymbol Is Nothing OrElse
Binder.GetUseSiteErrorForWellKnownTypeMember(constructorSymbol, constructor, False) IsNot Nothing Then
Return ReturnNothingOrThrowIfAttributeNonOptional(constructor)
Return ReturnNothingOrThrowIfAttributeNonOptional(constructor, isOptionalUse)
End If
If arguments.IsDefault Then
......@@ -172,8 +177,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return New SynthesizedAttributeData(constructorSymbol, arguments, namedStringArguments)
End Function
Private Function ReturnNothingOrThrowIfAttributeNonOptional(constructor As WellKnownMember) As SynthesizedAttributeData
If WellKnownMembers.IsSynthesizedAttributeOptional(constructor) Then
Private Function ReturnNothingOrThrowIfAttributeNonOptional(constructor As WellKnownMember, Optional isOptionalUse As Boolean = False) As SynthesizedAttributeData
If isOptionalUse OrElse WellKnownMembers.IsSynthesizedAttributeOptional(constructor) Then
Return Nothing
Else
Throw ExceptionUtilities.Unreachable
......
......@@ -1033,9 +1033,10 @@ End Class
Assert.Equal(TypeAttributes.Public Or TypeAttributes.SequentialLayout Or TypeAttributes.Class Or TypeAttributes.Sealed Or TypeAttributes.AnsiClass Or TypeAttributes.BeforeFieldInit, test2.TypeDefFlags)
attributes = test2.GetAttributes()
Assert.Equal(2, attributes.Length)
Assert.Equal(3, attributes.Length)
Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes(0).ToString())
Assert.Equal("System.Runtime.InteropServices.TypeIdentifierAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"", ""Test2"")", attributes(1).ToString())
Assert.Equal("System.Runtime.InteropServices.ComVisibleAttribute(True)", attributes(2).ToString())
Dim itest3 = [module].GlobalNamespace.GetMember(Of NamedTypeSymbol)("ITest3")
Assert.Equal(TypeKind.Interface, itest3.TypeKind)
......@@ -1093,9 +1094,10 @@ End Class
Assert.Equal(TypeAttributes.Public Or TypeAttributes.AutoLayout Or TypeAttributes.Class Or TypeAttributes.Sealed Or TypeAttributes.AnsiClass, test9.TypeDefFlags)
attributes = test9.GetAttributes()
Assert.Equal(2, attributes.Length)
Assert.Equal(3, attributes.Length)
Assert.Equal("System.Runtime.CompilerServices.CompilerGeneratedAttribute", attributes(0).ToString())
Assert.Equal("System.Runtime.InteropServices.TypeIdentifierAttribute(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"", ""Test9"")", attributes(1).ToString())
Assert.Equal("System.Runtime.InteropServices.ComVisibleAttribute(True)", attributes(2).ToString())
Dim fieldToEmit = test9.GetFieldsToEmit().ToArray().AsImmutableOrNull()
Assert.Equal(3, fieldToEmit.Length)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册