qualify static const/method: static members from default packages should be visible for call inside default package

This commit is contained in:
Dmitry Batkovich
2017-07-13 13:56:46 +03:00
parent 02bfe1680f
commit 4e8024e4b4
13 changed files with 200 additions and 11 deletions
@@ -56,4 +56,9 @@ public class QualifyStaticConstantFix extends StaticImportConstantFix {
}
};
}
@Override
protected boolean showMembersFromDefaultPackage() {
return true;
}
}
@@ -50,6 +50,11 @@ public class QualifyStaticMethodCallFix extends StaticImportMethodFix {
};
}
@Override
protected boolean showMembersFromDefaultPackage() {
return true;
}
public static void qualifyStatically(PsiMember toImport,
Project project,
PsiReferenceExpression qualifiedExpression) {
@@ -31,6 +31,8 @@ import java.util.Collections;
import java.util.List;
public class StaticImportConstantFix extends StaticImportMemberFix<PsiField> {
public static final String BASE_TEXT = "Import static constant";
protected final SmartPsiElementPointer<PsiJavaCodeReferenceElement> myRef;
public StaticImportConstantFix(@NotNull PsiJavaCodeReferenceElement referenceElement) {
@@ -40,7 +42,7 @@ public class StaticImportConstantFix extends StaticImportMemberFix<PsiField> {
@NotNull
@Override
protected String getBaseText() {
return "Import static constant";
return BASE_TEXT;
}
@NotNull
@@ -64,7 +66,7 @@ public class StaticImportConstantFix extends StaticImportMemberFix<PsiField> {
element.getParent() instanceof PsiAnnotation) {
return Collections.emptyList();
}
final StaticMembersProcessor<PsiField> processor = new StaticMembersProcessor<PsiField>(element) {
final StaticMembersProcessor<PsiField> processor = new StaticMembersProcessor<PsiField>(element, showMembersFromDefaultPackage()) {
@Override
protected boolean isApplicable(PsiField field, PsiElement place) {
final PsiType expectedType = getExpectedType();
@@ -105,4 +107,9 @@ public class StaticImportConstantFix extends StaticImportMemberFix<PsiField> {
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)getElement();
return referenceElement != null ? referenceElement.advancedResolve(true).getElement() : null;
}
@Override
protected boolean showMembersFromDefaultPackage() {
return false;
}
}
@@ -77,6 +77,8 @@ public abstract class StaticImportMemberFix<T extends PsiMember> implements Inte
@NotNull protected abstract List<T> getMembersToImport(boolean applicableOnly);
protected abstract boolean showMembersFromDefaultPackage();
public static boolean isExcluded(PsiMember method) {
String name = PsiUtil.getMemberQualifiedName(method);
return name != null && JavaProjectCodeInsightSettings.getSettings(method.getProject()).isExcluded(name);
@@ -61,11 +61,16 @@ public class StaticImportMethodFix extends StaticImportMemberFix<PsiMethod> {
PsiReferenceExpression reference = element == null ? null : element.getMethodExpression();
String name = reference == null ? null : reference.getReferenceName();
if (name == null) return Collections.emptyList();
final StaticMembersProcessor<PsiMethod> processor = new MyStaticMethodProcessor(element);
final StaticMembersProcessor<PsiMethod> processor = new MyStaticMethodProcessor(element, showMembersFromDefaultPackage());
cache.processMethodsWithName(name, element.getResolveScope(), processor);
return processor.getMembersToImport(applicableOnly);
}
@Override
protected boolean showMembersFromDefaultPackage() {
return false;
}
@NotNull
protected StaticImportMethodQuestionAction<PsiMethod> createQuestionAction(List<PsiMethod> methodsToImport, @NotNull Project project, Editor editor) {
return new StaticImportMethodQuestionAction<>(project, editor, methodsToImport, myMethodCall);
@@ -93,8 +98,8 @@ public class StaticImportMethodFix extends StaticImportMemberFix<PsiMethod> {
private static class MyStaticMethodProcessor extends StaticMembersProcessor<PsiMethod> {
private MyStaticMethodProcessor(PsiMethodCallExpression place) {
super(place);
private MyStaticMethodProcessor(@NotNull PsiMethodCallExpression place, boolean showMembersFromDefaultPackage) {
super(place, showMembersFromDefaultPackage);
}
@Override
@@ -36,10 +36,12 @@ abstract class StaticMembersProcessor<T extends PsiMember & PsiDocCommentOwner>
private final Map<PsiClass, Boolean> myPossibleClasses = new HashMap<>();
private final PsiElement myPlace;
private final boolean myShowMembersFromDefaultPackage;
private PsiType myExpectedType;
protected StaticMembersProcessor(PsiElement place) {
protected StaticMembersProcessor(@NotNull PsiElement place, boolean showMembersFromDefaultPackage) {
myPlace = place;
myShowMembersFromDefaultPackage = showMembersFromDefaultPackage && PsiUtil.isFromDefaultPackage(place);
myExpectedType = PsiType.NULL;
}
@@ -94,10 +96,7 @@ abstract class StaticMembersProcessor<T extends PsiMember & PsiDocCommentOwner>
}
}
PsiFile file = member.getContainingFile();
if (file instanceof PsiJavaFile
//do not show methods from default package
&& !((PsiJavaFile)file).getPackageName().isEmpty()) {
if (myShowMembersFromDefaultPackage || !PsiUtil.isFromDefaultPackage(member)) {
mySuggestions.putValue(containingClass, member);
}
return processCondition();
@@ -1209,7 +1209,11 @@ public final class PsiUtil extends PsiUtilCore {
}
public static boolean isFromDefaultPackage(PsiClass aClass) {
final PsiFile containingFile = aClass.getContainingFile();
return isFromDefaultPackage((PsiElement)aClass);
}
public static boolean isFromDefaultPackage(PsiElement element) {
final PsiFile containingFile = element.getContainingFile();
return containingFile instanceof PsiClassOwner && StringUtil.isEmpty(((PsiClassOwner)containingFile).getPackageName());
}
@@ -0,0 +1,6 @@
// "Qualify static call..." "true"
class Test {
void m() {
staticMet<caret>hod();
}
}
@@ -0,0 +1,8 @@
// "Qualify static call..." "true"
package org.intellij;
class Test {
void m() {
staticMet<caret>hod();
}
}
@@ -0,0 +1,6 @@
// "Import static method 'java.lang.Integer.parseInt'" "true"
class Test {
void m() {
staticMet<caret>hod();
}
}
@@ -0,0 +1,8 @@
// "Import static method 'java.lang.Integer.parseInt'" "true"
package org.intellij;
class Test {
void m() {
staticMet<caret>hod();
}
}
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
public class QualifyCallByClassFromDefaultPackageTest extends LightCodeInsightFixtureTestCase {
private static final String QUALIFY_METHOD_FIX_TEXT = "Qualify static call 'Util.staticMethod'";
private static final String QUALIFY_CONST_FIX_TEXT = "Qualify static constant access 'Util.STATIC_FIELD'";
@Override
protected void setUp() throws Exception {
super.setUp();
myFixture.addClass("public class Util {" +
" public static void staticMethod() {}" +
" public static final String STATIC_FIELD = \"XXX\";" +
"}");
}
public void testMethodCallFromDefaultPackage() {
myFixture.configureByText("Main.java", "class Main {" +
" void m() { staticMeth<caret>od(); }" +
"}");
assertOneElement(myFixture.filterAvailableIntentions(QUALIFY_METHOD_FIX_TEXT));
}
public void testMethodCallFromNonDefaultPackage() {
myFixture.configureByText("Main.java", "package org.some; " +
"class Main {" +
" void m() { staticMeth<caret>od(); }" +
"}");
assertEmpty(myFixture.filterAvailableIntentions(QUALIFY_METHOD_FIX_TEXT));
}
public void testFieldCallFromDefaultPackage() {
myFixture.configureByText("Main.java", "class Main {" +
" void m() { STATIC_FIE<caret>LD; }" +
"}");
assertOneElement(myFixture.filterAvailableIntentions(QUALIFY_CONST_FIX_TEXT));
}
public void testFieldCallFromNonDefaultPackage() {
myFixture.configureByText("Main.java", "package org.some; " +
"class Main {" +
" void m() { STATIC_FIE<caret>LD; }" +
"}");
assertEmpty(myFixture.filterAvailableIntentions(QUALIFY_CONST_FIX_TEXT));
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportConstantFix;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
public class StaticImportFromDefaultPackageTest extends LightCodeInsightFixtureTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
myFixture.addClass("public class Util {" +
" public static void staticMethod() {}" +
" public static final String STATIC_FIELD = \"XXX\";" +
"}");
}
public void testMethodCallFromDefaultPackage() {
myFixture.configureByText("Main.java", "class Main { void m () {" +
" staticMeht<caret>od();" +
"}}");
assertFixForMethodIsNotAvailable();
}
public void testMethodCallFromNonDefaultPackage() {
myFixture.configureByText("Main.java", "package org;" +
"class Main { void m () {" +
" staticMeht<caret>od();" +
"}}");
assertFixForMethodIsNotAvailable();
}
public void testFieldCallFromDefaultPackage() {
myFixture.configureByText("Main.java", "class Main { void m () {" +
" STATIC_<caret>FIELD();" +
"}}");
assertFixForFieldIsNotAvailable();
}
public void testFieldCallFromNonDefaultPackage() {
myFixture.configureByText("Main.java", "package org;" +
"class Main { void m () {" +
" STATIC_<caret>FIELD();" +
"}}");
assertFixForFieldIsNotAvailable();
}
private void assertFixForMethodIsNotAvailable() {
assertEmpty(myFixture.filterAvailableIntentions(QuickFixBundle.message("static.import.method.text")));
}
private void assertFixForFieldIsNotAvailable() {
assertEmpty(myFixture.filterAvailableIntentions(StaticImportConstantFix.BASE_TEXT));
}
}