Exemplo n.º 1
0
        public Expression LookupSimpleNameOrTypeName(ResolveContext rc, string identifier, IList <IType> typeArguments, NameLookupMode lookupMode)
        {
            // V# 4.0 spec: �8 Namespace and type names; �6.2 Simple Names

            if (identifier == null)
            {
                throw new ArgumentNullException("identifier");
            }
            if (typeArguments == null)
            {
                throw new ArgumentNullException("typeArguments");
            }

            int k = typeArguments.Count;

            if (k == 0)
            {
                if (lookupMode == NameLookupMode.Expression || lookupMode == NameLookupMode.InvocationTarget)
                {
                    // Look in local variables
                    foreach (IVariable v in rc.LocalVariables)
                    {
                        if (v.Name == identifier)
                        {
                            return(new LocalVariableExpression(v, Location));
                        }
                    }
                    // Look in parameters of current method
                    IParameterizedMember parameterizedMember = rc.CurrentMember as IParameterizedMember;
                    if (parameterizedMember != null)
                    {
                        foreach (IParameter p in parameterizedMember.Parameters)
                        {
                            if (p.Name == identifier)
                            {
                                return(new LocalVariableExpression(p, Location));
                            }
                        }
                    }
                }

                // look in type parameters of current method
                IMethod m = rc.CurrentMember as IMethod;
                if (m != null)
                {
                    foreach (ITypeParameter tp in m.TypeParameters)
                    {
                        if (tp.Name == identifier)
                        {
                            return(new TypeExpression(tp, Location));
                        }
                    }
                }
            }

            bool parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));

            Expression r = null;

            if (rc.currentTypeDefinitionCache != null)
            {
                Dictionary <string, Expression> cache = null;
                bool foundInCache = false;
                if (k == 0)
                {
                    switch (lookupMode)
                    {
                    case NameLookupMode.Expression:
                        cache = rc.currentTypeDefinitionCache.SimpleNameLookupCacheExpression;
                        break;

                    case NameLookupMode.InvocationTarget:
                        cache = rc.currentTypeDefinitionCache.SimpleNameLookupCacheInvocationTarget;
                        break;

                    case NameLookupMode.Type:
                        cache = rc.currentTypeDefinitionCache.SimpleTypeLookupCache;
                        break;
                    }
                    if (cache != null)
                    {
                        lock (cache)
                            foundInCache = cache.TryGetValue(identifier, out r);
                    }
                }
                if (foundInCache)
                {
                    r = (r != null ? r.ShallowClone() : null);
                }
                else
                {
                    r = LookInCurrentType(rc, identifier, typeArguments, lookupMode, parameterizeResultType);
                    if (cache != null)
                    {
                        // also cache missing members (r==null)
                        lock (cache)
                            cache[identifier] = r;
                    }
                }
                if (r != null)
                {
                    return(r);
                }
            }

            if (rc.context.CurrentUsingScope == null)
            {
                // If no using scope was specified, we still need to look in the global namespace:
                r = LookInUsingScopeNamespace(rc, null, rc.compilation.RootNamespace, identifier, typeArguments, parameterizeResultType);
            }
            else
            {
                if (k == 0 && lookupMode != NameLookupMode.TypeInUsingDeclaration)
                {
                    if (rc.context.CurrentUsingScope.ResolveCache.TryGetValue(identifier, out r))
                    {
                        r = (r != null ? r.ShallowClone() : null);
                    }
                    else
                    {
                        r = LookInCurrentUsingScope(rc, identifier, typeArguments, false, false);
                        rc.context.CurrentUsingScope.ResolveCache.TryAdd(identifier, r);
                    }
                }
                else
                {
                    r = LookInCurrentUsingScope(rc, identifier, typeArguments, lookupMode == NameLookupMode.TypeInUsingDeclaration, parameterizeResultType);
                }
            }
            if (r != null)
            {
                return(r);
            }

            if (typeArguments.Count == 0 && identifier == "dynamic")
            {
                return(new TypeExpression(SpecialTypeSpec.Dynamic as IType, Location));
            }
            else
            {
                return(ErrorResult);
            }
        }