From 32a13502c59a4cb5a11c8d85bb4e27c6a372c956 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 21 Nov 2014 18:46:18 +0300 Subject: [PATCH] Fixed one of the cases with lambda's returning Nothing --- .../jet/lang/psi/psiUtil/jetPsiUtil.kt | 9 ++++- .../resolve/lazy/PartialBodyResolveFilter.kt | 40 +++++++++++++++---- ...hing2.kt.todo => LambdaReturnsNothing2.kt} | 0 .../PartialBodyResolveTestGenerated.java | 6 +++ 4 files changed, 46 insertions(+), 9 deletions(-) rename idea/testData/resolve/partialBodyResolve/{LambdaReturnsNothing2.kt.todo => LambdaReturnsNothing2.kt} (100%) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt b/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt index 9f01f471aec..38eb85f1414 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/psiUtil/jetPsiUtil.kt @@ -392,5 +392,10 @@ public fun Call.isSafeCall(): Boolean { public fun Call.isExplicitSafeCall(): Boolean = getCallOperationNode()?.getElementType() == JetTokens.SAFE_ACCESS -public fun JetTypeReference?.isProbablyNothing(): Boolean - = (this?.getTypeElement() as? JetUserType)?.getReferencedName() == "Nothing" \ No newline at end of file +public fun JetTypeReference?.isProbablyNothing(): Boolean { + val userType = this?.getTypeElement() as? JetUserType ?: return false + return userType.isProbablyNothing() +} + +public fun JetUserType?.isProbablyNothing(): Boolean + = this?.getReferencedName() == "Nothing" \ No newline at end of file diff --git a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt index 8b2ac0dcd4a..570b8a7bf91 100644 --- a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt +++ b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt @@ -25,10 +25,10 @@ import java.util.ArrayList import java.util.HashMap import com.intellij.psi.PsiElement import org.jetbrains.jet.JetNodeTypes -import org.jetbrains.jet.lang.psi.psiUtil.isProbablyNothing import org.jetbrains.jet.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.jet.lang.psi.psiUtil.isAncestor import org.jetbrains.jet.lang.resolve.PartialBodyResolveProvider +import org.jetbrains.jet.lang.psi.psiUtil.isProbablyNothing //TODO: do resolve anonymous object's body @@ -41,7 +41,7 @@ class PartialBodyResolveFilter( private val statementMarks = StatementMarks() private val nothingFunctionNames = HashSet(probablyNothingCallableNames.functionNames()) - private val nothingPropertyNames = probablyNothingCallableNames.propertyNames() + private val nothingVariableNames = HashSet(probablyNothingCallableNames.propertyNames()) override val filter: ((JetElement) -> Boolean)? = { it is JetExpression && statementMarks.statementMark(it) != MarkLevel.SKIP } @@ -51,11 +51,21 @@ class PartialBodyResolveFilter( "Should never be invoked on local declaration otherwise we may miss some local declarations with type Nothing") declaration.accept(object : JetVisitorVoid() { - override fun visitNamedFunction(function: JetNamedFunction) { - super.visitNamedFunction(function) + override fun visitDeclaration(declaration: JetDeclaration) { + super.visitDeclaration(declaration) - if (function.getTypeReference().isProbablyNothing()) { - nothingFunctionNames.add(function.getName()) + if (declaration is JetCallableDeclaration) { + if (declaration.getTypeReference().containsProbablyNothing()) { + val name = declaration.getName() + if (name != null) { + if (declaration is JetNamedFunction) { + nothingFunctionNames.add(name) + } + else { + nothingVariableNames.add(name) + } + } + } } } @@ -338,7 +348,7 @@ class PartialBodyResolveFilter( override fun visitSimpleNameExpression(expression: JetSimpleNameExpression) { val name = expression.getReferencedName() - if (name in nothingPropertyNames) { + if (name in nothingVariableNames) { result.add(expression) } } @@ -495,6 +505,22 @@ class PartialBodyResolveFilter( = getLastChild()?.siblings(forward = false)?.firstIsInstanceOrNull() private fun PsiElement.isStatement() = this is JetExpression && getParent() is JetBlockExpression + + private fun JetTypeReference?.containsProbablyNothing(): Boolean { + var result = false + this?.getTypeElement()?.accept(object : JetVisitorVoid() { + override fun visitJetElement(element: JetElement) { + element.acceptChildren(this) + } + + override fun visitUserType(type: JetUserType) { + if (type.isProbablyNothing()) { + result = true + } + } + }) + return result + } } private inner class StatementMarks { diff --git a/idea/testData/resolve/partialBodyResolve/LambdaReturnsNothing2.kt.todo b/idea/testData/resolve/partialBodyResolve/LambdaReturnsNothing2.kt similarity index 100% rename from idea/testData/resolve/partialBodyResolve/LambdaReturnsNothing2.kt.todo rename to idea/testData/resolve/partialBodyResolve/LambdaReturnsNothing2.kt diff --git a/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java b/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java index b9b061908d9..bf729ae55f5 100644 --- a/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java @@ -276,6 +276,12 @@ public class PartialBodyResolveTestGenerated extends AbstractPartialBodyResolveT doTest(fileName); } + @TestMetadata("LambdaReturnsNothing2.kt") + public void testLambdaReturnsNothing2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/LambdaReturnsNothing2.kt"); + doTest(fileName); + } + @TestMetadata("LocalClass.kt") public void testLocalClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/LocalClass.kt");