Esempio n. 1
0
        public void TestMissingMetadataSymbol()
        {
            AssemblyIdentity missingAssemblyId = new AssemblyIdentity("foo");
            AssemblySymbol   assem             = new MockAssemblySymbol("banana");
            ModuleSymbol     module            = new MissingModuleSymbol(assem, ordinal: -1);
            NamedTypeSymbol  container         = new MockNamedTypeSymbol("TestClass", Enumerable.Empty <Symbol>(), TypeKind.Class);

            var mms1 = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(missingAssemblyId).Modules[0], "Elvis", "Lives", 2, true);

            Assert.Equal(2, mms1.Arity);
            Assert.Equal("Elvis", mms1.NamespaceName);
            Assert.Equal("Lives", mms1.Name);
            Assert.Equal("Elvis.Lives<,>[missing]", mms1.ToTestDisplayString());
            Assert.Equal("foo", mms1.ContainingAssembly.Identity.Name);

            var mms2 = new MissingMetadataTypeSymbol.TopLevel(module, "Elvis.Is", "Cool", 0, true);

            Assert.Equal(0, mms2.Arity);
            Assert.Equal("Elvis.Is", mms2.NamespaceName);
            Assert.Equal("Cool", mms2.Name);
            Assert.Equal("Elvis.Is.Cool[missing]", mms2.ToTestDisplayString());
            Assert.Same(assem, mms2.ContainingAssembly);

            // TODO: Add test for 3rd constructor.
        }
Esempio n. 2
0
        internal NamedTypeSymbol GetWellKnownType(WellKnownType type)
        {
            Debug.Assert(type >= WellKnownType.First && type <= WellKnownType.Last && type != WellKnownType.ExtSentinel);

            int index = (int)type - (int)WellKnownType.First;

            if (_lazyWellKnownTypes == null || (object)_lazyWellKnownTypes[index] == null)
            {
                if (_lazyWellKnownTypes == null)
                {
                    Interlocked.CompareExchange(ref _lazyWellKnownTypes, new NamedTypeSymbol[(int)WellKnownTypes.Count], null);
                }

                string          mdName   = type.GetMetadataName();
                var             warnings = DiagnosticBag.GetInstance();
                NamedTypeSymbol result;

                if (IsTypeMissing(type))
                {
                    result = null;
                }
                else
                {
                    // well-known types introduced before CSharp7 allow lookup ambiguity and report a warning
                    DiagnosticBag legacyWarnings = (type <= WellKnownType.CSharp7Sentinel) ? warnings : null;

                    result = this.Assembly.GetTypeByMetadataName(
                        mdName, includeReferences: true, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, warnings: legacyWarnings);
                }

                if ((object)result == null)
                {
                    // TODO: should GetTypeByMetadataName rather return a missing symbol?
                    MetadataTypeName emittedName = MetadataTypeName.FromFullName(mdName, useCLSCompliantNameArityEncoding: true);
                    result = new MissingMetadataTypeSymbol.TopLevel(this.Assembly.Modules[0], ref emittedName, type);
                }

                if ((object)Interlocked.CompareExchange(ref _lazyWellKnownTypes[index], result, null) != null)
                {
                    Debug.Assert(
                        result == _lazyWellKnownTypes[index] || (_lazyWellKnownTypes[index].IsErrorType() && result.IsErrorType())
                        );
                }
                else
                {
                    AdditionalCodegenWarnings.AddRange(warnings);
                }

                warnings.Free();
            }

            return(_lazyWellKnownTypes[index]);
        }
Esempio n. 3
0
        internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName, out bool isNoPiaLocalType)
        {
            NamedTypeSymbol   result;
            PENamespaceSymbol scope = (PENamespaceSymbol)this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegments);

            if ((object)scope == null)
            {
                // We failed to locate the namespace
                isNoPiaLocalType = false;
                result           = new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName);
            }
            else
            {
                result = scope.LookupMetadataType(ref emittedName, out isNoPiaLocalType);
                Debug.Assert((object)result != null);
            }

            return(result);
        }
