Inheritance: MethodOrPropertySymbol
            /////////////////////////////////////////////////////////////////////////////////

            public void AddInconvertibleResult(
                MethodSymbol method,
                AggregateType currentType,
                TypeArray currentTypeArgs)
            {
                if (InconvertibleResult.Sym == null)
                {
                    // This is the first one, so set it for error reporting usage.
                    InconvertibleResult.Set(method, currentType, currentTypeArgs);
                }
                _inconvertibleResults.Add(new MethPropWithInst(method, currentType, currentTypeArgs));
            }
        /*
        SPEC:

        CType inference occurs as part of the compile-time processing of a method invocation
        and takes place before the overload resolution step of the invocation. When a
        particular method group is specified in a method invocation, and no CType arguments
        are specified as part of the method invocation, CType inference is applied to each
        generic method in the method group. If CType inference succeeds, then the inferred
        CType arguments are used to determine the types of formal parameters for subsequent 
        overload resolution. If overload resolution chooses a generic method as the one to
        invoke then the inferred CType arguments are used as the actual CType arguments for the
        invocation. If CType inference for a particular method fails, that method does not
        participate in overload resolution. The failure of CType inference, in and of itself,
        does not cause a compile-time error. However, it often leads to a compile-time error
        when overload resolution then fails to find any applicable methods.

        If the supplied number of arguments is different than the number of parameters in
        the method, then inference immediately fails. Otherwise, assume that the generic
        method has the following signature:

        Tr M<X1...Xn>(T1 x1 ... Tm xm)

        With a method call of the form M(E1...Em) the task of CType inference is to find
        unique CType arguments S1...Sn for each of the CType parameters X1...Xn so that the
        call M<S1...Sn>(E1...Em)becomes valid.

        During the process of inference each CType parameter Xi is either fixed to a particular
        CType Si or unfixed with an associated set of bounds. Each of the bounds is some CType T.
        Each bound is classified as an upper bound, lower bound or exact bound.
        Initially each CType variable Xi is unfixed with an empty set of bounds.


        */

        // This file contains the implementation for method CType inference on calls (with
        // arguments, and method CType inference on conversion of method groups to delegate
        // types (which will not have arguments.)

        ////////////////////////////////////////////////////////////////////////////////

        public static bool Infer(
            ExpressionBinder binder,
            SymbolLoader symbolLoader,
            MethodSymbol pMethod,
            TypeArray pClassTypeArguments,
            TypeArray pMethodFormalParameterTypes,
            ArgInfos pMethodArguments,
            out TypeArray ppInferredTypeArguments)
        {
            Debug.Assert(pMethod != null);
            Debug.Assert(pMethod.typeVars.size > 0);
            Debug.Assert(pMethod.isParamArray || pMethod.Params == pMethodFormalParameterTypes);
            ppInferredTypeArguments = null;
            if (pMethodFormalParameterTypes.size == 0 || pMethod.InferenceMustFail())
            {
                return false;
            }
            Debug.Assert(pMethodArguments != null);
            Debug.Assert(pMethodFormalParameterTypes != null);
            Debug.Assert(pMethodArguments.carg <= pMethodFormalParameterTypes.size);

            var inferrer = new MethodTypeInferrer(binder, symbolLoader,
                pMethodFormalParameterTypes, pMethodArguments,
                pMethod.typeVars, pClassTypeArguments);
            bool success;
            if (pMethodArguments.fHasExprs)
            {
                success = inferrer.InferTypeArgs();
            }
            else
            {
                success = inferrer.InferForMethodGroupConversion();
            }

            ppInferredTypeArguments = inferrer.GetResults();
            return success;
        }
Exemple #3
0
        public TypeParameterSymbol CreateMethodTypeParameter(Name pName, MethodSymbol pParent, int index, int indexTotal)
        {
            TypeParameterSymbol pResult = newBasicSym(SYMKIND.SK_TypeParameterSymbol, pName, pParent).AsTypeParameterSymbol();
            pResult.SetIndexInOwnParameters(index);
            pResult.SetIndexInTotalParameters(indexTotal);

            pResult.SetIsMethodTypeParameter(true);
            pResult.SetAccess(ACCESS.ACC_PRIVATE); // Always private - not accessible anywhere except their own type.

            return pResult;
        }
