From cd90ab951ffe3b062f1504fbedcea11cbeaa5495 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 20 Nov 2014 13:35:49 +0300 Subject: [PATCH] Partial body resolve tests: more informative test output --- .../jetbrains/jet/lang/psi/JetPsiFactory.kt | 9 +++++ .../partialBodyResolve/AnonymousObjects.dump | 24 +++++++++++- .../resolve/partialBodyResolve/As.dump | 25 ++++++++++--- .../resolve/partialBodyResolve/BangBang.dump | 23 ++++++++++-- .../BangBangInIfCondition.dump | 10 ++++- .../DeclarationsBefore.dump | 24 +++++++++--- .../resolve/partialBodyResolve/DoWhile.dump | 9 ++++- .../resolve/partialBodyResolve/For.dump | 12 +++++- .../IfBranchesAutoCasts.dump | 8 +++- .../IfBranchesAutoCasts2.dump | 16 ++++++-- .../IfBranchesSmartCast.dump | 11 +++++- .../partialBodyResolve/IfEqAutoCast.dump | 6 ++- .../partialBodyResolve/IfNotIsError.dump | 8 +++- .../IfNotIsErrorQualifier.dump | 8 +++- .../IfNotIsErrorVariable.dump | 8 +++- .../partialBodyResolve/IfNotIsMyError.dump | 10 ++++- .../IfNotIsNothingProp.dump | 11 +++++- .../partialBodyResolve/IfNotIsReturn.dump | 15 +++++++- .../partialBodyResolve/IfNotIsReturn2.dump | 8 +++- .../partialBodyResolve/IfNotIsThrow.dump | 8 +++- .../IfNotNullElseReturn.dump | 12 +++++- .../partialBodyResolve/IfNotNullReturn.dump | 3 -- .../partialBodyResolve/IfNullBreak.dump | 11 +++++- .../IfNullConditionalReturn.dump | 13 ++++++- .../IfNullConditionalReturnWithElse.dump | 13 ++++++- .../partialBodyResolve/IfNullContinue.dump | 11 +++++- .../IfNullDoWhileWithBreak.dump | 14 ++++++- .../partialBodyResolve/IfNullElvisReturn.dump | 13 ++++++- .../IfNullForWithReturn.dump | 12 +++++- .../partialBodyResolve/IfNullPrint.dump | 7 +++- .../partialBodyResolve/IfNullReturn.dump | 10 ++++- .../IfNullWhileTrueWithBreak.dump | 14 ++++++- .../IfNullWhileWithReturn.dump | 13 ++++++- .../resolve/partialBodyResolve/IfReturn.dump | 7 +++- .../InIfExpressionElse.dump | 8 +++- .../resolve/partialBodyResolve/Lambda.dump | 11 +++++- .../LambdaInCurrentStatement.dump | 16 +++++++- .../partialBodyResolve/LocalClass.dump | 13 ++++++- .../resolve/partialBodyResolve/LocalFun.dump | 14 +++++-- .../partialBodyResolve/LocalNothingFun.dump | 12 +++++- .../partialBodyResolve/ReturnLambda.dump | 12 +++++- .../resolve/partialBodyResolve/Simple.dump | 11 ++++-- .../SmartCastPointsResolveRequired1.dump | 2 - .../SmartCastPointsResolveRequired2.dump | 2 - .../ThisQualifiedAutoCast.dump | 14 ++++++- .../resolve/partialBodyResolve/While.dump | 12 +++++- .../resolve/partialBodyResolve/WhileTrue.dump | 13 ++++++- .../WhileTrueCondition.dump | 12 +++++- .../resolve/AbstractPartialBodyResolveTest.kt | 37 ++++++++++++++----- 49 files changed, 495 insertions(+), 100 deletions(-) delete mode 100644 idea/testData/resolve/partialBodyResolve/IfNotNullReturn.dump delete mode 100644 idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired1.dump delete mode 100644 idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired2.dump diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt index 3b231f6a5b4..60cbd6c9464 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.kt @@ -30,6 +30,7 @@ import com.intellij.openapi.util.Key import java.io.PrintWriter import java.io.StringWriter import com.intellij.openapi.application.ApplicationManager +import com.intellij.psi.PsiComment public fun JetPsiFactory(project: Project?): JetPsiFactory = JetPsiFactory(project!!) public fun JetPsiFactory(contextElement: JetElement): JetPsiFactory = JetPsiFactory(contextElement.getProject()) @@ -632,6 +633,14 @@ public class JetPsiFactory(private val project: Project) { return createClass("class foo { class object { } }").getClassObject()!! } + public fun createComment(text: String): PsiComment { + val file = createFile(text) + val comments = file.getChildren().filterIsInstance() + val comment = comments.single() + assert(comment.getText() == text) + return comment + } + public fun wrapInABlock(expression: JetExpression): JetBlockExpression { if (expression is JetBlockExpression) { return expression as JetBlockExpression diff --git a/idea/testData/resolve/partialBodyResolve/AnonymousObjects.dump b/idea/testData/resolve/partialBodyResolve/AnonymousObjects.dump index 8671dde7711..3a760160652 100644 --- a/idea/testData/resolve/partialBodyResolve/AnonymousObjects.dump +++ b/idea/testData/resolve/partialBodyResolve/AnonymousObjects.dump @@ -1,2 +1,24 @@ Resolve target: value-parameter val p: kotlin.String? -Skipped statements: +---------------------------------------------- +open class C(p: Int) { + open fun f(){} +} + +fun foo(p: String?) { + val o = object : Runnable { + override fun run() { + if (p == null) return + print(p.size) + } + } + + val c = object : C(p!!.size) { + override fun f() { + super.f() + if (p == null) return + print(p.size) + } + } + + p?.size +} diff --git a/idea/testData/resolve/partialBodyResolve/As.dump b/idea/testData/resolve/partialBodyResolve/As.dump index fdd812621c6..c4a613d7c49 100644 --- a/idea/testData/resolve/partialBodyResolve/As.dump +++ b/idea/testData/resolve/partialBodyResolve/As.dump @@ -1,6 +1,21 @@ Resolve target: value-parameter val p: kotlin.Any smart-cast to kotlin.String -Skipped statements: -y(p as? Int) -z(f() as String) -p1 as String -z(p1 as String) +---------------------------------------------- +fun foo(p: Any, p1: Any?) { + x(e.f as String) + // STATEMENT DELETED: y(p as? Int) + // STATEMENT DELETED: z(f() as String) + + if (a) { + print((p as String).size) + } + else { + print((p as String).length) + } + + if (y()) { + print(p.size) + // STATEMENT DELETED: p1 as String + } + + // STATEMENT DELETED: z(p1 as String) +} diff --git a/idea/testData/resolve/partialBodyResolve/BangBang.dump b/idea/testData/resolve/partialBodyResolve/BangBang.dump index b2c613dec24..ac9570246bb 100644 --- a/idea/testData/resolve/partialBodyResolve/BangBang.dump +++ b/idea/testData/resolve/partialBodyResolve/BangBang.dump @@ -1,5 +1,20 @@ Resolve target: value-parameter val p: kotlin.String? smart-cast to kotlin.String -Skipped statements: -y(f()!!) -p1!! -z(p1!!) +---------------------------------------------- +fun foo(p: String?, p1: Any?) { + x(e.f!!) + // STATEMENT DELETED: y(f()!!) + + if (a) { + print(p!!.size) + } + else { + print(p!!.length) + } + + if (y()) { + print(p.size) + // STATEMENT DELETED: p1!! + } + + // STATEMENT DELETED: z(p1!!) +} diff --git a/idea/testData/resolve/partialBodyResolve/BangBangInIfCondition.dump b/idea/testData/resolve/partialBodyResolve/BangBangInIfCondition.dump index 6c209b341c8..c94acd4428a 100644 --- a/idea/testData/resolve/partialBodyResolve/BangBangInIfCondition.dump +++ b/idea/testData/resolve/partialBodyResolve/BangBangInIfCondition.dump @@ -1,3 +1,9 @@ Resolve target: value-parameter val p: kotlin.Boolean? smart-cast to kotlin.Boolean -Skipped statements: -print(p1!!.hashCode()) +---------------------------------------------- +fun foo(p: Boolean?, p1: Any?) { + if (p!!) { + // STATEMENT DELETED: print(p1!!.hashCode()) + } + + p.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/DeclarationsBefore.dump b/idea/testData/resolve/partialBodyResolve/DeclarationsBefore.dump index 22d45c28ccd..9569e371dcf 100644 --- a/idea/testData/resolve/partialBodyResolve/DeclarationsBefore.dump +++ b/idea/testData/resolve/partialBodyResolve/DeclarationsBefore.dump @@ -1,6 +1,20 @@ Resolve target: val v2: kotlin.Int -Skipped statements: -x() -run { val v2 = 1 println(v2) } -run { val v2 = 2 println(v2) } -z() +---------------------------------------------- +fun foo(p: Int) { + // STATEMENT DELETED: x() + + val v1 = p * p + + if (y()) { + val v2 = v1 * v1 + val v3 = v1 * v2 + + // STATEMENT DELETED: run { val v2 = 1 println(v2) } + + print(v2) + + // STATEMENT DELETED: run { val v2 = 2 println(v2) } + } + + // STATEMENT DELETED: z() +} diff --git a/idea/testData/resolve/partialBodyResolve/DoWhile.dump b/idea/testData/resolve/partialBodyResolve/DoWhile.dump index 323136d3498..6bdbf4205ea 100644 --- a/idea/testData/resolve/partialBodyResolve/DoWhile.dump +++ b/idea/testData/resolve/partialBodyResolve/DoWhile.dump @@ -1,2 +1,9 @@ Resolve target: value-parameter val p: kotlin.Any? -Skipped statements: +---------------------------------------------- +fun foo(p: Any?) { + do { + print(p!!) + } while (x()) + + p.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/For.dump b/idea/testData/resolve/partialBodyResolve/For.dump index 99904c51d02..f3338c65083 100644 --- a/idea/testData/resolve/partialBodyResolve/For.dump +++ b/idea/testData/resolve/partialBodyResolve/For.dump @@ -1,3 +1,11 @@ Resolve target: value-parameter val p: kotlin.Any? smart-cast to kotlin.String -Skipped statements: -print(p1!!) +---------------------------------------------- +fun x(s: String): Collection{} + +fun foo(p: Any?, p1: Any?) { + for (e in x(p as String)) { + // STATEMENT DELETED: print(p1!!) + } + + p.size +} diff --git a/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts.dump b/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts.dump index 9cf67c238a6..c96c893b3a6 100644 --- a/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts.dump +++ b/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts.dump @@ -1,3 +1,7 @@ Resolve target: null -Skipped statements: -if (x()) { y(p!!) } else { z(p1!!) } +---------------------------------------------- +fun foo(p: Any?, p1, Any?) { + // STATEMENT DELETED: if (x()) { y(p!!) } else { z(p1!!) } + + xxx +} diff --git a/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts2.dump b/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts2.dump index 186e30a76f2..1ad1b06e8c5 100644 --- a/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts2.dump +++ b/idea/testData/resolve/partialBodyResolve/IfBranchesAutoCasts2.dump @@ -1,4 +1,14 @@ Resolve target: value-parameter val p1: kotlin.Any? smart-cast to kotlin.Any -Skipped statements: -print(p!!) -print(p2!!) +---------------------------------------------- +fun foo(p: Any?, p1: Any?, p2: Any?) { + if (x()) { + // STATEMENT DELETED: print(p!!) + print(p1!!) + } + else { + print(p1 as String) + // STATEMENT DELETED: print(p2!!) + } + + p1.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/IfBranchesSmartCast.dump b/idea/testData/resolve/partialBodyResolve/IfBranchesSmartCast.dump index c4977876c04..8033cbf26a0 100644 --- a/idea/testData/resolve/partialBodyResolve/IfBranchesSmartCast.dump +++ b/idea/testData/resolve/partialBodyResolve/IfBranchesSmartCast.dump @@ -1,2 +1,11 @@ Resolve target: value-parameter val o: kotlin.Any? smart-cast to kotlin.Any -Skipped statements: +---------------------------------------------- +fun foo(o: Any?, p: Int) { + if (p > 0) { + if (o == null) return + } + else { + if (o !is String) return + } + o.javaClass +} diff --git a/idea/testData/resolve/partialBodyResolve/IfEqAutoCast.dump b/idea/testData/resolve/partialBodyResolve/IfEqAutoCast.dump index a37c92224ef..7327f2deb38 100644 --- a/idea/testData/resolve/partialBodyResolve/IfEqAutoCast.dump +++ b/idea/testData/resolve/partialBodyResolve/IfEqAutoCast.dump @@ -1,2 +1,6 @@ Resolve target: value-parameter val o: kotlin.String? smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +fun foo(o: String?, o1: String) { + if (o != o1) return + o.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsError.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsError.dump index 7d7ee5e312e..ba49c6647ef 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsError.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsError.dump @@ -1,2 +1,8 @@ Resolve target: value-parameter val p: kotlin.Any smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +fun foo(p: Any) { + if (p !is String) { + error("Not String") + } + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsErrorQualifier.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsErrorQualifier.dump index 7d7ee5e312e..a6a9b62ff92 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsErrorQualifier.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsErrorQualifier.dump @@ -1,2 +1,8 @@ Resolve target: value-parameter val p: kotlin.Any smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +fun foo(p: Any) { + if (p !is String) { + kotlin.error("Not String") + } + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsErrorVariable.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsErrorVariable.dump index fe169a3d4ae..c6124d7fffc 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsErrorVariable.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsErrorVariable.dump @@ -1,3 +1,7 @@ Resolve target: value-parameter val p: kotlin.Any -Skipped statements: -if (p !is String) { print(error) } +---------------------------------------------- +val error = "error" +fun foo(p: Any) { + // STATEMENT DELETED: if (p !is String) { print(error) } + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsMyError.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsMyError.dump index 7d7ee5e312e..1ad1d46ed2a 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsMyError.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsMyError.dump @@ -1,2 +1,10 @@ Resolve target: value-parameter val p: kotlin.Any smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +fun myError(): Nothing = throw Exception() + +fun foo(p: Any) { + if (p !is String) { + myError() + } + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsNothingProp.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsNothingProp.dump index 7d7ee5e312e..3d985ae0dee 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsNothingProp.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsNothingProp.dump @@ -1,2 +1,11 @@ Resolve target: value-parameter val p: kotlin.Any smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +val prop: Nothing + get() = throw Exception() + +fun foo(p: Any) { + if (p !is String) { + prop + } + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsReturn.dump index acb6ca6aaec..f4d78504bd9 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsReturn.dump @@ -1,3 +1,14 @@ Resolve target: value-parameter val p: kotlin.Any? smart-cast to kotlin.String -Skipped statements: -print("null") +---------------------------------------------- +fun foo(p: Any?) { + if (p !is String) { + if (p == null) { + // STATEMENT DELETED: print("null") + return + } + else { + return + } + } + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsReturn2.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsReturn2.dump index 8abf86f91c1..b9a6f7fe8b1 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsReturn2.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsReturn2.dump @@ -1,2 +1,8 @@ Resolve target: val v: kotlin.Any smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +class C(public val v: Any) + +fun foo(c: C) { + if (c.v !is String) return + println(c.v.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsThrow.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsThrow.dump index 7d7ee5e312e..da7718bb19c 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotIsThrow.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsThrow.dump @@ -1,2 +1,8 @@ Resolve target: value-parameter val p: kotlin.Any smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +fun foo(p: Any) { + if (p !is String) { + throw IllegalArgumentException() + } + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotNullElseReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNotNullElseReturn.dump index c551bd13abb..7d34a722ca4 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNotNullElseReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNotNullElseReturn.dump @@ -1,3 +1,11 @@ Resolve target: value-parameter val p: kotlin.Any? smart-cast to kotlin.Any -Skipped statements: -print("not null") +---------------------------------------------- +fun foo(p: Any?) { + if (p != null) { + // STATEMENT DELETED: print("not null") + } + else { + return + } + p.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotNullReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNotNullReturn.dump deleted file mode 100644 index e643a6f675e..00000000000 --- a/idea/testData/resolve/partialBodyResolve/IfNotNullReturn.dump +++ /dev/null @@ -1,3 +0,0 @@ -Resolve target: value-parameter val p: kotlin.Any? -Skipped statements: -if (p != null) return diff --git a/idea/testData/resolve/partialBodyResolve/IfNullBreak.dump b/idea/testData/resolve/partialBodyResolve/IfNullBreak.dump index 19278dac234..f5a14bdf0e0 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullBreak.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullBreak.dump @@ -1,2 +1,11 @@ Resolve target: val x: kotlin.Any? smart-cast to kotlin.Any -Skipped statements: +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + if (x == null) break + x.hashCode() + } +} + +fun take(): Any? = null diff --git a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.dump index db31922fc1f..f7911d55fb7 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.dump @@ -1,3 +1,12 @@ Resolve target: val x: kotlin.Any? -Skipped statements: -if (x == null) { print(1) if (f()) return } +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + // STATEMENT DELETED: if (x == null) { print(1) if (f()) return } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): Boolean{} diff --git a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.dump b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.dump index 11dc1a74351..3e045a378e4 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.dump @@ -1,3 +1,12 @@ Resolve target: val x: kotlin.Any? -Skipped statements: -if (x == null) { print(1) if (f()) { return } else { print(2) } } +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + // STATEMENT DELETED: if (x == null) { print(1) if (f()) { return } else { print(2) } } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): Boolean{} diff --git a/idea/testData/resolve/partialBodyResolve/IfNullContinue.dump b/idea/testData/resolve/partialBodyResolve/IfNullContinue.dump index 19278dac234..bb300aad493 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullContinue.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullContinue.dump @@ -1,2 +1,11 @@ Resolve target: val x: kotlin.Any? smart-cast to kotlin.Any -Skipped statements: +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + if (x == null) continue + x.hashCode() + } +} + +fun take(): Any? = null diff --git a/idea/testData/resolve/partialBodyResolve/IfNullDoWhileWithBreak.dump b/idea/testData/resolve/partialBodyResolve/IfNullDoWhileWithBreak.dump index 857da46776b..29f218dcfc1 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullDoWhileWithBreak.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullDoWhileWithBreak.dump @@ -1,3 +1,13 @@ Resolve target: val x: kotlin.Any? -Skipped statements: -if (x == null) { do { if (g()) break } while (f()) } +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + // STATEMENT DELETED: if (x == null) { do { if (g()) break } while (f()) } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): Boolean{} +fun g(): Boolean{} diff --git a/idea/testData/resolve/partialBodyResolve/IfNullElvisReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNullElvisReturn.dump index cf4bb52c28f..8cbadefe522 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullElvisReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullElvisReturn.dump @@ -1,3 +1,12 @@ Resolve target: val x: kotlin.Any? -Skipped statements: -if (x == null) { print(1) val v = f() ?: return } +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + // STATEMENT DELETED: if (x == null) { print(1) val v = f() ?: return } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): String? = null diff --git a/idea/testData/resolve/partialBodyResolve/IfNullForWithReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNullForWithReturn.dump index 7fea88635b5..bbd380c6a34 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullForWithReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullForWithReturn.dump @@ -1,3 +1,11 @@ Resolve target: val x: kotlin.Any? -Skipped statements: -if (x == null) { for (s in c) { print(s) return } } +---------------------------------------------- +fun foo(c: Collection) { + for (i in 1..10) { + val x = take() + // STATEMENT DELETED: if (x == null) { for (s in c) { print(s) return } } + x.hashCode() + } +} + +fun take(): Any? = null diff --git a/idea/testData/resolve/partialBodyResolve/IfNullPrint.dump b/idea/testData/resolve/partialBodyResolve/IfNullPrint.dump index 1598d70e5ce..41fb42795ab 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullPrint.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullPrint.dump @@ -1,3 +1,6 @@ Resolve target: value-parameter val p: kotlin.Any? -Skipped statements: -if (p == null) { print("null") } +---------------------------------------------- +fun foo(p: Any?) { + // STATEMENT DELETED: if (p == null) { print("null") } + p.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNullReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNullReturn.dump index e0a888b2395..b3b72159c2a 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullReturn.dump @@ -1,3 +1,9 @@ Resolve target: value-parameter val p: kotlin.Any? smart-cast to kotlin.Any -Skipped statements: -print("null") +---------------------------------------------- +fun foo(p: Any?) { + if (p == null) { + // STATEMENT DELETED: print("null") + return + } + p.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNullWhileTrueWithBreak.dump b/idea/testData/resolve/partialBodyResolve/IfNullWhileTrueWithBreak.dump index 75cc53db0b1..e68558d0348 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullWhileTrueWithBreak.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullWhileTrueWithBreak.dump @@ -1,3 +1,13 @@ Resolve target: val x: kotlin.Any? -Skipped statements: -if (x == null) { while (true) { if (g()) break } } +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + // STATEMENT DELETED: if (x == null) { while (true) { if (g()) break } } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): Boolean{} +fun g(): Boolean{} diff --git a/idea/testData/resolve/partialBodyResolve/IfNullWhileWithReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNullWhileWithReturn.dump index 53f9f180604..1ed9f5d2450 100644 --- a/idea/testData/resolve/partialBodyResolve/IfNullWhileWithReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfNullWhileWithReturn.dump @@ -1,3 +1,12 @@ Resolve target: val x: kotlin.Any? -Skipped statements: -if (x == null) { while (f()) { print(1) return } } +---------------------------------------------- +fun foo() { + for (i in 1..10) { + val x = take() + // STATEMENT DELETED: if (x == null) { while (f()) { print(1) return } } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): Boolean{} diff --git a/idea/testData/resolve/partialBodyResolve/IfReturn.dump b/idea/testData/resolve/partialBodyResolve/IfReturn.dump index b146f1d642a..49c51c7423d 100644 --- a/idea/testData/resolve/partialBodyResolve/IfReturn.dump +++ b/idea/testData/resolve/partialBodyResolve/IfReturn.dump @@ -1,3 +1,6 @@ Resolve target: val kotlin.String.size: kotlin.Int -Skipped statements: -if (x()) return +---------------------------------------------- +fun foo(p: String) { + // STATEMENT DELETED: if (x()) return + println(p.size) +} diff --git a/idea/testData/resolve/partialBodyResolve/InIfExpressionElse.dump b/idea/testData/resolve/partialBodyResolve/InIfExpressionElse.dump index dda141ad7a4..105bf20a56b 100644 --- a/idea/testData/resolve/partialBodyResolve/InIfExpressionElse.dump +++ b/idea/testData/resolve/partialBodyResolve/InIfExpressionElse.dump @@ -1,2 +1,8 @@ Resolve target: null -Skipped statements: +---------------------------------------------- +fun foo(s: String){} +fun foo(c: Char){} + +fun bar(b: Boolean, s: String, c: Char){ + foo(if (b) "abc" else xxx) +} diff --git a/idea/testData/resolve/partialBodyResolve/Lambda.dump b/idea/testData/resolve/partialBodyResolve/Lambda.dump index 9fd7087886f..880ea0ec156 100644 --- a/idea/testData/resolve/partialBodyResolve/Lambda.dump +++ b/idea/testData/resolve/partialBodyResolve/Lambda.dump @@ -1,3 +1,10 @@ Resolve target: fun f(): kotlin.Unit -Skipped statements: -x() +---------------------------------------------- +class C { + fun f(){} +} + +fun foo() { + val lambda = {() -> // STATEMENT DELETED: x(); C() } + lambda().f() +} diff --git a/idea/testData/resolve/partialBodyResolve/LambdaInCurrentStatement.dump b/idea/testData/resolve/partialBodyResolve/LambdaInCurrentStatement.dump index ef3ee2540c5..7ecbdfc17f6 100644 --- a/idea/testData/resolve/partialBodyResolve/LambdaInCurrentStatement.dump +++ b/idea/testData/resolve/partialBodyResolve/LambdaInCurrentStatement.dump @@ -1,3 +1,15 @@ Resolve target: value-parameter val c: kotlin.Collection -Skipped statements: -println() +---------------------------------------------- +fun foo(c: Collection): Collection { + return c.filter { + val v = it.length + val v1 = v * v + if (v1 > 10) { + true + } + else { + // STATEMENT DELETED: println() + it[0] == 'a' + } + } +} diff --git a/idea/testData/resolve/partialBodyResolve/LocalClass.dump b/idea/testData/resolve/partialBodyResolve/LocalClass.dump index 8671dde7711..6e965e2a888 100644 --- a/idea/testData/resolve/partialBodyResolve/LocalClass.dump +++ b/idea/testData/resolve/partialBodyResolve/LocalClass.dump @@ -1,2 +1,13 @@ Resolve target: value-parameter val p: kotlin.String? -Skipped statements: +---------------------------------------------- +fun foo(p: String?) { + class LocalClass { + fun f(): String? { + if (p == null) return null + print(p.size) + return "" + } + } + + p?.size +} diff --git a/idea/testData/resolve/partialBodyResolve/LocalFun.dump b/idea/testData/resolve/partialBodyResolve/LocalFun.dump index f938531de0f..310f8e19e51 100644 --- a/idea/testData/resolve/partialBodyResolve/LocalFun.dump +++ b/idea/testData/resolve/partialBodyResolve/LocalFun.dump @@ -1,5 +1,11 @@ Resolve target: value-parameter val p: kotlin.String? -Skipped statements: -if (p == null) return null -print(p.size) -return "" +---------------------------------------------- +fun foo(p: String?) { + fun local(): String? { + // STATEMENT DELETED: if (p == null) return null + // STATEMENT DELETED: print(p.size) + // STATEMENT DELETED: return "" + } + + p?.size +} diff --git a/idea/testData/resolve/partialBodyResolve/LocalNothingFun.dump b/idea/testData/resolve/partialBodyResolve/LocalNothingFun.dump index 01a452af78c..6742455fe37 100644 --- a/idea/testData/resolve/partialBodyResolve/LocalNothingFun.dump +++ b/idea/testData/resolve/partialBodyResolve/LocalNothingFun.dump @@ -1,2 +1,12 @@ Resolve target: value-parameter val p: kotlin.String? smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +fun foo(p: String?, p1: Any?) { + if (p1 == null) return + + fun localError(): Nothing = throw Exception() + + if (p == null) { + localError() + } + p.size +} diff --git a/idea/testData/resolve/partialBodyResolve/ReturnLambda.dump b/idea/testData/resolve/partialBodyResolve/ReturnLambda.dump index 5457feb8002..0663bc0b1f5 100644 --- a/idea/testData/resolve/partialBodyResolve/ReturnLambda.dump +++ b/idea/testData/resolve/partialBodyResolve/ReturnLambda.dump @@ -1,3 +1,11 @@ Resolve target: value-parameter val p: kotlin.String? smart-cast to kotlin.String -Skipped statements: -println() +---------------------------------------------- +fun foo(p: String?): () -> String { + if (p == null) { + return { + // STATEMENT DELETED: println() + "a" + } + } + p.size +} diff --git a/idea/testData/resolve/partialBodyResolve/Simple.dump b/idea/testData/resolve/partialBodyResolve/Simple.dump index 345025d0377..1f073d2b72a 100644 --- a/idea/testData/resolve/partialBodyResolve/Simple.dump +++ b/idea/testData/resolve/partialBodyResolve/Simple.dump @@ -1,4 +1,9 @@ Resolve target: value-parameter val p: kotlin.Int -Skipped statements: -x() -z() +---------------------------------------------- +fun foo(p: Int) { + // STATEMENT DELETED: x() + if (y()) { + print(p) + } + // STATEMENT DELETED: z() +} diff --git a/idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired1.dump b/idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired1.dump deleted file mode 100644 index 890fa034495..00000000000 --- a/idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired1.dump +++ /dev/null @@ -1,2 +0,0 @@ -Resolve target: value-parameter val x: kotlin.Any? -Skipped statements: diff --git a/idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired2.dump b/idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired2.dump deleted file mode 100644 index 890fa034495..00000000000 --- a/idea/testData/resolve/partialBodyResolve/SmartCastPointsResolveRequired2.dump +++ /dev/null @@ -1,2 +0,0 @@ -Resolve target: value-parameter val x: kotlin.Any? -Skipped statements: diff --git a/idea/testData/resolve/partialBodyResolve/ThisQualifiedAutoCast.dump b/idea/testData/resolve/partialBodyResolve/ThisQualifiedAutoCast.dump index d26b0ecf3ab..407b656da39 100644 --- a/idea/testData/resolve/partialBodyResolve/ThisQualifiedAutoCast.dump +++ b/idea/testData/resolve/partialBodyResolve/ThisQualifiedAutoCast.dump @@ -1,2 +1,14 @@ Resolve target: val s: kotlin.String? smart-cast to kotlin.String -Skipped statements: +---------------------------------------------- +class C(val s: String?) { + fun foo(p: Boolean) { + if (p) { + print(s!!) + } + else { + print(this.s!!) + } + + s.size + } +} diff --git a/idea/testData/resolve/partialBodyResolve/While.dump b/idea/testData/resolve/partialBodyResolve/While.dump index b0cb7570bfb..d997927147f 100644 --- a/idea/testData/resolve/partialBodyResolve/While.dump +++ b/idea/testData/resolve/partialBodyResolve/While.dump @@ -1,3 +1,11 @@ Resolve target: value-parameter val p: kotlin.Any? smart-cast to kotlin.Any -Skipped statements: -print(p1!!) +---------------------------------------------- +fun x(s: Any): Boolean{} + +fun foo(p: Any?, p1: Any?) { + while(x(p!!)) { + // STATEMENT DELETED: print(p1!!) + } + + p.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/WhileTrue.dump b/idea/testData/resolve/partialBodyResolve/WhileTrue.dump index e4526bb71de..c7793acd373 100644 --- a/idea/testData/resolve/partialBodyResolve/WhileTrue.dump +++ b/idea/testData/resolve/partialBodyResolve/WhileTrue.dump @@ -1,3 +1,12 @@ Resolve target: value-parameter val p: kotlin.Any? -Skipped statements: -if (x()) break +---------------------------------------------- +fun x(): Boolean{} + +fun foo(p: Any?) { + while(true) { + print(p!!) + // STATEMENT DELETED: if (x()) break + } + + p.hashCode() +} diff --git a/idea/testData/resolve/partialBodyResolve/WhileTrueCondition.dump b/idea/testData/resolve/partialBodyResolve/WhileTrueCondition.dump index f23bae1b0a4..fab457d3ae6 100644 --- a/idea/testData/resolve/partialBodyResolve/WhileTrueCondition.dump +++ b/idea/testData/resolve/partialBodyResolve/WhileTrueCondition.dump @@ -1,3 +1,11 @@ Resolve target: value-parameter val p: kotlin.Any? -Skipped statements: -while(2 * 2 == 4) { print(p!!) if (x()) break } +---------------------------------------------- +// this test will fail if control flow analysis will start to produce smart-casts after "while(2 * 2 == 4)" + +fun x(): Boolean{} + +fun foo(p: Any?) { + // STATEMENT DELETED: while(2 * 2 == 4) { print(p!!) if (x()) break } + + p.hashCode() +} diff --git a/idea/tests/org/jetbrains/jet/resolve/AbstractPartialBodyResolveTest.kt b/idea/tests/org/jetbrains/jet/resolve/AbstractPartialBodyResolveTest.kt index 7d7b5c985d5..2480e3af927 100644 --- a/idea/tests/org/jetbrains/jet/resolve/AbstractPartialBodyResolveTest.kt +++ b/idea/tests/org/jetbrains/jet/resolve/AbstractPartialBodyResolveTest.kt @@ -36,6 +36,9 @@ import org.jetbrains.jet.lang.psi.JetSimpleNameExpression import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression import org.jetbrains.jet.plugin.caches.resolve.getResolutionFacade import org.jetbrains.jet.lang.psi.psiUtil.parents +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.command.CommandProcessor +import org.jetbrains.jet.lang.psi.JetPsiFactory public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtureTestCase() { override fun getTestDataPath() = JetTestCaseBuilder.getHomeDirectory() @@ -45,7 +48,8 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur myFixture.configureByFile(testPath) val file = myFixture.getFile() as JetFile - val offset = myFixture.getEditor().getCaretModel().getOffset() + val editor = myFixture.getEditor() + val offset = editor.getCaretModel().getOffset() val element = file.findElementAt(offset) val refExpression = element.getParentByType(javaClass()) ?: error("No JetSimpleNameExpression at caret") @@ -63,16 +67,31 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur val builder = StringBuilder() builder.append("Resolve target: ${target2.presentation(type2)}\n") - builder.append("Skipped statements:\n") - set.sortBy { it.getTextOffset() }.forEach { - if (!it.parents(withItself = false).any { it in set }) { // do not dump skipped statements which are inside other skipped statement - builder append it.presentation() append "\n" - } - } + builder.append("----------------------------------------------\n") + + val skippedStatements = set + .filter { !it.parents(withItself = false).any { it in set } } // do not include skipped statements which are inside other skipped statement + .sortBy { it.getTextOffset() } + + CommandProcessor.getInstance().executeCommand( + { + ApplicationManager.getApplication().runWriteAction { + for (statement in skippedStatements) { + statement.replace(JetPsiFactory(getProject()).createComment("// STATEMENT DELETED: ${statement.compactPresentation()}")) + } + } + }, + "", + null + ) + val fileText = file.getText() + val newCaretOffset = editor.getCaretModel().getOffset() + builder.append(fileText.substring(0, newCaretOffset)) + builder.append("") + builder.append(fileText.substring(newCaretOffset)) JetTestUtils.assertEqualsToFile(File(testPath.substringBeforeLast('.') + ".dump"), builder.toString()) - //TODO: discuss that descriptors are different Assert.assertEquals(target2.presentation(type2), target1.presentation(type1)) } @@ -112,7 +131,7 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur return s + " smart-cast to " + if (type != null) DescriptorRenderer.COMPACT.renderType(type) else "unknown type" } - private fun JetExpression.presentation(): String { + private fun JetExpression.compactPresentation(): String { val text = getText() val builder = StringBuilder() var dropSpace = false