internal static void AssertReferencedIsUnmanagedAttribute(Accessibility accessibility, TypeParameterSymbol typeParameter, string assemblyName) { var attributes = ((PEModuleSymbol)typeParameter.ContainingModule).GetCustomAttributesForToken(((PETypeParameterSymbol)typeParameter).Handle); NamedTypeSymbol attributeType = attributes.Single().AttributeClass; Assert.Equal("IsUnmanagedAttribute", attributeType.Name); Assert.Equal(assemblyName, attributeType.ContainingAssembly.Name); Assert.Equal(accessibility, attributeType.DeclaredAccessibility); switch (accessibility) { case Accessibility.Internal: { var isUnmanagedTypeAttributes = attributeType.GetAttributes().OrderBy(attribute => attribute.AttributeClass.Name).ToArray(); Assert.Equal(2, isUnmanagedTypeAttributes.Length); Assert.Equal(WellKnownTypes.GetMetadataName(WellKnownType.System_Runtime_CompilerServices_CompilerGeneratedAttribute), isUnmanagedTypeAttributes[0].AttributeClass.ToDisplayString()); Assert.Equal(AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName, isUnmanagedTypeAttributes[1].AttributeClass.ToDisplayString()); break; } case Accessibility.Public: { Assert.Null(attributeType.ContainingAssembly.GetTypeByMetadataName(AttributeDescription.CodeAnalysisEmbeddedAttribute.FullName)); break; } default: throw ExceptionUtilities.UnexpectedValue(accessibility); } }
public override void VisitNamedType(NamedTypeSymbol type) { var previousContext = _nullableContext; _nullableContext = GetNullableContextAttribute(type.GetAttributes()) ?? _nullableContext; base.VisitNamedType(type); _nullableContext = previousContext; }
protected override void EmbedCorrespondingComEventInterfaceMethodInternal(SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics, bool isUsedForComAwareEventBinding) { // If the event happens to belong to a class with a ComEventInterfaceAttribute, there will also be // a paired method living on its source interface. The ComAwareEventInfo class expects to find this // method through reflection. If we embed an event, therefore, we must ensure that the associated source // interface method is also included, even if it is not otherwise referenced in the embedding project. NamedTypeSymbol underlyingContainingType = ContainingType.UnderlyingNamedType; foreach (var attrData in underlyingContainingType.GetAttributes()) { if (attrData.IsTargetAttribute(underlyingContainingType, AttributeDescription.ComEventInterfaceAttribute)) { bool foundMatch = false; NamedTypeSymbol sourceInterface = null; if (attrData.CommonConstructorArguments.Length == 2) { sourceInterface = attrData.CommonConstructorArguments[0].Value as NamedTypeSymbol; if ((object)sourceInterface != null) { foundMatch = EmbedMatchingInterfaceMethods(sourceInterface, syntaxNodeOpt, diagnostics); foreach (NamedTypeSymbol source in sourceInterface.AllInterfacesNoUseSiteDiagnostics) { if (EmbedMatchingInterfaceMethods(source, syntaxNodeOpt, diagnostics)) { foundMatch = true; } } } } if (!foundMatch && isUsedForComAwareEventBinding) { if ((object)sourceInterface == null) { // ERRID_SourceInterfaceMustBeInterface/ERR_MissingSourceInterface EmbeddedTypesManager.Error(diagnostics, ErrorCode.ERR_MissingSourceInterface, syntaxNodeOpt, underlyingContainingType, UnderlyingEvent); } else { HashSet <DiagnosticInfo> useSiteDiagnostics = null; sourceInterface.AllInterfacesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics); diagnostics.Add(syntaxNodeOpt == null ? NoLocation.Singleton : syntaxNodeOpt.Location, useSiteDiagnostics); // ERRID_EventNoPIANoBackingMember/ERR_MissingMethodOnSourceInterface EmbeddedTypesManager.Error(diagnostics, ErrorCode.ERR_MissingMethodOnSourceInterface, syntaxNodeOpt, sourceInterface, UnderlyingEvent.MetadataName, UnderlyingEvent); } } break; } } }
public override void VisitNamedType(NamedTypeSymbol type) { var previousContext = _nullableContext; _nullableContext = GetNullableContextAttribute(type.GetAttributes()) ?? _nullableContext; ReportSymbol(type); VisitList(type.TypeParameters); foreach (var member in type.GetMembers()) { // Skip accessors since those are covered by associated symbol. if (member.IsAccessor()) { continue; } Visit(member); } _nullableContext = previousContext; }
public override ImmutableArray <CSharpAttributeData> GetAttributes() { return(this.RetargetingTranslator.GetRetargetedAttributes(_underlyingType.GetAttributes(), ref _lazyCustomAttributes)); }
public void ReadOnlyStructApi() { var text = @" class Program { readonly struct S1 { public S1(int dummy) { } public string M1() { return ""1""; } public override string ToString() { return ""2""; } } readonly struct S1<T> { public S1(int dummy) { } public string M1() { return ""1""; } public override string ToString() { return ""2""; } } struct S2 { public S2(int dummy) { } public string M1() { return ""1""; } public override string ToString() { return ""2""; } } class C1 { public C1(int dummy) { } public string M1() { return ""1""; } public override string ToString() { return ""2""; } } delegate int D1(); } "; var comp = CreateCompilation(text, parseOptions: TestOptions.Regular); // S1 NamedTypeSymbol namedType = comp.GetTypeByMetadataName("Program+S1"); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); void validate(ModuleSymbol module) { var test = module.ContainingAssembly.GetTypeByMetadataName("Program+S1"); var peModule = (PEModuleSymbol)module; Assert.True(peModule.Module.HasIsReadOnlyAttribute(((PENamedTypeSymbol)test).Handle)); AssertDeclaresType(peModule, WellKnownType.System_Runtime_CompilerServices_IsReadOnlyAttribute, Accessibility.Internal); } CompileAndVerify(comp, symbolValidator: validate); // S1<T> namedType = comp.GetTypeByMetadataName("Program+S1`1"); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // T TypeSymbol type = namedType.TypeParameters[0]; Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S1<object> namedType = namedType.Construct(comp.ObjectType); Assert.True(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("M1").ThisParameter.RefKind); Assert.Equal(RefKind.In, namedType.GetMethod("ToString").ThisParameter.RefKind); // S2 namedType = comp.GetTypeByMetadataName("Program+S2"); Assert.False(namedType.IsReadOnly); Assert.Equal(RefKind.Out, namedType.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.Ref, namedType.GetMethod("M1").ThisParameter.RefKind); Assert.Equal(RefKind.Ref, namedType.GetMethod("ToString").ThisParameter.RefKind); // C1 namedType = comp.GetTypeByMetadataName("Program+C1"); Assert.False(namedType.IsReadOnly); Assert.Equal(RefKind.None, namedType.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.None, namedType.GetMethod("M1").ThisParameter.RefKind); Assert.Equal(RefKind.None, namedType.GetMethod("ToString").ThisParameter.RefKind); // D1 namedType = comp.GetTypeByMetadataName("Program+D1"); Assert.False(namedType.IsReadOnly); Assert.Equal(RefKind.None, namedType.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.None, namedType.GetMethod("Invoke").ThisParameter.RefKind); // object[] type = comp.CreateArrayTypeSymbol(comp.ObjectType); Assert.False(type.IsReadOnly); // dynamic type = comp.DynamicType; Assert.False(type.IsReadOnly); // object type = comp.ObjectType; Assert.False(type.IsReadOnly); // anonymous type type = (TypeSymbol)comp.CreateAnonymousTypeSymbol(ImmutableArray.Create <ITypeSymbol>(comp.ObjectType), ImmutableArray.Create("qq")); Assert.False(type.IsReadOnly); // pointer type type = (TypeSymbol)comp.CreatePointerTypeSymbol(comp.ObjectType); Assert.False(type.IsReadOnly); // tuple type type = (TypeSymbol)comp.CreateTupleTypeSymbol(ImmutableArray.Create <ITypeSymbol>(comp.ObjectType, comp.ObjectType)); Assert.False(type.IsReadOnly); // S1 from image var clientComp = CreateCompilation("", references: new[] { comp.EmitToImageReference() }); NamedTypeSymbol s1 = clientComp.GetTypeByMetadataName("Program+S1"); Assert.True(s1.IsReadOnly); Assert.Empty(s1.GetAttributes()); Assert.Equal(RefKind.Out, s1.Constructors[0].ThisParameter.RefKind); Assert.Equal(RefKind.In, s1.GetMethod("M1").ThisParameter.RefKind); Assert.Equal(RefKind.In, s1.GetMethod("ToString").ThisParameter.RefKind); }