Exemple #4
0
 private bool isConvInTable(List<UdConvInfo> convTable, MethodSymbol meth, AggregateType ats, bool fSrc, bool fDst)
 {
     foreach (UdConvInfo conv in convTable)
     {
         if (conv.mwt.Meth() == meth &&
             conv.mwt.GetType() == ats &&
             conv.fSrcImplicit == fSrc &&
             conv.fDstImplicit == fDst)
         {
             return true;
         }
     }
     return false;
 }
Exemple #5
0
 public void SetFirstUDConversion(MethodSymbol conv)
 {
     _pConvFirst = conv;
 }
Exemple #6
0
 public void SetConvNext(MethodSymbol conv)
 {
     Debug.Assert(isImplicit() || isExplicit());
     Debug.Assert(conv == null || conv.isImplicit() || conv.isExplicit());
     _convNext = conv;
 }
Exemple #7
0
 public void SetConvNext(MethodSymbol conv)
 {
     Debug.Assert(isImplicit() || isExplicit());
     Debug.Assert(conv == null || conv.isImplicit() || conv.isExplicit());
     _convNext = conv;
 }
 public ExprMethodInfo CreateMethodInfo(MethodSymbol method, AggregateType methodType, TypeArray methodParameters)
 {
     return(new ExprMethodInfo(
                Types.GetPredefAgg(method.IsConstructor() ? PredefinedType.PT_CONSTRUCTORINFO : PredefinedType.PT_METHODINFO).getThisType(),
                method, methodType, methodParameters));
 }
Exemple #9
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeParameterType LoadMethodTypeParameter(MethodSymbol parent, Type t)
        {
            for (Symbol sym = parent.firstChild; sym != null; sym = sym.nextChild)
            {
                if (!sym.IsTypeParameterSymbol())
                {
                    continue;
                }

                if (AreTypeParametersEquivalent(sym.AsTypeParameterSymbol().GetTypeParameterType().AssociatedSystemType, t))
                {
                    return sym.AsTypeParameterSymbol().GetTypeParameterType();
                }
            }
            return AddTypeParameterToSymbolTable(null, parent, t, false);
        }
Exemple #10
0
 protected void ErrAppendMethodParentSym(MethodSymbol sym, SubstContext pcxt, out TypeArray substMethTyParams)
 {
     substMethTyParams = null;
     ErrAppendParentSym(sym, pcxt);
 }
Exemple #11
0
 public MethWithType(MethodSymbol meth, AggregateType ats)
 {
     Set(meth, ats);
 }