Esempio n. 4
0
        internal NamedTypeSymbol GetWellKnownType(WellKnownType type)
        {
            Debug.Assert(type >= WellKnownType.First && type <= WellKnownType.Last);

            int index = (int)type - (int)WellKnownType.First;

            if (lazyWellKnownTypes == null || (object)lazyWellKnownTypes[index] == null)
            {
                if (lazyWellKnownTypes == null)
                {
                    Interlocked.CompareExchange(ref lazyWellKnownTypes, new NamedTypeSymbol[(int)WellKnownTypes.Count], null);
                }

                string          mdName   = type.GetMetadataName();
                var             warnings = DiagnosticBag.GetInstance();
                NamedTypeSymbol result   = this.Assembly.GetTypeByMetadataName(
                    mdName, includeReferences: true, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, warnings: warnings);

                if ((object)result == null)
                {
                    // TODO: should GetTypeByMetadataName rather return a missing symbol?
                    MetadataTypeName emittedName = MetadataTypeName.FromFullName(mdName, useCLSCompliantNameArityEncoding: true);
                    result = new MissingMetadataTypeSymbol.TopLevel(this.Assembly.Modules[0], ref emittedName, type);
                }

                if ((object)Interlocked.CompareExchange(ref lazyWellKnownTypes[index], result, null) != null)
                {
                    Debug.Assert(
                        result == lazyWellKnownTypes[index] || (lazyWellKnownTypes[index].IsErrorType() && result.IsErrorType())
                        );
                }
                else
                {
                    AdditionalCodegenWarnings.AddRange(warnings);
                }

                warnings.Free();
            }

            return(lazyWellKnownTypes[index]);
        }
