From 41d51e0a13241fb4e492e66d815e53587d67b9d2 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 19 Feb 2015 14:33:44 +0300 Subject: [PATCH] Create from usage: Assume String return type for function whch is called inside of string template #KT-6083 Fixed --- .../callableBuilder/typeUtils.kt | 15 ++++-------- .../call/afterCallInStringTemplateRuntime.kt | 9 +++++++ ...terQualifiedCallInStringTemplateRuntime.kt | 11 +++++++++ .../call/beforeCallInStringTemplateRuntime.kt | 5 ++++ ...oreQualifiedCallInStringTemplateRuntime.kt | 7 ++++++ ...fterQualifiedRefInStringTemplateRuntime.kt | 10 ++++++++ .../afterRefInStringTemplateRuntime.kt | 8 +++++++ ...foreQualifiedRefInStringTemplateRuntime.kt | 8 +++++++ .../beforeRefInStringTemplateRuntime.kt | 6 +++++ .../idea/quickfix/QuickFixTestGenerated.java | 24 +++++++++++++++++++ 10 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 idea/testData/quickfix/createFromUsage/createFunction/call/afterCallInStringTemplateRuntime.kt create mode 100644 idea/testData/quickfix/createFromUsage/createFunction/call/afterQualifiedCallInStringTemplateRuntime.kt create mode 100644 idea/testData/quickfix/createFromUsage/createFunction/call/beforeCallInStringTemplateRuntime.kt create mode 100644 idea/testData/quickfix/createFromUsage/createFunction/call/beforeQualifiedCallInStringTemplateRuntime.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/property/afterQualifiedRefInStringTemplateRuntime.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/property/afterRefInStringTemplateRuntime.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/property/beforeQualifiedRefInStringTemplateRuntime.kt create mode 100644 idea/testData/quickfix/createFromUsage/createVariable/property/beforeRefInStringTemplateRuntime.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt index 46e861a4a23..52fe9664130 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/callableBuilder/typeUtils.kt @@ -22,13 +22,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.scopes.JetScope import java.util.LinkedHashSet -import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.psi.JetTypeConstraint -import org.jetbrains.kotlin.psi.JetMultiDeclarationEntry -import org.jetbrains.kotlin.psi.JetParameter -import org.jetbrains.kotlin.psi.JetVariableDeclaration -import org.jetbrains.kotlin.psi.JetNamedDeclaration import com.intellij.refactoring.psi.SearchUtils import org.jetbrains.kotlin.idea.references.JetSimpleNameReference import java.util.HashSet @@ -41,16 +35,14 @@ import org.jetbrains.kotlin.types.JetTypeImpl import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.psi.JetDeclaration -import org.jetbrains.kotlin.psi.JetPropertyDelegate -import org.jetbrains.kotlin.psi.JetProperty import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.idea.util.makeNotNullable -import org.jetbrains.kotlin.psi.JetAnnotationEntry import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.calls.callUtil.* private fun JetType.contains(inner: JetType): Boolean { return JetTypeChecker.DEFAULT.equalTypes(this, inner) || getArguments().any { inner in it.getType() } @@ -183,6 +175,9 @@ fun JetExpression.guessTypes( val typeArguments = listOf(TypeProjectionImpl(receiverType), TypeProjectionImpl(property.getType())) array(TypeUtils.substituteProjectionsForParameters(delegateClass, typeArguments)) } + parent is JetStringTemplateEntryWithExpression && parent.getExpression() == this -> { + array(KotlinBuiltIns.getInstance().getStringType()) + } else -> array() // can't infer anything } } diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/afterCallInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/afterCallInStringTemplateRuntime.kt new file mode 100644 index 00000000000..6eb12097eda --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createFunction/call/afterCallInStringTemplateRuntime.kt @@ -0,0 +1,9 @@ +// "Create function 'foo'" "true" + +fun test() { + println("a = ${foo()}") +} + +fun foo(): String { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. +} diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/afterQualifiedCallInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/afterQualifiedCallInStringTemplateRuntime.kt new file mode 100644 index 00000000000..7bd1880e985 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createFunction/call/afterQualifiedCallInStringTemplateRuntime.kt @@ -0,0 +1,11 @@ +// "Create function 'foo'" "true" + +class A { + fun foo(): String { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} + +fun test() { + println("a = ${A().foo()}") +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/beforeCallInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/beforeCallInStringTemplateRuntime.kt new file mode 100644 index 00000000000..8863a1faf91 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createFunction/call/beforeCallInStringTemplateRuntime.kt @@ -0,0 +1,5 @@ +// "Create function 'foo'" "true" + +fun test() { + println("a = ${foo()}") +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/beforeQualifiedCallInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/beforeQualifiedCallInStringTemplateRuntime.kt new file mode 100644 index 00000000000..c5dab6979b9 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createFunction/call/beforeQualifiedCallInStringTemplateRuntime.kt @@ -0,0 +1,7 @@ +// "Create function 'foo'" "true" + +class A + +fun test() { + println("a = ${A().foo()}") +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/afterQualifiedRefInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/afterQualifiedRefInStringTemplateRuntime.kt new file mode 100644 index 00000000000..5fcacbeb245 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/property/afterQualifiedRefInStringTemplateRuntime.kt @@ -0,0 +1,10 @@ +// "Create property 'foo'" "true" +// ERROR: Property must be initialized or be abstract + +class A { + val foo: String +} + +fun test() { + println("a = ${A().foo}") +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/afterRefInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/afterRefInStringTemplateRuntime.kt new file mode 100644 index 00000000000..1158b7fcb98 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/property/afterRefInStringTemplateRuntime.kt @@ -0,0 +1,8 @@ +// "Create property 'foo'" "true" +// ERROR: Property must be initialized + +fun test() { + println("a = $foo") +} + +val foo: String diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/beforeQualifiedRefInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/beforeQualifiedRefInStringTemplateRuntime.kt new file mode 100644 index 00000000000..21e4a3063be --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/property/beforeQualifiedRefInStringTemplateRuntime.kt @@ -0,0 +1,8 @@ +// "Create property 'foo'" "true" +// ERROR: Property must be initialized or be abstract + +class A + +fun test() { + println("a = ${A().foo}") +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/beforeRefInStringTemplateRuntime.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/beforeRefInStringTemplateRuntime.kt new file mode 100644 index 00000000000..2821cff4a66 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createVariable/property/beforeRefInStringTemplateRuntime.kt @@ -0,0 +1,6 @@ +// "Create property 'foo'" "true" +// ERROR: Property must be initialized + +fun test() { + println("a = $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 b2b640823e3..05e35d8ef71 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -1522,6 +1522,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("beforeCallInStringTemplateRuntime.kt") + public void testCallInStringTemplateRuntime() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeCallInStringTemplateRuntime.kt"); + doTest(fileName); + } + @TestMetadata("beforeCallWithLambdaArg.kt") public void testCallWithLambdaArg() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeCallWithLambdaArg.kt"); @@ -1690,6 +1696,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("beforeQualifiedCallInStringTemplateRuntime.kt") + public void testQualifiedCallInStringTemplateRuntime() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeQualifiedCallInStringTemplateRuntime.kt"); + doTest(fileName); + } + @TestMetadata("beforeThisInClass.kt") public void testThisInClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeThisInClass.kt"); @@ -2549,6 +2561,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("beforeQualifiedRefInStringTemplateRuntime.kt") + public void testQualifiedRefInStringTemplateRuntime() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeQualifiedRefInStringTemplateRuntime.kt"); + doTest(fileName); + } + + @TestMetadata("beforeRefInStringTemplateRuntime.kt") + public void testRefInStringTemplateRuntime() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeRefInStringTemplateRuntime.kt"); + doTest(fileName); + } + @TestMetadata("beforeThisInClass.kt") public void testThisInClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/beforeThisInClass.kt");