Exemple #12
0
        public EXPRMETHODINFO CreateMethodInfo(MethodSymbol method, AggregateType methodType, TypeArray methodParameters)
        {
            Debug.Assert(method != null);
            Debug.Assert(methodType != null);
            EXPRMETHODINFO methodInfo = new EXPRMETHODINFO();
            CType type;
            if (method.IsConstructor())
            {
                type = GetTypes().GetOptPredefAgg(PredefinedType.PT_CONSTRUCTORINFO).getThisType();
            }
            else
            {
                type = GetTypes().GetOptPredefAgg(PredefinedType.PT_METHODINFO).getThisType();
            }

            methodInfo.kind = ExpressionKind.EK_METHODINFO;
            methodInfo.type = type;
            methodInfo.flags = 0;
            methodInfo.Method = new MethWithInst(method, methodType, methodParameters);
            return methodInfo;
        }
        protected Symbol newBasicSym(
            SYMKIND kind,
            Name name,
            ParentSymbol parent)
        {
            // The parser creates names with PN_MISSING when attempting to recover from errors
            // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM)
            // so that they are never found when doing lookup.
            if (name == m_pMissingNameNode)
            {
                name = m_pMissingNameSym;
            }

            Symbol sym;
            switch (kind)
            {
                case SYMKIND.SK_NamespaceSymbol:
                    sym = new NamespaceSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_NamespaceDeclaration:
                    sym = new NamespaceDeclaration();
                    sym.name = name;
                    break;
                case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                    sym = new AssemblyQualifiedNamespaceSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_AggregateSymbol:
                    sym = new AggregateSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_AggregateDeclaration:
                    sym = new AggregateDeclaration();
                    sym.name = name;
                    break;
                case SYMKIND.SK_TypeParameterSymbol:
                    sym = new TypeParameterSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_FieldSymbol:
                    sym = new FieldSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_LocalVariableSymbol:
                    sym = new LocalVariableSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_MethodSymbol:
                    sym = new MethodSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_PropertySymbol:
                    sym = new PropertySymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_EventSymbol:
                    sym = new EventSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_TransparentIdentifierMemberSymbol:
                    sym = new TransparentIdentifierMemberSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_Scope:
                    sym = new Scope();
                    sym.name = name;
                    break;
                case SYMKIND.SK_LabelSymbol:
                    sym = new LabelSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_GlobalAttributeDeclaration:
                    sym = new GlobalAttributeDeclaration();
                    sym.name = name;
                    break;
                case SYMKIND.SK_UnresolvedAggregateSymbol:
                    sym = new UnresolvedAggregateSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_InterfaceImplementationMethodSymbol:
                    sym = new InterfaceImplementationMethodSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_IndexerSymbol:
                    sym = new IndexerSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_ParentSymbol:
                    sym = new ParentSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_IteratorFinallyMethodSymbol:
                    sym = new IteratorFinallyMethodSymbol();
                    sym.name = name;
                    break;
                default:
                    throw Error.InternalCompilerError();
            }

            sym.setKind(kind);

            if (parent != null)
            {
                // Set the parent element of the child symbol.
                parent.AddToChildList(sym);
                m_pSymTable.InsertChild(parent, sym);
            }

            return (sym);
        }
Exemple #14
0
 private void ReportBogusForEventsAndProperties(SymWithType swt, MethodSymbol meth1, MethodSymbol meth2)
 {
     if (meth1 != null && meth2 != null)
     {
         GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp2, swt.Sym.name, new SymWithType(meth1, swt.GetType()), new SymWithType(meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym));
         return;
     }
     if (meth1 != null || meth2 != null)
     {
         GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp1, swt.Sym.name, new SymWithType(meth1 != null ? meth1 : meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym));
         return;
     }
     throw Error.InternalCompilerError();
 }
Exemple #15
0
 public void SetFirstUDConversion(MethodSymbol conv)
 {
     _pConvFirst = conv;
 }
Exemple #16
0
        private Symbol NewBasicSymbol(
            SYMKIND kind,
            Name name,
            ParentSymbol parent)
        {
            Symbol sym;

            switch (kind)
            {
            case SYMKIND.SK_NamespaceSymbol:
                sym      = new NamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                sym      = new AssemblyQualifiedNamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateSymbol:
                sym      = new AggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateDeclaration:
                sym      = new AggregateDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_TypeParameterSymbol:
                sym      = new TypeParameterSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_FieldSymbol:
                sym      = new FieldSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_LocalVariableSymbol:
                sym      = new LocalVariableSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_MethodSymbol:
                sym      = new MethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_PropertySymbol:
                sym      = new PropertySymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_EventSymbol:
                sym      = new EventSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_Scope:
                sym      = new Scope();
                sym.name = name;
                break;

            case SYMKIND.SK_IndexerSymbol:
                sym      = new IndexerSymbol();
                sym.name = name;
                break;

            default:
                throw Error.InternalCompilerError();
            }

            sym.setKind(kind);

            if (parent != null)
            {
                // Set the parent element of the child symbol.
                parent.AddToChildList(sym);
                _symbolTable.InsertChild(parent, sym);
            }

            return(sym);
        }
