PsiBasedClassResolver: use ImpreciseResolveResult instead of Boolean?
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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<KtUserType>() ?: return null
|
||||
val userType = ref.getStrictParentOfType<KtUserType>() ?: return UNSURE
|
||||
if (forceAmbiguityForNonAnnotations && userType.getParentOfTypeAndBranch<KtAnnotationEntry> { 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 {
|
||||
|
||||
+4
-2
@@ -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<PsiModifierListOwner, Anno
|
||||
psiBasedClassResolver.canBeTargetReference(ref)
|
||||
}
|
||||
|
||||
if (psiBasedResolveResult == false) return true
|
||||
if (psiBasedResolveResult == null) {
|
||||
if (psiBasedResolveResult == NO_MATCH) return true
|
||||
if (psiBasedResolveResult == UNSURE) {
|
||||
val context = elt.analyze(BodyResolveMode.PARTIAL)
|
||||
val annotationDescriptor = context.get(BindingContext.ANNOTATION, elt) ?: return true
|
||||
|
||||
|
||||
@@ -108,6 +108,8 @@ class PsiBasedClassResolverTest : KotlinLightCodeInsightFixtureTestCaseBase() {
|
||||
fileText) as KtFile
|
||||
val index = fileText.indexOf(marker)
|
||||
val ref = file.findElementAt(index + marker.indexOf("Test"))!!.getParentOfType<KtSimpleNameExpression>(false)!!
|
||||
return resolver.canBeTargetReference(ref)
|
||||
val canBeTargetReference = resolver.canBeTargetReference(ref)
|
||||
canBeTargetReference.ifSure { return it }
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user