Browse Source

Fixed code completion bug: calls from nested classes to static methods in the parent class now are resolved correctly.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2619 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
6d9000dc5e
  1. 37
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
  2. 45
      src/Main/Base/Test/InnerClassesResolverTests.cs
  3. 44
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultCompilationUnit.cs
  4. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/ICompilationUnit.cs
  5. 33
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

37
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs

@ -92,10 +92,6 @@ namespace CSharpBinding
} }
} }
} }
} else if (ch == ';') {
LineSegment curLine = editor.Document.GetLineSegmentForOffset(cursor);
// don't return true when inference succeeds, otherwise the ';' won't be added to the document.
TryDeclarationTypeInference(editor, curLine);
} }
if ((char.IsLetter(ch) || ch == '_') && CodeCompletionOptions.CompleteWhenTyping) { if ((char.IsLetter(ch) || ch == '_') && CodeCompletionOptions.CompleteWhenTyping) {
@ -113,39 +109,6 @@ namespace CSharpBinding
return base.HandleKeyPress(editor, ch); return base.HandleKeyPress(editor, ch);
} }
bool TryDeclarationTypeInference(SharpDevelopTextAreaControl editor, LineSegment curLine)
{
string lineText = editor.Document.GetText(curLine.Offset, curLine.Length);
ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.CSharp, new System.IO.StringReader(lineText));
Token typeToken = lexer.NextToken();
if (typeToken.kind == CSTokens.Question) {
if (lexer.NextToken().kind == CSTokens.Identifier) {
Token t = lexer.NextToken();
if (t.kind == CSTokens.Assign) {
string expr = lineText.Substring(t.col);
LoggingService.Debug("DeclarationTypeInference: >" + expr + "<");
ResolveResult rr = ParserService.Resolve(new ExpressionResult(expr),
editor.ActiveTextAreaControl.Caret.Line + 1,
t.col, editor.FileName,
editor.Document.TextContent);
if (rr != null && rr.ResolvedType != null) {
ClassFinder context = new ClassFinder(ParserService.GetParseInformation(editor.FileName),
editor.ActiveTextAreaControl.Caret.Line, t.col);
if (CodeGenerator.CanUseShortTypeName(rr.ResolvedType, context))
CSharpAmbience.Instance.ConversionFlags = ConversionFlags.None;
else
CSharpAmbience.Instance.ConversionFlags = ConversionFlags.UseFullyQualifiedTypeNames;
string typeName = CSharpAmbience.Instance.Convert(rr.ResolvedType);
editor.Document.Replace(curLine.Offset + typeToken.col - 1, 1, typeName);
editor.ActiveTextAreaControl.Caret.Column += typeName.Length - 1;
return true;
}
}
}
}
return false;
}
bool IsInComment(SharpDevelopTextAreaControl editor) bool IsInComment(SharpDevelopTextAreaControl editor)
{ {
CSharpExpressionFinder ef = CreateExpressionFinder(editor.FileName); CSharpExpressionFinder ef = CreateExpressionFinder(editor.FileName);

45
src/Main/Base/Test/InnerClassesResolverTests.cs

@ -23,6 +23,11 @@ namespace ICSharpCode.SharpDevelop.Tests
return nrrt.Resolve(program, expression, line); return nrrt.Resolve(program, expression, line);
} }
T Resolve<T>(string program, string expression, int line) where T : ResolveResult
{
return nrrt.Resolve<T>(program, expression, line);
}
ResolveResult ResolveVB(string program, string expression, int line) ResolveResult ResolveVB(string program, string expression, int line)
{ {
return nrrt.ResolveVB(program, expression, line); return nrrt.ResolveVB(program, expression, line);
@ -60,7 +65,7 @@ class A {
} }
[Test] [Test]
public void OuterclassPrivateFieldResolveTest() public void OuterclassPrivateFieldCtrlSpaceTest()
{ {
string program = @"class A string program = @"class A
{ {
@ -88,6 +93,44 @@ class A {
Assert.Fail("private field not visible from inner class"); Assert.Fail("private field not visible from inner class");
} }
[Test]
public void OuterclassStaticFieldResolveTest()
{
string program = @"class A
{
static int myField;
class B
{
void MyMethod()
{
}
}
}
";
MemberResolveResult result = Resolve<MemberResolveResult>(program, "myField", 8);
Assert.AreEqual("A.myField", result.ResolvedMember.FullyQualifiedName);
}
[Test]
public void OuterclassStaticMethodCallResolveTest()
{
string program = @"class A
{
static void Test(int arg);
class B
{
void MyMethod()
{
}
}
}
";
MemberResolveResult result = Resolve<MemberResolveResult>(program, "Test(4)", 8);
Assert.AreEqual("A.Test", result.ResolvedMember.FullyQualifiedName);
}
[Test] [Test]
public void InheritedInnerClass() public void InheritedInnerClass()
{ {

44
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultCompilationUnit.cs

@ -122,50 +122,6 @@ namespace ICSharpCode.SharpDevelop.Dom
return null; return null;
} }
/// <summary>
/// Returns all (nested) classes in which the caret currently is exept
/// the innermost class, returns an empty collection if the caret is in
/// no class or only in the innermost class.
/// Zhe most outer class is the last in the collection.
/// </summary>
public List<IClass> GetOuterClasses(int caretLine, int caretColumn)
{
List<IClass> classes = new List<IClass>();
IClass innerMostClass = GetInnermostClass(caretLine, caretColumn);
foreach (IClass c in Classes) {
if (c != null && c.Region.IsInside(caretLine, caretColumn)) {
if (c != innerMostClass) {
GetOuterClasses(classes, c, caretLine, caretColumn);
if (!classes.Contains(c)) {
classes.Add(c);
}
}
break;
}
}
return classes;
}
void GetOuterClasses(List<IClass> classes, IClass curClass, int caretLine, int caretColumn)
{
if (curClass != null && curClass.InnerClasses.Count > 0) {
IClass innerMostClass = GetInnermostClass(caretLine, caretColumn);
foreach (IClass c in curClass.InnerClasses) {
if (c != null && c.Region.IsInside(caretLine, caretColumn)) {
if (c != innerMostClass) {
GetOuterClasses(classes, c, caretLine, caretColumn);
if (!classes.Contains(c)) {
classes.Add(c);
}
}
break;
}
}
}
}
public override string ToString() { public override string ToString() {
return String.Format("[CompilationUnit: classes = {0}, fileName = {1}]", return String.Format("[CompilationUnit: classes = {0}, fileName = {1}]",
classes.Count, classes.Count,

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/ICompilationUnit.cs

@ -64,7 +64,5 @@ namespace ICSharpCode.SharpDevelop.Dom
/// if the carret is outside any class boundaries. /// if the carret is outside any class boundaries.
/// </summary> /// </summary>
IClass GetInnermostClass(int caretLine, int caretColumn); IClass GetInnermostClass(int caretLine, int caretColumn);
List<IClass> GetOuterClasses(int caretLine, int caretColumn);
} }
} }

33
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -674,14 +674,15 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
ResolveResult result = ResolveMethod(callingClass.DefaultReturnType, identifier); ResolveResult result = ResolveMethod(callingClass.DefaultReturnType, identifier);
if (result != null) if (result != null)
return result; return result;
}
// try if there exists a static member in outer classes named typeName
// try if there exists a static member in outer classes named typeName IClass tmp = callingClass.DeclaringType;
List<IClass> classes = cu.GetOuterClasses(position.Line, position.Column); while (tmp != null) {
foreach (IClass c in classes) { member = GetMember(tmp.DefaultReturnType, identifier);
IMember member = GetMember(c.DefaultReturnType, identifier); if (member != null && member.IsStatic) {
if (member != null && member.IsStatic) { return new MemberResolveResult(callingClass, callingMember, member);
return new MemberResolveResult(callingClass, callingMember, member); }
tmp = tmp.DeclaringType;
} }
} }
@ -857,9 +858,16 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
public List<IMethod> SearchMethod(string memberName) public List<IMethod> SearchMethod(string memberName)
{ {
List<IMethod> methods = SearchMethod(callingClass.DefaultReturnType, memberName); List<IMethod> methods = null;
if (methods.Count > 0)
return methods; // Search for the method in the callingClass and outer classes
IClass tmp = callingClass;
while (tmp != null) {
methods = SearchMethod(tmp.DefaultReturnType, memberName);
if (methods.Count > 0)
return methods;
tmp = tmp.DeclaringType;
}
if (languageProperties.CanImportClasses) { if (languageProperties.CanImportClasses) {
foreach (IUsing @using in cu.Usings) { foreach (IUsing @using in cu.Usings) {
@ -874,6 +882,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
} }
if (methods == null)
methods = new List<IMethod>();
if (languageProperties.ImportModules) { if (languageProperties.ImportModules) {
ArrayList list = new ArrayList(); ArrayList list = new ArrayList();
CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, cu, callingClass); CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, cu, callingClass);

Loading…
Cancel
Save