Browse Source

Added constructor overload lookup.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@147 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 21 years ago
parent
commit
dc6c33595a
  1. 5
      src/Main/Base/Project/Src/Dom/Implementations/AbstractNamedEntity.cs
  2. 77
      src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs
  3. 6
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  4. 9
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs
  5. 1
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj
  6. 46
      src/Main/Base/Test/ReflectionLayerTests.cs
  7. 4
      src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

5
src/Main/Base/Project/Src/Dom/Implementations/AbstractNamedEntity.cs

@ -96,5 +96,10 @@ namespace ICSharpCode.SharpDevelop.Dom
nspace = declaringType.FullyQualifiedName; nspace = declaringType.FullyQualifiedName;
fullyQualifiedName = nspace + '.' + name; fullyQualifiedName = nspace + '.' + name;
} }
public override string ToString()
{
return String.Format("[{0}: {1}]", GetType().Name, fullyQualifiedName);
}
} }
} }

77
src/Main/Base/Project/Src/Dom/Implementations/DefaultClass.cs

@ -292,7 +292,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
return false; return false;
} }
*/ */
/* /*
public IMember SearchMember(string memberName) public IMember SearchMember(string memberName)
{ {
@ -343,7 +343,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
return null; return null;
} }
*/ */
public IClass GetInnermostClass(int caretLine, int caretColumn) public IClass GetInnermostClass(int caretLine, int caretColumn)
{ {
@ -438,20 +438,32 @@ namespace ICSharpCode.SharpDevelop.Dom
return members; return members;
} }
*/ */
public class ClassInheritanceEnumerator : IEnumerator, IEnumerable public class ClassInheritanceEnumerator : IEnumerator, IEnumerable
{ {
IClass topLevelClass; IClass topLevelClass;
IClass currentClass = null; IClass currentClass = null;
Queue baseTypeQueue = new Queue();
private struct BaseType {
internal IClass parent;
internal string name;
internal BaseType(IClass parent, string name) {
this.parent = parent;
this.name = name;
}
}
Queue<BaseType> baseTypeQueue = new Queue<BaseType>();
List<IClass> finishedClasses = new List<IClass>();
public ClassInheritanceEnumerator(IClass topLevelClass) public ClassInheritanceEnumerator(IClass topLevelClass)
{ {
this.topLevelClass = topLevelClass; this.topLevelClass = topLevelClass;
baseTypeQueue.Enqueue(topLevelClass.FullyQualifiedName);
PutBaseClassesOnStack(topLevelClass); PutBaseClassesOnStack(topLevelClass);
baseTypeQueue.Enqueue("System.Object"); baseTypeQueue.Enqueue(new BaseType(null, "System.Object"));
} }
public IEnumerator GetEnumerator() public IEnumerator GetEnumerator()
@ -462,7 +474,7 @@ namespace ICSharpCode.SharpDevelop.Dom
void PutBaseClassesOnStack(IClass c) void PutBaseClassesOnStack(IClass c)
{ {
foreach (string baseTypeName in c.BaseTypes) { foreach (string baseTypeName in c.BaseTypes) {
baseTypeQueue.Enqueue(baseTypeName); baseTypeQueue.Enqueue(new BaseType(c, baseTypeName));
} }
} }
@ -478,42 +490,40 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
bool first = true;
public bool MoveNext() public bool MoveNext()
{ {
try { try {
if (first) {
first = false;
currentClass = topLevelClass;
return true;
}
if (baseTypeQueue.Count == 0) { if (baseTypeQueue.Count == 0) {
return false; return false;
} }
string baseTypeName = baseTypeQueue.Dequeue().ToString();
IClass baseType = ParserService.CurrentProjectContent.GetClass(baseTypeName); BaseType baseTypeStruct = baseTypeQueue.Dequeue();
// search through all usings the top level class compilation unit has.
if (baseType == null) {
ICompilationUnit unit = currentClass == null ? null : currentClass.CompilationUnit;
if (unit != null) {
foreach (IUsing u in unit.Usings) {
baseType = u.SearchType(baseTypeName);
if (baseType != null) {
break;
}
}
}
}
// search through all namespaces the top level class is defined in. IClass baseType;
if (baseType == null) { if (baseTypeStruct.parent == null) {
string[] namespaces = topLevelClass.Namespace.Split('.'); baseType = ProjectContentRegistry.GetMscorlibContent().GetClass(baseTypeStruct.name);
for (int i = namespaces.Length; i > 0 && baseType == null; --i) { } else {
baseType = ParserService.CurrentProjectContent.GetClass(String.Join(".", namespaces, 0, i) + "." + baseTypeName); baseType = baseTypeStruct.parent.ProjectContent.SearchType(baseTypeStruct.name, baseTypeStruct.parent, 1, 1);
}
} }
if (baseType != null) { if (baseType != null) {
currentClass = baseType; currentClass = baseType;
// prevent enumerating interfaces multiple times and endless loops when
// circular inheritance is found
if (finishedClasses.Contains(currentClass)) {
return MoveNext();
}
finishedClasses.Add(currentClass);
PutBaseClassesOnStack(currentClass); PutBaseClassesOnStack(currentClass);
return true;
} }
return baseType != null;
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine(e); Console.WriteLine(e);
} }
@ -522,10 +532,11 @@ namespace ICSharpCode.SharpDevelop.Dom
public void Reset() public void Reset()
{ {
first = true;
baseTypeQueue.Clear(); baseTypeQueue.Clear();
baseTypeQueue.Enqueue(topLevelClass.FullyQualifiedName); finishedClasses.Clear();
PutBaseClassesOnStack(topLevelClass); PutBaseClassesOnStack(topLevelClass);
baseTypeQueue.Enqueue("System.Object"); baseTypeQueue.Enqueue(new BaseType(null, "System.Object"));
} }
} }
} }

