Exemple #1
0
        // finds syntax location where given type was inherited
        // should be used for error reporting on unexpected inherited types.
        private SourceLocation FindBaseRefSyntax(NamedTypeSymbol baseSym)
        {
            foreach (var decl in this.declaration.Declarations)
            {
                ImplementListSyntax implements = GetImplementListOpt(decl);
                if (implements != null)
                {
                    var baseBinder = this.DeclaringCompilation.GetBinder(implements);
                    // Wrap base binder in a location-specific binder that will avoid generic constraint checks.
                    baseBinder = baseBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);

                    foreach (var baseTypeSyntax in implements.Types)
                    {
                        var b          = baseTypeSyntax.Type;
                        var tmpDiag    = DiagnosticBag.GetInstance();
                        var curBaseSym = baseBinder.BindType(b, tmpDiag).TypeSymbol;
                        tmpDiag.Free();

                        if (baseSym.Equals(curBaseSym))
                        {
                            return(new SourceLocation(b));
                        }
                    }
                }
            }

            return(null);
        }
        private ImmutableArray <string> GetInheritanceNames(StringTable stringTable, ImplementListSyntax implementList)
        {
            if (implementList == null)
            {
                return(ImmutableArray <string> .Empty);
            }

            var builder = ArrayBuilder <string> .GetInstance(implementList.Types.Count);

            // It's not sufficient to just store the textual names we see in the inheritance list
            // of a type.  For example if we have:
            //
            //   using Y = X;
            //      ...
            //      using Z = Y;
            //      ...
            //      class C : Z
            //
            // It's insufficient to just state that 'C' derives from 'Z'.  If we search for derived
            // types from 'B' we won't examine 'C'.  To solve this, we keep track of the aliasing
            // that occurs in containing scopes.  Then, when we're adding an inheritance name we
            // walk the alias maps and we also add any names that these names alias to.  In the
            // above example we'd put Z, Y, and X in the inheritance names list for 'C'.

            // Each dictionary in this list is a mapping from alias name to the name of the thing
            // it aliases.  Then, each scope with alias mapping gets its own entry in this list.
            // For the above example, we would produce:  [{Z => Y}, {Y => X}]
            var aliasMaps = AllocateAliasMapList();

            try
            {
                AddAliasMaps(implementList, aliasMaps);

                foreach (var baseType in implementList.Types)
                {
                    AddInheritanceName(builder, baseType.Type, aliasMaps);
                }

                Intern(stringTable, builder);
                return(builder.ToImmutableAndFree());
            }
            finally
            {
                FreeAliasMapList(aliasMaps);
            }
        }
