private static ImplementListSyntax GetImplementListOpt(SingleTypeDeclaration decl) { if (decl.HasBaseDeclarations) { var typeDeclaration = (BaseTypeDeclarationSyntax)decl.SyntaxReference.GetSyntax(); return(typeDeclaration.ImplementList); } return(null); }
internal SynthesizedSimpleProgramEntryPointSymbol(SimpleProgramNamedTypeSymbol containingType, SingleTypeDeclaration declaration, DiagnosticBag diagnostics) : base(containingType, syntaxReferenceOpt: declaration.SyntaxReference, ImmutableArray.Create(declaration.SyntaxReference.GetLocation()), isIterator: declaration.IsIterator) { _declaration = declaration; bool hasAwait = declaration.HasAwaitExpressions; bool hasReturnWithExpression = declaration.HasReturnWithExpression; CSharpCompilation compilation = containingType.DeclaringCompilation; switch (hasAwait, hasReturnWithExpression) {
internal SynthesizedSimpleProgramEntryPointSymbol(SourceMemberContainerTypeSymbol containingType, SingleTypeDeclaration declaration, BindingDiagnosticBag diagnostics) : base(containingType, syntaxReferenceOpt: declaration.SyntaxReference, ImmutableArray.Create(declaration.SyntaxReference.GetLocation()), isIterator: declaration.IsIterator) { Debug.Assert(declaration.SyntaxReference.GetSyntax() is CompilationUnitSyntax); _declaration = declaration; bool hasAwait = declaration.HasAwaitExpressions; bool hasReturnWithExpression = declaration.HasReturnWithExpression; CSharpCompilation compilation = containingType.DeclaringCompilation; switch (hasAwait, hasReturnWithExpression) {
// 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())); }
// 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 <Symbol> newBasesBeingResolved, SingleTypeDeclaration decl, DiagnosticBag diagnostics) { BaseListSyntax bases = GetBaseListOpt(decl); if (bases == null) { return(null); } NamedTypeSymbol localBase = null; var localInterfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance(); var baseBinder = this.DeclaringCompilation.GetBinder(bases); // 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); int i = -1; foreach (var baseTypeSyntax in bases.Types) { i++; var typeSyntax = baseTypeSyntax.Type; var location = new SourceLocation(typeSyntax); TypeSymbol baseType; if (i == 0 && TypeKind == TypeKind.Class) // allow class in the first position { baseType = baseBinder.BindType(typeSyntax, diagnostics, newBasesBeingResolved); SpecialType baseSpecialType = baseType.SpecialType; if (IsRestrictedBaseType(baseSpecialType)) { // check for one of the specific exceptions required for compiling mscorlib if (this.SpecialType == SpecialType.System_Enum && baseSpecialType == SpecialType.System_ValueType || this.SpecialType == SpecialType.System_MulticastDelegate && baseSpecialType == SpecialType.System_Delegate) { // allowed } else if (baseSpecialType == SpecialType.System_Array && this.ContainingAssembly.CorLibrary == this.ContainingAssembly) { // Specific exception for System.ArrayContracts, which is only built when CONTRACTS_FULL is defined. // (See InheritanceResolver::CheckForBaseClassErrors). } else { // '{0}' cannot derive from special class '{1}' diagnostics.Add(ErrorCode.ERR_DeriveFromEnumOrValueType, Locations[0], this, baseType); continue; } } if (baseType.IsSealed && !this.IsStatic) // Give precedence to ERR_StaticDerivedFromNonObject { diagnostics.Add(ErrorCode.ERR_CantDeriveFromSealedType, Locations[0], this, baseType); continue; } bool baseTypeIsErrorWithoutInterfaceGuess = false; // If baseType is an error symbol and our best guess is that the desired symbol // is an interface, then put baseType in the interfaces list, rather than the // base type slot, to avoid the frustrating scenario where an error message // indicates that the symbol being returned as the base type was elsewhere // interpreted as an interface. if (baseType.TypeKind == TypeKind.Error) { baseTypeIsErrorWithoutInterfaceGuess = true; TypeKind guessTypeKind = baseType.GetNonErrorTypeKindGuess(); if (guessTypeKind == TypeKind.Interface) { //base type is an error *with* a guessed interface baseTypeIsErrorWithoutInterfaceGuess = false; } } if ((baseType.TypeKind == TypeKind.Class || baseType.TypeKind == TypeKind.Delegate || baseType.TypeKind == TypeKind.Struct || baseTypeIsErrorWithoutInterfaceGuess) && ((object)localBase == null)) { localBase = (NamedTypeSymbol)baseType; Debug.Assert((object)localBase != null); if (this.IsStatic && localBase.SpecialType != SpecialType.System_Object) { // Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object. var info = diagnostics.Add(ErrorCode.ERR_StaticDerivedFromNonObject, location, this, localBase); localBase = new ExtendedErrorTypeSymbol(localBase, LookupResultKind.NotReferencable, info); } continue; } } else { baseType = baseBinder.BindType(typeSyntax, diagnostics, newBasesBeingResolved); } switch (baseType.TypeKind) { case TypeKind.Interface: foreach (var t in localInterfaces) { if (t == baseType) { diagnostics.Add(ErrorCode.ERR_DuplicateInterfaceInBaseList, location, baseType); continue; } } if (this.IsStatic) { // '{0}': static classes cannot implement interfaces diagnostics.Add(ErrorCode.ERR_StaticClassInterfaceImpl, location, this, baseType); } if (baseType.ContainsDynamic()) { diagnostics.Add(ErrorCode.ERR_DeriveFromConstructedDynamic, location, this, baseType); } localInterfaces.Add((NamedTypeSymbol)baseType); continue; case TypeKind.Class: if (TypeKind == TypeKind.Class) { if ((object)localBase == null) { localBase = (NamedTypeSymbol)baseType; diagnostics.Add(ErrorCode.ERR_BaseClassMustBeFirst, location, baseType); continue; } else { diagnostics.Add(ErrorCode.ERR_NoMultipleInheritance, location, this, localBase, baseType); continue; } } goto default; case TypeKind.TypeParameter: diagnostics.Add(ErrorCode.ERR_DerivingFromATyVar, location, baseType); continue; case TypeKind.Error: // put the error type in the interface list so we don't lose track of it localInterfaces.Add((NamedTypeSymbol)baseType); continue; case TypeKind.Dynamic: diagnostics.Add(ErrorCode.ERR_DeriveFromDynamic, location, this); continue; case TypeKind.Submission: throw ExceptionUtilities.UnexpectedValue(baseType.TypeKind); default: diagnostics.Add(ErrorCode.ERR_NonInterfaceInInterfaceList, location, baseType); continue; } } if (this.SpecialType == SpecialType.System_Object && ((object)localBase != null || localInterfaces.Count != 0)) { var name = GetName(bases.Parent); diagnostics.Add(ErrorCode.ERR_ObjectCantHaveBases, new SourceLocation(name)); } return(new Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> >(localBase, localInterfaces.ToImmutableAndFree())); }
// 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<Symbol> newBasesBeingResolved, SingleTypeDeclaration decl, DiagnosticBag diagnostics) { BaseListSyntax bases = GetBaseListOpt(decl); if (bases == null) { return null; } NamedTypeSymbol localBase = null; var localInterfaces = ArrayBuilder<NamedTypeSymbol>.GetInstance(); var baseBinder = this.DeclaringCompilation.GetBinder(bases); // 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); int i = -1; foreach (var baseTypeSyntax in bases.Types) { i++; var typeSyntax = baseTypeSyntax.Type; var location = new SourceLocation(typeSyntax); TypeSymbol baseType; if (i == 0 && TypeKind == TypeKind.Class) // allow class in the first position { baseType = baseBinder.BindType(typeSyntax, diagnostics, newBasesBeingResolved); SpecialType baseSpecialType = baseType.SpecialType; if (IsRestrictedBaseType(baseSpecialType)) { // check for one of the specific exceptions required for compiling mscorlib if (this.SpecialType == SpecialType.System_Enum && baseSpecialType == SpecialType.System_ValueType || this.SpecialType == SpecialType.System_MulticastDelegate && baseSpecialType == SpecialType.System_Delegate) { // allowed } else if (baseSpecialType == SpecialType.System_Array && this.ContainingAssembly.CorLibrary == this.ContainingAssembly) { // Specific exception for System.ArrayContracts, which is only built when CONTRACTS_FULL is defined. // (See InheritanceResolver::CheckForBaseClassErrors). } else { // '{0}' cannot derive from special class '{1}' diagnostics.Add(ErrorCode.ERR_DeriveFromEnumOrValueType, Locations[0], this, baseType); continue; } } if (baseType.IsSealed && !this.IsStatic) // Give precedence to ERR_StaticDerivedFromNonObject { diagnostics.Add(ErrorCode.ERR_CantDeriveFromSealedType, Locations[0], this, baseType); continue; } bool baseTypeIsErrorWithoutInterfaceGuess = false; // If baseType is an error symbol and our best guess is that the desired symbol // is an interface, then put baseType in the interfaces list, rather than the // base type slot, to avoid the frustrating scenario where an error message // indicates that the symbol being returned as the base type was elsewhere // interpreted as an interface. if (baseType.TypeKind == TypeKind.Error) { baseTypeIsErrorWithoutInterfaceGuess = true; TypeKind guessTypeKind = baseType.GetNonErrorTypeKindGuess(); if (guessTypeKind == TypeKind.Interface) { //base type is an error *with* a guessed interface baseTypeIsErrorWithoutInterfaceGuess = false; } } if ((baseType.TypeKind == TypeKind.Class || baseType.TypeKind == TypeKind.Delegate || baseType.TypeKind == TypeKind.Struct || baseTypeIsErrorWithoutInterfaceGuess) && ((object)localBase == null)) { localBase = (NamedTypeSymbol)baseType; Debug.Assert((object)localBase != null); if (this.IsStatic && localBase.SpecialType != SpecialType.System_Object) { // Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object. var info = diagnostics.Add(ErrorCode.ERR_StaticDerivedFromNonObject, location, this, localBase); localBase = new ExtendedErrorTypeSymbol(localBase, LookupResultKind.NotReferencable, info); } continue; } } else { baseType = baseBinder.BindType(typeSyntax, diagnostics, newBasesBeingResolved); } switch (baseType.TypeKind) { case TypeKind.Interface: foreach (var t in localInterfaces) { if (t == baseType) { diagnostics.Add(ErrorCode.ERR_DuplicateInterfaceInBaseList, location, baseType); continue; } } if (this.IsStatic) { // '{0}': static classes cannot implement interfaces diagnostics.Add(ErrorCode.ERR_StaticClassInterfaceImpl, location, this, baseType); } if (baseType.ContainsDynamic()) { diagnostics.Add(ErrorCode.ERR_DeriveFromConstructedDynamic, location, this, baseType); } localInterfaces.Add((NamedTypeSymbol)baseType); continue; case TypeKind.Class: if (TypeKind == TypeKind.Class) { if ((object)localBase == null) { localBase = (NamedTypeSymbol)baseType; diagnostics.Add(ErrorCode.ERR_BaseClassMustBeFirst, location, baseType); continue; } else { diagnostics.Add(ErrorCode.ERR_NoMultipleInheritance, location, this, localBase, baseType); continue; } } goto default; case TypeKind.TypeParameter: diagnostics.Add(ErrorCode.ERR_DerivingFromATyVar, location, baseType); continue; case TypeKind.Error: // put the error type in the interface list so we don't lose track of it localInterfaces.Add((NamedTypeSymbol)baseType); continue; case TypeKind.Dynamic: diagnostics.Add(ErrorCode.ERR_DeriveFromDynamic, location, this); continue; case TypeKind.Submission: throw ExceptionUtilities.UnexpectedValue(baseType.TypeKind); default: diagnostics.Add(ErrorCode.ERR_NonInterfaceInInterfaceList, location, baseType); continue; } } if (this.SpecialType == SpecialType.System_Object && ((object)localBase != null || localInterfaces.Count != 0)) { var name = GetName(bases.Parent); diagnostics.Add(ErrorCode.ERR_ObjectCantHaveBases, new SourceLocation(name)); } return new Tuple<NamedTypeSymbol, ImmutableArray<NamedTypeSymbol>>(localBase, localInterfaces.ToImmutableAndFree()); }
private static BaseListSyntax GetBaseListOpt(SingleTypeDeclaration decl) { if (decl.HasBaseDeclarations) { var typeDeclaration = (BaseTypeDeclarationSyntax)decl.SyntaxReference.GetSyntax(); return typeDeclaration.BaseList; } return null; }