6
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs

@ -201,11 +201,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return null; return null;
} }
if (expr is ObjectCreateExpression) { if (expr is ObjectCreateExpression) {
ArrayList constructors = new ArrayList();
foreach (IMethod m in type.GetMethods()) { foreach (IMethod m in type.GetMethods()) {
if (m.IsConstructor && !m.IsStatic) if (m.IsConstructor && !m.IsStatic)
return CreateMemberResolveResult(m); constructors.Add(m);
} }
return null; return CreateMemberResolveResult(typeVisitor.FindOverload(constructors, ((ObjectCreateExpression)expr).Parameters, null));
} }
return new ResolveResult(callingClass, callingMember, type); return new ResolveResult(callingClass, callingMember, type);
} }
@ -331,6 +332,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
private ResolveResult CreateMemberResolveResult(IMember member) private ResolveResult CreateMemberResolveResult(IMember member)
{ {
if (member == null) return null;
return new MemberResolveResult(callingClass, callingMember, member); return new MemberResolveResult(callingClass, callingMember, member);
} }

9
src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return m.ReturnType; return m.ReturnType;
} }
IMethod FindOverload(ArrayList methods, InvocationExpression invocationExpression, object data) public IMethod FindOverload(ArrayList methods, ArrayList arguments, object data)
{ {
if (methods.Count <= 0) { if (methods.Count <= 0) {
return null; return null;
@ -61,7 +61,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (methods.Count == 1) if (methods.Count == 1)
return bestMethod; return bestMethod;
ArrayList arguments = invocationExpression.Parameters;
IReturnType[] types = new IReturnType[arguments.Count]; IReturnType[] types = new IReturnType[arguments.Count];
for (int i = 0; i < types.Length; ++i) { for (int i = 0; i < types.Length; ++i) {
types[i] = ((Expression)arguments[i]).AcceptVisitor(this, data) as IReturnType; types[i] = ((Expression)arguments[i]).AcceptVisitor(this, data) as IReturnType;
@ -103,14 +102,14 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
FieldReferenceExpression field = (FieldReferenceExpression)invocationExpression.TargetObject; FieldReferenceExpression field = (FieldReferenceExpression)invocationExpression.TargetObject;
IReturnType type = field.TargetObject.AcceptVisitor(this, data) as IReturnType; IReturnType type = field.TargetObject.AcceptVisitor(this, data) as IReturnType;
ArrayList methods = resolver.SearchMethod(type, field.FieldName); ArrayList methods = resolver.SearchMethod(type, field.FieldName);
return FindOverload(methods, invocationExpression, data); return FindOverload(methods, invocationExpression.Parameters, data);
} else if (invocationExpression.TargetObject is IdentifierExpression) { } else if (invocationExpression.TargetObject is IdentifierExpression) {
string id = ((IdentifierExpression)invocationExpression.TargetObject).Identifier; string id = ((IdentifierExpression)invocationExpression.TargetObject).Identifier;
if (resolver.CallingClass == null) { if (resolver.CallingClass == null) {
return null; return null;
} }
ArrayList methods = resolver.SearchMethod(resolver.CallingClass.DefaultReturnType, id); ArrayList methods = resolver.SearchMethod(resolver.CallingClass.DefaultReturnType, id);
return FindOverload(methods, invocationExpression, data); return FindOverload(methods, invocationExpression.Parameters, data);
} }
// invocationExpression is delegate call // invocationExpression is delegate call
IReturnType t = invocationExpression.AcceptChildren(this, data) as IReturnType; IReturnType t = invocationExpression.AcceptChildren(this, data) as IReturnType;
@ -120,7 +119,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
IClass c = resolver.SearchType(t.FullyQualifiedName, resolver.CallingClass, resolver.CompilationUnit); IClass c = resolver.SearchType(t.FullyQualifiedName, resolver.CallingClass, resolver.CompilationUnit);
if (c.ClassType == ClassType.Delegate) { if (c.ClassType == ClassType.Delegate) {
ArrayList methods = resolver.SearchMethod(t, "Invoke"); ArrayList methods = resolver.SearchMethod(t, "Invoke");
return FindOverload(methods, invocationExpression, data); return FindOverload(methods, invocationExpression.Parameters, data);
} }
return null; return null;
} }

1
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj

@ -42,6 +42,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="AssemblyInfo.cs" /> <Compile Include="AssemblyInfo.cs" />
<Compile Include="NRefactoryResolverTests.cs" /> <Compile Include="NRefactoryResolverTests.cs" />
<Compile Include="ReflectionLayerTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Project\ICSharpCode.SharpDevelop.csproj"> <ProjectReference Include="..\Project\ICSharpCode.SharpDevelop.csproj">

46
src/Main/Base/Test/ReflectionLayerTests.cs

@ -0,0 +1,46 @@
/*
* Created by SharpDevelop.
* User: Daniel Grunwald
* Date: 17.05.2005
* Time: 21:33
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using NUnit.Framework;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.SharpDevelop.Tests
{
[TestFixture]
public class ReflectionLayerTests
{
IProjectContent pc = ProjectContentRegistry.GetMscorlibContent();
[Test]
public void InheritanceTest()
{
IClass c = pc.GetClass("System.SystemException");
IClass c2 = pc.GetClass("System.Exception");
Assert.IsNotNull(c, "c is null");
Assert.IsNotNull(c2, "c2 is null");
Assert.AreEqual(3, c.BaseTypes.Count); // 2 interfaces
Assert.AreEqual("System.Exception", c.BaseTypes[0]);
Assert.AreSame(c2, c.BaseClass);
List<IClass> subClasses = new List<IClass>();
foreach (IClass subClass in c.ClassInheritanceTree) {
subClasses.Add(subClass);
}
Assert.AreEqual(5, subClasses.Count, "ClassInheritanceTree length");
Assert.AreEqual("System.SystemException", subClasses[0].FullyQualifiedName);
Assert.AreEqual("System.Exception", subClasses[1].FullyQualifiedName);
Assert.AreEqual("System.Runtime.Serialization.ISerializable", subClasses[2].FullyQualifiedName);
Assert.AreEqual("System.Runtime.InteropServices._Exception", subClasses[3].FullyQualifiedName);
Assert.AreEqual("System.Object", subClasses[4].FullyQualifiedName);
}
}
}

4
src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

@ -172,9 +172,9 @@ namespace ICSharpCode.Core
fileName2 = fileName2.Substring(0, fileName2.Length - 1); fileName2 = fileName2.Substring(0, fileName2.Length - 1);
try { try {
if (fileName1.Length < 2 || fileName1[1] != ':') if (fileName1.Length < 2 || fileName1[1] != ':' || fileName1.IndexOf("/.") >= 0 || fileName1.IndexOf("\\.") >= 0)
fileName1 = Path.GetFullPath(fileName1); fileName1 = Path.GetFullPath(fileName1);
if (fileName2.Length < 2 || fileName2[1] != ':') if (fileName2.Length < 2 || fileName2[1] != ':' || fileName2.IndexOf("/.") >= 0 || fileName2.IndexOf("\\.") >= 0)
fileName2 = Path.GetFullPath(fileName2); fileName2 = Path.GetFullPath(fileName2);
} catch (Exception) { } catch (Exception) {
return false; return false;

Loading…
Cancel
Save