Exemple #17
0
        ////////////////////////////////////////////////////////////////////////////////
        //
        // In error recovery and reporting scenarios we sometimes end up in a situation
        // like this:
        //
        // x.Foo( y=>
        //
        // and the question is, "is Foo a valid extension method of x?"  If Foo is
        // generic, then Foo will be something like:
        //
        // static Blah Foo<T>(this Bar<T> bar, Func<T, T> f){ ... }
        //
        // What we would like to know is: given _only_ the expression x, can we infer
        // what T is in Bar<T> ?  If we can, then for error recovery and reporting
        // we can provisionally consider Foo to be an extension method of x. If we 
        // cannot deduce this just from x then we should consider Foo to not be an
        // extension method of x, at least until we have more information.
        //
        // Clearly it is pointless to run multiple phases

        public static bool CanObjectOfExtensionBeInferred(
            ExpressionBinder binder,
            SymbolLoader symbolLoader,
            MethodSymbol pMethod,
            TypeArray pClassTypeArguments,
            TypeArray pMethodFormalParameterTypes,
            ArgInfos pMethodArguments)
        {
            Debug.Assert(pMethod != null);
            Debug.Assert(pMethod.typeVars.size > 0);
            Debug.Assert(pMethodFormalParameterTypes != null);
            Debug.Assert(pMethod.isParamArray || pMethod.Params == pMethodFormalParameterTypes);
            // We need at least one formal parameter type and at least one argument.
            if (pMethodFormalParameterTypes.size < 1 || pMethod.InferenceMustFail())
            {
                return false;
            }
            Debug.Assert(pMethodArguments != null);
            Debug.Assert(pMethodArguments.carg <= pMethodFormalParameterTypes.size);
            if (pMethodArguments.carg < 1)
            {
                return false;
            }
            var inferrer = new MethodTypeInferrer(binder, symbolLoader,
            pMethodFormalParameterTypes, pMethodArguments, pMethod.typeVars, pClassTypeArguments);
            return inferrer.CanInferExtensionObject();
        }
Exemple #18
0
 public MethWithInst(MethodSymbol meth, AggregateType ats, TypeArray typeArgs)
 {
     Set(meth, ats, typeArgs);
 }
Exemple #19
0
        protected void ErrAppendMethod(MethodSymbol meth, SubstContext pctx, bool fArgs)
        {
            if (meth.IsExpImpl() && meth.swtSlot)
            {
                ErrAppendParentSym(meth, pctx);

                // Get the type args from the explicit impl type and substitute using pctx (if there is one).
                SubstContext ctx = new SubstContext(GetTypeManager().SubstType(meth.swtSlot.GetType(), pctx).AsAggregateType());
                ErrAppendSym(meth.swtSlot.Sym, ctx, fArgs);

                // args already added
                return;
            }

            if (meth.isPropertyAccessor())
            {
                PropertySymbol prop = meth.getProperty();

                // this includes the parent class
                ErrAppendSym(prop, pctx);

                // add accessor name
                if (prop.methGet == meth)
                {
                    ErrAppendString(".get");
                }
                else
                {
                    Debug.Assert(meth == prop.methSet);
                    ErrAppendString(".set");
                }

                // args already added
                return;
            }

            if (meth.isEventAccessor())
            {
                EventSymbol @event = meth.getEvent();

                // this includes the parent class
                ErrAppendSym(@event, pctx);

                // add accessor name
                if (@event.methAdd == meth)
                {
                    ErrAppendString(".add");
                }
                else
                {
                    Debug.Assert(meth == @event.methRemove);
                    ErrAppendString(".remove");
                }

                // args already added
                return;
            }

            TypeArray replacementTypeArray = null;
            ErrAppendMethodParentSym(meth, pctx, out replacementTypeArray);
            if (meth.IsConstructor())
            {
                // Use the name of the parent class instead of the name "<ctor>".
                ErrAppendName(meth.getClass().name);
            }
            else if (meth.IsDestructor())
            {
                // Use the name of the parent class instead of the name "Finalize".
                ErrAppendChar('~');
                ErrAppendName(meth.getClass().name);
            }
            else if (meth.isConversionOperator())
            {
                // implicit/explicit
                ErrAppendString(meth.isImplicit() ? "implicit" : "explicit");
                ErrAppendString(" operator ");

                // destination type name
                ErrAppendType(meth.RetType, pctx);
            }
            else if (meth.isOperator)
            {
                // handle user defined operators
                // map from CLS predefined names to "operator <X>"
                ErrAppendString("operator ");

                //
                // This is kinda slow, but the alternative is to add bits to methsym.
                //
                string operatorName;
                OperatorKind op = Operators.OperatorOfMethodName(GetNameManager(), meth.name);
                if (Operators.HasDisplayName(op))
                {
                    operatorName = Operators.GetDisplayName(op);
                }
                else
                {
                    //
                    // either equals or compare
                    //
                    if (meth.name == GetNameManager().GetPredefName(PredefinedName.PN_OPEQUALS))
                    {
                        operatorName = "equals";
                    }
                    else
                    {
                        Debug.Assert(meth.name == GetNameManager().GetPredefName(PredefinedName.PN_OPCOMPARE));
                        operatorName = "compare";
                    }
                }
                ErrAppendString(operatorName);
            }
            else if (meth.IsExpImpl())
            {
                if (meth.errExpImpl != null)
                    ErrAppendType(meth.errExpImpl, pctx, fArgs);
            }
            else
            {
                // regular method
                ErrAppendName(meth.name);
            }

            if (null == replacementTypeArray)
            {
                ErrAppendTypeParameters(meth.typeVars, pctx, false);
            }

            if (fArgs)
            {
                // append argument types
                ErrAppendChar('(');

                if (!meth.computeCurrentBogusState())
                {
                    ErrAppendParamList(GetTypeManager().SubstTypeArray(meth.Params, pctx), meth.isVarargs, meth.isParamArray);
                }

                ErrAppendChar(')');
            }
        }
