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;
        }
Example #3
0
        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;
                }
            }
        }
Example #4
0
        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;
        }
Example #5
0
 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);
        }