mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
add single static import: process nested references (IDEA-94951)
This commit is contained in:
+53
-46
@@ -61,8 +61,7 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
|
||||
if (parent instanceof PsiMethodReferenceExpression) return null;
|
||||
if (parent instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement)parent).getQualifier() != null) {
|
||||
PsiJavaCodeReferenceElement refExpr = (PsiJavaCodeReferenceElement)parent;
|
||||
PsiReferenceParameterList parameterList = refExpr.getParameterList();
|
||||
if (parameterList != null && parameterList.getFirstChild() != null) return null;
|
||||
if (checkParameterizedReference(refExpr)) return null;
|
||||
PsiElement resolved = refExpr.resolve();
|
||||
if (resolved instanceof PsiMember && ((PsiModifierListOwner)resolved).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiClass aClass = getResolvedClass(element, (PsiMember)resolved);
|
||||
@@ -99,6 +98,11 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean checkParameterizedReference(PsiJavaCodeReferenceElement refExpr) {
|
||||
PsiReferenceParameterList parameterList = refExpr instanceof PsiReferenceExpression ? refExpr.getParameterList() : null;
|
||||
return parameterList != null && parameterList.getFirstChild() != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getResolvedClass(PsiElement element, PsiMember resolved) {
|
||||
PsiClass aClass = resolved.getContainingClass();
|
||||
@@ -158,58 +162,61 @@ public class AddSingleMemberStaticImportAction extends PsiElementBaseIntentionAc
|
||||
@Override
|
||||
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
|
||||
if (reference.getParameterList() != null &&
|
||||
reference.getParameterList().getFirstChild() != null) return;
|
||||
try {
|
||||
if (checkParameterizedReference(reference)) return;
|
||||
|
||||
if (referenceName.equals(reference.getReferenceName()) && !(reference instanceof PsiMethodReferenceExpression)) {
|
||||
final PsiElement qualifierExpression = reference.getQualifier();
|
||||
PsiElement referent = reference.getUserData(TEMP_REFERENT_USER_DATA);
|
||||
if (!reference.isQualified()) {
|
||||
if (referent instanceof PsiMember && referent != reference.resolve()) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(reference.getProject()).getElementFactory();
|
||||
try {
|
||||
final PsiClass containingClass = ((PsiMember)referent).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
PsiReferenceExpression copy = (PsiReferenceExpression)factory.createExpressionFromText("A." + reference.getReferenceName(), null);
|
||||
reference = (PsiReferenceExpression)reference.replace(copy);
|
||||
((PsiReferenceExpression)reference.getQualifier()).bindToElement(containingClass);
|
||||
if (referenceName.equals(reference.getReferenceName()) && !(reference instanceof PsiMethodReferenceExpression)) {
|
||||
final PsiElement qualifierExpression = reference.getQualifier();
|
||||
PsiElement referent = reference.getUserData(TEMP_REFERENT_USER_DATA);
|
||||
if (!reference.isQualified()) {
|
||||
if (referent instanceof PsiMember && referent != reference.resolve()) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(reference.getProject()).getElementFactory();
|
||||
try {
|
||||
final PsiClass containingClass = ((PsiMember)referent).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
PsiReferenceExpression copy = (PsiReferenceExpression)factory.createExpressionFromText("A." + reference.getReferenceName(), null);
|
||||
reference = (PsiReferenceExpression)reference.replace(copy);
|
||||
((PsiReferenceExpression)reference.getQualifier()).bindToElement(containingClass);
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error (e);
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error (e);
|
||||
reference.putUserData(TEMP_REFERENT_USER_DATA, null);
|
||||
} else {
|
||||
if (qualifierExpression instanceof PsiJavaCodeReferenceElement) {
|
||||
PsiElement aClass = ((PsiJavaCodeReferenceElement)qualifierExpression).resolve();
|
||||
if (aClass instanceof PsiVariable) {
|
||||
aClass = PsiUtil.resolveClassInClassTypeOnly(((PsiVariable)aClass).getType());
|
||||
}
|
||||
if (aClass instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)aClass, resolvedClass, true)) {
|
||||
boolean foundMemberByName = false;
|
||||
if (referent instanceof PsiMember) {
|
||||
final String memberName = ((PsiMember)referent).getName();
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(reference, PsiClass.class);
|
||||
if (containingClass != null) {
|
||||
foundMemberByName |= containingClass.findFieldByName(memberName, true) != null;
|
||||
foundMemberByName |= containingClass.findMethodsByName(memberName, true).length > 0;
|
||||
}
|
||||
}
|
||||
if (!foundMemberByName) {
|
||||
try {
|
||||
qualifierExpression.delete();
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reference.putUserData(TEMP_REFERENT_USER_DATA, null);
|
||||
} else {
|
||||
if (qualifierExpression instanceof PsiJavaCodeReferenceElement) {
|
||||
PsiElement aClass = ((PsiJavaCodeReferenceElement)qualifierExpression).resolve();
|
||||
if (aClass instanceof PsiVariable) {
|
||||
aClass = PsiUtil.resolveClassInClassTypeOnly(((PsiVariable)aClass).getType());
|
||||
}
|
||||
if (aClass instanceof PsiClass && InheritanceUtil.isInheritorOrSelf((PsiClass)aClass, resolvedClass, true)) {
|
||||
boolean foundMemberByName = false;
|
||||
if (referent instanceof PsiMember) {
|
||||
final String memberName = ((PsiMember)referent).getName();
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(reference, PsiClass.class);
|
||||
if (containingClass != null) {
|
||||
foundMemberByName |= containingClass.findFieldByName(memberName, true) != null;
|
||||
foundMemberByName |= containingClass.findMethodsByName(memberName, true).length > 0;
|
||||
}
|
||||
}
|
||||
if (!foundMemberByName) {
|
||||
try {
|
||||
qualifierExpression.delete();
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reference.putUserData(TEMP_REFERENT_USER_DATA, null);
|
||||
}
|
||||
super.visitReferenceElement(reference);
|
||||
finally {
|
||||
super.visitReferenceElement(reference);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import foo.*;
|
||||
class Class2 {
|
||||
public static void main(String[] args) {
|
||||
Class1.<String>f<caret>oo();
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import foo.*;
|
||||
class Class2 {
|
||||
public static void main(String[] args) {
|
||||
new Class1.Inn<caret>er2<Class1.Inner1>();
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import foo.*;
|
||||
class Class2 {
|
||||
public static void main(String[] args) {
|
||||
new Class1.Inner2<Class1.In<caret>ner1>();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import foo.*;
|
||||
|
||||
import static foo.Class1.Inner1;
|
||||
|
||||
class Class2 {
|
||||
public static void main(String[] args) {
|
||||
new Class1.Inner2<Inner1>();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import foo.*;
|
||||
|
||||
import static foo.Class1.Inner2;
|
||||
|
||||
class Class2 {
|
||||
public static void main(String[] args) {
|
||||
new Inner2<Class1.Inner1>();
|
||||
}
|
||||
}
|
||||
+39
@@ -30,6 +30,45 @@ public class AddSingleStaticImportActionTest extends JavaCodeInsightFixtureTestC
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
public void testInsideParameterizedReference() {
|
||||
myFixture.addClass("package foo; " +
|
||||
"public class Class1 {" +
|
||||
" public static class Inner1 {}\n" +
|
||||
" public static class Inner2<T> {}" +
|
||||
"}");
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
|
||||
final IntentionAction intentionAction = myFixture.findSingleIntention("Add static import for 'foo.Class1.Inner2'");
|
||||
assertNotNull(intentionAction);
|
||||
myFixture.launchAction(intentionAction);
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
public void testInsideParameterizedReferenceInsideParameterizedReference() {
|
||||
myFixture.addClass("package foo; " +
|
||||
"public class Class1 {" +
|
||||
" public static class Inner1 {}\n" +
|
||||
" public static class Inner2<T> {}" +
|
||||
"}");
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
|
||||
final IntentionAction intentionAction = myFixture.findSingleIntention("Add static import for 'foo.Class1.Inner1'");
|
||||
assertNotNull(intentionAction);
|
||||
myFixture.launchAction(intentionAction);
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
public void testDisabledInsideParameterizedReference() {
|
||||
myFixture.addClass("package foo; " +
|
||||
"public class Class1 {" +
|
||||
" public static <T> T foo(){return null;}\n" +
|
||||
"}");
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
|
||||
final IntentionAction intentionAction = myFixture.getAvailableIntention("Add static import for 'foo.Class1.foo'");
|
||||
assertNull(intentionAction);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
|
||||
Reference in New Issue
Block a user