Example #1
0
        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)
            {
Example #4
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()));
        }
Example #5
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 <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;
        }