Browse Source

Worked on CSharpResolver.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
06c1adf1a0
  1. 5
      ICSharpCode.NRefactory/CSharp/Resolver/ByReferenceResolveResult.cs
  2. 126
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
  3. 5
      ICSharpCode.NRefactory/CSharp/Resolver/ConstantResolveResult.cs
  4. 34
      ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs
  5. 7
      ICSharpCode.NRefactory/CSharp/Resolver/MemberResolveResult.cs
  6. 13
      ICSharpCode.NRefactory/CSharp/Resolver/MethodGroupResolveResult.cs
  7. 2
      ICSharpCode.NRefactory/CSharp/Resolver/NamespaceResolveResult.cs
  8. 73
      ICSharpCode.NRefactory/CSharp/Resolver/UnknownMemberResolveResult.cs
  9. 4
      ICSharpCode.NRefactory/CSharp/Resolver/UsingScope.cs
  10. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

5
ICSharpCode.NRefactory/CSharp/Resolver/ByReferenceResolveResult.cs

@ -23,5 +23,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -23,5 +23,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public IType ElementType {
get { return ((ByReferenceType)this.Type).ElementType; }
}
public override string ToString()
{
return string.Format("[{0} {1} {2}]", GetType().Name, IsOut ? "out" : "ref", ElementType);
}
}
}

126
ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs

