From 901aa9c18bc4fcf75feb50878b88dfd7647ae599 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 24 Apr 2017 17:30:35 +0300 Subject: [PATCH] PsiBasedClassResolver: use ImpreciseResolveResult instead of Boolean? --- .../kotlin/asJava/ImpreciseResolveResult.kt | 29 +++++++++++++++++ .../idea/search/PsiBasedClassResolver.kt | 32 ++++++++++--------- .../KotlinAnnotatedElementsSearcher.kt | 6 ++-- .../idea/search/PsiBasedClassResolverTest.kt | 4 ++- 4 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 compiler/light-classes/src/org/jetbrains/kotlin/asJava/ImpreciseResolveResult.kt diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/ImpreciseResolveResult.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/ImpreciseResolveResult.kt new file mode 100644 index 00000000000..35fd70c3ed5 --- /dev/null +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/ImpreciseResolveResult.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.asJava + +enum class ImpreciseResolveResult { + MATCH, + NO_MATCH, + UNSURE; + + inline fun ifSure(body: (Boolean) -> Unit) = when (this) { + MATCH -> body(true) + NO_MATCH -> body(false) + UNSURE -> Unit + } +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt index be6849d69e9..98377554335 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt @@ -21,6 +21,8 @@ import com.intellij.psi.PsiModifier import com.intellij.psi.search.PsiShortNamesCache import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.analyzer.LanguageSettingsProvider +import org.jetbrains.kotlin.asJava.ImpreciseResolveResult +import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.* import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.caches.resolve.getNullableModuleInfo import org.jetbrains.kotlin.idea.project.TargetPlatformDetector @@ -123,22 +125,22 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: * @return true if it will definitely resolve to that class, false if it will definitely resolve to something else, * null if full resolve is required to answer that question. */ - fun canBeTargetReference(ref: KtSimpleNameExpression): Boolean? { + fun canBeTargetReference(ref: KtSimpleNameExpression): ImpreciseResolveResult { attempts.incrementAndGet() // The names can be different if the target was imported via an import alias if (ref.getReferencedName() != targetShortName) { - return null + return UNSURE } // Names in expressions can conflict with local declarations and methods of implicit receivers, // so we can't find out what they refer to without a full resolve. - val userType = ref.getStrictParentOfType() ?: return null + val userType = ref.getStrictParentOfType() ?: return UNSURE if (forceAmbiguityForNonAnnotations && userType.getParentOfTypeAndBranch { typeReference } == null) { - return null + return UNSURE } if (forceAmbiguity) { - return null + return UNSURE } val qualifiedCheckResult = checkQualifiedReferenceToTarget(ref) @@ -156,23 +158,23 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: result = result.changeTo(Result.FoundOther) } else if (filePackage in packagesWithTypeAliases) { - return null + return UNSURE } for (importPath in file.getDefaultImports()) { result = analyzeSingleImport(result, importPath.fqName, importPath.isAllUnder, importPath.alias?.asString()) - if (result == Result.Ambiguity) return null + if (result == Result.Ambiguity) return UNSURE } for (importDirective in file.importDirectives) { result = analyzeSingleImport(result, importDirective.importedFqName, importDirective.isAllUnder, importDirective.aliasName) - if (result == Result.Ambiguity) return null + if (result == Result.Ambiguity) return UNSURE } - if (result.returnValue == true) { + if (result.returnValue == MATCH) { trueHits.incrementAndGet() } - else if (result.returnValue == false) { + else if (result.returnValue == NO_MATCH) { falseHits.incrementAndGet() } return result.returnValue @@ -225,11 +227,11 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: return null } - enum class Result(val returnValue: Boolean?) { - NothingFound(false), - Found(true), - FoundOther(false), - Ambiguity(null) + enum class Result(val returnValue: ImpreciseResolveResult) { + NothingFound(NO_MATCH), + Found(MATCH), + FoundOther(NO_MATCH), + Ambiguity(UNSURE) } fun Result.changeTo(newResult: Result): Result { diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt index 91d92a31441..57c35168e4b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt @@ -28,6 +28,8 @@ import com.intellij.psi.util.PsiUtilCore import com.intellij.util.Processor import com.intellij.util.QueryExecutor import com.intellij.util.indexing.FileBasedIndex +import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.NO_MATCH +import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.UNSURE import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.idea.caches.resolve.analyze @@ -94,8 +96,8 @@ class KotlinAnnotatedElementsSearcher : QueryExecutor(false)!! - return resolver.canBeTargetReference(ref) + val canBeTargetReference = resolver.canBeTargetReference(ref) + canBeTargetReference.ifSure { return it } + return null } }