private Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > MakeDeclaredBases(ConsList <TypeSymbol> basesBeingResolved, DiagnosticBag diagnostics) { if (this.TypeKind == TypeKind.Enum) { // Handled by GetEnumUnderlyingType(). return(new Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> >(null, ImmutableArray <NamedTypeSymbol> .Empty)); } var reportedPartialConflict = false; Debug.Assert(basesBeingResolved == null || !basesBeingResolved.ContainsReference(this.OriginalDefinition)); var newBasesBeingResolved = basesBeingResolved.Prepend(this.OriginalDefinition); var baseInterfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance(); NamedTypeSymbol baseType = null; SourceLocation baseTypeLocation = null; var interfaceLocations = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance <NamedTypeSymbol, SourceLocation>(); foreach (var decl in this.declaration.Declarations) { Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > one = MakeOneDeclaredBases(newBasesBeingResolved, decl, diagnostics); if ((object)one == null) { continue; } var partBase = one.Item1; var partInterfaces = one.Item2; if (!reportedPartialConflict) { if ((object)baseType == null) { baseType = partBase; baseTypeLocation = decl.NameLocation; } else if (baseType.TypeKind == TypeKind.Error && (object)partBase != null) { // if the old base was an error symbol, copy it to the interfaces list so it doesn't get lost partInterfaces = partInterfaces.Add(baseType); baseType = partBase; baseTypeLocation = decl.NameLocation; } else if ((object)partBase != null && !TypeSymbol.Equals(partBase, baseType, TypeCompareKind.ConsiderEverything2) && partBase.TypeKind != TypeKind.Error) { // the parts do not agree var info = diagnostics.Add(ErrorCode.ERR_PartialMultipleBases, Locations[0], this); baseType = new ExtendedErrorTypeSymbol(baseType, LookupResultKind.Ambiguous, info); baseTypeLocation = decl.NameLocation; reportedPartialConflict = true; } } foreach (var t in partInterfaces) { if (!interfaceLocations.ContainsKey(t)) { baseInterfaces.Add(t); interfaceLocations.Add(t, decl.NameLocation); } } } HashSet <DiagnosticInfo> useSiteDiagnostics = null; if ((object)baseType != null) { Debug.Assert(baseTypeLocation != null); if (baseType.IsStatic) { // '{1}': cannot derive from static class '{0}' diagnostics.Add(ErrorCode.ERR_StaticBaseClass, baseTypeLocation, baseType, this); } if (!this.IsNoMoreVisibleThan(baseType, ref useSiteDiagnostics)) { // Inconsistent accessibility: base class '{1}' is less accessible than class '{0}' diagnostics.Add(ErrorCode.ERR_BadVisBaseClass, baseTypeLocation, this, baseType); } } var baseInterfacesRO = baseInterfaces.ToImmutableAndFree(); if (DeclaredAccessibility != Accessibility.Private && IsInterface) { foreach (var i in baseInterfacesRO) { if (!i.IsAtLeastAsVisibleAs(this, ref useSiteDiagnostics)) { // Inconsistent accessibility: base interface '{1}' is less accessible than interface '{0}' diagnostics.Add(ErrorCode.ERR_BadVisBaseInterface, interfaceLocations[i], this, i); } } } interfaceLocations.Free(); diagnostics.Add(Locations[0], useSiteDiagnostics); return(new Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> >(baseType, baseInterfacesRO)); }
private Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > MakeDeclaredBases(ConsList <TypeSymbol> basesBeingResolved, BindingDiagnosticBag diagnostics) { if (this.TypeKind == TypeKind.Enum) { // Handled by GetEnumUnderlyingType(). return(new Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> >(null, ImmutableArray <NamedTypeSymbol> .Empty)); } var reportedPartialConflict = false; Debug.Assert(basesBeingResolved == null || !basesBeingResolved.ContainsReference(this.OriginalDefinition)); var newBasesBeingResolved = basesBeingResolved.Prepend(this.OriginalDefinition); var baseInterfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance(); NamedTypeSymbol baseType = null; SourceLocation baseTypeLocation = null; var interfaceLocations = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance <NamedTypeSymbol, SourceLocation>(); foreach (var decl in this.declaration.Declarations) { Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > one = MakeOneDeclaredBases(newBasesBeingResolved, decl, diagnostics); if ((object)one == null) { continue; } var partBase = one.Item1; var partInterfaces = one.Item2; if (!reportedPartialConflict) { if ((object)baseType == null) { baseType = partBase; baseTypeLocation = decl.NameLocation; } else if (baseType.TypeKind == TypeKind.Error && (object)partBase != null) { // if the old base was an error symbol, copy it to the interfaces list so it doesn't get lost partInterfaces = partInterfaces.Add(baseType); baseType = partBase; baseTypeLocation = decl.NameLocation; } else if ((object)partBase != null && !TypeSymbol.Equals(partBase, baseType, TypeCompareKind.ConsiderEverything) && partBase.TypeKind != TypeKind.Error) { // the parts do not agree if (partBase.Equals(baseType, TypeCompareKind.ObliviousNullableModifierMatchesAny)) { if (containsOnlyOblivious(baseType)) { baseType = partBase; baseTypeLocation = decl.NameLocation; continue; } else if (containsOnlyOblivious(partBase)) { continue; } } var info = diagnostics.Add(ErrorCode.ERR_PartialMultipleBases, Locations[0], this); baseType = new ExtendedErrorTypeSymbol(baseType, LookupResultKind.Ambiguous, info); baseTypeLocation = decl.NameLocation; reportedPartialConflict = true;