@ -1344,16 +1344,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1344,16 +1344,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
enum SimpleNameLookupMode
{
Expression,
InvocationTarget,
Type,
TypeInUsingDeclaration
}
public ResolveResult ResolveSimpleName(string identifier, IList<IType> typeArguments)
public ResolveResult ResolveSimpleName(string identifier, IList<IType> typeArguments, bool isInvocationTarget = false)
{
// C# 4.0 spec: §7.6.2 Simple Names
// TODO: lookup in local variables, in parameters, etc.
return LookupSimpleNameOrTypeName(identifier, typeArguments, SimpleNameLookupMode.Expression);
return LookupSimpleNameOrTypeName(identifier, typeArguments,
isInvocationTarget ? SimpleNameLookupMode.InvocationTarget : SimpleNameLookupMode.Expression);
}
public ResolveResult LookupSimpleNamespaceOrTypeName(string identifier, IList<IType> typeArguments, bool isUsingDeclaration = false)
@ -1379,6 +1381,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1379,6 +1381,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
MemberLookup lookup = new MemberLookup(context, this.CurrentTypeDefinition, this.UsingScope.ProjectContent);
// look in current type definitions
for (ITypeDefinition t = this.CurrentTypeDefinition; t != null; t = t.DeclaringTypeDefinition) {
if (k == 0) {
@ -1389,12 +1392,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1389,12 +1392,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
if (lookupMode == SimpleNameLookupMode.Expression) {
if (lookupMode == SimpleNameLookupMode.Expression || lookupMode == SimpleNameLookupMode.InvocationTarget) {
// TODO: perform member lookup within the type t
ResolveResult r = lookup.Lookup(t, identifier, typeArguments, lookupMode == SimpleNameLookupMode.InvocationTarget);
if (!(r is UnknownMemberResolveResult))
return r;
} else {
// TODO: perform member lookup within the type t, restricted to finding types
throw new NotImplementedException();
}
}
// look in current namespace definitions
@ -1485,5 +1490,116 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1485,5 +1490,116 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return ErrorResult;
}
#endregion
#region ResolveMemberAccess
public ResolveResult ResolveMemberAccess(ResolveResult target, string identifier, IList<IType> typeArguments, bool isInvocationTarget = false)
{
// C# 4.0 spec: §7.6.4
NamespaceResolveResult nrr = target as NamespaceResolveResult;
if (nrr != null) {
string fullName = NamespaceDeclaration.BuildQualifiedName(nrr.NamespaceName, identifier);
if (typeArguments.Count == 0) {
if (context.GetNamespace(fullName, StringComparer.Ordinal) != null)
return new NamespaceResolveResult(fullName);
}
ITypeDefinition def = context.GetClass(fullName, typeArguments.Count, StringComparer.Ordinal);
if (def != null)
return new TypeResolveResult(def);
return ErrorResult;
}
if (target.Type == SharedTypes.Dynamic)
return DynamicResult;
MemberLookup lookup = new MemberLookup(context, this.CurrentTypeDefinition, this.UsingScope.ProjectContent);
return lookup.Lookup(target.Type, identifier, typeArguments, isInvocationTarget);
}
#endregion
#region ResolveInvocation
public ResolveResult ResolveInvocation(ResolveResult target, ResolveResult[] arguments, string[] argumentNames = null)
{
// C# 4.0 spec: §7.6.5
if (target.Type == SharedTypes.Dynamic)
return DynamicResult;
MethodGroupResolveResult mgrr = target as MethodGroupResolveResult;
if (mgrr != null) {
throw new NotImplementedException();
}
UnknownMemberResolveResult umrr = target as UnknownMemberResolveResult;
if (umrr != null) {
return new UnknownMethodResolveResult(umrr.TargetType, umrr.MemberName, umrr.TypeArguments, CreateParameters(arguments, argumentNames));
}
IMethod invokeMethod = target.Type.GetDelegateInvokeMethod();
if (invokeMethod != null) {
return new ResolveResult(invokeMethod.ReturnType.Resolve(context));
}
return ErrorResult;
}
static List<DefaultParameter> CreateParameters(ResolveResult[] arguments, string[] argumentNames)
{
List<DefaultParameter> list = new List<DefaultParameter>();
if (argumentNames == null) {
argumentNames = new string[arguments.Length];
} else {
if (argumentNames.Length != arguments.Length)
throw new ArgumentException();
argumentNames = (string[])argumentNames.Clone();
}
for (int i = 0; i < arguments.Length; i++) {
// invent argument names where necessary:
if (arguments[i] == null) {
string newArgumentName = GuessParameterName(arguments[i]);
if (argumentNames.Contains(newArgumentName)) {
// disambiguate argument name (e.g. add a number)
throw new NotImplementedException();
}
argumentNames[i] = newArgumentName;
}
// create the parameter:
ByReferenceResolveResult brrr = arguments[i] as ByReferenceResolveResult;
if (brrr != null) {
list.Add(new DefaultParameter(arguments[i].Type, argumentNames[i]) {
IsRef = brrr.IsRef,
IsOut = brrr.IsOut
});
} else {
// argument might be a lambda or delegate type, so we have to try to guess the delegate type
IType type = arguments[i].Type;
if (type == SharedTypes.Null || type == SharedTypes.UnknownType) {
list.Add(new DefaultParameter(TypeCode.Object.ToTypeReference(), argumentNames[i]));
} else {
list.Add(new DefaultParameter(type, argumentNames[i]));
}
}
}
return list;
}
static string GuessParameterName(ResolveResult rr)
{
MemberResolveResult mrr = rr as MemberResolveResult;
if (mrr != null)
return mrr.Member.Name;
UnknownMemberResolveResult umrr = rr as UnknownMemberResolveResult;
if (umrr != null)
return umrr.MemberName;
MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;
if (mgrr != null && mgrr.Methods.Count > 0)
return mgrr.Methods[0].Name;
if (!string.IsNullOrEmpty(rr.Type.Name)) {
return char.ToLower(rr.Type.Name[0]) + rr.Type.Name.Substring(1);
} else {
return "parameter";
}
}
#endregion
}
}

5
ICSharpCode.NRefactory/CSharp/Resolver/ConstantResolveResult.cs

@ -25,5 +25,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -25,5 +25,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override object ConstantValue {
get { return constantValue; }
}
public override string ToString()
{
return string.Format("[{0} {1} = {2}]", GetType().Name, this.Type, constantValue);
}
}
}

34
ICSharpCode.NRefactory/CSharp/Resolver/MemberLookup.cs

