mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] KTIJ-7870 prefer subtypes of sealed classes in as and is operation completions
^KTIJ-7870 fixed GitOrigin-RevId: 4a63559fc0ce79ac6c54a49f896e97ac1928137b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3b716e2453
commit
50795e0f46
+20
-2
@@ -10,14 +10,17 @@ import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import com.intellij.psi.createSmartPointer
|
||||
import com.intellij.psi.search.searches.DirectClassInheritorsSearch
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.concurrency.annotations.RequiresReadLock
|
||||
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
|
||||
import org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.components.KaScopeWithKind
|
||||
import org.jetbrains.kotlin.analysis.api.components.ShortenCommand
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.symbol
|
||||
import org.jetbrains.kotlin.idea.base.psi.replaced
|
||||
import org.jetbrains.kotlin.idea.completion.KotlinFirCompletionParameters
|
||||
import org.jetbrains.kotlin.idea.completion.contributors.helpers.CompletionSymbolOrigin
|
||||
@@ -40,6 +43,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.sequences.emptySequence
|
||||
|
||||
internal open class FirClassifierCompletionContributor(
|
||||
parameters: KotlinFirCompletionParameters,
|
||||
@@ -134,8 +138,22 @@ internal open class FirClassifierCompletionContributor(
|
||||
context: WeighingContext,
|
||||
): Sequence<LookupElementBuilder> {
|
||||
val availableFromScope = mutableSetOf<KaClassifierSymbol>()
|
||||
val scopeClassifiers = context.scopeContext!!
|
||||
.scopes
|
||||
val scopesToCheck = context.scopeContext!!.scopes.toMutableList()
|
||||
|
||||
context.preferredSubtype?.symbol?.let { preferredSubtypeSymbol ->
|
||||
preferredSubtypeSymbol.staticScope?.let {
|
||||
if (!scopesToCheck.contains(it)) {
|
||||
scopesToCheck.add(it)
|
||||
}
|
||||
}
|
||||
preferredSubtypeSymbol.containingSymbol?.staticScope?.let {
|
||||
if (!scopesToCheck.contains(it)) {
|
||||
scopesToCheck.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val scopeClassifiers = scopesToCheck
|
||||
.asSequence()
|
||||
.flatMap { it.getAvailableClassifiers(positionContext, scopeNameFilter, visibilityChecker) }
|
||||
.filter { filterClassifiers(it.symbol) }
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.completion.impl.k2.weighers
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementWeigher
|
||||
import com.intellij.openapi.util.Key
|
||||
import org.jetbrains.kotlin.analysis.api.KaSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KaClassLikeSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbol
|
||||
import org.jetbrains.kotlin.idea.completion.weighers.WeighingContext
|
||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||
|
||||
internal object PreferredSubtypeWeigher {
|
||||
private const val WEIGHER_ID = "kotlin.preferredSubtype"
|
||||
|
||||
private enum class Weight {
|
||||
PREFERRED_SUBTYPE,
|
||||
PREFERRED_EXACT_TYPE, // In this weigher we prefer subtypes over the exact type
|
||||
UNRELATED
|
||||
}
|
||||
|
||||
context(KaSession)
|
||||
fun addWeight(context: WeighingContext, lookupElement: LookupElement, symbol: KaSymbol) {
|
||||
val actualClassType = (symbol as? KaClassLikeSymbol)?.defaultType ?: return
|
||||
val preferredSubtype = context.preferredSubtype ?: return
|
||||
lookupElement.hasPreferredSubtype = if (actualClassType.semanticallyEquals(preferredSubtype)) {
|
||||
Weight.PREFERRED_EXACT_TYPE
|
||||
} else if (!actualClassType.isNothingType && actualClassType.isSubtypeOf(preferredSubtype)) {
|
||||
Weight.PREFERRED_SUBTYPE
|
||||
} else {
|
||||
Weight.UNRELATED
|
||||
}
|
||||
}
|
||||
|
||||
private var LookupElement.hasPreferredSubtype: Weight? by UserDataProperty(Key("KOTLIN_HAS_PREFERRED_SUBTYPE"))
|
||||
|
||||
object Weigher : LookupElementWeigher(WEIGHER_ID) {
|
||||
override fun weigh(element: LookupElement): Comparable<*> = element.hasPreferredSubtype ?: Weight.UNRELATED
|
||||
}
|
||||
}
|
||||
+46
-3
@@ -16,7 +16,9 @@ import org.jetbrains.kotlin.analysis.api.resolution.KaAnnotationCall
|
||||
import org.jetbrains.kotlin.analysis.api.resolution.successfulCallOrNull
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KaCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbolModality
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaNamedSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaErrorType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KaTypeNullability
|
||||
@@ -32,6 +34,7 @@ import org.jetbrains.kotlin.idea.completion.contributors.helpers.CompletionSymbo
|
||||
import org.jetbrains.kotlin.idea.completion.contributors.helpers.KtSymbolWithOrigin
|
||||
import org.jetbrains.kotlin.idea.completion.impl.k2.context.getOriginalDeclarationOrSelf
|
||||
import org.jetbrains.kotlin.idea.completion.impl.k2.weighers.K2SoftDeprecationWeigher
|
||||
import org.jetbrains.kotlin.idea.completion.impl.k2.weighers.PreferredSubtypeWeigher
|
||||
import org.jetbrains.kotlin.idea.completion.impl.k2.weighers.TrailingLambdaParameterNameWeigher
|
||||
import org.jetbrains.kotlin.idea.completion.impl.k2.weighers.TrailingLambdaWeigher
|
||||
import org.jetbrains.kotlin.idea.completion.implCommon.weighers.PreferKotlinClassesWeigher
|
||||
@@ -52,6 +55,7 @@ internal class WeighingContext private constructor(
|
||||
private val myScopeContext: KaScopeContext?,
|
||||
private val myExpectedType: KaType?,
|
||||
private val myActualReceiverTypes: List<List<KaType>>,
|
||||
private val myPreferredSubtype: KaClassType?,
|
||||
val contextualSymbolsCache: ContextualSymbolsCache,
|
||||
val importableFqNameClassifier: ImportableFqNameClassifier,
|
||||
private val mySymbolsToSkip: Set<KaSymbol>,
|
||||
@@ -62,6 +66,7 @@ internal class WeighingContext private constructor(
|
||||
*/
|
||||
class ContextualSymbolsCache(private val symbolsContainingPosition: Map<Name, List<KaCallableSymbol>>) {
|
||||
private val contextualOverriddenSymbols: MutableMap<Name, Set<KaCallableSymbol>> = mutableMapOf()
|
||||
|
||||
context(KaSession)
|
||||
fun symbolIsPresentInContext(symbol: KaCallableSymbol): Boolean = withValidityAssertion {
|
||||
if (symbol !is KaNamedSymbol) return false
|
||||
@@ -88,6 +93,12 @@ internal class WeighingContext private constructor(
|
||||
myExpectedType
|
||||
}
|
||||
|
||||
val preferredSubtype: KaClassType?
|
||||
get() = withValidityAssertion {
|
||||
myPreferredSubtype
|
||||
}
|
||||
|
||||
|
||||
val actualReceiverTypes: List<List<KaType>>
|
||||
get() = withValidityAssertion { myActualReceiverTypes }
|
||||
|
||||
@@ -110,8 +121,9 @@ internal class WeighingContext private constructor(
|
||||
elementInCompletionFile: PsiElement,
|
||||
scopeContext: KaScopeContext? = null,
|
||||
expectedType: KaType? = null,
|
||||
preferredSubtype: KaClassType? = null,
|
||||
actualReceiverTypes: List<List<KaType>> = emptyList(),
|
||||
symbolsToSkip: Set<KaSymbol> = emptySet(),
|
||||
symbolsToSkip: Set<KaSymbol> = emptySet()
|
||||
): WeighingContext {
|
||||
val completionFile = parameters.completionFile
|
||||
val defaultImportPaths = completionFile.getDefaultImportPaths(useSiteModule = parameters.useSiteModule).toSet()
|
||||
@@ -128,11 +140,20 @@ internal class WeighingContext private constructor(
|
||||
originalFile = parameters.originalFile,
|
||||
)
|
||||
),
|
||||
myPreferredSubtype = preferredSubtype,
|
||||
importableFqNameClassifier = ImportableFqNameClassifier(completionFile) { defaultImportPaths.hasImport(it) },
|
||||
mySymbolsToSkip = symbolsToSkip,
|
||||
)
|
||||
}
|
||||
|
||||
// For `is` and `as` operations we want to prefer sealed inheritors
|
||||
context(KaSession)
|
||||
fun KtExpression.getPreferredSealedType(): KaClassType? {
|
||||
val comparisonType = expressionType as? KaClassType ?: return null
|
||||
if (comparisonType.symbol.modality != KaSymbolModality.SEALED) return null
|
||||
return comparisonType
|
||||
}
|
||||
|
||||
context(KaSession)
|
||||
fun create(
|
||||
parameters: KotlinFirCompletionParameters,
|
||||
@@ -152,6 +173,25 @@ internal class WeighingContext private constructor(
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun KtBinaryExpressionWithTypeRHS.isAsOrSafeAs(): Boolean {
|
||||
val operationElementType = operationReference.getReferencedNameElementType()
|
||||
return operationElementType == KtTokens.AS_KEYWORD || operationElementType == KtTokens.AS_SAFE
|
||||
}
|
||||
|
||||
val preferredSubtype = when (positionContext) {
|
||||
is KotlinTypeNameReferencePositionContext -> {
|
||||
val typeReferenceOwner = positionContext.typeReference?.parent
|
||||
val leftHandExpression = when {
|
||||
typeReferenceOwner is KtIsExpression -> typeReferenceOwner.leftHandSide
|
||||
typeReferenceOwner is KtBinaryExpressionWithTypeRHS && typeReferenceOwner.isAsOrSafeAs() -> typeReferenceOwner.left
|
||||
else -> null
|
||||
}
|
||||
leftHandExpression?.getPreferredSealedType()
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
val symbolToSkip = when (positionContext) {
|
||||
is KotlinWithSubjectEntryPositionContext -> (positionContext.subjectExpression as? KtSimpleNameExpression)
|
||||
?.mainReference
|
||||
@@ -174,11 +214,12 @@ internal class WeighingContext private constructor(
|
||||
elementInCompletionFile = positionContext.position,
|
||||
scopeContext = scopeContext,
|
||||
expectedType = expectedType,
|
||||
preferredSubtype = preferredSubtype,
|
||||
actualReceiverTypes = CallableMetadataProvider.calculateActualReceiverTypes(
|
||||
explicitReceiver = positionContext.explicitReceiver,
|
||||
implicitReceivers = ::implicitReceivers,
|
||||
),
|
||||
symbolsToSkip = setOfNotNull(symbolToSkip),
|
||||
symbolsToSkip = setOfNotNull(symbolToSkip)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -275,13 +316,14 @@ internal object Weighers {
|
||||
NotImportedWeigher.addWeight(context, lookupElement, symbol, availableWithoutImport)
|
||||
ClassifierWeigher.addWeight(lookupElement, symbol, symbolWithOrigin.origin)
|
||||
VariableOrFunctionWeigher.addWeight(lookupElement, symbol)
|
||||
PreferredSubtypeWeigher.addWeight(context, lookupElement, symbol)
|
||||
|
||||
if (symbol !is KaCallableSymbol) return@also
|
||||
|
||||
K2SoftDeprecationWeigher.addWeight(lookupElement, symbol, context.languageVersionSettings)
|
||||
|
||||
PreferContextualCallablesWeigher.addWeight(lookupElement, symbol, context.contextualSymbolsCache)
|
||||
PreferFewerParametersWeigher. addWeight(lookupElement, symbol)
|
||||
PreferFewerParametersWeigher.addWeight(lookupElement, symbol)
|
||||
}
|
||||
|
||||
fun CompletionSorter.applyWeighers(positionContext: KotlinRawPositionContext): CompletionSorter =
|
||||
@@ -292,6 +334,7 @@ internal object Weighers {
|
||||
ExpectedTypeWeigher.Weigher,
|
||||
DeprecatedWeigher.Weigher,
|
||||
PriorityWeigher.Weigher,
|
||||
PreferredSubtypeWeigher.Weigher,
|
||||
PreferGetSetMethodsToPropertyWeigher.Weigher,
|
||||
NotImportedWeigher.Weigher,
|
||||
KindWeigher.Weigher,
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// IGNORE_K1
|
||||
class A1
|
||||
class Z1
|
||||
sealed class Foo
|
||||
class A2
|
||||
class Z2
|
||||
class Bar: Foo()
|
||||
class Baz: Foo()
|
||||
class A3
|
||||
class Z3
|
||||
|
||||
|
||||
fun f(foo: Foo) {
|
||||
val t = foo as <caret>
|
||||
}
|
||||
|
||||
// WITH_ORDER
|
||||
// EXIST: Bar
|
||||
// EXIST: Baz
|
||||
// EXIST: Foo
|
||||
// EXIST: A1
|
||||
// EXIST: A2
|
||||
// EXIST: A3
|
||||
// EXIST: Z1
|
||||
// EXIST: Z2
|
||||
// EXIST: Z3
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// IGNORE_K1
|
||||
class A1
|
||||
class Z1
|
||||
sealed class Foo
|
||||
class A2
|
||||
class Z2
|
||||
class Bar: Foo()
|
||||
class Baz: Foo()
|
||||
class A3
|
||||
class Z3
|
||||
|
||||
|
||||
fun f(foo: Foo) {
|
||||
if (foo is <caret>) {}
|
||||
}
|
||||
|
||||
// WITH_ORDER
|
||||
// EXIST: Bar
|
||||
// EXIST: Baz
|
||||
// EXIST: Foo
|
||||
// EXIST: A1
|
||||
// EXIST: A2
|
||||
// EXIST: A3
|
||||
// EXIST: Z1
|
||||
// EXIST: Z2
|
||||
// EXIST: Z3
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// IGNORE_K1
|
||||
class A1
|
||||
class Z1
|
||||
sealed class Foo
|
||||
class A2
|
||||
class Z2
|
||||
class Bar: Foo()
|
||||
class Baz: Foo()
|
||||
class A3
|
||||
class Z3
|
||||
|
||||
|
||||
fun f(foo: Foo) {
|
||||
val t = foo as? <caret>
|
||||
}
|
||||
|
||||
// WITH_ORDER
|
||||
// EXIST: Bar
|
||||
// EXIST: Baz
|
||||
// EXIST: Foo
|
||||
// EXIST: A1
|
||||
// EXIST: A2
|
||||
// EXIST: A3
|
||||
// EXIST: Z1
|
||||
// EXIST: Z2
|
||||
// EXIST: Z3
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// IGNORE_K1
|
||||
class A1
|
||||
class Z1
|
||||
class A2
|
||||
sealed interface Foo {
|
||||
sealed interface Bar : Foo
|
||||
sealed interface Baz : Foo
|
||||
}
|
||||
class BarImpl : Foo.Bar
|
||||
class BazImpl : Foo.Baz
|
||||
class Z2
|
||||
class A3
|
||||
class Z3
|
||||
|
||||
|
||||
fun f(foo: Foo) {
|
||||
val t = foo as <caret>
|
||||
}
|
||||
|
||||
// WITH_ORDER
|
||||
// EXIST: Bar
|
||||
// EXIST: Baz
|
||||
// EXIST: BarImpl
|
||||
// EXIST: BazImpl
|
||||
// EXIST: Foo
|
||||
// EXIST: A1
|
||||
// EXIST: A2
|
||||
// EXIST: A3
|
||||
// EXIST: Z1
|
||||
// EXIST: Z2
|
||||
// EXIST: Z3
|
||||
+34
@@ -2523,6 +2523,40 @@ public abstract class K1JSBasicCompletionTestGenerated extends AbstractK1JSBasic
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractK1JSBasicCompletionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K1;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractK1JSBasicCompletionTest {
|
||||
|
||||
+34
@@ -2523,6 +2523,40 @@ public abstract class K1JvmBasicCompletionTestGenerated extends AbstractK1JvmBas
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractK1JvmBasicCompletionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K1;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractK1JvmBasicCompletionTest {
|
||||
|
||||
+34
@@ -2523,6 +2523,40 @@ public abstract class K1MLPerformanceCompletionTestGenerated extends AbstractK1M
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractK1MLPerformanceCompletionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K1;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractK1MLPerformanceCompletionTest {
|
||||
|
||||
+34
@@ -2523,6 +2523,40 @@ public abstract class K2JsBasicCompletionLegacyStdlibTestGenerated extends Abstr
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractK2JsBasicCompletionLegacyStdlibTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractK2JsBasicCompletionLegacyStdlibTest {
|
||||
|
||||
+34
@@ -2523,6 +2523,40 @@ public abstract class K2JvmBasicCompletionTestGenerated extends AbstractK2JvmBas
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractK2JvmBasicCompletionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractK2JvmBasicCompletionTest {
|
||||
|
||||
+39
@@ -2667,6 +2667,45 @@ public abstract class CommonNativeJvmKotlinKmpCompletionTestGenerated extends Ab
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractKotlinKmpCompletionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
public KMPTestPlatform getTestPlatform() {
|
||||
return KMPTestPlatform.CommonNativeJvm;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractKotlinKmpCompletionTest {
|
||||
|
||||
+39
@@ -2667,6 +2667,45 @@ public abstract class JsKotlinKmpCompletionTestGenerated extends AbstractKotlinK
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractKotlinKmpCompletionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
public KMPTestPlatform getTestPlatform() {
|
||||
return KMPTestPlatform.Js;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractKotlinKmpCompletionTest {
|
||||
|
||||
+39
@@ -2667,6 +2667,45 @@ public abstract class NativeLinuxKotlinKmpCompletionTestGenerated extends Abstra
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/sealedHierarchy")
|
||||
public static class SealedHierarchy extends AbstractKotlinKmpCompletionTest {
|
||||
@java.lang.Override
|
||||
@org.jetbrains.annotations.NotNull
|
||||
public final KotlinPluginMode getPluginMode() {
|
||||
return KotlinPluginMode.K2;
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
public KMPTestPlatform getTestPlatform() {
|
||||
return KMPTestPlatform.NativeLinux;
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInAs.kt")
|
||||
public void testPreferSealedHierarchyInAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInIs.kt")
|
||||
public void testPreferSealedHierarchyInIs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInIs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyInSafeAs.kt")
|
||||
public void testPreferSealedHierarchyInSafeAs() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyInSafeAs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("PreferSealedHierarchyNested.kt")
|
||||
public void testPreferSealedHierarchyNested() throws Exception {
|
||||
runTest("../../completion/testData/basic/common/sealedHierarchy/PreferSealedHierarchyNested.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../../completion/testData/basic/common/shadowing")
|
||||
public static class Shadowing extends AbstractKotlinKmpCompletionTest {
|
||||
|
||||
+4
-3
@@ -89,6 +89,7 @@ class KotlinTypeNameReferencePositionContext(
|
||||
val typeReference: KtTypeReference?,
|
||||
) : KotlinSimpleNameReferencePositionContext()
|
||||
|
||||
|
||||
class KotlinAnnotationTypeNameReferencePositionContext(
|
||||
override val position: PsiElement,
|
||||
override val reference: KtSimpleNameReference,
|
||||
@@ -159,10 +160,10 @@ class KotlinInfixCallPositionContext(
|
||||
|
||||
/**
|
||||
* Represents an operator call - binary or unary, postfix or prefix.
|
||||
*
|
||||
*
|
||||
* [nameExpression] does not represent any name in this case - it references
|
||||
* an operator reference, like `+`, `+=` or unary `-`.
|
||||
*
|
||||
*
|
||||
* [explicitReceiver] points to the main expression in the operator call:
|
||||
* - the LHS in the binary call (except for the `contains` operator, where the receiver is on the RHS)
|
||||
* - the underlying expression in the unary call
|
||||
@@ -349,7 +350,7 @@ object KotlinPositionContextDetector {
|
||||
KotlinOperatorCallPositionContext(position, reference, nameExpression, explicitReceiver)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parent is KtUnaryExpression && parent.operationReference == nameExpression ->
|
||||
KotlinOperatorCallPositionContext(position, reference, nameExpression, explicitReceiver)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user