Browse Source

Resolver can now find correct overload in a method invocation.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@86 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 21 years ago
parent
commit
2b0fd8cc53
  1. 4
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  2. 10
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  3. 34
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs
  4. 73
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs
  5. 4
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs
  6. 91
      src/Main/Base/Test/NRefactoryResolverTests.cs
  7. 7
      src/Main/Core/Test/TopologicalSortTest.cs

4
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -59,7 +59,7 @@ @@ -59,7 +59,7 @@
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Src\OptionPanels\BuildOptions.cs">
<SubType>Form</SubType>
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Src\OptionPanels\DebugOptions.cs">
<SubType>UserControl</SubType>

10
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -13,10 +13,6 @@ @@ -13,10 +13,6 @@
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>Resources\ICSharpCode.SharpDevelop.snk</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<RootNamespace>ICSharpCode.SharpDevelop</RootNamespace>
<StartupObject />
<ApplicationIcon />
<Win32Resource />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
@ -207,10 +203,10 @@ @@ -207,10 +203,10 @@
<SubType>Form</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\TipOfTheDay.cs">
<SubType>UserControl</SubType>
<SubType>Form</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\TreeViewOptions.cs">
<SubType>Component</SubType>
<SubType>Form</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\ViewGPLDialog.cs">
<SubType>Form</SubType>

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

