FIR IDE: handle reference to package and outer classes
For a qualified name like `foo.bar.Outer.Inner`, FIR represents it as one atomic FIR element. Hence, to properly resolve these names to the corresponding package and class, we need some additional work.
This commit is contained in:
committed by
Ilya Kirillov
parent
a537074e1e
commit
84f8d4d315
@@ -116,6 +116,12 @@ fun FirRegularClassBuilder.addDeclarations(declarations: Collection<FirDeclarati
|
||||
|
||||
val FirTypeAlias.expandedConeType: ConeClassLikeType? get() = expandedTypeRef.coneTypeSafe()
|
||||
|
||||
val FirClassLikeDeclaration<*>.classId
|
||||
get() = when (this) {
|
||||
is FirClass<*> -> symbol.classId
|
||||
is FirTypeAlias -> symbol.classId
|
||||
}
|
||||
|
||||
val FirClass<*>.classId get() = symbol.classId
|
||||
|
||||
val FirClassSymbol<*>.superConeTypes
|
||||
|
||||
-11
@@ -5,13 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.resolve
|
||||
|
||||
import org.jetbrains.kotlin.idea.completion.test.configureWithExtraFile
|
||||
import org.jetbrains.kotlin.idea.fir.invalidateCaches
|
||||
import org.jetbrains.kotlin.idea.resolve.AbstractReferenceResolveTest
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.utils.IgnoreTests
|
||||
|
||||
abstract class AbstractFirReferenceResolveTest : AbstractReferenceResolveTest() {
|
||||
override fun isFirPlugin(): Boolean = true
|
||||
@@ -23,13 +21,4 @@ abstract class AbstractFirReferenceResolveTest : AbstractReferenceResolveTest()
|
||||
project.invalidateCaches(myFixture.file as? KtFile)
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
override fun doTest(path: String) {
|
||||
assert(path.endsWith(".kt")) { path }
|
||||
myFixture.configureWithExtraFile(path, ".Data")
|
||||
|
||||
IgnoreTests.runTestIfNotDisabledByFileDirective(testDataFile().toPath(), IgnoreTests.DIRECTIVES.IGNORE_FIR) {
|
||||
performChecks()
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+48
@@ -957,4 +957,52 @@ public class FirReferenceResolveTestGenerated extends AbstractFirReferenceResolv
|
||||
runTest("idea/testData/resolve/references/packageReference/kotlinPackageSecondQualifier.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/resolve/references/qualifiedAccess")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class QualifiedAccess extends AbstractFirReferenceResolveTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInQualifiedAccess() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/resolve/references/qualifiedAccess"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference1.kt")
|
||||
public void testCallableReference1() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/callableReference1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference2.kt")
|
||||
public void testCallableReference2() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/callableReference2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference3.kt")
|
||||
public void testCallableReference3() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/callableReference3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolveFirstPackageOfFullyQualifiedReference.kt")
|
||||
public void testResolveFirstPackageOfFullyQualifiedReference() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolveFirstPackageOfFullyQualifiedReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolveFullyQualifiedCompanionObject.kt")
|
||||
public void testResolveFullyQualifiedCompanionObject() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolveFullyQualifiedCompanionObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolveOuterClassOfFullyQualifiedReference.kt")
|
||||
public void testResolveOuterClassOfFullyQualifiedReference() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolveOuterClassOfFullyQualifiedReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolvePackageOfFullyQualifiedReference.kt")
|
||||
public void testResolvePackageOfFullyQualifiedReference() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolvePackageOfFullyQualifiedReference.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+120
-36
@@ -69,7 +69,7 @@ internal object FirReferenceResolveHelper {
|
||||
private fun ClassId.toTargetPsi(
|
||||
session: FirSession,
|
||||
symbolBuilder: KtSymbolByFirBuilder,
|
||||
calleeReference: FirReference? = null
|
||||
calleeReference: FirReference? = null,
|
||||
): KtSymbol? {
|
||||
val classLikeDeclaration = ConeClassLikeLookupTagImpl(this).toSymbol(session)?.fir
|
||||
if (classLikeDeclaration is FirRegularClass) {
|
||||
@@ -178,7 +178,7 @@ internal object FirReferenceResolveHelper {
|
||||
return when (fir) {
|
||||
is FirResolvedTypeRef -> getSymbolsForResolvedTypeRef(fir, expression, session, symbolBuilder)
|
||||
is FirResolvedQualifier ->
|
||||
getSymbolsForResolvedQualifier(fir, expression, session, symbolBuilder, analysisSession)
|
||||
getSymbolsForResolvedQualifier(fir, expression, session, symbolBuilder)
|
||||
is FirAnnotationCall -> getSymbolsForAnnotationCall(fir, session, symbolBuilder)
|
||||
is FirResolvedImport -> getSymbolsByResolvedImport(expression, symbolBuilder, fir, session)
|
||||
is FirFile -> getSymbolsByFirFile(expression, symbolBuilder, fir)
|
||||
@@ -374,42 +374,126 @@ internal object FirReferenceResolveHelper {
|
||||
fir: FirResolvedQualifier,
|
||||
expression: KtSimpleNameExpression,
|
||||
session: FirSession,
|
||||
symbolBuilder: KtSymbolByFirBuilder,
|
||||
analysisSession: KtFirAnalysisSession
|
||||
symbolBuilder: KtSymbolByFirBuilder
|
||||
): Collection<KtSymbol> {
|
||||
// TODO refactor that block
|
||||
val classId = fir.classId ?: return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder, forQualifiedType = false))
|
||||
|
||||
var parent = expression.parent as? KtDotQualifiedExpression
|
||||
// Distinguish A.foo() from A(.Companion).foo()
|
||||
// Make expression.parent as? KtDotQualifiedExpression local function
|
||||
while (parent != null) {
|
||||
val selectorExpression = parent.selectorExpression ?: break
|
||||
if (selectorExpression === expression) {
|
||||
parent = parent.parent as? KtDotQualifiedExpression
|
||||
continue
|
||||
}
|
||||
val receiverClassId = if (parent.receiverExpression == expression) {
|
||||
/*
|
||||
* <caret>A.Named.i -> class A
|
||||
*/
|
||||
val name = fir.relativeClassFqName?.pathSegments()?.firstOrNull()
|
||||
name?.let { ClassId(fir.packageFqName, it) }
|
||||
} else null
|
||||
val parentFir = selectorExpression.getOrBuildFir(analysisSession.firResolveState)
|
||||
when {
|
||||
parentFir is FirQualifiedAccess -> {
|
||||
return listOfNotNull(
|
||||
(receiverClassId ?: classId).toTargetPsi(session, symbolBuilder, parentFir.calleeReference)
|
||||
)
|
||||
}
|
||||
receiverClassId != null -> {
|
||||
return listOfNotNull(receiverClassId.toTargetPsi(session, symbolBuilder))
|
||||
}
|
||||
else -> parent = parent.parent as? KtDotQualifiedExpression
|
||||
}
|
||||
val referencedSymbol = if (fir.resolvedToCompanionObject) {
|
||||
(fir.symbol?.fir as? FirRegularClass)?.companionObject?.symbol
|
||||
} else {
|
||||
fir.symbol
|
||||
}
|
||||
return listOfNotNull(classId.toTargetPsi(session, symbolBuilder))
|
||||
if (referencedSymbol == null) {
|
||||
// If referencedSymbol is null, it means the reference goes to a package.
|
||||
val parent = expression.parent as? KtDotQualifiedExpression ?: return emptyList()
|
||||
val fqNameSegments =
|
||||
when (expression) {
|
||||
parent.selectorExpression -> parent.fqNameSegments() ?: return emptyList()
|
||||
parent.receiverExpression -> listOf(expression.getReferencedName())
|
||||
else -> return emptyList()
|
||||
}
|
||||
return listOfNotNull(symbolBuilder.createPackageSymbolIfOneExists(FqName.fromSegments(fqNameSegments)))
|
||||
}
|
||||
val referencedClass = referencedSymbol.fir
|
||||
val referencedSymbolsByFir = listOfNotNull(symbolBuilder.buildSymbol(referencedClass))
|
||||
val firSourcePsi = fir.source.psi ?: referencedSymbolsByFir
|
||||
// The source of an `FirResolvedQualifier` is either a KtNamedReferenceExpression or a KtDotQualifiedExpression. In the former case,
|
||||
// it implies the qualifier is an atomic reference and therefore, it should be identical with the `expression`. In the latter case,
|
||||
// we need to manually break up the qualified access and resolve individual parts of it because in FIR, the entire qualified access
|
||||
// is one element.
|
||||
if (firSourcePsi === expression) return referencedSymbolsByFir
|
||||
require(firSourcePsi is KtDotQualifiedExpression)
|
||||
|
||||
if (referencedClass.isLocal) {
|
||||
// TODO: handle local classes after KT-47135 is fixed
|
||||
return referencedSymbolsByFir
|
||||
} else {
|
||||
var qualifiedAccess: KtDotQualifiedExpression = firSourcePsi
|
||||
val referencedClassId =
|
||||
if ((referencedClass as? FirRegularClass)?.isCompanion == true &&
|
||||
(qualifiedAccess.selectorExpression as? KtNameReferenceExpression)?.getReferencedName() != "Companion"
|
||||
) {
|
||||
// Remove the last "Companion" part if the qualified access does not contain it. This is needed because the "Companion"
|
||||
// part is optional.
|
||||
referencedClass.classId.outerClassId ?: return referencedSymbolsByFir
|
||||
} else {
|
||||
referencedClass.classId
|
||||
}
|
||||
val qualifiedAccessSegments = qualifiedAccess.fqNameSegments() ?: return referencedSymbolsByFir
|
||||
assert(referencedClassId.asSingleFqName().pathSegments().takeLast(qualifiedAccessSegments.size)
|
||||
.map { it.identifierOrNullIfSpecial } == qualifiedAccessSegments) {
|
||||
"Referenced classId $referencedClassId should end with qualifiedAccess expression ${qualifiedAccess.text} "
|
||||
}
|
||||
|
||||
// In the code below, we always maintain the contract that `classId` and `qualifiedAccess` should stay "in-sync", i.e. they
|
||||
// refer to the same class and classId should be null if `qualifiedAccess` references to a package.
|
||||
var classId: ClassId? = referencedClassId
|
||||
|
||||
// Handle nested classes.
|
||||
while (classId != null) {
|
||||
if (expression === qualifiedAccess.selectorExpression) {
|
||||
return listOfNotNull(classId.toTargetPsi(session, symbolBuilder))
|
||||
}
|
||||
val outerClassId = classId.outerClassId
|
||||
val receiverExpression = qualifiedAccess.receiverExpression
|
||||
if (receiverExpression !is KtDotQualifiedExpression) {
|
||||
// If the receiver is not a KtDotQualifiedExpression, it means we are hitting the end of nested receivers. In other
|
||||
// words, this receiver expression should be pointing at an unqualified name of a class, whose class ID is
|
||||
// `outerClassId`.
|
||||
if (receiverExpression == expression) {
|
||||
// If there is still an outer class, then return symbol of that class
|
||||
outerClassId?.let { return listOfNotNull(it.toTargetPsi(session, symbolBuilder)) }
|
||||
// Otherwise, it should be a package, so we return that
|
||||
return listOfNotNull(symbolBuilder.createPackageSymbolIfOneExists(classId.packageFqName))
|
||||
} else {
|
||||
// This is unexpected. The code probably contains some weird structures. In this case, we just fail the resolution
|
||||
// with zero results.
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
qualifiedAccess = receiverExpression
|
||||
classId = outerClassId
|
||||
}
|
||||
|
||||
// Handle package names
|
||||
var packageFqName = referencedClassId.packageFqName
|
||||
|
||||
while (!packageFqName.isRoot) {
|
||||
if (expression === qualifiedAccess.selectorExpression) {
|
||||
return listOfNotNull(symbolBuilder.createPackageSymbolIfOneExists(packageFqName))
|
||||
}
|
||||
val parentPackageFqName = packageFqName.parent()
|
||||
val receiverExpression = qualifiedAccess.receiverExpression
|
||||
if (receiverExpression !is KtDotQualifiedExpression) {
|
||||
// If the receiver is not a KtDotQualifiedExpression, it means we are hitting the end of nested receivers. In other
|
||||
// words, this receiver expression should be pointing at a top-level package now.
|
||||
if (receiverExpression == expression) {
|
||||
return listOfNotNull(symbolBuilder.createPackageSymbolIfOneExists(parentPackageFqName))
|
||||
} else {
|
||||
// This is unexpected. The code probably contains some weird structures. In this case, we just fail the resolution
|
||||
// with zero results.
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
qualifiedAccess = receiverExpression
|
||||
packageFqName = parentPackageFqName
|
||||
}
|
||||
return referencedSymbolsByFir
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the segments of a qualified access PSI. For example, given `foo.bar.OuterClass.InnerClass`, this returns `["foo", "bar",
|
||||
* "OuterClass", "InnerClass"]`.
|
||||
*/
|
||||
private fun KtDotQualifiedExpression.fqNameSegments(): List<String>? {
|
||||
val result: MutableList<String> = mutableListOf()
|
||||
var current: KtExpression = this
|
||||
while (current is KtDotQualifiedExpression) {
|
||||
result += (current.selectorExpression as? KtNameReferenceExpression)?.getReferencedName() ?: return null
|
||||
current = current.receiverExpression
|
||||
}
|
||||
result += (current as? KtNameReferenceExpression)?.getReferencedName() ?: return null
|
||||
result.reverse()
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getSymbolsForAnnotationCall(
|
||||
|
||||
@@ -37,13 +37,9 @@ import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.scri
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import java.util.*
|
||||
|
||||
infix fun SearchScope.and(otherScope: SearchScope): SearchScope = intersectWith(otherScope)
|
||||
infix fun SearchScope.or(otherScope: SearchScope): SearchScope = union(otherScope)
|
||||
|
||||
@@ -218,6 +218,7 @@ object IgnoreTests {
|
||||
const val FIR_IDENTICAL = "// FIR_IDENTICAL"
|
||||
|
||||
const val IGNORE_FE10_BINDING_BY_FIR = "// IGNORE_FE10_BINDING_BY_FIR"
|
||||
const val IGNORE_FE10 = "// IGNORE_FE10"
|
||||
}
|
||||
|
||||
enum class DirectivePosition {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
// OPTIONS: usages
|
||||
class Foo {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
// OPTIONS: usages
|
||||
class Foo {
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
// OPTIONS: usages
|
||||
fun foo(): Any {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Value read 6 return Bar
|
||||
Value read 7 return Bar
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_COMPARISON
|
||||
// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
// OPTIONS: usages
|
||||
fun foo(): Any {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Value read 7 return Bar
|
||||
Value read 8 return Bar
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
package test
|
||||
|
||||
class Conflict
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_FIR
|
||||
package test
|
||||
|
||||
object Conflict
|
||||
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
package foo.bar.baz
|
||||
|
||||
class AA {
|
||||
class BB {
|
||||
companion object
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val b = f<caret>oo.bar.baz.AA.BB
|
||||
}
|
||||
|
||||
// REF: foo
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// IGNORE_FIR
|
||||
package foo.bar.baz
|
||||
|
||||
class AA {
|
||||
class BB {
|
||||
companion object
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val b = foo.bar.baz.AA.B<caret>B
|
||||
}
|
||||
|
||||
// REF: companion object of (in foo.bar.baz.AA).BB
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
package foo.bar.baz
|
||||
|
||||
class AA {
|
||||
class BB {
|
||||
companion object
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val b = foo.bar.baz.A<caret>A.BB
|
||||
}
|
||||
|
||||
// REF: (foo.bar.baz).AA
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
package foo.bar.baz
|
||||
|
||||
class AA {
|
||||
class BB {
|
||||
companion object
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val b = foo.bar.b<caret>az.AA.BB
|
||||
}
|
||||
|
||||
// REF: baz
|
||||
@@ -0,0 +1,11 @@
|
||||
package foo.bar.baz
|
||||
|
||||
class AA {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A<caret>A::foo
|
||||
}
|
||||
|
||||
// REF: (foo.bar.baz).AA
|
||||
@@ -0,0 +1,14 @@
|
||||
// IGNORE_FE10
|
||||
package foo.bar.baz
|
||||
|
||||
class AA {
|
||||
companion object {
|
||||
fun foo() {}
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
A<caret>A::foo // FE1.0 won't resolve this
|
||||
}
|
||||
|
||||
// REF: companion object of (foo.bar.baz).AA
|
||||
@@ -0,0 +1,14 @@
|
||||
// IGNORE_FE10
|
||||
package foo.bar.baz
|
||||
|
||||
class AA {
|
||||
companion object
|
||||
}
|
||||
|
||||
fun AA.Companion.foo() {}
|
||||
|
||||
fun test() {
|
||||
A<caret>A::foo // FE1.0 won't resolve this
|
||||
}
|
||||
|
||||
// REF: companion object of (foo.bar.baz).AA
|
||||
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.util.renderAsGotoImplementation
|
||||
import org.jetbrains.kotlin.test.utils.IgnoreTests
|
||||
import org.junit.Assert
|
||||
import java.util.concurrent.Callable
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
abstract class AbstractReferenceResolveTest : KotlinLightPlatformCodeInsightFixtureTestCase() {
|
||||
@@ -35,7 +35,14 @@ abstract class AbstractReferenceResolveTest : KotlinLightPlatformCodeInsightFixt
|
||||
protected open fun doTest(path: String) {
|
||||
assert(path.endsWith(".kt")) { path }
|
||||
myFixture.configureWithExtraFile(path, ".Data")
|
||||
performChecks()
|
||||
val controlDirective = if (isFirPlugin()) {
|
||||
IgnoreTests.DIRECTIVES.IGNORE_FIR
|
||||
} else {
|
||||
IgnoreTests.DIRECTIVES.IGNORE_FE10
|
||||
}
|
||||
IgnoreTests.runTestIfNotDisabledByFileDirective(testDataFile().toPath(), controlDirective) {
|
||||
performChecks()
|
||||
}
|
||||
}
|
||||
|
||||
protected fun performChecks() {
|
||||
|
||||
+48
@@ -957,4 +957,52 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest
|
||||
runTest("idea/testData/resolve/references/packageReference/kotlinPackageSecondQualifier.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/resolve/references/qualifiedAccess")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class QualifiedAccess extends AbstractReferenceResolveTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInQualifiedAccess() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/resolve/references/qualifiedAccess"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference1.kt")
|
||||
public void testCallableReference1() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/callableReference1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference2.kt")
|
||||
public void testCallableReference2() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/callableReference2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("callableReference3.kt")
|
||||
public void testCallableReference3() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/callableReference3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolveFirstPackageOfFullyQualifiedReference.kt")
|
||||
public void testResolveFirstPackageOfFullyQualifiedReference() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolveFirstPackageOfFullyQualifiedReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolveFullyQualifiedCompanionObject.kt")
|
||||
public void testResolveFullyQualifiedCompanionObject() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolveFullyQualifiedCompanionObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolveOuterClassOfFullyQualifiedReference.kt")
|
||||
public void testResolveOuterClassOfFullyQualifiedReference() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolveOuterClassOfFullyQualifiedReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ResolvePackageOfFullyQualifiedReference.kt")
|
||||
public void testResolvePackageOfFullyQualifiedReference() throws Exception {
|
||||
runTest("idea/testData/resolve/references/qualifiedAccess/ResolvePackageOfFullyQualifiedReference.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user