@ -96,21 +96,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -96,21 +96,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <summary>
/// Performs a member lookup.
/// </summary>
public ResolveResult Lookup(IType type, string name, int typeParameterCount, bool isInvocation)
public ResolveResult Lookup(IType type, string name, IList<IType> typeArguments, bool isInvocation)
{
int typeArgumentCount = typeArguments.Count;
List<IType> types = new List<IType>();
List<IMember> members = new List<IMember>();
if (!isInvocation) {
// Consider nested types only if it's not an invocation. The type parameter count must match in this case.
types.AddRange(type.GetNestedTypes(context,
d => d.TypeParameterCount == typeParameterCount
d => d.TypeParameterCount == typeArgumentCount
&& d.Name == name && IsAccessible(d, true)));
}
ITypeDefinition typeDef = type.GetDefinition();
bool allowProtectedAccess = typeDef != null && typeDef.IsDerivedFrom(currentTypeDefinition, context);
if (typeParameterCount == 0) {
if (typeArgumentCount == 0) {
Predicate<IMember> memberFilter = delegate(IMember member) {
return !member.IsOverride && member.Name == name && IsAccessible(member, allowProtectedAccess);
};
@ -124,12 +126,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -124,12 +126,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// No need to check for isInvocation/isInvocable here:
// we filter out all non-methods
Predicate<IMethod> memberFilter = delegate(IMethod method) {
return method.TypeParameters.Count == typeParameterCount
return method.TypeParameters.Count == typeArgumentCount
&& !method.IsOverride && method.Name == name && IsAccessible(method, allowProtectedAccess);
};
members.AddRange(type.GetMethods(context, memberFilter));
}
// TODO: can't members also hide types?
// remove types hidden by other types
for (int i = types.Count - 1; i >= 0; i--) {
ITypeDefinition d = GetDeclaringTypeDef(types[i]);
@ -196,20 +200,32 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -196,20 +200,32 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
if (types.Count == 1 && members.Count == 0)
return new TypeResolveResult(types[0]);
if (types.Count > 0)
return new AmbiguousTypeResolveResult(types[0]);
if (types.Count > 0) {
IType returnedType = types[0];
if (typeArguments.Count > 0) {
// parameterize the type if necessary
ITypeDefinition returnedTypeDef = returnedType as ITypeDefinition;
if (returnedTypeDef != null)
returnedType = new ParameterizedType(returnedTypeDef, typeArguments);
}
if (types.Count == 1 && members.Count == 0)
return new TypeResolveResult(types[0]);
else
return new AmbiguousTypeResolveResult(types[0]);
}
if (members.Count == 0)
return new UnknownMemberResolveResult(type, name, typeArguments);
IMember firstNonMethod = members.FirstOrDefault(m => !(m is IMethod));
if (members.Count == 1 && firstNonMethod != null)
return new MemberResolveResult(firstNonMethod, firstNonMethod.ReturnType.Resolve(context));
if (firstNonMethod == null)
return new MethodGroupResolveResult(members.ConvertAll(m => (IMethod)m));
return new MethodGroupResolveResult(members.ConvertAll(m => (IMethod)m), typeArguments);
return new AmbiguousMemberResultResult(firstNonMethod, firstNonMethod.ReturnType.Resolve(context));
}
static bool IsNonInterfaceType(ITypeDefinition def)
{
// return type if def is neither an interface nor System.Object
return def.ClassType != ClassType.Interface && !(def.Name == "Object" && def.Namespace == "System" && def.TypeParameterCount == 0);
}

7
ICSharpCode.NRefactory/CSharp/Resolver/MemberResolveResult.cs

@ -15,11 +15,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -15,11 +15,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public MemberResolveResult(IMember member, IType returnType) : base(returnType)
{
if (member == null)
throw new ArgumentNullException("member");
this.member = member;
}
public IMember Member {
get { return member; }
}
public override string ToString()
{
return string.Format("[{0} {1}]", GetType().Name, member);
}
}
}