@ -398,7 +398,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -398,7 +398,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
/// </remarks>
public IClass SearchType(string name, IClass curType)
{
return projectContent.SearchType(name, curType, caretLine, caretColumn);
IClass c = SearchLocalType(name);
if (c != null)
return c;
else
return projectContent.SearchType(name, curType, caretLine, caretColumn);
}
/// <remarks>
@ -406,7 +410,25 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -406,7 +410,25 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
/// </remarks>
public IClass SearchType(string name, IClass curType, ICompilationUnit unit)
{
return projectContent.SearchType(name, curType, unit, caretLine, caretColumn);
IClass c = SearchLocalType(name);
if (c != null)
return c;
else
return projectContent.SearchType(name, curType, unit, caretLine, caretColumn);
}
IClass SearchLocalType(string name)
{
if (cu == null) return null;
foreach (IClass c in cu.Classes) {
//foreach (IClass innerClass in c.InnerClasses) {
// if (IsSameName(innerClass.FullyQualifiedName, name))
// return innerClass;
//}
if (IsSameName(c.FullyQualifiedName, name))
return c;
}
return null;
}
#region Helper for TypeVisitor
@ -428,6 +450,14 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -428,6 +450,14 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return SearchMethod(new ArrayList(), curType, memberName);
}
/// <summary>
/// Gets the list of methods on the class that have the specified name.
/// </summary>
public ArrayList SearchMethod(IClass type, string memberName)
{
return SearchMethod(new ArrayList(), type, memberName);
}
ArrayList SearchMethod(ArrayList methods, IClass curType, string memberName)
{
if (curType == null)

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

@ -30,7 +30,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -30,7 +30,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
public override object Visit(BinaryOperatorExpression binaryOperatorExpression, object data)
{
// TODO : Operators
// TODO : Operators
return binaryOperatorExpression.Left.AcceptVisitor(this, data);
}
@ -51,29 +51,65 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -51,29 +51,65 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return m.ReturnType;
}
IMethod FindOverload(ArrayList methods, InvocationExpression invocationExpression, object data)
{
if (methods.Count <= 0) {
return null;
}
IMethod bestMethod = (IMethod)methods[0]; // when in doubt, use first method
if (methods.Count == 1)
return bestMethod;
ArrayList arguments = invocationExpression.Parameters;
IReturnType[] types = new IReturnType[arguments.Count];
for (int i = 0; i < types.Length; ++i) {
types[i] = ((Expression)arguments[i]).AcceptVisitor(this, data) as IReturnType;
}
int bestScore = ScoreOverload(bestMethod, types);
foreach (IMethod method in methods) {
if (method == bestMethod) continue;
int score = ScoreOverload(method, types);
if (score > bestScore) {
bestScore = score;
bestMethod = method;
}
}
return bestMethod;
}
int ScoreOverload(IMethod method, IReturnType[] types)
{
if (method.Parameters.Count == types.Length) {
int points = types.Length;
for (int i = 0; i < types.Length; ++i) {
IReturnType type = method.Parameters[i].ReturnType;
if (type != null && types[i] != null) {
if (type.CompareTo(types[i]) == 0)
points += 1;
}
}
return points;
} else {
return types.Length - Math.Abs(method.Parameters.Count - types.Length);
}
}
public IMethod GetMethod(InvocationExpression invocationExpression, object data)
{
if (invocationExpression.TargetObject is FieldReferenceExpression) {
FieldReferenceExpression field = (FieldReferenceExpression)invocationExpression.TargetObject;
IReturnType type = field.TargetObject.AcceptVisitor(this, data) as IReturnType;
ArrayList methods = resolver.SearchMethod(type, field.FieldName);
if (methods.Count <= 0) {
return null;
}
// TODO: Find the right method
return (IMethod)methods[0];
return FindOverload(methods, invocationExpression, data);
} else if (invocationExpression.TargetObject is IdentifierExpression) {
string id = ((IdentifierExpression)invocationExpression.TargetObject).Identifier;
if (resolver.CallingClass == null) {
return null;
}
IReturnType type = new ReturnType(resolver.CallingClass.FullyQualifiedName);
ArrayList methods = resolver.SearchMethod(type, id);
if (methods.Count <= 0) {
return null;
}
// TODO: Find the right method
return (IMethod)methods[0];
ArrayList methods = resolver.SearchMethod(resolver.CallingClass, id);
return FindOverload(methods, invocationExpression, data);
}
// invocationExpression is delegate call
IReturnType t = invocationExpression.AcceptChildren(this, data) as IReturnType;
@ -82,11 +118,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -82,11 +118,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
IClass c = resolver.SearchType(t.FullyQualifiedName, resolver.CallingClass, resolver.CompilationUnit);
if (c.ClassType == ClassType.Delegate) {
ArrayList methods = resolver.SearchMethod(t, "invoke");
if (methods.Count <= 0) {
return null;
}
return (IMethod)methods[0];
ArrayList methods = resolver.SearchMethod(t, "Invoke");
return FindOverload(methods, invocationExpression, data);
}
return null;
}
@ -183,7 +216,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -183,7 +216,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
--expressionType.PointerNestingLevel;
break;
case UnaryOperatorType.BitWiseAnd: // get reference
++expressionType.PointerNestingLevel;
++expressionType.PointerNestingLevel;
break;
case UnaryOperatorType.None:
break;
@ -250,7 +283,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -250,7 +283,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return ((IIndexer)indexer[0]).ReturnType;
}
// TODO: what is a[0] if a is pointer to array or array of pointer ?
// TODO: what is a[0] if a is pointer to array or array of pointer ?
if (type.ArrayDimensions[type.ArrayDimensions.Length - 1] != indexerExpression.Indices.Count) {
return null;
}

4
src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs

@ -421,7 +421,9 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -421,7 +421,9 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
public void ParseInformationUpdated(ParseInformation parseInfo)
{
if (textAreaControl.TextEditorProperties.EnableFolding) {
textAreaControl.ActiveTextAreaControl.TextArea.Invoke(new ParseInformationDelegate(ParseInformationUpdatedInternal), new object[] { parseInfo });
TextArea textArea = textAreaControl.ActiveTextAreaControl.TextArea;
if (textArea.IsHandleCreated)
textArea.Invoke(new ParseInformationDelegate(ParseInformationUpdatedInternal), new object[] { parseInfo });
}
}

91
src/Main/Base/Test/NRefactoryResolverTests.cs

