Merge branch 'cjfm3' of git://github.com/max-kammerer/intellij-community into pull87

This commit is contained in:
Dmitry Jemerov
2013-08-28 20:26:39 +02:00
2 changed files with 145 additions and 27 deletions
@@ -26,10 +26,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* @author yole
@@ -138,36 +135,48 @@ public class CoreJavaFileManager implements JavaFileManager {
if (classes.length == 1) {
PsiClass curClass = classes[0];
if (bucks > 0) {
int newComponentStart = 0;
int lookupStart = 0;
if (bucks > 0) {
Stack<ClassAndOffsets> currentPath = new Stack<ClassAndOffsets>();
currentPath.add(new ClassAndOffsets(curClass, 0, 0));
currentPath.add(currentPath.peek());
while (lookupStart <= className.length()) {
int b = className.indexOf("$", lookupStart);
b = b < 0 ? className.length(): b;
while (currentPath.size() > 1) {
ClassAndOffsets classAndOffset = currentPath.pop();
int newComponentStart = classAndOffset.componentStart;
int lookupStart = classAndOffset.lookupStart;
curClass = currentPath.peek().clazz; //owner class
String component = className.substring(newComponentStart, b);
PsiClass inner = curClass.findInnerClassByName(component, false);
while (lookupStart <= className.length()) {
int bucksIndex = className.indexOf("$", lookupStart);
bucksIndex = bucksIndex < 0 ? className.length(): bucksIndex;
lookupStart = b + 1;
if (inner == null) {
continue;
String component = className.substring(newComponentStart, bucksIndex);
PsiClass inner = curClass.findInnerClassByName(component, false);
lookupStart = bucksIndex + 1;
if (inner == null) {
continue;
}
currentPath.add(new ClassAndOffsets(inner, newComponentStart, lookupStart));
newComponentStart = lookupStart;
curClass = inner;
}
if (lookupStart == newComponentStart) {
return curClass;
}
}
newComponentStart = lookupStart;
curClass = inner;
}
if (lookupStart != newComponentStart) {
return null;
} else {
return curClass;
}
}
return curClass;
}
}
}
return null;
}
@@ -196,4 +205,17 @@ public class CoreJavaFileManager implements JavaFileManager {
public void addToClasspath(VirtualFile root) {
myClasspath.add(root);
}
private static class ClassAndOffsets {
final PsiClass clazz;
final int componentStart;
final int lookupStart;
ClassAndOffsets(PsiClass clazz, int componentStart, int lookupStart) {
this.clazz = clazz;
this.componentStart = componentStart;
this.lookupStart = lookupStart;
}
}
}
@@ -22,26 +22,36 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.PsiTestCase;
import com.intellij.testFramework.PsiTestUtil;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class CoreJavaFileManagerTest extends PsiTestCase {
public void testNotNullInnerClass() throws Exception {
private VirtualFile prepareClasses(String clazzName, String clazzData) throws Exception {
VirtualFile root = PsiTestUtil.createTestProjectStructure(myProject, myModule, myFilesToDelete);
VirtualFile pkg = root.createChildDirectory(this, "foo");
PsiDirectory dir = myPsiManager.findDirectory(pkg);
assertNotNull(dir);
PsiElement created = dir.add(PsiFileFactory.getInstance(getProject()).createFileFromText(clazzName + ".java", JavaFileType.INSTANCE, clazzData));
return root;
}
public void testNotNullInnerClass() throws Exception {
String text = "package foo;\n\n" +
"public class Nested {\n" +
"public class InnerGeneral {}\n" +
"public class Inner$ {}\n" +
"public class Inner$ {" +
"}\n" +
"\n" +
"public Inner$ inner() {\n" +
" return new Inner$();\n" +
"}\n" +
"\n" +
"}";
PsiElement created = dir.add(PsiFileFactory.getInstance(getProject()).createFileFromText("Nested.java", JavaFileType.INSTANCE, text));
VirtualFile root = prepareClasses("Nested", text);
GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
CoreJavaFileManager manager = new CoreJavaFileManager(myPsiManager);
manager.addToClasspath(root);
@@ -65,4 +75,90 @@ public class CoreJavaFileManagerTest extends PsiTestCase {
assertNull(clazzInner$Wrong3);
}
public void testNotNullInnerClass2() throws Exception {
String text = "package foo;\n\n" +
"public class Nested {\n" +
"public class Inner {" +
" public class XInner{}" +
" public class XInner${}" +
"}\n" +
"public class Inner$ {" +
" public class XInner{}" +
" public class XInner${}" +
"}\n" +
"\n" +
"}";
VirtualFile root = prepareClasses("Nested", text);
GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
CoreJavaFileManager manager = new CoreJavaFileManager(myPsiManager);
manager.addToClasspath(root);
PsiClass clazzInner = manager.findClass("foo.Nested.Inner", scope);
assertNotNull(clazzInner);
PsiClass clazzXInner = manager.findClass("foo.Nested.Inner.XInner", scope);
assertNotNull(clazzXInner);
PsiClass clazzXInner$ = manager.findClass("foo.Nested.Inner.XInner$", scope);
assertNotNull(clazzXInner$);
PsiClass clazz$XInner = manager.findClass("foo.Nested.Inner$.XInner", scope);
assertNotNull(clazz$XInner);
PsiClass clazz$XInner$ = manager.findClass("foo.Nested.Inner$.XInner$", scope);
assertNotNull(clazz$XInner$);
}
public void testNotNullInnerClass3() throws Exception {
String text = "package foo;\n\n" +
"public class NestedX {\n" +
"public class XX {" +
" public class XXX{" +
" public class XXXX{ }" +
" public class XXXX${ }" +
" }" +
" public class XXX${" +
" public class XXXX{ }" +
" public class XXXX${ }" +
" }" +
"}\n" +
"public class XX$ {" +
" public class XXX{" +
" public class XXXX{ }" +
" public class XXXX${ }" +
" }" +
" public class XXX${" +
" public class XXXX{ }" +
" public class XXXX${ }" +
" }" +
"}\n" +
"\n" +
"}";
VirtualFile root = prepareClasses("NestedX", text);
GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
CoreJavaFileManager manager = new CoreJavaFileManager(myPsiManager);
manager.addToClasspath(root);
Queue<String> queue = new LinkedList<String>();
queue.add("foo.NestedX");
while(!queue.isEmpty()) {
String head = queue.remove();
PsiClass clazzInner = manager.findClass(head, scope);
assertNotNull(head, clazzInner);
String lastSegment = head.substring(head.lastIndexOf('.'));
String xs = lastSegment.substring(lastSegment.indexOf("X")).replace("$", "");
if (xs.length() < 4) {
queue.add(head + "." + xs + "X");
queue.add(head + "." + xs + "X$");
}
}
}
}