mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 05:21:29 +07:00
IDEA-190558 Join lines: smart concatenation of assignment and the subsequent reassignment with the method call
This commit is contained in:
@@ -408,6 +408,7 @@
|
||||
order="before samePsiMember"/>
|
||||
<joinLinesHandler implementation="com.intellij.codeInsight.editorActions.BlockJoinLinesHandler"/>
|
||||
<joinLinesHandler implementation="com.intellij.codeInsight.editorActions.ChainCallJoinLinesHandler"/>
|
||||
<joinLinesHandler implementation="com.intellij.codeInsight.editorActions.AssignmentSequenceJoinLinesHandler"/>
|
||||
<joinLinesHandler implementation="com.intellij.codeInsight.editorActions.DeclarationJoinLinesHandler"/>
|
||||
<joinLinesHandler implementation="com.intellij.codeInsight.editorActions.LiteralJoinLinesHandler"/>
|
||||
<editorSmartKeysConfigurable instance="com.intellij.application.options.JavadocOptionsProvider"
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2000-2018 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.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
/**
|
||||
* <pre>{@code
|
||||
* x = ...;
|
||||
* x = x.a().b().c();
|
||||
* =>
|
||||
* x = (...).a().b().c();}</pre>
|
||||
*/
|
||||
public class AssignmentSequenceJoinLinesHandler implements JoinLinesHandlerDelegate {
|
||||
@Override
|
||||
public int tryJoinLines(@NotNull final Document document, @NotNull final PsiFile psiFile, final int start, final int end) {
|
||||
PsiJavaToken elementAtStartLineEnd = tryCast(psiFile.findElementAt(start), PsiJavaToken.class);
|
||||
if (elementAtStartLineEnd == null) return CANNOT_JOIN;
|
||||
PsiElement firstElement = elementAtStartLineEnd.getParent();
|
||||
PsiExpression firstValue = null;
|
||||
PsiVariable variable = null;
|
||||
if (firstElement instanceof PsiExpressionStatement) {
|
||||
PsiExpressionStatement firstStatement = (PsiExpressionStatement)firstElement;
|
||||
PsiAssignmentExpression firstAssignment = ExpressionUtils.getAssignment(firstStatement);
|
||||
if (firstAssignment == null) return CANNOT_JOIN;
|
||||
PsiReferenceExpression ref = tryCast(PsiUtil.skipParenthesizedExprDown(firstAssignment.getLExpression()), PsiReferenceExpression.class);
|
||||
if (ref == null) return CANNOT_JOIN;
|
||||
variable = tryCast(ref.resolve(), PsiVariable.class);
|
||||
firstValue = firstAssignment.getRExpression();
|
||||
} else if (firstElement instanceof PsiLocalVariable) {
|
||||
variable = (PsiLocalVariable)firstElement;
|
||||
firstValue = variable.getInitializer();
|
||||
}
|
||||
if (firstValue == null || !(variable instanceof PsiLocalVariable) && !(variable instanceof PsiParameter)) return CANNOT_JOIN;
|
||||
|
||||
PsiExpressionStatement secondStatement = PsiTreeUtil.getParentOfType(psiFile.findElementAt(end), PsiExpressionStatement.class);
|
||||
PsiExpression secondValue = ExpressionUtils.getAssignmentTo(secondStatement, variable);
|
||||
if (!(secondValue instanceof PsiMethodCallExpression)) return CANNOT_JOIN;
|
||||
PsiExpression qualifier = ChainCallJoinLinesHandler.getDeepQualifier((PsiMethodCallExpression)secondValue);
|
||||
if (!ExpressionUtils.isReferenceTo(qualifier, variable)) return CANNOT_JOIN;
|
||||
if (ReferencesSearch.search(variable, new LocalSearchScope(secondValue)).findAll().size() > 1) return CANNOT_JOIN;
|
||||
qualifier.replace(firstValue);
|
||||
firstValue.replace(secondValue);
|
||||
secondStatement.delete();
|
||||
return firstElement.getTextRange().getEndOffset();
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
/**
|
||||
* <pre>{@code
|
||||
* sb.append(a);
|
||||
* sb.append(b);
|
||||
* =>
|
||||
* sb.append(a).append(b);
|
||||
* }</pre>
|
||||
*/
|
||||
public class ChainCallJoinLinesHandler implements JoinLinesHandlerDelegate {
|
||||
@Override
|
||||
public int tryJoinLines(@NotNull final Document document, @NotNull final PsiFile psiFile, final int start, final int end) {
|
||||
@@ -80,7 +88,7 @@ public class ChainCallJoinLinesHandler implements JoinLinesHandlerDelegate {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiExpression getDeepQualifier(PsiMethodCallExpression firstCall) {
|
||||
static PsiExpression getDeepQualifier(PsiMethodCallExpression firstCall) {
|
||||
PsiExpression firstQualifier = firstCall;
|
||||
while (firstQualifier instanceof PsiMethodCallExpression) {
|
||||
firstQualifier = ((PsiMethodCallExpression)firstQualifier).getMethodExpression().getQualifierExpression();
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
interface X {
|
||||
X getParent();
|
||||
}
|
||||
|
||||
void test(X x) {
|
||||
<caret>x = x.getParent();
|
||||
x = x.getParent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
interface X {
|
||||
X getParent();
|
||||
}
|
||||
|
||||
void test(X x) {
|
||||
x = x.getParent().getParent();<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
interface X {
|
||||
X getParent();
|
||||
}
|
||||
|
||||
void test(X x1, X x2, boolean b) {
|
||||
<caret>X x = b ? x1 : x2;
|
||||
x = x.getParent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Foo {
|
||||
interface X {
|
||||
X getParent();
|
||||
}
|
||||
|
||||
void test(X x1, X x2, boolean b) {
|
||||
X x = (b ? x1 : x2).getParent();<caret>
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,9 @@ public class JoinLinesTest extends LightCodeInsightTestCase {
|
||||
public void testDeclarationAndCallSelfRef() { doTest(); }
|
||||
public void testAssignmentAndCall() { doTest(); }
|
||||
|
||||
public void testDeclarationAndReassignmentWithCall() { doTest(); }
|
||||
public void testAssignmentAndReassignmentWithCall() { doTest(); }
|
||||
|
||||
public void testSCR3493() {
|
||||
CommonCodeStyleSettings settings = getJavaSettings();
|
||||
boolean use_tab_character = settings.getIndentOptions().USE_TAB_CHARACTER;
|
||||
|
||||
Reference in New Issue
Block a user