mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-26 19:06:24 +07:00
inline to anonymous: allow to inline from library (IDEA-162893)
This commit is contained in:
+6
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -81,6 +81,11 @@ public class InlineToAnonymousClassDialog extends InlineOptionsWithSearchSetting
|
||||
protected void saveSearchInCommentsAndStrings(boolean searchInComments) {
|
||||
JavaRefactoringSettings.getInstance().INLINE_CLASS_SEARCH_IN_COMMENTS = searchInComments;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowInlineAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSearchInTextOccurrences(boolean searchInTextOccurrences) {
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
@@ -115,7 +116,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
|
||||
final Ref<String> errorMessage = new Ref<>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> ApplicationManager.getApplication().runReadAction(() -> errorMessage.set(getCannotInlineMessage(psiClass))), "Check if inline is possible...", true, project)) return;
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> ApplicationManager.getApplication().runReadAction(() -> errorMessage.set(getCannotInlineMessage((PsiClass)psiClass.getNavigationElement()))), "Check if inline is possible...", true, project)) return;
|
||||
if (errorMessage.get() != null) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, errorMessage.get(), RefactoringBundle.message("inline.to.anonymous.refactoring"), null);
|
||||
return;
|
||||
@@ -201,7 +202,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
return RefactoringBundle.message("inline.to.anonymous.no.abstract");
|
||||
}
|
||||
if (!psiClass.getManager().isInProject(psiClass)) {
|
||||
if (psiClass instanceof PsiCompiledElement) {
|
||||
return "Library classes cannot be inlined";
|
||||
}
|
||||
|
||||
@@ -230,6 +231,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(psiClass.getProject());
|
||||
final PsiMethod[] methods = psiClass.getMethods();
|
||||
for(PsiMethod method: methods) {
|
||||
if (method.isConstructor()) {
|
||||
@@ -238,7 +240,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
}
|
||||
else if (method.findSuperMethods().length == 0) {
|
||||
if (!ReferencesSearch.search(method).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
if (!ReferencesSearch.search(method, searchScope).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
return "Class cannot be inlined because there are usages of its methods not inherited from its superclass or interface";
|
||||
}
|
||||
}
|
||||
@@ -253,7 +255,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
if (classModifiers.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return "Class cannot be inlined because it has static inner classes";
|
||||
}
|
||||
if (!ReferencesSearch.search(innerClass).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
if (!ReferencesSearch.search(innerClass, searchScope).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
return "Class cannot be inlined because it has usages of its inner classes";
|
||||
}
|
||||
}
|
||||
@@ -274,7 +276,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
return "Class cannot be inlined because it has static fields with non-constant initializers";
|
||||
}
|
||||
}
|
||||
if (!ReferencesSearch.search(field).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
if (!ReferencesSearch.search(field, searchScope).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
return "Class cannot be inlined because it has usages of fields not inherited from its superclass";
|
||||
}
|
||||
}
|
||||
@@ -305,7 +307,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
@Nullable
|
||||
private static String getCannotInlineDueToUsagesMessage(final PsiClass aClass) {
|
||||
boolean hasUsages = false;
|
||||
for(PsiReference reference : ReferencesSearch.search(aClass)) {
|
||||
for(PsiReference reference : ReferencesSearch.search(aClass, GlobalSearchScope.projectScope(aClass.getProject()))) {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (element == null) continue;
|
||||
if (!PsiTreeUtil.isAncestor(aClass, element, false)) {
|
||||
@@ -359,10 +361,10 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
|
||||
@Override
|
||||
public boolean process(final PsiReference psiReference) {
|
||||
if (PsiTreeUtil.isAncestor(myPsiElement, psiReference.getElement(), false)) {
|
||||
PsiElement element = psiReference.getElement();
|
||||
if (element != null && PsiTreeUtil.isAncestor(myPsiElement, element.getNavigationElement(), false)) {
|
||||
return true;
|
||||
}
|
||||
PsiElement element = psiReference.getElement();
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression();
|
||||
while (qualifier instanceof PsiParenthesizedExpression) {
|
||||
@@ -371,7 +373,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
if (qualifier instanceof PsiNewExpression) {
|
||||
PsiNewExpression newExpr = (PsiNewExpression) qualifier;
|
||||
PsiJavaCodeReferenceElement classRef = newExpr.getClassReference();
|
||||
if (classRef != null && myPsiElement.equals(classRef.resolve())) {
|
||||
if (classRef != null && myPsiElement.isEquivalentTo(classRef.resolve())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+21
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -76,7 +76,8 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
return new UsageInfo[] { new UsageInfo(myCallToInline) };
|
||||
}
|
||||
Set<UsageInfo> usages = new HashSet<>();
|
||||
for (PsiReference reference : ReferencesSearch.search(myClass)) {
|
||||
final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(myProject);
|
||||
for (PsiReference reference : ReferencesSearch.search(myClass, searchScope)) {
|
||||
usages.add(new UsageInfo(reference.getElement()));
|
||||
}
|
||||
|
||||
@@ -89,9 +90,8 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
if (mySearchInNonJavaFiles) {
|
||||
GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myClass.getProject());
|
||||
TextOccurrencesUtil.addTextOccurences(myClass, qName, projectScope, nonCodeUsages,
|
||||
new NonCodeUsageInfoFactory(myClass, qName));
|
||||
TextOccurrencesUtil.addTextOccurences(myClass, qName, searchScope, nonCodeUsages,
|
||||
new NonCodeUsageInfoFactory(myClass, qName));
|
||||
}
|
||||
usages.addAll(nonCodeUsages);
|
||||
}
|
||||
@@ -99,6 +99,15 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
return usages.toArray(new UsageInfo[usages.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<? extends PsiElement> getElementsToWrite(@NotNull UsageViewDescriptor descriptor) {
|
||||
if (!myInlineThisOnly && !myClass.isWritable()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return super.getElementsToWrite(descriptor);
|
||||
}
|
||||
|
||||
protected void refreshElements(@NotNull PsiElement[] elements) {
|
||||
assert elements.length == 1;
|
||||
myClass = (PsiClass) elements [0];
|
||||
@@ -156,7 +165,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
@Override
|
||||
public void visitParameter(PsiParameter parameter) {
|
||||
super.visitParameter(parameter);
|
||||
if (PsiUtil.resolveClassInType(parameter.getType()) != myClass) return;
|
||||
if (!myClass.isEquivalentTo(PsiUtil.resolveClassInType(parameter.getType()))) return;
|
||||
|
||||
for (PsiReference psiReference : ReferencesSearch.search(parameter)) {
|
||||
final PsiElement refElement = psiReference.getElement();
|
||||
@@ -180,7 +189,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
super.visitNewExpression(expression);
|
||||
if (PsiUtil.resolveClassInType(expression.getType()) != myClass) return;
|
||||
if (!myClass.isEquivalentTo(PsiUtil.resolveClassInType(expression.getType()))) return;
|
||||
result.putValue(expression, "Class cannot be inlined because a call to its constructor inside body");
|
||||
}
|
||||
|
||||
@@ -189,7 +198,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
super.visitMethodCallExpression(expression);
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
|
||||
if (qualifierExpression != null && PsiUtil.resolveClassInType(qualifierExpression.getType()) != myClass) return;
|
||||
if (qualifierExpression != null && !myClass.isEquivalentTo(PsiUtil.resolveClassInType(qualifierExpression.getType()))) return;
|
||||
final PsiElement resolved = methodExpression.resolve();
|
||||
if (resolved instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)resolved;
|
||||
@@ -244,7 +253,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
if (!myInlineThisOnly) {
|
||||
if (!myInlineThisOnly && myClass.getOriginalElement().isWritable()) {
|
||||
try {
|
||||
myClass.delete();
|
||||
}
|
||||
@@ -262,7 +271,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
else {
|
||||
PsiClass target = superType.resolve();
|
||||
assert target != null : superType;
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
|
||||
PsiJavaCodeReferenceElement element = factory.createClassReferenceElement(target);
|
||||
PsiJavaCodeReferenceElement reference = psiNewExpression.getClassReference();
|
||||
assert reference != null : psiNewExpression;
|
||||
@@ -275,11 +284,11 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
private void replaceWithSuperType(final PsiTypeElement typeElement, final PsiClassType superType) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
|
||||
PsiClassType psiType = (PsiClassType) typeElement.getType();
|
||||
PsiClassType.ClassResolveResult classResolveResult = psiType.resolveGenerics();
|
||||
PsiType substType = classResolveResult.getSubstitutor().substitute(superType);
|
||||
assert classResolveResult.getElement() == myClass;
|
||||
assert myClass.isEquivalentTo(classResolveResult.getElement());
|
||||
try {
|
||||
PsiElement replaced = typeElement.replace(factory.createTypeElement(substType));
|
||||
JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced);
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -82,7 +82,8 @@ class InlineToAnonymousConstructorProcessor {
|
||||
checkInlineChainingConstructor();
|
||||
JavaResolveResult classResolveResult = myNewExpression.getClassReference().advancedResolve(false);
|
||||
JavaResolveResult methodResolveResult = myNewExpression.resolveMethodGenerics();
|
||||
myConstructor = (PsiMethod) methodResolveResult.getElement();
|
||||
final PsiElement element = methodResolveResult.getElement();
|
||||
myConstructor = element != null ? (PsiMethod) element.getNavigationElement() : null;
|
||||
myConstructorArguments = myNewExpression.getArgumentList();
|
||||
|
||||
PsiSubstitutor classResolveSubstitutor = classResolveResult.getSubstitutor();
|
||||
|
||||
Reference in New Issue
Block a user