mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
introduce injected fragment as string (IDEA-90322)
This commit is contained in:
+37
-9
@@ -25,6 +25,7 @@ import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.featureStatistics.ProductivityFeatureNames;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -48,6 +49,7 @@ import com.intellij.psi.impl.PsiDiamondTypeUtil;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspCodeBlock;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
|
||||
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil;
|
||||
import com.intellij.psi.scope.processor.VariablesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
@@ -243,11 +245,18 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
/**
|
||||
* @return can return NotNull value although extraction will fail: reason could be retrieved from {@link #getErrorMessage(PsiExpression)}
|
||||
*/
|
||||
public static PsiExpression getSelectedExpression(final Project project, final PsiFile file, int startOffset, int endOffset) {
|
||||
public static PsiExpression getSelectedExpression(final Project project, PsiFile file, int startOffset, int endOffset) {
|
||||
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(project);
|
||||
PsiElement elementAtStart = file.findElementAt(startOffset);
|
||||
if (elementAtStart == null || elementAtStart instanceof PsiWhiteSpace || elementAtStart instanceof PsiComment) {
|
||||
elementAtStart = PsiTreeUtil.skipSiblingsForward(elementAtStart, PsiWhiteSpace.class, PsiComment.class);
|
||||
if (elementAtStart == null) return null;
|
||||
if (elementAtStart == null) {
|
||||
if (injectedLanguageManager.isInjectedFragment(file)) {
|
||||
return getSelectionFromInjectedHost(project, file, injectedLanguageManager);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
startOffset = elementAtStart.getTextOffset();
|
||||
}
|
||||
PsiElement elementAtEnd = file.findElementAt(endOffset - 1);
|
||||
@@ -261,6 +270,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
|
||||
PsiElement elementAt = PsiTreeUtil.findCommonParent(elementAtStart, elementAtEnd);
|
||||
if (PsiTreeUtil.getParentOfType(elementAt, PsiExpression.class, false) == null) {
|
||||
if (injectedLanguageManager.isInjectedFragment(file)) {
|
||||
return getSelectionFromInjectedHost(project, file, injectedLanguageManager);
|
||||
}
|
||||
elementAt = null;
|
||||
}
|
||||
final PsiLiteralExpression literalExpression = PsiTreeUtil.getParentOfType(elementAt, PsiLiteralExpression.class);
|
||||
@@ -395,6 +407,14 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
return tempExpr;
|
||||
}
|
||||
|
||||
private static PsiExpression getSelectionFromInjectedHost(Project project,
|
||||
PsiFile file,
|
||||
InjectedLanguageManager injectedLanguageManager) {
|
||||
final PsiLanguageInjectionHost injectionHost = injectedLanguageManager.getInjectionHost(file);
|
||||
final TextRange range = injectionHost.getTextRange();
|
||||
return getSelectedExpression(project, injectionHost.getContainingFile(), range.getStartOffset(), range.getEndOffset());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getErrorMessage(PsiExpression expr) {
|
||||
final Boolean needParenthesis = expr.getCopyableUserData(NEED_PARENTHESIS);
|
||||
@@ -550,26 +570,34 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
final boolean allOccurences = choice != OccurrencesChooser.ReplaceChoice.NO;
|
||||
final PsiElement chosenAnchor = allOccurences ? anchorStatementIfAll : anchorStatement;
|
||||
final Ref<SmartPsiElementPointer<PsiVariable>> variable = new Ref<SmartPsiElementPointer<PsiVariable>>();
|
||||
|
||||
final Editor topLevelEditor;
|
||||
if (!InjectedLanguageManager.getInstance(project).isInjectedFragment(anchorStatement.getContainingFile())) {
|
||||
topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(editor);
|
||||
} else {
|
||||
topLevelEditor = editor;
|
||||
}
|
||||
|
||||
final IntroduceVariableSettings settings =
|
||||
getSettings(project, editor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, chosenAnchor, choice);
|
||||
getSettings(project, topLevelEditor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, chosenAnchor, choice);
|
||||
if (!settings.isOK()) {
|
||||
wasSucceed[0] = false;
|
||||
return;
|
||||
}
|
||||
typeSelectorManager.setAllOccurrences(allOccurences);
|
||||
final TypeExpression expression = new TypeExpression(project, allOccurences ? typeSelectorManager.getTypesForAll() : typeSelectorManager.getTypesForOne());
|
||||
final RangeMarker exprMarker = editor.getDocument().createRangeMarker(expr.getTextRange());
|
||||
final RangeMarker exprMarker = topLevelEditor.getDocument().createRangeMarker(expr.getTextRange());
|
||||
final SuggestedNameInfo suggestedName = getSuggestedName(settings.getSelectedType(), expr, chosenAnchor);
|
||||
final List<RangeMarker> occurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
final boolean noWrite = choice == OccurrencesChooser.ReplaceChoice.NO_WRITE;
|
||||
for (PsiExpression occurrence : occurrences) {
|
||||
if (allOccurences || (noWrite && !PsiUtil.isAccessedForWriting(occurrence))) {
|
||||
occurrenceMarkers.add(editor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
occurrenceMarkers.add(topLevelEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
}
|
||||
final String expressionText = expr.getText();
|
||||
final Runnable runnable =
|
||||
introduce(project, expr, editor, anchorStatement, tempContainer, occurrences, anchorStatementIfAll, settings, variable);
|
||||
introduce(project, expr, topLevelEditor, anchorStatement, tempContainer, occurrences, anchorStatementIfAll, settings, variable);
|
||||
CommandProcessor.getInstance().executeCommand(
|
||||
project,
|
||||
new Runnable() {
|
||||
@@ -578,14 +606,14 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
if (isInplaceAvailableOnDataContext) {
|
||||
final PsiVariable elementToRename = variable.get().getElement();
|
||||
if (elementToRename != null) {
|
||||
editor.getCaretModel().moveToOffset(elementToRename.getTextOffset());
|
||||
topLevelEditor.getCaretModel().moveToOffset(elementToRename.getTextOffset());
|
||||
final boolean cantChangeFinalModifier = (hasWriteAccess || inFinalContext) && choice == OccurrencesChooser.ReplaceChoice.ALL;
|
||||
final JavaVariableInplaceIntroducer renamer =
|
||||
new JavaVariableInplaceIntroducer(project, expression, editor, elementToRename, cantChangeFinalModifier,
|
||||
new JavaVariableInplaceIntroducer(project, expression, topLevelEditor, elementToRename, cantChangeFinalModifier,
|
||||
typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers,
|
||||
IntroduceVariableBase.REFACTORING_NAME);
|
||||
renamer.initInitialText(expressionText);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(topLevelEditor.getDocument());
|
||||
renamer.performInplaceRefactoring(new LinkedHashSet<String>(Arrays.asList(suggestedName.names)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
{
|
||||
String regexp = "|\t";
|
||||
String[] parts = "".split(regexp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Test {
|
||||
{
|
||||
String[] parts = "".split("|<caret>\t");
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
|
||||
doTest(new MockIntroduceVariableHandler("it", false, false, false, "java.lang.String"));
|
||||
}
|
||||
|
||||
public void testFromInjected() throws Exception {
|
||||
doTest(new MockIntroduceVariableHandler("regexp", false, false, false, "java.lang.String"));
|
||||
}
|
||||
|
||||
public void testSCR10412() throws Exception {
|
||||
doTest(new MockIntroduceVariableHandler("newVar", false, false, false, "java.lang.String[]"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user