Exemple #1
0
        private bool _fMulti;              // Whether symFirst is of a kind for which we collect multiples (methods and indexers).

        /***************************************************************************************************
        *   Another match was found. Increment the count of syms and add the type to our list if it's not
        *   already there.
        ***************************************************************************************************/
        private void RecordType(AggregateType type, Symbol sym)
        {
            Debug.Assert(type != null && sym != null);

            if (!_prgtype.Contains(type))
            {
                _prgtype.Add(type);
            }

            // Now record the sym....

            _csym++;

            // If it is first, record it.
            if (_swtFirst == null)
            {
                _swtFirst.Set(sym, type);
                Debug.Assert(_csym == 1);
                Debug.Assert(_prgtype[0] == type);
                _fMulti = sym.IsMethodSymbol() || sym.IsPropertySymbol() && sym.AsPropertySymbol().isIndexer();
            }
        }
Exemple #2
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;
            MethPropWithType mwpInsert;

            pfHideByName = false;

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

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

            // Loop through symbols.
            Symbol symCur = null;

            for (symCur = GetSymbolLoader().LookupAggMember(_name, typeCur.getAggregate(), symbmask_t.MASK_ALL);
                 symCur != null;
                 symCur = GetSymbolLoader().LookupNextSym(symCur, typeCur.getAggregate(), symbmask_t.MASK_ALL))
            {
                // Check for arity.
                switch (symCur.getKind())
                {
                case SYMKIND.SK_MethodSymbol:
                    // 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.
                    if (_arity > 0 && symCur.AsMethodSymbol().typeVars.size != _arity)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;

                case SYMKIND.SK_AggregateSymbol:
                    // For types, always filter on arity.
                    if (symCur.AsAggregateSymbol().GetTypeVars().size != _arity)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;

                case SYMKIND.SK_TypeParameterSymbol:
                    if ((_flags & MemLookFlags.TypeVarsAllowed) == 0)
                    {
                        continue;
                    }
                    if (_arity > 0)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;

                default:
                    // All others are only considered when arity is zero.
                    if (_arity > 0)
                    {
                        if (!_swtBadArity)
                        {
                            _swtBadArity.Set(symCur, typeCur);
                        }
                        continue;
                    }
                    break;
                }

                // Check for user callability.
                if (symCur.IsOverride() && !symCur.IsHideByName())
                {
                    if (!_swtOverride)
                    {
                        _swtOverride.Set(symCur, typeCur);
                    }
                    continue;
                }
                if ((_flags & MemLookFlags.UserCallable) != 0 && symCur.IsMethodOrPropertySymbol() && !symCur.AsMethodOrPropertySymbol().isUserCallable())
                {
                    bool bIsIndexedProperty = false;
                    // If its an indexed property method symbol, let it through.
                    if (symCur.IsMethodSymbol() &&
                        symCur.AsMethodSymbol().isPropertyAccessor() &&
                        ((symCur.name.Text.StartsWith("set_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 1) ||
                         (symCur.name.Text.StartsWith("get_", StringComparison.Ordinal) && symCur.AsMethodSymbol().Params.size > 0)))
                    {
                        bIsIndexedProperty = true;
                    }

                    if (!bIsIndexedProperty)
                    {
                        if (!_swtInaccess)
                        {
                            _swtInaccess.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

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

                // Make sure that whether we're seeing a ctor, operator, or indexer is consistent with the flags.
                if (((_flags & MemLookFlags.Ctor) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().IsConstructor()) ||
                    ((_flags & MemLookFlags.Operator) == 0) != (!symCur.IsMethodSymbol() || !symCur.AsMethodSymbol().isOperator) ||
                    ((_flags & MemLookFlags.Indexer) == 0) != (!symCur.IsPropertySymbol() || !symCur.AsPropertySymbol().isIndexer()))
                {
                    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.IsMethodSymbol() && (_flags & MemLookFlags.Indexer) == 0 && GetSemanticChecker().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.IsFieldSymbol() && !IsDelegateType(symCur.AsFieldSymbol().GetType(), typeCur) && !IsDynamicMember(symCur)) ||
                        (symCur.IsPropertySymbol() && !IsDelegateType(symCur.AsPropertySymbol().RetType, typeCur) && !IsDynamicMember(symCur)))
                    {
                        if (!_swtBad)
                        {
                            _swtBad.Set(symCur, typeCur);
                        }
                        continue;
                    }
                }

                if (symCur.IsMethodOrPropertySymbol())
                {
                    mwpInsert = new MethPropWithType(symCur.AsMethodOrPropertySymbol(), 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.IsFieldSymbol() && symCur.IsEventSymbol()
#if !CSEE                       // 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
#endif
                                )
                            {
                                // m_swtFirst is just the field behind the event symCur so ignore symCur.
                                continue;
                            }
                            else if (_swtFirst.Sym.IsFieldSymbol() && symCur.IsEventSymbol())
                            {
                                // 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 (/* !GetSymbolLoader().options.fLookupHack ||*/ !symCur.IsMethodSymbol())
                        {
                            goto LAmbig;
                        }
                        _swtAmbigWarn = _swtFirst;
                        // 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.fDiffHidden)
                        {
                            // Give method groups priority.
                            if (/*!GetSymbolLoader().options.fLookupHack ||*/ !_swtFirst.Sym.IsMethodSymbol())
                            {
                                goto LAmbig;
                            }
                            if (!_swtAmbigWarn)
                            {
                                _swtAmbigWarn.Set(symCur, typeCur);
                            }
                        }
                        // This one is hidden by another. This one also hides any more in base types.
                        pfHideByName = true;
                        continue;
                    }
                }

                RecordType(typeCur, symCur);

                if (symCur.IsMethodOrPropertySymbol() && symCur.AsMethodOrPropertySymbol().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 #3
0
        public void ErrAppendSym(Symbol sym, SubstContext pctx, bool fArgs)
        {
            switch (sym.getKind())
            {
                case SYMKIND.SK_NamespaceDeclaration:
                    // for namespace declarations just convert the namespace
                    ErrAppendSym(sym.AsNamespaceDeclaration().NameSpace(), null);
                    break;

                case SYMKIND.SK_GlobalAttributeDeclaration:
                    ErrAppendName(sym.name);
                    break;

                case SYMKIND.SK_AggregateDeclaration:
                    ErrAppendSym(sym.AsAggregateDeclaration().Agg(), pctx);
                    break;

                case SYMKIND.SK_AggregateSymbol:
                    {
                        // Check for a predefined class with a special "nice" name for
                        // error reported.
                        string text = PredefinedTypes.GetNiceName(sym.AsAggregateSymbol());
                        if (text != null)
                        {
                            // Found a nice name.
                            ErrAppendString(text);
                        }
                        else if (sym.AsAggregateSymbol().IsAnonymousType())
                        {
                            ErrAppendId(MessageID.AnonymousType);
                            break;
                        }
                        else
                        {
                            ErrAppendParentSym(sym, pctx);
                            ErrAppendName(sym.name);
                            ErrAppendTypeParameters(sym.AsAggregateSymbol().GetTypeVars(), pctx, true);
                        }
                        break;
                    }

                case SYMKIND.SK_MethodSymbol:
                    ErrAppendMethod(sym.AsMethodSymbol(), pctx, fArgs);
                    break;

                case SYMKIND.SK_PropertySymbol:
                    ErrAppendProperty(sym.AsPropertySymbol(), pctx);
                    break;

                case SYMKIND.SK_EventSymbol:
                    ErrAppendEvent(sym.AsEventSymbol(), pctx);
                    break;

                case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                case SYMKIND.SK_NamespaceSymbol:
                    if (sym == getBSymmgr().GetRootNS())
                    {
                        ErrAppendId(MessageID.GlobalNamespace);
                    }
                    else
                    {
                        ErrAppendParentSym(sym, null);
                        ErrAppendName(sym.name);
                    }
                    break;

                case SYMKIND.SK_FieldSymbol:
                    ErrAppendParentSym(sym, pctx);
                    ErrAppendName(sym.name);
                    break;

                case SYMKIND.SK_TypeParameterSymbol:
                    if (null == sym.name)
                    {
                        // It's a standard type variable.
                        if (sym.AsTypeParameterSymbol().IsMethodTypeParameter())
                            ErrAppendChar('!');
                        ErrAppendChar('!');
                        ErrAppendPrintf("{0}", sym.AsTypeParameterSymbol().GetIndexInTotalParameters());
                    }
                    else
                        ErrAppendName(sym.name);
                    break;

                case SYMKIND.SK_LocalVariableSymbol:
                case SYMKIND.SK_LabelSymbol:
                case SYMKIND.SK_TransparentIdentifierMemberSymbol:
                    // Generate symbol name.
                    ErrAppendName(sym.name);
                    break;

                case SYMKIND.SK_Scope:
                case SYMKIND.SK_LambdaScope:
                default:
                    // Shouldn't happen.
                    Debug.Assert(false, "Bad symbol kind");
                    break;
            }
        }
Exemple #4
0
        private bool _fMulti;              // Whether symFirst is of a kind for which we collect multiples (methods and indexers).

        /***************************************************************************************************
            Another match was found. Increment the count of syms and add the type to our list if it's not
            already there.
        ***************************************************************************************************/
        private void RecordType(AggregateType type, Symbol sym)
        {
            Debug.Assert(type != null && sym != null);

            if (!_prgtype.Contains(type))
            {
                _prgtype.Add(type);
            }

            // Now record the sym....

            _csym++;

            // If it is first, record it.
            if (_swtFirst == null)
            {
                _swtFirst.Set(sym, type);
                Debug.Assert(_csym == 1);
                Debug.Assert(_prgtype[0] == type);
                _fMulti = sym.IsMethodSymbol() || sym.IsPropertySymbol() && sym.AsPropertySymbol().isIndexer();
            }
        }
Exemple #5
0
        private bool IsDynamicMember(Symbol sym)
        {
            System.Runtime.CompilerServices.DynamicAttribute da = null;
            if (sym.IsFieldSymbol())
            {
                if (!sym.AsFieldSymbol().getType().isPredefType(PredefinedType.PT_OBJECT))
                {
                    return false;
                }
                var o = sym.AsFieldSymbol().AssociatedFieldInfo.GetCustomAttributes(typeof(System.Runtime.CompilerServices.DynamicAttribute), false).ToArray();
                if (o.Length == 1)
                {
                    da = o[0] as System.Runtime.CompilerServices.DynamicAttribute;
                }
            }
            else
            {
                Debug.Assert(sym.IsPropertySymbol());
                if (!sym.AsPropertySymbol().getType().isPredefType(PredefinedType.PT_OBJECT))
                {
                    return false;
                }
                var o = sym.AsPropertySymbol().AssociatedPropertyInfo.GetCustomAttributes(typeof(System.Runtime.CompilerServices.DynamicAttribute), false).ToArray();
                if (o.Length == 1)
                {
                    da = o[0] as System.Runtime.CompilerServices.DynamicAttribute;
                }
            }

            if (da == null)
            {
                return false;
            }
            return (da.TransformFlags.Count == 0 || (da.TransformFlags.Count == 1 && da.TransformFlags[0]));
        }