Esempio n. 5
0
        public void Equality()
        {
            var assemblies = MetadataTestHelpers.GetSymbolsForReferences(new[]
            {
                TestReferences.SymbolsTests.MissingTypes.MissingTypesEquality1,
                TestReferences.SymbolsTests.MissingTypes.MissingTypesEquality2,
                TestReferences.SymbolsTests.MDTestLib1,
                TestReferences.SymbolsTests.MDTestLib2
            });


            var asm1 = assemblies[0];

            var asm1classC = asm1.GlobalNamespace.GetTypeMembers("C").Single();

            var asm1m1 = asm1classC.GetMembers("M1").OfType <MethodSymbol>().Single();
            var asm1m2 = asm1classC.GetMembers("M2").OfType <MethodSymbol>().Single();
            var asm1m3 = asm1classC.GetMembers("M3").OfType <MethodSymbol>().Single();
            var asm1m4 = asm1classC.GetMembers("M4").OfType <MethodSymbol>().Single();
            var asm1m5 = asm1classC.GetMembers("M5").OfType <MethodSymbol>().Single();
            var asm1m6 = asm1classC.GetMembers("M6").OfType <MethodSymbol>().Single();
            var asm1m7 = asm1classC.GetMembers("M7").OfType <MethodSymbol>().Single();
            var asm1m8 = asm1classC.GetMembers("M8").OfType <MethodSymbol>().Single();

            Assert.NotEqual(asm1m2.ReturnType, asm1m1.ReturnType);
            Assert.NotEqual(asm1m3.ReturnType, asm1m1.ReturnType);
            Assert.NotEqual(asm1m4.ReturnType, asm1m1.ReturnType);

            Assert.NotEqual(asm1m5.ReturnType, asm1m4.ReturnType);
            Assert.NotEqual(asm1m6.ReturnType, asm1m4.ReturnType);

            Assert.Equal(asm1m7.ReturnType, asm1m1.ReturnType);
            Assert.Equal(asm1m8.ReturnType, asm1m4.ReturnType);

            var asm2 = assemblies[1];

            var asm2classC = asm2.GlobalNamespace.GetTypeMembers("C").Single();

            var asm2m1 = asm2classC.GetMembers("M1").OfType <MethodSymbol>().Single();
            var asm2m4 = asm2classC.GetMembers("M4").OfType <MethodSymbol>().Single();

            Assert.Equal(asm2m1.ReturnType, asm1m1.ReturnType);

            Assert.NotSame(asm1m4.ReturnType, asm2m4.ReturnType);
            Assert.Equal(asm2m4.ReturnType, asm1m4.ReturnType);

            Assert.Equal(asm1.GetSpecialType(SpecialType.System_Boolean), asm1.GetSpecialType(SpecialType.System_Boolean));
            Assert.Equal(asm1.GetSpecialType(SpecialType.System_Boolean), asm2.GetSpecialType(SpecialType.System_Boolean));

            MissingMetadataTypeSymbol[] missingTypes1 = new MissingMetadataTypeSymbol[15];
            MissingMetadataTypeSymbol[] missingTypes2 = new MissingMetadataTypeSymbol[15];

            var defaultName = new AssemblyIdentity("missing");

            missingTypes1[0]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(defaultName).Modules[0], "", "test1", 0, true);
            missingTypes1[1]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(defaultName).Modules[0], "", "test1", 1, true);
            missingTypes1[2]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(defaultName).Modules[0], "", "test2", 0, true);
            missingTypes1[3]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm1")).Modules[0], "", "test1", 0, true);
            missingTypes1[4]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm1")).Modules[0], "", "test1", 1, true);
            missingTypes1[5]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm1")).Modules[0], "", "test2", 0, true);
            missingTypes1[6]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm2")).Modules[0], "", "test1", 0, true);
            missingTypes1[7]  = new MissingMetadataTypeSymbol.TopLevel(asm1.Modules[0], "", "test1", 0, true);
            missingTypes1[8]  = new MissingMetadataTypeSymbol.TopLevel(asm1.Modules[0], "", "test1", 1, true);
            missingTypes1[9]  = new MissingMetadataTypeSymbol.TopLevel(asm1.Modules[0], "", "test2", 0, true);
            missingTypes1[10] = new MissingMetadataTypeSymbol.TopLevel(asm2.Modules[0], "", "test1", 0, true);
            missingTypes1[11] = new MissingMetadataTypeSymbol.Nested(asm1classC, "test1", 0, true);
            missingTypes1[12] = new MissingMetadataTypeSymbol.Nested(asm1classC, "test1", 1, true);
            missingTypes1[13] = new MissingMetadataTypeSymbol.Nested(asm1classC, "test2", 0, true);
            missingTypes1[14] = new MissingMetadataTypeSymbol.Nested(asm2classC, "test1", 0, true);

            missingTypes2[0]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(defaultName).Modules[0], "", "test1", 0, true);
            missingTypes2[1]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(defaultName).Modules[0], "", "test1", 1, true);
            missingTypes2[2]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(defaultName).Modules[0], "", "test2", 0, true);
            missingTypes2[3]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm1")).Modules[0], "", "test1", 0, true);
            missingTypes2[4]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm1")).Modules[0], "", "test1", 1, true);
            missingTypes2[5]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm1")).Modules[0], "", "test2", 0, true);
            missingTypes2[6]  = new MissingMetadataTypeSymbol.TopLevel(new MissingAssemblySymbol(new AssemblyIdentity("asm2")).Modules[0], "", "test1", 0, true);
            missingTypes2[7]  = new MissingMetadataTypeSymbol.TopLevel(asm1.Modules[0], "", "test1", 0, true);
            missingTypes2[8]  = new MissingMetadataTypeSymbol.TopLevel(asm1.Modules[0], "", "test1", 1, true);
            missingTypes2[9]  = new MissingMetadataTypeSymbol.TopLevel(asm1.Modules[0], "", "test2", 0, true);
            missingTypes2[10] = new MissingMetadataTypeSymbol.TopLevel(asm2.Modules[0], "", "test1", 0, true);
            missingTypes2[11] = new MissingMetadataTypeSymbol.Nested(asm1classC, "test1", 0, true);
            missingTypes2[12] = new MissingMetadataTypeSymbol.Nested(asm1classC, "test1", 1, true);
            missingTypes2[13] = new MissingMetadataTypeSymbol.Nested(asm1classC, "test2", 0, true);
            missingTypes2[14] = new MissingMetadataTypeSymbol.Nested(asm2classC, "test1", 0, true);

            for (int i = 0; i < missingTypes1.Length; i++)
            {
                for (int j = 0; j < missingTypes2.Length; j++)
                {
                    if (i == j)
                    {
                        Assert.Equal(missingTypes2[j], missingTypes1[i]);
                        Assert.Equal(missingTypes1[i], missingTypes2[j]);
                    }
                    else
                    {
                        Assert.NotEqual(missingTypes2[j], missingTypes1[i]);
                        Assert.NotEqual(missingTypes1[i], missingTypes2[j]);
                    }
                }
            }

            var missingAssembly = new MissingAssemblySymbol(new AssemblyIdentity("asm1"));

            Assert.True(missingAssembly.Equals(missingAssembly));
            Assert.NotEqual(new object(), missingAssembly);
            Assert.False(missingAssembly.Equals(null));
        }
