Prevent expression selector from selecting just a label
Previously, extract variable could act on e.g. 'break@outerLoop' and extract the label, leading into nonsensical 'val x = @outerLoop'. Prevent JetRefactoringUtil.selectExpression from returning label expressions to fix this. #KT-4515 Fixed
This commit is contained in:
committed by
Nikolay Krasko
parent
998d2c5ec8
commit
7a2321460d
@@ -1042,4 +1042,9 @@ public class JetPsiUtil {
|
|||||||
expression;
|
expression;
|
||||||
return (JetToken) elementType;
|
return (JetToken) elementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isLabelIdentifierExpression(PsiElement element) {
|
||||||
|
return element instanceof JetSimpleNameExpression &&
|
||||||
|
((JetSimpleNameExpression) element).getReferencedNameElementType() == JetTokens.LABEL_IDENTIFIER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetBlockExpression;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||||
@@ -35,7 +32,13 @@ public class CodeInsightUtils {
|
|||||||
else if (!(element instanceof JetExpression)) {
|
else if (!(element instanceof JetExpression)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else if (element instanceof JetBlockExpression) {
|
|
||||||
|
// For cases like 'this@outerClass', don't return the label part
|
||||||
|
if (JetPsiUtil.isLabelIdentifierExpression(element)) {
|
||||||
|
element = PsiTreeUtil.getParentOfType(element, JetExpression.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element instanceof JetBlockExpression) {
|
||||||
List<JetElement> statements = ((JetBlockExpression) element).getStatements();
|
List<JetElement> statements = ((JetBlockExpression) element).getStatements();
|
||||||
if (statements.size() == 1) {
|
if (statements.size() == 1) {
|
||||||
JetElement elem = statements.get(0);
|
JetElement elem = statements.get(0);
|
||||||
|
|||||||
@@ -405,7 +405,11 @@ public class JetRefactoringUtil {
|
|||||||
&& !(element instanceof JetClassBody)) {
|
&& !(element instanceof JetClassBody)) {
|
||||||
if (element instanceof JetExpression && !(element instanceof JetStatementExpression)) {
|
if (element instanceof JetExpression && !(element instanceof JetStatementExpression)) {
|
||||||
boolean addExpression = true;
|
boolean addExpression = true;
|
||||||
if (element.getParent() instanceof JetQualifiedExpression) {
|
|
||||||
|
if (JetPsiUtil.isLabelIdentifierExpression(element)) {
|
||||||
|
addExpression = false;
|
||||||
|
}
|
||||||
|
else if (element.getParent() instanceof JetQualifiedExpression) {
|
||||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) element.getParent();
|
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) element.getParent();
|
||||||
if (qualifiedExpression.getReceiverExpression() != element) {
|
if (qualifiedExpression.getReceiverExpression() != element) {
|
||||||
addExpression = false;
|
addExpression = false;
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun f() {
|
||||||
|
@loop while (true) {
|
||||||
|
break@lo<selection>o</selection>p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// KT-4515: Extract variable can attempt to extract a label from a labelled statement.
|
||||||
|
/* break@loop */
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class Foo() {
|
||||||
|
val s = this@F<selection>o</selection>o.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// KT-4515: Extract variable can attempt to extract a label from a labelled statement.
|
||||||
|
/* this@Foo */
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun f() {
|
||||||
|
@loop while (true) {
|
||||||
|
break@lo<caret>op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// KT-4515: Extract variable can attempt to extract a label from a labelled statement.
|
||||||
|
/* */
|
||||||
@@ -41,6 +41,16 @@ public class ExpressionSelectionTestGenerated extends AbstractExpressionSelectio
|
|||||||
doTestExpressionSelection("idea/testData/expressionSelection/binaryExpr.kt");
|
doTestExpressionSelection("idea/testData/expressionSelection/binaryExpr.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("labelledStatement.kt")
|
||||||
|
public void testLabelledStatement() throws Exception {
|
||||||
|
doTestExpressionSelection("idea/testData/expressionSelection/labelledStatement.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("labelledThis.kt")
|
||||||
|
public void testLabelledThis() throws Exception {
|
||||||
|
doTestExpressionSelection("idea/testData/expressionSelection/labelledThis.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noExpression.kt")
|
@TestMetadata("noExpression.kt")
|
||||||
public void testNoExpression() throws Exception {
|
public void testNoExpression() throws Exception {
|
||||||
doTestExpressionSelection("idea/testData/expressionSelection/noExpression.kt");
|
doTestExpressionSelection("idea/testData/expressionSelection/noExpression.kt");
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ public class SmartSelectionTestGenerated extends AbstractSmartSelectionTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/smartSelection"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/smartSelection"), Pattern.compile("^([^\\.]+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("labelledStatement.kt")
|
||||||
|
public void testLabelledStatement() throws Exception {
|
||||||
|
doTestSmartSelection("idea/testData/smartSelection/labelledStatement.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("labelledThis.kt")
|
@TestMetadata("labelledThis.kt")
|
||||||
public void testLabelledThis() throws Exception {
|
public void testLabelledThis() throws Exception {
|
||||||
doTestSmartSelection("idea/testData/smartSelection/labelledThis.kt");
|
doTestSmartSelection("idea/testData/smartSelection/labelledThis.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user