@ -11,9 +11,9 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -11,9 +11,9 @@ namespace ICSharpCode.SharpDevelop.Tests
[TestFixture]
public class NRefactoryResolverTests
{
#region Test helper methods
ICompilationUnit Parse(string fileName, string fileContent)
{
ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(ICSharpCode.NRefactory.Parser.SupportedLanguages.CSharp, new StringReader(fileContent));
p.Parse();
IProjectContent pc = new CaseSensitiveProjectContent();
@ -55,23 +55,23 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -55,23 +55,23 @@ namespace ICSharpCode.SharpDevelop.Tests
ParserService.UpdateParseInformation(parserOutput, fileName, false, false);
}
ResolveResult Resolve(string program, string expression, int line, int column)
ResolveResult Resolve(string program, string expression, int line)
{
AddCompilationUnit(Parse("a.cs", program), "a.cs");
NRefactoryResolver resolver = new NRefactoryResolver(ICSharpCode.NRefactory.Parser.SupportedLanguages.VBNet);
NRefactoryResolver resolver = new NRefactoryResolver(ICSharpCode.NRefactory.Parser.SupportedLanguages.CSharp);
return resolver.Resolve(expression,
line, column,
line, 0,
"a.cs");
}
ResolveResult ResolveVB(string program, string expression, int line, int column)
ResolveResult ResolveVB(string program, string expression, int line)
{
AddCompilationUnit(ParseVB("a.vb", program), "a.vb");
NRefactoryResolver resolver = new NRefactoryResolver(ICSharpCode.NRefactory.Parser.SupportedLanguages.VBNet);
return resolver.Resolve(expression,
line, column,
line, 0,
"a.vb");
}
@ -80,17 +80,11 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -80,17 +80,11 @@ namespace ICSharpCode.SharpDevelop.Tests
[TestFixtureSetUp]
public void Init()
{
corLib = CaseSensitiveProjectContent.Create(typeof(string).Assembly);
corLib = ProjectContentRegistry.GetMscorlibContent();
}
//
// public static void Main(string[] args)
// {
// NRefactoryResolverTests test = new NRefactoryResolverTests();
// test.Init();
// test.OuterclassPrivateFieldResolveTest();
//
// }
#endregion
#region Test for old issues
// Issue SD-291
[Test]
public void VBNetMultipleVariableDeclarationsTest()
@ -102,12 +96,12 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -102,12 +96,12 @@ namespace ICSharpCode.SharpDevelop.Tests
End Sub
End Class
";
ResolveResult result = ResolveVB(program, "a", 4, 24);
ResolveResult result = ResolveVB(program, "a", 4);
Assert.IsNotNull(result, "result");
Assert.IsTrue(result is LocalResolveResult, "result is LocalResolveResult");
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName);
result = ResolveVB(program, "b", 4, 24);
result = ResolveVB(program, "b", 4);
Assert.IsNotNull(result, "result");
Assert.IsTrue(result is LocalResolveResult, "result is LocalResolveResult");
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName);
@ -125,7 +119,7 @@ End Class @@ -125,7 +119,7 @@ End Class
End Sub
End Class
";
ResolveResult result = ResolveVB(program, "c", 4, 24);
ResolveResult result = ResolveVB(program, "c", 4);
Assert.IsNotNull(result, "result");
Assert.IsTrue(result is LocalResolveResult, "result is LocalResolveResult");
Assert.AreEqual("System.String", result.ResolvedType.FullyQualifiedName);
@ -142,7 +136,7 @@ End Class @@ -142,7 +136,7 @@ End Class
End Sub
End Class
";
ResolveResult result = ResolveVB(program, "a", 4, 24);
ResolveResult result = ResolveVB(program, "a", 4);
Assert.IsNotNull(result, "result");
ArrayList arr = result.GetCompletionData(lastPC);
Assert.IsNotNull(arr, "arr");
@ -166,7 +160,7 @@ End Class @@ -166,7 +160,7 @@ End Class
End Sub
End Module
";
ResolveResult result = ResolveVB(program, "t", 4, 24);
ResolveResult result = ResolveVB(program, "t", 4);
Assert.IsNotNull(result, "result");
Assert.IsTrue(result is LocalResolveResult, "result is LocalResolveResult");
@ -196,7 +190,7 @@ End Module @@ -196,7 +190,7 @@ End Module
}
}
";
ResolveResult result = Resolve(program, "a", 8, 24);
ResolveResult result = Resolve(program, "a", 8);
Assert.IsNotNull(result, "result");
Assert.IsTrue(result is LocalResolveResult, "result is LocalResolveResult");
ArrayList arr = result.GetCompletionData(lastPC);
@ -209,7 +203,9 @@ End Module @@ -209,7 +203,9 @@ End Module
}
Assert.Fail("private field not visible from inner class");
}
#endregion
#region BasicTests
[Test]
public void InheritedInterfaceResolveTest()
{
@ -225,7 +221,7 @@ interface IInterface2 { @@ -225,7 +221,7 @@ interface IInterface2 {
void Method2();
}
";
ResolveResult result = Resolve(program, "a", 3, 24);
ResolveResult result = Resolve(program, "a", 3);
Assert.IsNotNull(result, "result");
Assert.IsTrue(result is LocalResolveResult, "result is LocalResolveResult");
ArrayList arr = result.GetCompletionData(lastPC);
@ -247,7 +243,7 @@ interface IInterface2 { @@ -247,7 +243,7 @@ interface IInterface2 {
}
}
";
ResolveResult result = Resolve(program, "b.ThisMethodDoesNotExistOnString()", 3, 24);
ResolveResult result = Resolve(program, "b.ThisMethodDoesNotExistOnString()", 3);
Assert.IsNull(result, "result");
}
@ -260,10 +256,48 @@ interface IInterface2 { @@ -260,10 +256,48 @@ interface IInterface2 {
}
}
";
ResolveResult result = Resolve(program, "new ThisClassDoesNotExist()", 3, 24);
ResolveResult result = Resolve(program, "new ThisClassDoesNotExist()", 3);
Assert.IsNull(result);
}
[Test]
public void MethodCallTest()
{
string program = @"class A {
void Method() {
}
int TargetMethod() {
return 3;
}
}
";
ResolveResult result = Resolve(program, "TargetMethod()", 3);
Assert.IsNotNull(result);
Assert.IsTrue(result is MemberResolveResult);
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName, "'TargetMethod()'");
}
[Test]
public void ThisMethodCallTest()
{
string program = @"class A {
void Method() {
}
int TargetMethod() {
return 3;
}
}
";
ResolveResult result = Resolve(program, "this.TargetMethod()", 3);
Assert.IsNotNull(result);
Assert.IsTrue(result is MemberResolveResult);
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName, "'this.TargetMethod()'");
}
[Test]
public void OverloadLookupTest()
{
@ -276,15 +310,16 @@ interface IInterface2 { @@ -276,15 +310,16 @@ interface IInterface2 {
double Multiply(double a, double b) { return a * b; }
}
";
ResolveResult result = Resolve(program, "Multiply(1, 1)", 3, 24);
ResolveResult result = Resolve(program, "Multiply(1, 1)", 3);
Assert.IsNotNull(result);
Assert.IsTrue(result is MethodResolveResult, "'Multiply(1,1)' is MethodResolveResult");
Assert.IsTrue(result is MemberResolveResult, "'Multiply(1,1)' is MemberResolveResult");
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName, "'Multiply(1,1)'");
result = Resolve(program, "Multiply(1.0, 1.0)", 3, 24);
result = Resolve(program, "Multiply(1.0, 1.0)", 3);
Assert.IsNotNull(result);
Assert.IsTrue(result is MethodResolveResult, "'Multiply(1.0,1.0)' is MethodResolveResult");
Assert.IsTrue(result is MemberResolveResult, "'Multiply(1.0,1.0)' is MemberResolveResult");
Assert.AreEqual("System.Double", result.ResolvedType.FullyQualifiedName, "'Multiply(1.0,1.0)'");
}
#endregion
}
}

7
src/Main/Core/Test/TopologicalSortTest.cs

@ -17,13 +17,12 @@ namespace ICSharpCode.Core.Tests.AddInTreeTests.Tests @@ -17,13 +17,12 @@ namespace ICSharpCode.Core.Tests.AddInTreeTests.Tests
[TestFixture]
public class TopologicalSortTest
{
[Test]
[Test, Ignore("TODO: Write test")]
public void Test()
{
List<Codon> codons = new List<Codon>(5);
List<Codon> codons = new List<Codon>();
for (int i = 0; i < 5; ++i) {
codons[i] = new Codon(null, "codon" + i, null, null);
codons.Add(new Codon(null, "codon" + i, null, null));
}
}
}

Loading…
Cancel
Save