From 2dcc38b92ffdf691efddb956404955109fa26f7e Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 26 Nov 2015 18:17:24 +0300 Subject: [PATCH] Create from Usage: Forbid "Create parameter/local variable/property" on label references #KT-10119 Fixed --- .../CreateCallableFromCallActionFactory.kt | 2 +- .../CreateLocalVariableActionFactory.kt | 6 ++-- .../CreateParameterByRefActionFactory.kt | 6 ++-- .../autoImports/infixCall2.before.Main.kt | 4 --- .../localVariable/inBinaryOperation.kt | 7 ++++ .../localVariable/inLabelRef.kt | 5 +++ .../parameter/inBinaryOperation.kt | 7 ++++ .../createVariable/parameter/inLabelRef.kt | 5 +++ .../property/inBinaryOperation.kt | 7 ++++ .../createVariable/property/inLabelRef.kt | 5 +++ .../idea/quickfix/QuickFixTestGenerated.java | 36 +++++++++++++++++++ 11 files changed, 77 insertions(+), 13 deletions(-) create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/localVariable/inBinaryOperation.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/localVariable/inLabelRef.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/parameter/inBinaryOperation.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/parameter/inLabelRef.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/property/inBinaryOperation.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/property/inLabelRef.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt index 547abb5485b..d80a3f8c72c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromCallActionFactory.kt @@ -129,7 +129,7 @@ sealed class CreateCallableFromCallActionFactory( object Property: CreateCallableFromCallActionFactory() { override fun getElementOfInterest(diagnostic: Diagnostic): KtSimpleNameExpression? { - return getExpressionOfInterest(diagnostic) as? KtSimpleNameExpression + return getExpressionOfInterest(diagnostic) as? KtNameReferenceExpression } override fun doCreateCallableInfo( diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateLocalVariableActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateLocalVariableActionFactory.kt index 2c98cbbe0c7..d789ddb17f4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateLocalVariableActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateLocalVariableActionFactory.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory import org.jetbrains.kotlin.idea.quickfix.createFromUsage.CreateFromUsageFixBase import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.kotlin.idea.util.application.executeCommand -import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement @@ -38,9 +37,8 @@ import java.util.* object CreateLocalVariableActionFactory: KotlinSingleIntentionActionFactory() { override fun createAction(diagnostic: Diagnostic): IntentionAction? { - val refExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass()) ?: return null + val refExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass()) ?: return null if (refExpr.getQualifiedElement() != refExpr) return null - if (refExpr.getReferencedNameElementType() != KtTokens.IDENTIFIER) return null val propertyName = refExpr.getReferencedName() @@ -54,7 +52,7 @@ object CreateLocalVariableActionFactory: KotlinSingleIntentionActionFactory() { override fun invoke(project: Project, editor: Editor?, file: KtFile) { val assignment = refExpr.getAssignmentByLHS() val varExpected = assignment != null - var originalElement = assignment ?: refExpr + var originalElement: KtExpression = assignment ?: refExpr val actualContainer = when (container) { is KtBlockExpression -> container diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt index f08b31cf0e9..6eb4fde5bb3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createVariable/CreateParameterByRefActionFactory.kt @@ -24,15 +24,14 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade -import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getExpressionForTypeGuess import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getTypeParameters import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.guessTypes import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinParameterInfo import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar +import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement @@ -47,9 +46,8 @@ import java.util.* object CreateParameterByRefActionFactory : CreateParameterFromUsageFactory() { override fun getElementOfInterest(diagnostic: Diagnostic): KtSimpleNameExpression? { - val refExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass()) ?: return null + val refExpr = QuickFixUtil.getParentElementOfType(diagnostic, javaClass()) ?: return null if (refExpr.getQualifiedElement() != refExpr) return null - if (refExpr.getReferencedNameElementType() != KtTokens.IDENTIFIER) return null return refExpr } diff --git a/idea/testData/quickfix/autoImports/infixCall2.before.Main.kt b/idea/testData/quickfix/autoImports/infixCall2.before.Main.kt index 9ad455c6b24..167b5beb8c8 100644 --- a/idea/testData/quickfix/autoImports/infixCall2.before.Main.kt +++ b/idea/testData/quickfix/autoImports/infixCall2.before.Main.kt @@ -1,11 +1,7 @@ // "Import" "false" // ERROR: Unresolved reference: foo // ACTION: Create extension function 'foo' -// ACTION: Create extension property 'foo' -// ACTION: Create local variable 'foo' // ACTION: Create member function 'foo' -// ACTION: Create member property 'foo' -// ACTION: Create parameter 'foo' // ACTION: Replace infix call with ordinary call package h diff --git a/idea/testData/quickfix/createFromUsage/createVariable/localVariable/inBinaryOperation.kt b/idea/testData/quickfix/createFromUsage/createVariable/localVariable/inBinaryOperation.kt new file mode 100644 index 00000000000..d3e4bc27f6b --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/localVariable/inBinaryOperation.kt @@ -0,0 +1,7 @@ +// "Create local variable 'foo'" "false" +// ERROR: Unresolved reference: foo +// ACTION: Create extension function 'foo' +// ACTION: Replace infix call with ordinary call +fun refer() { + 1 foo 2 +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/localVariable/inLabelRef.kt b/idea/testData/quickfix/createFromUsage/createVariable/localVariable/inLabelRef.kt new file mode 100644 index 00000000000..164de8685cf --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/localVariable/inLabelRef.kt @@ -0,0 +1,5 @@ +// "Create local variable 'foo'" "false" +// ERROR: Unresolved reference: @foo +fun refer() { + val v = this@foo +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inBinaryOperation.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inBinaryOperation.kt new file mode 100644 index 00000000000..8c8e9890fb3 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inBinaryOperation.kt @@ -0,0 +1,7 @@ +// "Create parameter 'foo'" "false" +// ERROR: Unresolved reference: foo +// ACTION: Create extension function 'foo' +// ACTION: Replace infix call with ordinary call +fun refer() { + 1 foo 2 +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inLabelRef.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inLabelRef.kt new file mode 100644 index 00000000000..5a58097aabc --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inLabelRef.kt @@ -0,0 +1,5 @@ +// "Create parameter 'foo'" "false" +// ERROR: Unresolved reference: @foo +fun refer() { + val v = this@foo +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/inBinaryOperation.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/inBinaryOperation.kt new file mode 100644 index 00000000000..417f0795498 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/property/inBinaryOperation.kt @@ -0,0 +1,7 @@ +// "Create property 'foo'" "false" +// ERROR: Unresolved reference: foo +// ACTION: Create extension function 'foo' +// ACTION: Replace infix call with ordinary call +fun refer() { + 1 foo 2 +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/inLabelRef.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/inLabelRef.kt new file mode 100644 index 00000000000..733acdd550f --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/property/inLabelRef.kt @@ -0,0 +1,5 @@ +// "Create property 'foo'" "false" +// ERROR: Unresolved reference: @foo +fun refer() { + val v = this@foo +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 69ccef7f092..adc52b014bc 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -2558,6 +2558,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("inBinaryOperation.kt") + public void testInBinaryOperation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/localVariable/inBinaryOperation.kt"); + doTest(fileName); + } + @TestMetadata("inClass.kt") public void testInClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/localVariable/inClass.kt"); @@ -2576,6 +2582,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("inLabelRef.kt") + public void testInLabelRef() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/localVariable/inLabelRef.kt"); + doTest(fileName); + } + @TestMetadata("inLambdaNoParams.kt") public void testInLambdaNoParams() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/localVariable/inLambdaNoParams.kt"); @@ -2723,6 +2735,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("inBinaryOperation.kt") + public void testInBinaryOperation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/inBinaryOperation.kt"); + doTest(fileName); + } + @TestMetadata("inClassInitializer.kt") public void testInClassInitializer() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/inClassInitializer.kt"); @@ -2777,6 +2795,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("inLabelRef.kt") + public void testInLabelRef() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/inLabelRef.kt"); + doTest(fileName); + } + @TestMetadata("inLambdaNoParams.kt") public void testInLambdaNoParams() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/parameter/inLambdaNoParams.kt"); @@ -3041,6 +3065,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("inBinaryOperation.kt") + public void testInBinaryOperation() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/inBinaryOperation.kt"); + doTest(fileName); + } + + @TestMetadata("inLabelRef.kt") + public void testInLabelRef() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/inLabelRef.kt"); + doTest(fileName); + } + @TestMetadata("inconsistentTypes.kt") public void testInconsistentTypes() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/inconsistentTypes.kt");