mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
IDEA-178890 "Inline" Foo.class.getName(), Foo.class.getSimpleName()
GitOrigin-RevId: 12c063d4e41ba8f5244a9c0609ebf016980c97c8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6e1e629b31
commit
505bdd1c87
@@ -17,6 +17,7 @@ import com.intellij.refactoring.util.InlineUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
class InlineMethodHandler extends JavaInlineActionHandler {
|
||||
private static final String REFACTORING_NAME = RefactoringBundle.message("inline.method.title");
|
||||
@@ -32,7 +33,16 @@ class InlineMethodHandler extends JavaInlineActionHandler {
|
||||
@Override
|
||||
public void inlineElement(final Project project, Editor editor, PsiElement element) {
|
||||
PsiMethod method = (PsiMethod)element.getNavigationElement();
|
||||
final PsiCodeBlock methodBody = method.getBody();
|
||||
PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null;
|
||||
|
||||
boolean allowInlineThisOnly = false;
|
||||
PsiCodeBlock methodBody = method.getBody();
|
||||
Supplier<PsiCodeBlock> specialization = InlineMethodSpecialization.forReference(reference);
|
||||
if (specialization != null) {
|
||||
allowInlineThisOnly = true;
|
||||
methodBody = specialization.get();
|
||||
}
|
||||
|
||||
if (methodBody == null){
|
||||
String message;
|
||||
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
@@ -48,7 +58,6 @@ class InlineMethodHandler extends JavaInlineActionHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null;
|
||||
if (reference != null) {
|
||||
final PsiElement refElement = reference.getElement();
|
||||
if (!isEnabledForLanguage(refElement.getLanguage())) {
|
||||
@@ -73,7 +82,6 @@ class InlineMethodHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
boolean allowInlineThisOnly = false;
|
||||
if (method.isConstructor()) {
|
||||
if (method.isVarArgs()) {
|
||||
String message = RefactoringBundle.message("refactoring.cannot.be.applied.to.vararg.constructors", REFACTORING_NAME);
|
||||
|
||||
@@ -111,8 +111,8 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
boolean searchForTextOccurrences,
|
||||
boolean isDeleteTheDeclaration) {
|
||||
super(project);
|
||||
myMethod = method;
|
||||
myTransformerChooser = InlineTransformer.getSuitableTransformer(myMethod);
|
||||
myMethod = InlineMethodSpecialization.specialize(method, reference);
|
||||
myTransformerSelector = InlineTransformerSelector.forMethod(myMethod);
|
||||
myReference = reference;
|
||||
myEditor = editor;
|
||||
myInlineThisOnly = isInlineThisOnly;
|
||||
@@ -773,7 +773,10 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
|
||||
private PsiSubstitutor getCallSubstitutor(PsiMethodCallExpression methodCall) {
|
||||
JavaResolveResult resolveResult = methodCall.getMethodExpression().advancedResolve(false);
|
||||
LOG.assertTrue(myManager.areElementsEquivalent(resolveResult.getElement(), myMethod));
|
||||
if (myMethod.isPhysical()) {
|
||||
// Could be specialized
|
||||
LOG.assertTrue(myManager.areElementsEquivalent(resolveResult.getElement(), myMethod));
|
||||
}
|
||||
if (resolveResult.getSubstitutor() != PsiSubstitutor.EMPTY) {
|
||||
Iterator<PsiTypeParameter> oldTypeParameters = PsiUtil.typeParametersIterator(myMethod);
|
||||
Iterator<PsiTypeParameter> newTypeParameters = PsiUtil.typeParametersIterator(myMethodCopy);
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.refactoring.inline;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.callMatcher.CallMapper;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class InlineMethodSpecialization {
|
||||
private static final CallMatcher
|
||||
CLASS_METHODS = CallMatcher.exactInstanceCall(CommonClassNames.JAVA_LANG_CLASS, "getName", "getSimpleName").parameterCount(0);
|
||||
|
||||
private static final CallMapper<Supplier<PsiCodeBlock>> SPECIALIZATIONS = new CallMapper<Supplier<PsiCodeBlock>>()
|
||||
.register(CLASS_METHODS, (PsiMethodCallExpression call) -> {
|
||||
PsiReferenceExpression ref = call.getMethodExpression();
|
||||
PsiExpression qualifier = ref.getQualifierExpression();
|
||||
PsiClassObjectAccessExpression receiver =
|
||||
ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(qualifier), PsiClassObjectAccessExpression.class);
|
||||
if (receiver != null) {
|
||||
PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(receiver.getOperand().getType());
|
||||
if (psiClass != null) {
|
||||
String name = "getSimpleName".equals(ref.getReferenceName()) ? psiClass.getName() : psiClass.getQualifiedName();
|
||||
if (name != null) {
|
||||
return () -> {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(call.getProject());
|
||||
return factory.createCodeBlockFromText("{return \"" + StringUtil.escapeStringCharacters(name) + "\";}", call);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
static Supplier<PsiCodeBlock> forReference(PsiReference ref) {
|
||||
if (!(ref instanceof PsiReferenceExpression)) return null;
|
||||
PsiMethodCallExpression call = ObjectUtils.tryCast(((PsiReferenceExpression)ref).getParent(), PsiMethodCallExpression.class);
|
||||
return SPECIALIZATIONS.mapFirst(call);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace method body with specialized implementation for some known methods
|
||||
* @param method method to specialize
|
||||
* @param ref method call site reference
|
||||
* @return call-site-specific specialization of method body; or original method if there's no specialization for given method
|
||||
*/
|
||||
static PsiMethod specialize(PsiMethod method, PsiReference ref) {
|
||||
Supplier<PsiCodeBlock> specialization = forReference(ref);
|
||||
if (specialization == null) return method;
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject());
|
||||
String parameters = method.getParameterList().getText();
|
||||
PsiType returnType = method.getReturnType();
|
||||
String type = returnType == null ? "" : returnType.getCanonicalText(true);
|
||||
PsiMethod copy = factory.createMethodFromText(type + " " + method.getName() + parameters + " {}", method);
|
||||
Objects.requireNonNull(copy.getBody()).replace(specialization.get());
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package foo.bar.baz;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
String s = Test.class.get<caret>Name();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package foo.bar.baz;
|
||||
|
||||
class Test {
|
||||
void test() {
|
||||
String s = "foo.bar.baz.Test";
|
||||
}
|
||||
}
|
||||
@@ -483,6 +483,10 @@ public class InlineMethodTest extends LightRefactoringTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSpecializeClassGetName() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return getTestName(false).contains("Src") ? IdeaTestUtil.getMockJdk17() : super.getProjectJDK();
|
||||
|
||||
Reference in New Issue
Block a user