13
ICSharpCode.NRefactory/CSharp/Resolver/MethodGroupResolveResult.cs

@ -15,16 +15,27 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -15,16 +15,27 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public class MethodGroupResolveResult : ResolveResult
{
readonly ReadOnlyCollection<IMethod> methods;
readonly ReadOnlyCollection<IType> typeArguments;
public MethodGroupResolveResult(IList<IMethod> methods) : base(SharedTypes.UnknownType)
public MethodGroupResolveResult(IList<IMethod> methods, IList<IType> typeArguments) : base(SharedTypes.UnknownType)
{
if (methods == null)
throw new ArgumentNullException("methods");
this.methods = new ReadOnlyCollection<IMethod>(methods);
this.typeArguments = new ReadOnlyCollection<IType>(typeArguments);
}
public ReadOnlyCollection<IMethod> Methods {
get { return methods; }
}
public ReadOnlyCollection<IType> TypeArguments {
get { return typeArguments; }
}
public override string ToString()
{
return string.Format("[{0} with {1} method(s)]", GetType().Name, methods.Count);
}
}
}

2
ICSharpCode.NRefactory/CSharp/Resolver/NamespaceResolveResult.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override string ToString()
{
return "[NamespaceResolveResult " + namespaceName + "]";
return string.Format("[{0} {1}]", GetType().Name, namespaceName);
}
}
}

73
ICSharpCode.NRefactory/CSharp/Resolver/UnknownMemberResolveResult.cs

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
/// <summary>
/// Represents an unknown member.
/// </summary>
public class UnknownMemberResolveResult : ResolveResult
{
readonly IType targetType;
readonly string memberName;
readonly ReadOnlyCollection<IType> typeArguments;
public UnknownMemberResolveResult(IType targetType, string memberName, IEnumerable<IType> typeArguments) : base(SharedTypes.UnknownType)
{
if (targetType == null)
throw new ArgumentNullException("targetType");
this.targetType = targetType;
this.memberName = memberName;
this.typeArguments = new ReadOnlyCollection<IType>(typeArguments.ToArray());
}
public IType TargetType {
get { return targetType; }
}
public string MemberName {
get { return memberName; }
}
public ReadOnlyCollection<IType> TypeArguments {
get { return typeArguments; }
}
public override bool IsError {
get { return true; }
}
public override string ToString()
{
return string.Format("[{0} {1}.{2}]", GetType().Name, targetType, memberName);
}
}
/// <summary>
/// Represents an unknown method.
/// </summary>
public class UnknownMethodResolveResult : UnknownMemberResolveResult
{
readonly ReadOnlyCollection<IParameter> parameters;
public UnknownMethodResolveResult(IType targetType, string methodName, IEnumerable<IType> typeArguments, IEnumerable<IParameter> parameters)
: base(targetType, methodName, typeArguments)
{
this.parameters = new ReadOnlyCollection<IParameter>(parameters.ToArray());
}
public ReadOnlyCollection<IParameter> Parameters {
get { return parameters; }
}
public override bool IsError {
get { return true; }
}
}
}

4
ICSharpCode.NRefactory/CSharp/Resolver/UsingScope.cs

@ -70,6 +70,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -70,6 +70,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
get { return parent; }
}
public IProjectContent ProjectContent {
get { return projectContent; }
}
public DomRegion Region {
get { return region; }
set {

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -155,6 +155,7 @@ @@ -155,6 +155,7 @@
<Compile Include="CSharp\Resolver\ResolveResult.cs" />
<Compile Include="CSharp\Resolver\SimpleTypeOrNamespaceReference.cs" />
<Compile Include="CSharp\Resolver\TypeResolveResult.cs" />
<Compile Include="CSharp\Resolver\UnknownMemberResolveResult.cs" />
<Compile Include="CSharp\Resolver\UsingScope.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TypeSystem\Accessibility.cs" />

Loading…
Cancel
Save