public ResolveResult LookupSimpleNameOrTypeName(string identifier, IList<IType> typeArguments, NameLookupMode lookupMode)
{
// C# 4.0 spec: §3.8 Namespace and type names; §7.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 this.LocalVariables) {
if (v.Name == identifier) {
return new LocalResolveResult(v);
}
}
// Look in parameters of current method
IParameterizedMember parameterizedMember = this.CurrentMember as IParameterizedMember;
if (parameterizedMember != null) {
foreach (IParameter p in parameterizedMember.Parameters) {
if (p.Name == identifier) {
return new LocalResolveResult(p);
}
}
}
}
// look in type parameters of current method
IMethod m = this.CurrentMember as IMethod;
if (m != null) {
foreach (ITypeParameter tp in m.TypeParameters) {
if (tp.Name == identifier)
return new TypeResolveResult(tp);
}
}
}
bool parameterizeResultType = !(typeArguments.Count != 0 && typeArguments.All(t => t.Kind == TypeKind.UnboundTypeArgument));
ResolveResult r = null;
if (currentTypeDefinitionCache != null) {
Dictionary<string, ResolveResult> cache = null;
bool foundInCache = false;
if (k == 0) {
switch (lookupMode) {
case NameLookupMode.Expression:
cache = currentTypeDefinitionCache.SimpleNameLookupCacheExpression;
break;
case NameLookupMode.InvocationTarget:
cache = currentTypeDefinitionCache.SimpleNameLookupCacheInvocationTarget;
break;
case NameLookupMode.Type:
cache = 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(identifier, typeArguments, lookupMode, parameterizeResultType);
if (cache != null) {
// also cache missing members (r==null)
lock (cache)
cache[identifier] = r;
}
}
if (r != null)
return r;
}
if (context.CurrentUsingScope == null) {
// If no using scope was specified, we still need to look in the global namespace:
r = LookInUsingScopeNamespace(null, compilation.RootNamespace, identifier, typeArguments, parameterizeResultType);
} else {
if (k == 0 && lookupMode != NameLookupMode.TypeInUsingDeclaration) {
if (context.CurrentUsingScope.ResolveCache.TryGetValue(identifier, out r)) {
r = (r != null ? r.ShallowClone() : null);
} else {
r = LookInCurrentUsingScope(identifier, typeArguments, false, false);
context.CurrentUsingScope.ResolveCache.TryAdd(identifier, r);
}
} else {
r = LookInCurrentUsingScope(identifier, typeArguments, lookupMode == NameLookupMode.TypeInUsingDeclaration, parameterizeResultType);
}
}
if (r != null)
return r;
if (typeArguments.Count == 0 && identifier == "dynamic") {
return new TypeResolveResult(SpecialType.Dynamic);
} else {
return new UnknownIdentifierResolveResult(identifier, typeArguments.Count);
}
}