From 7d8ef5c7a260b357426a376c3303459e580d65c6 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Mon, 13 Jul 2020 15:56:11 +0300 Subject: [PATCH] FIR IDE: introduce KtFirConstructorDelegationReference --- .../FirReferenceResolveTestGenerated.java | 23 +++++++++++++++++ .../org/jetbrains/kotlin/idea/fir/FirUtils.kt | 7 ++++++ .../KotlinFirReferenceContributor.kt | 1 + .../KtFirConstructorDelegationReference.kt | 25 +++++++++++++++++++ .../toPrimary.kt | 6 +++++ .../toSecondary.kt | 8 ++++++ .../ReferenceResolveTestGenerated.java | 23 +++++++++++++++++ 7 files changed, 93 insertions(+) create mode 100644 idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt create mode 100644 idea/testData/resolve/references/constructorDelegatingReference/toPrimary.kt create mode 100644 idea/testData/resolve/references/constructorDelegatingReference/toSecondary.kt diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java index c26d10c7225..c7b1ae98e91 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/resolve/FirReferenceResolveTestGenerated.java @@ -441,6 +441,29 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv } } + @TestMetadata("idea/testData/resolve/references/constructorDelegatingReference") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ConstructorDelegatingReference extends AbstractFirReferenceResolveTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInConstructorDelegatingReference() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/resolve/references/constructorDelegatingReference"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("toPrimary.kt") + public void testToPrimary() throws Exception { + runTest("idea/testData/resolve/references/constructorDelegatingReference/toPrimary.kt"); + } + + @TestMetadata("toSecondary.kt") + public void testToSecondary() throws Exception { + runTest("idea/testData/resolve/references/constructorDelegatingReference/toSecondary.kt"); + } + } + @TestMetadata("idea/testData/resolve/references/delegatedPropertyAccessors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt index 5802d0cf4a4..6e9f5e8cad5 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt @@ -18,6 +18,8 @@ import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade +import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.util.OperatorNameConventions import kotlin.reflect.KClass @@ -63,6 +65,11 @@ fun FirFunctionCall.getCalleeSymbol(): FirBasedSymbol<*>? = fun FirReference.getResolvedSymbolOfNameReference(): FirBasedSymbol<*>? = (this as? FirResolvedNamedReference)?.resolvedSymbol +internal fun FirReference.getResolvedKtSymbolOfNameReference(builder: KtSymbolByFirBuilder): KtSymbol? = + (getResolvedSymbolOfNameReference()?.fir as? FirDeclaration)?.let { firDeclaration -> + builder.buildSymbol(firDeclaration) + } + inline fun D.unrollFakeOverrides(): D where D : FirDeclaration, D : FirSymbolOwner<*> { val symbol = symbol if (symbol !is PossiblyFirFakeOverrideSymbol<*, *>) return this diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KotlinFirReferenceContributor.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KotlinFirReferenceContributor.kt index 01b8f5859e3..331371fe76e 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KotlinFirReferenceContributor.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KotlinFirReferenceContributor.kt @@ -14,6 +14,7 @@ class KotlinFirReferenceContributor : KotlinReferenceProviderContributor { registerProvider(factory = ::KtFirPropertyDelegationMethodsReference) registerProvider(factory = ::KtFirDestructuringDeclarationReference) registerProvider(factory = ::KtFirArrayAccessReference) + registerProvider(factory = ::KtFirConstructorDelegationReference) } } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt new file mode 100644 index 00000000000..b34a619e838 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirConstructorDelegationReference.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.references + +import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall +import org.jetbrains.kotlin.idea.fir.getOrBuildFirSafe +import org.jetbrains.kotlin.idea.fir.getResolvedKtSymbolOfNameReference +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol +import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression + +class KtFirConstructorDelegationReference( + expression: KtConstructorDelegationReferenceExpression +) : KtConstructorDelegationReference(expression), KtFirReference { + + override fun resolveToSymbols(analysisSession: KtAnalysisSession): Collection { + check(analysisSession is KtFirAnalysisSession) + val fir = expression.getOrBuildFirSafe(analysisSession.firResolveState) ?: return emptyList() + return listOfNotNull(fir.calleeReference.getResolvedKtSymbolOfNameReference(analysisSession.firSymbolBuilder)) + } +} diff --git a/idea/testData/resolve/references/constructorDelegatingReference/toPrimary.kt b/idea/testData/resolve/references/constructorDelegatingReference/toPrimary.kt new file mode 100644 index 00000000000..d0e9bc02bac --- /dev/null +++ b/idea/testData/resolve/references/constructorDelegatingReference/toPrimary.kt @@ -0,0 +1,6 @@ +class A(a: Int) { + constructor() : this(2) +} + +// REF: (in A).A(Int) + diff --git a/idea/testData/resolve/references/constructorDelegatingReference/toSecondary.kt b/idea/testData/resolve/references/constructorDelegatingReference/toSecondary.kt new file mode 100644 index 00000000000..9d7acea2224 --- /dev/null +++ b/idea/testData/resolve/references/constructorDelegatingReference/toSecondary.kt @@ -0,0 +1,8 @@ +class A(a: Int) { + constructor(b: String) : this(2) + + constructor() : this("2") +} + +// REF: (in A).A(String) + diff --git a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java index d181ad5bf93..d927be17c0d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java @@ -441,6 +441,29 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest } } + @TestMetadata("idea/testData/resolve/references/constructorDelegatingReference") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ConstructorDelegatingReference extends AbstractReferenceResolveTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInConstructorDelegatingReference() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/resolve/references/constructorDelegatingReference"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("toPrimary.kt") + public void testToPrimary() throws Exception { + runTest("idea/testData/resolve/references/constructorDelegatingReference/toPrimary.kt"); + } + + @TestMetadata("toSecondary.kt") + public void testToSecondary() throws Exception { + runTest("idea/testData/resolve/references/constructorDelegatingReference/toSecondary.kt"); + } + } + @TestMetadata("idea/testData/resolve/references/delegatedPropertyAccessors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)