Exemple #20
0
        /******************************************************************************
        *   Search just the given type (not any bases). Returns true iff it finds
        *   something (which will have been recorded by RecordType).
        *
        *   pfHideByName is set to true iff something was found that hides all
        *   members of base types (eg, a hidebyname method).
        ******************************************************************************/
        private bool SearchSingleType(AggregateType typeCur, out bool pfHideByName)
        {
            bool fFoundSome = false;

            pfHideByName = false;

            // Make sure this type is accessible. It may not be due to private inheritance
            // or friend assemblies.
            bool fInaccess = !CSemanticChecker.CheckTypeAccess(typeCur, _symWhere);

            if (fInaccess && (_csym != 0 || _swtInaccess != null))
            {
                return(false);
            }

            // Loop through symbols.
            Symbol symCur;

            for (symCur = SymbolLoader.LookupAggMember(_name, typeCur.OwningAggregate, symbmask_t.MASK_Member);
                 symCur != null;
                 symCur = symCur.LookupNext(symbmask_t.MASK_Member))
            {
                Debug.Assert(!(symCur is AggregateSymbol));
                // Check for arity.
                // For non-zero arity, only methods of the correct arity are considered.
                // For zero arity, don't filter out any methods since we do type argument
                // inferencing.
                // All others are only considered when arity is zero.
                if (_arity > 0 && (!(symCur is MethodSymbol curMeth) || curMeth.typeVars.Count != _arity))
                {
                    if (!_swtBadArity)
                    {
                        _swtBadArity.Set(symCur, typeCur);
                    }

                    continue;
                }

                // Check for user callability.
                if (symCur.IsOverride() && !symCur.IsHideByName())
                {
                    continue;
                }

                MethodOrPropertySymbol methProp = symCur as MethodOrPropertySymbol;
                MethodSymbol           meth     = symCur as MethodSymbol;
                if (methProp != null && (_flags & MemLookFlags.UserCallable) != 0 && !methProp.isUserCallable())
                {
                    // If its an indexed property method symbol, let it through.
                    // This is too liberal, but maintained for compatibility.
                    if (meth == null ||
                        !meth.isPropertyAccessor() ||
                        (!symCur.name.Text.StartsWith("set_", StringComparison.Ordinal) || meth.Params.Count <= 1) &&
                        (!symCur.name.Text.StartsWith("get_", StringComparison.Ordinal) || meth.Params.Count <= 0))
                    {
                        if (!_swtInaccess)
                        {
                            _swtInaccess.Set(symCur, typeCur);
                        }

                        continue;
                    }
                }

                if (fInaccess || !CSemanticChecker.CheckAccess(symCur, typeCur, _symWhere, _typeQual))
                {
                    // Not accessible so get the next sym.
                    if (!_swtInaccess)
                    {
                        _swtInaccess.Set(symCur, typeCur);
                    }
                    if (fInaccess)
                    {
                        return(false);
                    }
                    continue;
                }

                PropertySymbol prop = symCur as PropertySymbol;

                // Make sure that whether we're seeing a ctor, operator, or indexer is consistent with the flags.
                if (((_flags & MemLookFlags.Ctor) == 0) != (meth == null || !meth.IsConstructor()) ||
                    ((_flags & MemLookFlags.Operator) == 0) != (meth == null || !meth.isOperator) ||
                    ((_flags & MemLookFlags.Indexer) == 0) != !(prop is IndexerSymbol))
                {
                    if (!_swtBad)
                    {
                        _swtBad.Set(symCur, typeCur);
                    }
                    continue;
                }

                // We can't call CheckBogus on methods or indexers because if the method has the wrong
                // number of parameters people don't think they should have to /r the assemblies containing
                // the parameter types and they complain about the resulting CS0012 errors.
                if (!(symCur is MethodSymbol) && (_flags & MemLookFlags.Indexer) == 0 && CSemanticChecker.CheckBogus(symCur))
                {
                    // A bogus member - we can't use these, so only record them for error reporting.
                    if (!_swtBogus)
                    {
                        _swtBogus.Set(symCur, typeCur);
                    }
                    continue;
                }

                // if we are in a calling context then we should only find a property if it is delegate valued
                if ((_flags & MemLookFlags.MustBeInvocable) != 0)
                {
                    if ((symCur is FieldSymbol field && !IsDelegateType(field.GetType(), typeCur) && !IsDynamicMember(symCur)) ||
                        (prop != null && !IsDelegateType(prop.RetType, typeCur) && !IsDynamicMember(symCur)))
                    {
                        if (!_swtBad)
                        {
                            _swtBad.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

                if (methProp != null)
                {
                    MethPropWithType mwpInsert = new MethPropWithType(methProp, typeCur);
                    _methPropWithTypeList.Add(mwpInsert);
                }

                // We have a visible symbol.
                fFoundSome = true;

                if (_swtFirst)
                {
                    if (!typeCur.IsInterfaceType)
                    {
                        // Non-interface case.
                        Debug.Assert(_fMulti || typeCur == _prgtype[0]);
                        if (!_fMulti)
                        {
                            if (_swtFirst.Sym is FieldSymbol && symCur is EventSymbol
                                // The isEvent bit is only set on symbols which come from source...
                                // This is not a problem for the compiler because the field is only
                                // accessible in the scope in which it is declared,
                                // but in the EE we ignore accessibility...
                                && _swtFirst.Field().isEvent
                                )
                            {
                                // m_swtFirst is just the field behind the event symCur so ignore symCur.
                                continue;
                            }
                            else if (_swtFirst.Sym is FieldSymbol && symCur is EventSymbol)
                            {
                                // symCur is the matching event.
                                continue;
                            }
                            goto LAmbig;
                        }
                        if (_swtFirst.Sym.getKind() != symCur.getKind())
                        {
                            if (typeCur == _prgtype[0])
                            {
                                goto LAmbig;
                            }
                            // This one is hidden by the first one. This one also hides any more in base types.
                            pfHideByName = true;
                            continue;
                        }
                    }
                    // Interface case.
                    // m_fMulti   : n n n y y y y y
                    // same-kind  : * * * y n n n n
                    // fDiffHidden: * * * * y n n n
                    // meth       : * * * * * y n *  can n happen? just in case, we better handle it....
                    // hack       : n * y * * y * n
                    // meth-2     : * n y * * * * *
                    // res        : A A S R H H A A
                    else if (!_fMulti)
                    {
                        // Give method groups priority.
                        if (!(symCur is MethodSymbol))
                        {
                            goto LAmbig;
                        }
                        // Erase previous results so we'll record this method as the first.
                        _prgtype = new List <AggregateType>();
                        _csym    = 0;
                        _swtFirst.Clear();
                        _swtAmbig.Clear();
                    }
                    else if (_swtFirst.Sym.getKind() != symCur.getKind())
                    {
                        if (!typeCur.DiffHidden)
                        {
                            // Give method groups priority.
                            if (!(_swtFirst.Sym is MethodSymbol))
                            {
                                goto LAmbig;
                            }
                        }
                        // This one is hidden by another. This one also hides any more in base types.
                        pfHideByName = true;
                        continue;
                    }
                }

                RecordType(typeCur, symCur);

                if (methProp != null && methProp.isHideByName)
                {
                    pfHideByName = true;
                }
                // We've found a symbol in this type but need to make sure there aren't any conflicting
                // syms here, so keep searching the type.
            }

            Debug.Assert(!fInaccess || !fFoundSome);

            return(fFoundSome);

LAmbig:
            // Ambiguous!
            if (!_swtAmbig)
            {
                _swtAmbig.Set(symCur, typeCur);
            }
            pfHideByName = true;
            return(true);
        }
Exemple #21
0
 public MethWithInst(MethodSymbol meth, AggregateType ats)
     : this(meth, ats, null)
 {
 }
Exemple #22
0
 private bool UserDefinedBinaryOperatorCanBeLifted(ExpressionKind ek, MethodSymbol method, AggregateType ats,
     TypeArray Params)
 {
     if (!Params.Item(0).IsNonNubValType())
     {
         return false;
     }
     if (!Params.Item(1).IsNonNubValType())
     {
         return false;
     }
     CType typeRet = GetTypes().SubstType(method.RetType, ats);
     if (!typeRet.IsNonNubValType())
     {
         return false;
     }
     switch (ek)
     {
         case ExpressionKind.EK_EQ:
         case ExpressionKind.EK_NE:
             if (!typeRet.isPredefType(PredefinedType.PT_BOOL))
             {
                 return false;
             }
             if (Params.Item(0) != Params.Item(1))
             {
                 return false;
             }
             return true;
         case ExpressionKind.EK_GT:
         case ExpressionKind.EK_GE:
         case ExpressionKind.EK_LT:
         case ExpressionKind.EK_LE:
             if (!typeRet.isPredefType(PredefinedType.PT_BOOL))
             {
                 return false;
             }
             return true;
         default:
             return true;
     }
 }
Exemple #23
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeArray GetMethodTypeParameters(MethodInfo method, MethodSymbol parent)
        {
            if (method.IsGenericMethod)
            {
                Type[] genericArguments = method.GetGenericArguments();
                CType[] ctypes = new CType[genericArguments.Length];
                for (int i = 0; i < genericArguments.Length; i++)
                {
                    Type t = genericArguments[i];
                    ctypes[i] = LoadMethodTypeParameter(parent, t);
                }

                // After we load the type parameters, we need to resolve their bounds.
                for (int i = 0; i < genericArguments.Length; i++)
                {
                    Type t = genericArguments[i];
                    ctypes[i].AsTypeParameterType().GetTypeParameterSymbol().SetBounds(
                        _bsymmgr.AllocParams(
                        GetCTypeArrayFromTypes(t.GetTypeInfo().GetGenericParameterConstraints())));
                }
                return _bsymmgr.AllocParams(ctypes.Length, ctypes);
            }
            return BSYMMGR.EmptyTypeArray();
        }
Exemple #24
0
 // If the operator is applicable in either its regular or lifted forms, 
 // add it to the candidate set and return true, otherwise return false.
 private bool UserDefinedBinaryOperatorIsApplicable(List<CandidateFunctionMember> candidateList,
     ExpressionKind ek, MethodSymbol method, AggregateType ats, EXPR arg1, EXPR arg2, bool fDontLift)
 {
     if (!method.isOperator || method.Params.size != 2)
     {
         return false;
     }
     Debug.Assert(method.typeVars.size == 0);
     TypeArray paramsCur = GetTypes().SubstTypeArray(method.Params, ats);
     if (canConvert(arg1, paramsCur.Item(0)) && canConvert(arg2, paramsCur.Item(1)))
     {
         candidateList.Add(new CandidateFunctionMember(
             new MethPropWithInst(method, ats, BSYMMGR.EmptyTypeArray()),
             paramsCur,
             0, // No lifted arguments
             false));
         return true;
     }
     if (fDontLift || !GetSymbolLoader().FCanLift() ||
         !UserDefinedBinaryOperatorCanBeLifted(ek, method, ats, paramsCur))
     {
         return false;
     }
     CType[] rgtype = new CType[2];
     rgtype[0] = GetTypes().GetNullable(paramsCur.Item(0));
     rgtype[1] = GetTypes().GetNullable(paramsCur.Item(1));
     if (!canConvert(arg1, rgtype[0]) || !canConvert(arg2, rgtype[1]))
     {
         return false;
     }
     candidateList.Add(new CandidateFunctionMember(
         new MethPropWithInst(method, ats, BSYMMGR.EmptyTypeArray()),
         GetGlobalSymbols().AllocParams(2, rgtype),
         2, // two lifted arguments
         false));
     return true;
 }
Exemple #25
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeParameterType AddTypeParameterToSymbolTable(
                AggregateSymbol agg,
                MethodSymbol meth,
                Type t,
                bool bIsAggregate)
        {
            Debug.Assert((agg != null && bIsAggregate) || (meth != null && !bIsAggregate));

            TypeParameterSymbol typeParam;
            if (bIsAggregate)
            {
                typeParam = _symFactory.CreateClassTypeParameter(
                    GetName(t),
                    agg,
                    t.GenericParameterPosition,
                    t.GenericParameterPosition);
            }
            else
            {
                typeParam = _symFactory.CreateMethodTypeParameter(
                    GetName(t),
                    meth,
                    t.GenericParameterPosition,
                    t.GenericParameterPosition);
            }

            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.Covariant) != 0)
            {
                typeParam.Covariant = true;
            }
            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0)
            {
                typeParam.Contravariant = true;
            }

            SpecCons cons = SpecCons.None;

            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
            {
                cons |= SpecCons.New;
            }
            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
            {
                cons |= SpecCons.Ref;
            }
            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
            {
                cons |= SpecCons.Val;
            }

            typeParam.SetConstraints(cons);
            typeParam.SetAccess(ACCESS.ACC_PUBLIC);
            TypeParameterType typeParamType = _typeManager.GetTypeParameter(typeParam);

            return typeParamType;
        }
