mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
type migration: RootTypeConversionRule delete unnecessarily qualified static method qualifier IDEA-CR-6898
This commit is contained in:
+11
-5
@@ -23,6 +23,8 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
|
||||
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.style.UnnecessarilyQualifiedStaticUsageInspection;
|
||||
import com.siyeh.ig.style.UnnecessarilyQualifiedStaticallyImportedElementInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -141,16 +143,20 @@ public class RootTypeConversionRule extends TypeConversionRule {
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
|
||||
final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject());
|
||||
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject());
|
||||
final PsiMethodCallExpression newMethodCall;
|
||||
if (qualifierExpression != null) {
|
||||
codeStyleManager.shortenClassReferences(qualifierExpression.replace(elementFactory.createExpressionFromText(myTargetClassQName, expression)));
|
||||
return expression;
|
||||
JavaCodeStyleManager.getInstance(expression.getProject())
|
||||
.shortenClassReferences(qualifierExpression.replace(elementFactory.createExpressionFromText(myTargetClassQName, expression)));
|
||||
newMethodCall = methodCallExpression;
|
||||
}
|
||||
else {
|
||||
final PsiElement replacedExpression = expression.replace(
|
||||
newMethodCall = (PsiMethodCallExpression)expression.replace(
|
||||
elementFactory.createExpressionFromText(myTargetClassQName + "." + expression.getText(), expression));
|
||||
return (PsiExpression)codeStyleManager.shortenClassReferences(replacedExpression);
|
||||
}
|
||||
if (UnnecessarilyQualifiedStaticUsageInspection.isUnnecessarilyQualifiedAccess(newMethodCall.getMethodExpression(), false, false, false)) {
|
||||
newMethodCall.getMethodExpression().getQualifierExpression().delete();
|
||||
}
|
||||
return newMethodCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -896,6 +896,12 @@ public class TypeMigrationTest extends TypeMigrationTestBase {
|
||||
myFactory.createTypeFromText("Test.AnInterface2<java.lang.String, java.lang.Void>", null));
|
||||
}
|
||||
|
||||
public void testRemoveStaticMethodQualifier() {
|
||||
doTestFirstParamType("meth",
|
||||
myFactory.createTypeFromText("java.lang.Long", null),
|
||||
myFactory.createTypeFromText("Test", null));
|
||||
}
|
||||
|
||||
public void testPropagateViaEquals() {
|
||||
doTestFirstParamType("meth", myFactory.createTypeFromText("java.lang.String", null), myFactory.createTypeFromText("java.lang.Long", null));
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
Types:
|
||||
PsiMethod:meth : Test
|
||||
PsiParameter:l : Test
|
||||
PsiReferenceExpression:l : Test
|
||||
PsiReferenceExpression:l : Test
|
||||
|
||||
Conversions:
|
||||
Long.valueOf("256") -> Static method qualifier conversion -> Test
|
||||
|
||||
New expression type changes:
|
||||
Fails:
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
public Test meth(Test l) {
|
||||
l = valueOf("256");
|
||||
return l;
|
||||
}
|
||||
|
||||
public static Test valueOf(String s) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Test {
|
||||
public Long meth(Long l) {
|
||||
l = Long.valueOf("256");
|
||||
return l;
|
||||
}
|
||||
|
||||
public static Test valueOf(String s) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+97
-94
@@ -121,7 +121,7 @@ public class UnnecessarilyQualifiedStaticUsageInspection extends BaseInspection
|
||||
if (qualifier == null) {
|
||||
return;
|
||||
}
|
||||
if (!isUnnecessarilyQualifiedAccess(reference)) {
|
||||
if (!isUnnecessarilyQualifiedAccess(reference, m_ignoreStaticAccessFromStaticContext, m_ignoreStaticFieldAccesses, m_ignoreStaticMethodCalls)) {
|
||||
return;
|
||||
}
|
||||
registerError(qualifier, ProblemHighlightType.LIKE_UNUSED_SYMBOL, reference);
|
||||
@@ -131,102 +131,105 @@ public class UnnecessarilyQualifiedStaticUsageInspection extends BaseInspection
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
visitReferenceElement(expression);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUnnecessarilyQualifiedAccess(@NotNull PsiJavaCodeReferenceElement referenceElement) {
|
||||
if (referenceElement instanceof PsiMethodReferenceExpression) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement parent = referenceElement.getParent();
|
||||
if (parent instanceof PsiImportStatementBase) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement qualifierElement = referenceElement.getQualifier();
|
||||
if (!(qualifierElement instanceof PsiJavaCodeReferenceElement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiJavaCodeReferenceElement qualifier = (PsiJavaCodeReferenceElement)qualifierElement;
|
||||
if (isGenericReference(referenceElement, qualifier)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement target = referenceElement.resolve();
|
||||
if ((!(target instanceof PsiField) || m_ignoreStaticFieldAccesses) && (!(target instanceof PsiMethod) || m_ignoreStaticMethodCalls)) {
|
||||
return false;
|
||||
}
|
||||
if (m_ignoreStaticAccessFromStaticContext) {
|
||||
final PsiMember containingMember = PsiTreeUtil.getParentOfType(referenceElement, PsiMember.class);
|
||||
if (containingMember != null && !containingMember.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final String referenceName = referenceElement.getReferenceName();
|
||||
if (referenceName == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement resolvedQualifier = qualifier.resolve();
|
||||
if (!(resolvedQualifier instanceof PsiClass)) {
|
||||
return false;
|
||||
}
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(referenceElement, PsiClass.class);
|
||||
final PsiClass qualifyingClass = (PsiClass)resolvedQualifier;
|
||||
if (containingClass == null || !PsiTreeUtil.isAncestor(qualifyingClass, containingClass, false)) {
|
||||
return false;
|
||||
}
|
||||
final Project project = referenceElement.getProject();
|
||||
final JavaPsiFacade manager = JavaPsiFacade.getInstance(project);
|
||||
final PsiResolveHelper resolveHelper = manager.getResolveHelper();
|
||||
final PsiMember member = (PsiMember)target;
|
||||
final PsiClass memberClass;
|
||||
if (target instanceof PsiField) {
|
||||
final PsiVariable variable = resolveHelper.resolveReferencedVariable(referenceName, referenceElement);
|
||||
if (variable == null || !variable.equals(member)) {
|
||||
return false;
|
||||
}
|
||||
final TextRange referenceElementTextRange = referenceElement.getTextRange();
|
||||
if (referenceElementTextRange == null) {
|
||||
return false;
|
||||
}
|
||||
final TextRange variableTextRange = variable.getTextRange();
|
||||
if (variableTextRange == null) {
|
||||
return false;
|
||||
}
|
||||
//illegal forward ref
|
||||
if (referenceElementTextRange.getStartOffset() < variableTextRange.getEndOffset()) {
|
||||
return false;
|
||||
}
|
||||
final PsiMember memberVariable = (PsiMember)variable;
|
||||
memberClass = memberVariable.getContainingClass();
|
||||
}
|
||||
else if (target instanceof PsiClass) {
|
||||
final PsiClass aClass = resolveHelper.resolveReferencedClass(referenceName, referenceElement);
|
||||
if (aClass == null || !aClass.equals(member)) {
|
||||
return false;
|
||||
}
|
||||
memberClass = aClass.getContainingClass();
|
||||
}
|
||||
else {
|
||||
return isMethodAccessibleWithoutQualifier(referenceElement, qualifyingClass);
|
||||
}
|
||||
return resolvedQualifier.equals(memberClass);
|
||||
}
|
||||
|
||||
private boolean isMethodAccessibleWithoutQualifier(PsiJavaCodeReferenceElement referenceElement, PsiClass qualifyingClass) {
|
||||
final String referenceName = referenceElement.getReferenceName();
|
||||
if (referenceName == null) {
|
||||
return false;
|
||||
}
|
||||
PsiClass containingClass = ClassUtils.getContainingClass(referenceElement);
|
||||
while (containingClass != null) {
|
||||
final PsiMethod[] methods = containingClass.findMethodsByName(referenceName, true);
|
||||
for (final PsiMethod method : methods) {
|
||||
final String name = method.getName();
|
||||
if (referenceName.equals(name)) {
|
||||
return containingClass.equals(qualifyingClass);
|
||||
}
|
||||
}
|
||||
containingClass = ClassUtils.getContainingClass(containingClass);
|
||||
}
|
||||
public static boolean isUnnecessarilyQualifiedAccess(@NotNull PsiJavaCodeReferenceElement referenceElement,
|
||||
boolean ignoreStaticAccessFromStaticContext,
|
||||
boolean ignoreStaticFieldAccesses,
|
||||
boolean ignoreStaticMethodCalls) {
|
||||
if (referenceElement instanceof PsiMethodReferenceExpression) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement parent = referenceElement.getParent();
|
||||
if (parent instanceof PsiImportStatementBase) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement qualifierElement = referenceElement.getQualifier();
|
||||
if (!(qualifierElement instanceof PsiJavaCodeReferenceElement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiJavaCodeReferenceElement qualifier = (PsiJavaCodeReferenceElement)qualifierElement;
|
||||
if (isGenericReference(referenceElement, qualifier)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement target = referenceElement.resolve();
|
||||
if ((!(target instanceof PsiField) || ignoreStaticFieldAccesses) && (!(target instanceof PsiMethod) || ignoreStaticMethodCalls)) {
|
||||
return false;
|
||||
}
|
||||
if (ignoreStaticAccessFromStaticContext) {
|
||||
final PsiMember containingMember = PsiTreeUtil.getParentOfType(referenceElement, PsiMember.class);
|
||||
if (containingMember != null && !containingMember.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final String referenceName = referenceElement.getReferenceName();
|
||||
if (referenceName == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement resolvedQualifier = qualifier.resolve();
|
||||
if (!(resolvedQualifier instanceof PsiClass)) {
|
||||
return false;
|
||||
}
|
||||
final PsiClass containingClass = PsiTreeUtil.getParentOfType(referenceElement, PsiClass.class);
|
||||
final PsiClass qualifyingClass = (PsiClass)resolvedQualifier;
|
||||
if (containingClass == null || !PsiTreeUtil.isAncestor(qualifyingClass, containingClass, false)) {
|
||||
return false;
|
||||
}
|
||||
final Project project = referenceElement.getProject();
|
||||
final JavaPsiFacade manager = JavaPsiFacade.getInstance(project);
|
||||
final PsiResolveHelper resolveHelper = manager.getResolveHelper();
|
||||
final PsiMember member = (PsiMember)target;
|
||||
final PsiClass memberClass;
|
||||
if (target instanceof PsiField) {
|
||||
final PsiVariable variable = resolveHelper.resolveReferencedVariable(referenceName, referenceElement);
|
||||
if (variable == null || !variable.equals(member)) {
|
||||
return false;
|
||||
}
|
||||
final TextRange referenceElementTextRange = referenceElement.getTextRange();
|
||||
if (referenceElementTextRange == null) {
|
||||
return false;
|
||||
}
|
||||
final TextRange variableTextRange = variable.getTextRange();
|
||||
if (variableTextRange == null) {
|
||||
return false;
|
||||
}
|
||||
//illegal forward ref
|
||||
if (referenceElementTextRange.getStartOffset() < variableTextRange.getEndOffset()) {
|
||||
return false;
|
||||
}
|
||||
final PsiMember memberVariable = (PsiMember)variable;
|
||||
memberClass = memberVariable.getContainingClass();
|
||||
}
|
||||
else if (target instanceof PsiClass) {
|
||||
final PsiClass aClass = resolveHelper.resolveReferencedClass(referenceName, referenceElement);
|
||||
if (aClass == null || !aClass.equals(member)) {
|
||||
return false;
|
||||
}
|
||||
memberClass = aClass.getContainingClass();
|
||||
}
|
||||
else {
|
||||
return isMethodAccessibleWithoutQualifier(referenceElement, qualifyingClass);
|
||||
}
|
||||
return resolvedQualifier.equals(memberClass);
|
||||
}
|
||||
|
||||
private static boolean isMethodAccessibleWithoutQualifier(PsiJavaCodeReferenceElement referenceElement, PsiClass qualifyingClass) {
|
||||
final String referenceName = referenceElement.getReferenceName();
|
||||
if (referenceName == null) {
|
||||
return false;
|
||||
}
|
||||
PsiClass containingClass = ClassUtils.getContainingClass(referenceElement);
|
||||
while (containingClass != null) {
|
||||
final PsiMethod[] methods = containingClass.findMethodsByName(referenceName, true);
|
||||
for (final PsiMethod method : methods) {
|
||||
final String name = method.getName();
|
||||
if (referenceName.equals(name)) {
|
||||
return containingClass.equals(qualifyingClass);
|
||||
}
|
||||
}
|
||||
containingClass = ClassUtils.getContainingClass(containingClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean isGenericReference(PsiJavaCodeReferenceElement referenceElement, PsiJavaCodeReferenceElement qualifierElement) {
|
||||
|
||||
Reference in New Issue
Block a user