Exemple #3
0
        // process the base list for one part of a partial class, or for the only part of any other type declaration.
        private Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > MakeOneDeclaredBases(ConsList <TypeSymbol> newBasesBeingResolved, SingleTypeDeclaration decl, DiagnosticBag diagnostics)
        {
            ExtendListSyntax    extends    = GetExtendListOpt(decl);
            ImplementListSyntax implements = GetImplementListOpt(decl);

            if (extends == null && implements == null)
            {
                return(null);
            }

            NamedTypeSymbol localBase       = null;
            var             localInterfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance();

            var baseBinder = this.DeclaringCompilation.GetBinder((BaseListSyntax)extends ?? implements);

            // Wrap base binder in a location-specific binder that will avoid generic constraint checks
            // (to avoid cycles if the constraint types are not bound yet). Instead, constraint checks
            // are handled by the caller.
            baseBinder = baseBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);

            if (extends != null)
            {
                ResolveBases(extends, newBasesBeingResolved, diagnostics, baseBinder, ref localBase, localInterfaces);
            }

            if (implements != null)
            {
                ResolveBases(implements, newBasesBeingResolved, diagnostics, baseBinder, ref localBase, localInterfaces);
            }

            if (this.SpecialType == SpecialType.System_Object && ((object)localBase != null || localInterfaces.Count != 0))
            {
                var name = GetName(extends?.Parent ?? implements?.Parent);
                diagnostics.Add(ErrorCode.ERR_ObjectCantHaveBases, new SourceLocation(name));
            }

            return(new Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> >(localBase, localInterfaces.ToImmutableAndFree()));
        }
        protected override Location GetCorrespondingBaseListLocation(NamedTypeSymbol @base)
        {
            Location backupLocation    = null;
            var      unusedDiagnostics = DiagnosticBag.GetInstance();

            foreach (SyntaxReference part in SyntaxReferences)
            {
                TypeDeclarationSyntax typeBlock  = (TypeDeclarationSyntax)part.GetSyntax();
                ImplementListSyntax   implements = typeBlock.ImplementList;
                if (implements == null)
                {
                    continue;
                }
                SeparatedSyntaxList <BaseTypeSyntax> inheritedTypeDecls = implements.Types;

                var baseBinder = this.DeclaringCompilation.GetBinder(implements);
                baseBinder = baseBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this);

                if ((object)backupLocation == null)
                {
                    backupLocation = inheritedTypeDecls[0].Type.GetLocation();
                }

                foreach (BaseTypeSyntax baseTypeSyntax in inheritedTypeDecls)
                {
                    TypeSyntax t  = baseTypeSyntax.Type;
                    TypeSymbol bt = baseBinder.BindType(t, unusedDiagnostics).TypeSymbol;

                    if (TypeSymbol.Equals(bt, @base, TypeCompareKind.ConsiderEverything2))
                    {
                        unusedDiagnostics.Free();
                        return(t.GetLocation());
                    }
                }
            }
            unusedDiagnostics.Free();
            return(backupLocation);
        }
Exemple #5
0
 public static ClassDeclarationSyntax ClassDeclaration(SyntaxList <AttributeSyntax> attributeLists, SyntaxTokenList modifiers, SyntaxToken identifier, TypeParameterListSyntax typeParameterList, ExtendListSyntax extendList, ImplementListSyntax implementList,
                                                       SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses, SyntaxList <MemberDeclarationSyntax> members)
 {
     return(SyntaxFactory.ClassDeclaration(attributeLists,
                                           modifiers,
                                           identifier,
                                           typeParameterList,
                                           extendList,
                                           implementList,
                                           constraintClauses,
                                           members,
                                           SyntaxFactory.EndOfLineToken()));
 }
Exemple #6
0
        public static TypeDeclarationSyntax TypeDeclaration(SyntaxKind kind, SyntaxList <AttributeSyntax> attributes, SyntaxTokenList modifiers, SyntaxToken keyword, SyntaxToken identifier, TypeParameterListSyntax typeParameterList, ExtendListSyntax extendList, ImplementListSyntax implementList, SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses, SyntaxToken openBraceToken, SyntaxList <MemberDeclarationSyntax> members, SyntaxToken closeBraceToken, SyntaxToken semicolonToken)
        {
            switch (kind)
            {
            case SyntaxKind.ClassDeclaration:
                return(SyntaxFactory.ClassDeclaration(attributes, modifiers, keyword, identifier, typeParameterList, extendList, implementList, constraintClauses, openBraceToken, members, closeBraceToken, semicolonToken));

            case SyntaxKind.StructDeclaration:
                return(SyntaxFactory.StructDeclaration(attributes, modifiers, keyword, identifier, typeParameterList, extendList, implementList, constraintClauses, openBraceToken, members, closeBraceToken, semicolonToken));

            case SyntaxKind.InterfaceDeclaration:
                return(SyntaxFactory.InterfaceDeclaration(attributes, modifiers, keyword, identifier, typeParameterList, extendList, implementList, constraintClauses, openBraceToken, members, closeBraceToken, semicolonToken));

            default:
                throw new ArgumentException("kind");
            }
        }