Esempio n. 6
0
        internal NamedTypeSymbol LookupTopLevelMetadataType(ref MetadataTypeName emittedName, out bool isNoPiaLocalType)
        {
            NamedTypeSymbol result;
            PENamespaceSymbol scope = (PENamespaceSymbol)this.GlobalNamespace.LookupNestedNamespace(emittedName.NamespaceSegments);

            if ((object)scope == null)
            {
                // We failed to locate the namespace
                isNoPiaLocalType = false;
                result = new MissingMetadataTypeSymbol.TopLevel(this, ref emittedName);
            }
            else
            {
                result = scope.LookupMetadataType(ref emittedName, out isNoPiaLocalType);
                Debug.Assert((object)result != null);
            }

            return result;
        }
        /// <summary>
        /// This method handles duplicate types in a few different ways:
        /// - for types before C# 7, the first candidate is returned with a warning
        /// - for types after C# 7, the type is considered missing
        /// - in both cases, when BinderFlags.IgnoreCorLibraryDuplicatedTypes is set, any duplicate coming from corlib will be ignored (ie not count as a duplicate)
        /// </summary>
        internal NamedTypeSymbol GetWellKnownType(WellKnownType type)
        {
            Debug.Assert(type.IsValid());

            bool ignoreCorLibraryDuplicatedTypes = this.Options.TopLevelBinderFlags.Includes(BinderFlags.IgnoreCorLibraryDuplicatedTypes);

            int index = (int)type - (int)WellKnownType.First;

            if (_lazyWellKnownTypes == null || (object)_lazyWellKnownTypes[index] == null)
            {
                if (_lazyWellKnownTypes == null)
                {
                    Interlocked.CompareExchange(ref _lazyWellKnownTypes, new NamedTypeSymbol[(int)WellKnownTypes.Count], null);
                }

                string          mdName   = type.GetMetadataName();
                var             warnings = DiagnosticBag.GetInstance();
                NamedTypeSymbol result;
                (AssemblySymbol, AssemblySymbol)conflicts = default;

                if (IsTypeMissing(type))
                {
                    result = null;
                }
                else
                {
                    // well-known types introduced before CSharp7 allow lookup ambiguity and report a warning
                    DiagnosticBag legacyWarnings = (type <= WellKnownType.CSharp7Sentinel) ? warnings : null;
                    result = this.Assembly.GetTypeByMetadataName(
                        mdName, includeReferences: true, useCLSCompliantNameArityEncoding: true, isWellKnownType: true, conflicts: out conflicts,
                        warnings: legacyWarnings, ignoreCorLibraryDuplicatedTypes: ignoreCorLibraryDuplicatedTypes);
                }

                if ((object)result == null)
                {
                    // TODO: should GetTypeByMetadataName rather return a missing symbol?
                    MetadataTypeName emittedName = MetadataTypeName.FromFullName(mdName, useCLSCompliantNameArityEncoding: true);
                    if (type.IsValueTupleType())
                    {
                        CSDiagnosticInfo errorInfo;
                        if (conflicts.Item1 is null)
                        {
                            Debug.Assert(conflicts.Item2 is null);
                            errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, emittedName.FullName);
                        }
                        else
                        {
                            errorInfo = new CSDiagnosticInfo(ErrorCode.ERR_PredefinedValueTupleTypeAmbiguous3, emittedName.FullName, conflicts.Item1, conflicts.Item2);
                        }

                        result = new MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(this.Assembly.Modules[0], ref emittedName, errorInfo, type);
                    }
                    else
                    {
                        result = new MissingMetadataTypeSymbol.TopLevel(this.Assembly.Modules[0], ref emittedName, type);
                    }
                }

                if ((object)Interlocked.CompareExchange(ref _lazyWellKnownTypes[index], result, null) != null)
                {
                    Debug.Assert(
                        result == _lazyWellKnownTypes[index] || (_lazyWellKnownTypes[index].IsErrorType() && result.IsErrorType())
                        );
                }
                else
                {
                    AdditionalCodegenWarnings.AddRange(warnings);
                }

                warnings.Free();
            }

            return(_lazyWellKnownTypes[index]);
        }