// 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); } }
// 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); }
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())); }
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"); } }