diff --git a/idea/ide-common/src/org/jetbrains/kotlin/util/TypeIndexUtil.kt b/idea/ide-common/src/org/jetbrains/kotlin/util/TypeIndexUtil.kt index a1d25800ce9..f898c92d868 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/util/TypeIndexUtil.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/util/TypeIndexUtil.kt @@ -18,12 +18,20 @@ package org.jetbrains.kotlin.util import com.google.common.collect.HashMultimap import com.google.common.collect.Multimap +import com.google.common.collect.Multimaps import com.intellij.openapi.util.Key import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetTypeReference import org.jetbrains.kotlin.psi.JetUserType +import org.jetbrains.kotlin.psi.stubs.getContainingFileStub -public fun JetFile.aliasImportMap(): Multimap { +public fun JetUserType.aliasImportMap(): Multimap { + // we need to access containing file via stub because getPsi() may return null when indexing and getContainingFile() will crash + val file = getStub()?.getContainingFileStub()?.getPsi() ?: return HashMultimap.create() + return (file as JetFile).aliasImportMap() +} + +private fun JetFile.aliasImportMap(): Multimap { val cached = getUserData(ALIAS_IMPORT_DATA_KEY) val modificationStamp = getModificationStamp() if (cached != null && modificationStamp == cached.fileModificationStamp) { @@ -55,6 +63,9 @@ public fun JetTypeReference?.isProbablyNothing(): Boolean { return userType.isProbablyNothing() } -public fun JetUserType?.isProbablyNothing(): Boolean - = this?.getReferencedName() == "Nothing" +public fun JetUserType?.isProbablyNothing(): Boolean { + if (this == null) return false + val referencedName = getReferencedName() + return referencedName == "Nothing" || aliasImportMap()[referencedName].contains("Nothing") +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IndexUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IndexUtils.kt index 9b37775a6a9..cb4bce61a7f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IndexUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IndexUtils.kt @@ -28,11 +28,11 @@ import org.jetbrains.kotlin.util.aliasImportMap fun indexTopLevelExtension(stub: KotlinCallableStubBase, sink: IndexSink) { if (stub.isExtension()) { val declaration = stub.getPsi() - declaration.getReceiverTypeReference()!!.getTypeElement()?.index(declaration, stub.getContainingFileStub().getPsi() != null, sink) + declaration.getReceiverTypeReference()!!.getTypeElement()?.index(declaration, sink) } } -private fun JetTypeElement.index(declaration: TDeclaration, hasFile: Boolean, sink: IndexSink) { +private fun JetTypeElement.index(declaration: TDeclaration, sink: IndexSink) { fun occurrence(typeName: String) { val name = declaration.getName() ?: return sink.occurrence(JetTopLevelExtensionsByReceiverTypeIndex.INSTANCE.getKey(), @@ -48,7 +48,7 @@ private fun JetTypeElement.index(declara if (typeParameter != null) { val bound = typeParameter.getExtendsBound() if (bound != null) { - bound.getTypeElement()?.index(declaration, hasFile, sink) + bound.getTypeElement()?.index(declaration, sink) return } occurrence("Any") @@ -58,13 +58,10 @@ private fun JetTypeElement.index(declara occurrence(referenceName) - if (hasFile) { - val aliasNames = declaration.getContainingJetFile().aliasImportMap()[referenceName] - aliasNames.forEach { occurrence(it) } - } + aliasImportMap()[referenceName].forEach { occurrence(it) } } - is JetNullableType -> getInnerType()?.index(declaration, hasFile, sink) + is JetNullableType -> getInnerType()?.index(declaration, sink) is JetFunctionType -> { val typeName = (if (getReceiverTypeReference() != null) "ExtensionFunction" else "Function") + getParameters().size() diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsMyErrorWithAliasImport.dump b/idea/testData/resolve/partialBodyResolve/IfNotIsMyErrorWithAliasImport.dump new file mode 100644 index 00000000000..124b67a91e1 --- /dev/null +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsMyErrorWithAliasImport.dump @@ -0,0 +1,12 @@ +Resolve target: value-parameter val p: kotlin.Any smart-cast to kotlin.String +---------------------------------------------- +import kotlin.Nothing as MyNothing + +fun myNothingFun(): MyNothing = throw Exception() + +fun foo(p: Any) { + if (p !is String) { + myNothingFun() + } + println(p.length()) +} diff --git a/idea/testData/resolve/partialBodyResolve/IfNotIsMyErrorWithAliasImport.kt b/idea/testData/resolve/partialBodyResolve/IfNotIsMyErrorWithAliasImport.kt new file mode 100644 index 00000000000..4c275c07592 --- /dev/null +++ b/idea/testData/resolve/partialBodyResolve/IfNotIsMyErrorWithAliasImport.kt @@ -0,0 +1,10 @@ +import kotlin.Nothing as MyNothing + +fun myNothingFun(): MyNothing = throw Exception() + +fun foo(p: Any) { + if (p !is String) { + myNothingFun() + } + println(p.length()) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/completion/MultiFileJvmBasicCompletionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/completion/MultiFileJvmBasicCompletionTestGenerated.java index 66ada716664..9cfecf9cf62 100644 --- a/idea/tests/org/jetbrains/kotlin/completion/MultiFileJvmBasicCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/completion/MultiFileJvmBasicCompletionTestGenerated.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.completion; import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.InnerTestClasses; import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; import org.jetbrains.kotlin.test.JetTestUtils; import org.jetbrains.kotlin.test.TestMetadata; diff --git a/idea/tests/org/jetbrains/kotlin/idea/resolve/PartialBodyResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/resolve/PartialBodyResolveTestGenerated.java index a1704942d29..e05f04bbaf0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/resolve/PartialBodyResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/resolve/PartialBodyResolveTestGenerated.java @@ -174,6 +174,12 @@ public class PartialBodyResolveTestGenerated extends AbstractPartialBodyResolveT doTest(fileName); } + @TestMetadata("IfNotIsMyErrorWithAliasImport.kt") + public void testIfNotIsMyErrorWithAliasImport() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/IfNotIsMyErrorWithAliasImport.kt"); + doTest(fileName); + } + @TestMetadata("IfNotIsNothingProp.kt") public void testIfNotIsNothingProp() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/IfNotIsNothingProp.kt");