Exemple #26
0
        protected Symbol newBasicSym(
            SYMKIND kind,
            Name name,
            ParentSymbol parent)
        {
            // The parser creates names with PN_MISSING when attempting to recover from errors
            // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM)
            // so that they are never found when doing lookup.
            if (name == m_pMissingNameNode)
            {
                name = m_pMissingNameSym;
            }

            Symbol sym;

            switch (kind)
            {
            case SYMKIND.SK_NamespaceSymbol:
                sym      = new NamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_NamespaceDeclaration:
                sym      = new NamespaceDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                sym      = new AssemblyQualifiedNamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateSymbol:
                sym      = new AggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateDeclaration:
                sym      = new AggregateDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_TypeParameterSymbol:
                sym      = new TypeParameterSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_FieldSymbol:
                sym      = new FieldSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_LocalVariableSymbol:
                sym      = new LocalVariableSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_MethodSymbol:
                sym      = new MethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_PropertySymbol:
                sym      = new PropertySymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_EventSymbol:
                sym      = new EventSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_TransparentIdentifierMemberSymbol:
                sym      = new TransparentIdentifierMemberSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_Scope:
                sym      = new Scope();
                sym.name = name;
                break;

            case SYMKIND.SK_LabelSymbol:
                sym      = new LabelSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_GlobalAttributeDeclaration:
                sym      = new GlobalAttributeDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_UnresolvedAggregateSymbol:
                sym      = new UnresolvedAggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_InterfaceImplementationMethodSymbol:
                sym      = new InterfaceImplementationMethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_IndexerSymbol:
                sym      = new IndexerSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_ParentSymbol:
                sym      = new ParentSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_IteratorFinallyMethodSymbol:
                sym      = new IteratorFinallyMethodSymbol();
                sym.name = name;
                break;

            default:
                throw Error.InternalCompilerError();
            }

            sym.setKind(kind);

            if (parent != null)
            {
                // Set the parent element of the child symbol.
                parent.AddToChildList(sym);
                m_pSymTable.InsertChild(parent, sym);
            }

            return(sym);
        }