diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java index bd8bda3055c3..44f4c10dae18 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java @@ -10,6 +10,7 @@ import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.cache.TypeInfo; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; import com.intellij.psi.impl.java.stubs.PsiParameterStub; +import com.intellij.psi.impl.java.stubs.impl.PsiParameterStubImpl; import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.search.LocalSearchScope; @@ -48,7 +49,13 @@ public class ClsParameterImpl extends ClsRepositoryPsiElement ClsMethodImpl method = (ClsMethodImpl)getDeclarationScope(); PsiMethod sourceMethod = (PsiMethod)method.getNavigationElement(); - if (sourceMethod == method) return null; + if (sourceMethod == method) { + final PsiParameterStubImpl parameterStub = (PsiParameterStubImpl) getStub(); + if (!parameterStub.isAutoGeneratedName()) { + return parameterStub.getName(); + } + return null; + } myName = sourceMethod.getParameterList().getParameters()[getIndex()].getName(); } return myName; @@ -114,6 +121,11 @@ public class ClsParameterImpl extends ClsRepositoryPsiElement private String getMirrorName() { synchronized (LAZY_BUILT_LOCK) { if (myMirrorName == null) { + final PsiParameterStubImpl parameterStub = (PsiParameterStubImpl) getStub(); + if (!parameterStub.isAutoGeneratedName()) { + myMirrorName = parameterStub.getName(); + return myMirrorName; + } PsiParameter[] parms = ((PsiParameterList) getParent()).getParameters(); if (DumbService.getInstance(getProject()).isDumb()) { return "p" + Arrays.asList(parms).indexOf(this); diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java index 298ad202700e..c7fd75d74173 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsStubBuilder.java @@ -65,7 +65,7 @@ public class ClsStubBuilder { ClassReader reader = new ClassReader(bytes); final MyClassVisitor classVisitor = new MyClassVisitor(vFile, parent, access); - reader.accept(classVisitor, ClassReader.SKIP_CODE); + reader.accept(classVisitor, 0); return classVisitor.getResult(); } @@ -379,6 +379,7 @@ public class ClsStubBuilder { final PsiParameterListStubImpl parameterList = new PsiParameterListStubImpl(stub); final int paramCount = args.size(); + final PsiParameterStubImpl[] paramStubs = new PsiParameterStubImpl[paramCount]; for (int i = 0; i < paramCount; i++) { if (nonStaticInnerClassConstructor && i == 0) continue; @@ -387,13 +388,15 @@ public class ClsStubBuilder { final TypeInfo typeInfo = TypeInfo.fromString(arg, isEllipsisParam); PsiParameterStubImpl parameterStub = new PsiParameterStubImpl(parameterList, "p" + (i + 1), typeInfo, isEllipsisParam); + paramStubs [i] = parameterStub; new PsiModifierListStubImpl(parameterStub, 0); } String[] thrownTypes = buildThrowsList(exceptions, throwables, parsedViaGenericSignature[0]); new PsiClassReferenceListStubImpl(JavaStubElementTypes.THROWS_LIST, stub, thrownTypes, PsiReferenceList.Role.THROWS_LIST); - return new AnnotationCollectingVisitor(stub, modlist[0]); + int ignoreCount = (access & Opcodes.ACC_STATIC) != 0 ? 0 : 1; + return new AnnotationParamCollectingVisitor(stub, modlist[0], ignoreCount, paramCount, paramStubs); } private static String[] buildThrowsList(String[] exceptions, List throwables, boolean parsedViaGenericSignature) { @@ -574,6 +577,27 @@ public class ClsStubBuilder { } } + private static class AnnotationParamCollectingVisitor extends AnnotationCollectingVisitor { + private final int myIgnoreCount; + private final int myParamCount; + private final PsiParameterStubImpl[] myParamStubs; + + private AnnotationParamCollectingVisitor(final StubElement owner, final PsiModifierListStub modList, int ignoreCount, int paramCount, + PsiParameterStubImpl[] paramStubs) { + super(owner, modList); + myIgnoreCount = ignoreCount; + myParamCount = paramCount; + myParamStubs = paramStubs; + } + + @Override + public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { + if (index >= myIgnoreCount && index < myIgnoreCount + myParamCount) { + myParamStubs [index - myIgnoreCount].setName(name); + } + } + } + @SuppressWarnings({"HardCodedStringLiteral"}) @Nullable private static String constToString(final Object value) { diff --git a/java/java-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java b/java/java-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java index 4f4369a80202..6ba2bf539e91 100644 --- a/java/java-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java @@ -13,8 +13,10 @@ import com.intellij.psi.stubs.StubElement; import com.intellij.util.io.StringRef; import org.jetbrains.annotations.NotNull; +import java.util.List; + public class PsiParameterStubImpl extends StubBase implements PsiParameterStub { - private final StringRef myName; + private StringRef myName; private final TypeInfo myType; private final boolean myIsEllipsis; @@ -61,4 +63,20 @@ public class PsiParameterStubImpl extends StubBase implements PsiP append(']'); return builder.toString(); } + + public void setName(String name) { + myName = StringRef.fromString(name); + } + + public boolean isAutoGeneratedName() { + final List children = getParentStub().getChildrenStubs(); + int paramIndex = 0; + for (Object o : children) { + if (o instanceof PsiParameterStub) { + paramIndex++; + if (o == this) break; + } + } + return ("p" + paramIndex).equals(getName()); + } } diff --git a/java/java-tests/testData/psi/cls/stubBuilder/TestSuite.class b/java/java-tests/testData/psi/cls/stubBuilder/TestSuite.class new file mode 100644 index 000000000000..2764cafb3830 Binary files /dev/null and b/java/java-tests/testData/psi/cls/stubBuilder/TestSuite.class differ diff --git a/java/java-tests/testData/psi/cls/stubBuilder/TestSuite.txt b/java/java-tests/testData/psi/cls/stubBuilder/TestSuite.txt new file mode 100644 index 000000000000..1d1b22a070c2 --- /dev/null +++ b/java/java-tests/testData/psi/cls/stubBuilder/TestSuite.txt @@ -0,0 +1,162 @@ +PsiJavaFileStub [junit.framework] + PsiClassStub[name=TestSuite fqn=junit.framework.TestSuite] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiRefListStub[EXTENDS_LIST:] + PsiRefListStub[IMPLEMENTS_LIST:junit.framework.Test] + PsiFieldStub[fTests:java.util.Vector] + PsiModifierListStub[mask=2] + PsiFieldStub[fName:java.lang.String] + PsiModifierListStub[mask=2] + PsiMethodStub[cons TestSuite:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[cons TestSuite:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[theClass:java.lang.Class] + PsiModifierListStub[mask=0] + PsiParameterStub[name:java.lang.String] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[cons TestSuite:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[theClass:java.lang.Class] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[cons TestSuite:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[name:java.lang.String] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[addTest:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[test:junit.framework.Test] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[addTestSuite:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[testClass:java.lang.Class] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[addTestMethod:void] + PsiModifierListStub[mask=2] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[m:java.lang.reflect.Method] + PsiModifierListStub[mask=0] + PsiParameterStub[names:java.util.Vector] + PsiModifierListStub[mask=0] + PsiParameterStub[theClass:java.lang.Class] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[createTest:junit.framework.Test] + PsiModifierListStub[mask=9] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[theClass:java.lang.Class] + PsiModifierListStub[mask=0] + PsiParameterStub[name:java.lang.String] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[exceptionToString:java.lang.String] + PsiModifierListStub[mask=10] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[t:java.lang.Throwable] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[countTestCases:int] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[getTestConstructor:java.lang.reflect.Constructor] + PsiModifierListStub[mask=9] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[theClass:java.lang.Class] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:java.lang.NoSuchMethodException] + PsiMethodStub[isPublicTestMethod:boolean] + PsiModifierListStub[mask=2] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[m:java.lang.reflect.Method] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[isTestMethod:boolean] + PsiModifierListStub[mask=2] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[m:java.lang.reflect.Method] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[run:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[result:junit.framework.TestResult] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[runTest:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[test:junit.framework.Test] + PsiModifierListStub[mask=0] + PsiParameterStub[result:junit.framework.TestResult] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[testAt:junit.framework.Test] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[index:int] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[testCount:int] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[tests:java.util.Enumeration] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[toString:java.lang.String] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[setName:void] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[name:java.lang.String] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[getName:java.lang.String] + PsiModifierListStub[mask=1] + PsiTypeParameterListStub + PsiParameterListStub + PsiRefListStub[THROWS_LIST:] + PsiMethodStub[warning:junit.framework.Test] + PsiModifierListStub[mask=10] + PsiTypeParameterListStub + PsiParameterListStub + PsiParameterStub[message:java.lang.String] + PsiModifierListStub[mask=0] + PsiRefListStub[THROWS_LIST:] diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java index 9d635c1460af..925e2e492262 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java @@ -9,6 +9,7 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.impl.compiled.ClsStubBuilder; import com.intellij.psi.stubs.PsiFileStub; @@ -50,9 +51,19 @@ public class ClsBuilderTest extends LightIdeaTestCase { doTest("java/util/concurrent/TimeUnit.class", "TimeUnit.txt"); } + public void testParameterNames() throws Exception { + final String clsFilePath = JavaTestUtil.getJavaTestDataPath() + "/psi/cls/stubBuilder/TestSuite.class"; + VirtualFile clsFile = LocalFileSystem.getInstance().findFileByPath(clsFilePath); + doTest(clsFile, "TestSuite.txt"); + } + private void doTest(final String classname, final String goldFile) throws IOException, ClsFormatException { VirtualFile vFile = findFile(classname); + doTest(vFile, goldFile); + } + + private static void doTest(VirtualFile vFile, String goldFile) throws ClsFormatException, IOException { final PsiFileStub stub = ClsStubBuilder.build(vFile, vFile.contentsToByteArray()); final String butWas = ((StubBase)stub).printTree(); @@ -84,4 +95,4 @@ public class ClsBuilderTest extends LightIdeaTestCase { fail("Cannot file classfile for: " + classname); return null; } -} \ No newline at end of file +}