[java] reads MethodParameters attribute on building .class stubs (IDEA-173644)

This commit is contained in:
Roman Shevchenko
2017-05-30 21:50:35 +03:00
parent 41556b0325
commit 4df0708880
6 changed files with 59 additions and 13 deletions
@@ -42,9 +42,7 @@ import java.io.IOException;
import java.lang.reflect.Array;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static com.intellij.openapi.util.Pair.pair;
import static com.intellij.util.BitUtil.isSet;
@@ -545,6 +543,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
private final int myParamCount;
private final PsiParameterStubImpl[] myParamStubs;
private final Function<String, String> myMapping;
private int myParamNameIndex;
private int myUsedParamSize;
private int myUsedParamCount;
private List<Set<String>> myFilters;
@@ -605,22 +604,31 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
return new AnnotationTextCollector(null, myMapping, text -> ((PsiMethodStubImpl)myOwner).setDefaultValueText(text));
}
@Override
public void visitParameter(String name, int access) {
if ((access & Opcodes.ACC_SYNTHETIC) == 0 && myParamNameIndex < myParamCount) {
setName(name, myParamNameIndex);
myParamNameIndex++;
}
}
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
if (index >= myIgnoreCount) {
// long and double variables increase the index by 2, not by 1
int paramIndex = index - myIgnoreCount == myUsedParamSize ? myUsedParamCount : index - myIgnoreCount;
if (paramIndex >= myParamCount) return;
if (ClsParsingUtil.isJavaIdentifier(name, LanguageLevel.HIGHEST)) {
PsiParameterStubImpl parameterStub = myParamStubs[paramIndex];
if (parameterStub != null) {
parameterStub.setName(name);
}
if (paramIndex < myParamCount) {
setName(name, paramIndex);
myUsedParamCount = paramIndex + 1;
myUsedParamSize += "D".equals(desc) || "J".equals(desc) ? 2 : 1;
}
}
}
myUsedParamCount = paramIndex + 1;
myUsedParamSize += "D".equals(desc) || "J".equals(desc) ? 2 : 1;
private void setName(String name, int paramIndex) {
if (ClsParsingUtil.isJavaIdentifier(name, LanguageLevel.HIGHEST)) {
PsiParameterStubImpl stub = myParamStubs[paramIndex];
if (stub != null) stub.setName(name);
}
}
@@ -774,7 +782,7 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
className = p.first;
if (p.second != null) {
className = fun(p.first) + '.' + p.second;
mapping.put(className, pair(className, (String)null));
mapping.put(className, pair(className, null));
}
}
@@ -0,0 +1,19 @@
PsiJavaFileStub []
PsiClassStub[enum name=EParams fqn=EParams]
PsiModifierListStub[mask=17]
PsiTypeParameterListStub
PsiRefListStub[EXTENDS_LIST:]
PsiRefListStub[IMPLEMENTS_LIST:]
PsiFieldStub[enumconst C:EParams]
PsiModifierListStub[mask=25]
PsiMethodStub[cons EParams:void]
PsiModifierListStub[mask=2]
PsiTypeParameterListStub
PsiParameterListStub
PsiParameterStub[first:int]
PsiModifierListStub[mask=0]
PsiParameterStub[second:java.lang.String]
PsiModifierListStub[mask=0]
PsiParameterStub[last:java.lang.Boolean]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
@@ -0,0 +1,17 @@
PsiJavaFileStub []
PsiClassStub[interface name=IParams fqn=IParams]
PsiModifierListStub[mask=1025]
PsiTypeParameterListStub
PsiRefListStub[EXTENDS_LIST:]
PsiRefListStub[IMPLEMENTS_LIST:]
PsiMethodStub[m:void]
PsiModifierListStub[mask=1025]
PsiTypeParameterListStub
PsiParameterListStub
PsiParameterStub[first:int]
PsiModifierListStub[mask=0]
PsiParameterStub[second:java.lang.String]
PsiModifierListStub[mask=0]
PsiParameterStub[last:java.lang.Boolean]
PsiModifierListStub[mask=0]
PsiRefListStub[THROWS_LIST:]
@@ -43,6 +43,8 @@ public class ClsStubBuilderTest extends LightIdeaTestCase {
public void testDoubleTest() { doTest(); /* IDEA-53195 */ }
public void testAnnotatedNonStaticInnerClassConstructor() { doTest(); }
public void testAnnotatedEnumConstructor() { doTest(); }
public void testInterfaceMethodParameters() { doTest(); }
public void testEnumMethodParameters() { doTest(); }
public void testModifiers() {
String clsFilePath = JavaTestUtil.getJavaTestDataPath() + "/psi/cls/repo/pack/" + getTestName(false) + ".class";