From 4626f21c585c940dad08afea722e2b4a03419ec7 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 2 Dec 2020 13:21:35 +0300 Subject: [PATCH] Record type arguments for FirResolvedQualifier --- ...ypeArgumentsNotAllowedExpressionChecker.kt | 35 +------------------ .../jetbrains/kotlin/fir/FirCallResolver.kt | 2 +- .../kotlin/fir/FirQualifiedNameResolver.kt | 12 ++++--- .../function/longQualifiedNameGeneric.fir.kt | 2 +- 4 files changed, 11 insertions(+), 40 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt index 7362bb279bd..2f8762e32d4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirTypeArgumentsNotAllowedExpressionChecker.kt @@ -5,22 +5,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression -import com.intellij.lang.LighterASTNode -import com.intellij.openapi.util.Ref -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiErrorElement -import com.intellij.util.diff.FlyweightCapableTreeStructure -import org.jetbrains.kotlin.KtNodeTypes.TYPE_ARGUMENT_LIST -import org.jetbrains.kotlin.fir.FirLightSourceElement import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext -import org.jetbrains.kotlin.fir.analysis.checkers.getChildren import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier -import org.jetbrains.kotlin.fir.psi -import org.jetbrains.kotlin.psi.KtTypeArgumentList object FirTypeArgumentsNotAllowedExpressionChecker : FirQualifiedAccessChecker() { override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { @@ -29,36 +19,13 @@ object FirTypeArgumentsNotAllowedExpressionChecker : FirQualifiedAccessChecker() val explicitReceiver = expression.explicitReceiver if (explicitReceiver is FirResolvedQualifier && explicitReceiver.symbol == null) { - if (explicitReceiver.source?.hasAnyArguments() == true) { + if (explicitReceiver.typeArguments.isNotEmpty()) { reporter.report(explicitReceiver.source) return } } } - private fun FirSourceElement.hasAnyArguments(): Boolean { - val localPsi = this.psi - val localLight = this.lighterASTNode - - if (localPsi != null && localPsi !is PsiErrorElement) { - return localPsi.hasAnyArguments() - } else if (this is FirLightSourceElement) { - return localLight.hasAnyArguments(this.treeStructure) - } - - return false - } - - private fun PsiElement.hasAnyArguments(): Boolean { - val children = this.children // this is a method call and it collects children - return children.size > 1 && children[1] is KtTypeArgumentList - } - - private fun LighterASTNode.hasAnyArguments(tree: FlyweightCapableTreeStructure): Boolean { - val children = getChildren(tree) - return children.count { it != null } > 1 && children[1]?.tokenType == TYPE_ARGUMENT_LIST - } - private fun DiagnosticReporter.report(source: FirSourceElement?) { source?.let { report(FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(it)) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 50e01c9e118..96063040316 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -168,7 +168,7 @@ class FirCallResolver( fun resolveVariableAccessAndSelectCandidate(qualifiedAccess: T): FirStatement { val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess - qualifiedResolver.initProcessingQualifiedAccess(callee) + qualifiedResolver.initProcessingQualifiedAccess(callee, qualifiedAccess.typeArguments) @Suppress("NAME_SHADOWING") val qualifiedAccess = qualifiedAccess.transformExplicitReceiver() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt index 3b73b85dd67..6ca46209b58 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt @@ -16,14 +16,17 @@ import org.jetbrains.kotlin.fir.resolve.transformers.PackageOrClass import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.transformers.resolveToPackageOrClass import org.jetbrains.kotlin.fir.resolve.typeForQualifier +import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name class FirQualifiedNameResolver(private val components: BodyResolveComponents) { private val session = components.session - private var qualifierStack = mutableListOf() + private var qualifierStack = mutableListOf() private var qualifierPartsToDrop = 0 + private class NameWithTypeArguments(val name: Name, val typeArguments: List) + fun reset() { qualifierStack.clear() qualifierPartsToDrop = 0 @@ -41,11 +44,11 @@ class FirQualifiedNameResolver(private val components: BodyResolveComponents) { */ fun isPotentialQualifierPartPosition() = qualifierStack.size > 1 - fun initProcessingQualifiedAccess(callee: FirSimpleNamedReference) { + fun initProcessingQualifiedAccess(callee: FirSimpleNamedReference, typeArguments: List) { if (callee.name.isSpecial) { qualifierStack.clear() } else { - qualifierStack.add(callee.name) + qualifierStack.add(NameWithTypeArguments(callee.name, typeArguments)) } } @@ -62,7 +65,7 @@ class FirQualifiedNameResolver(private val components: BodyResolveComponents) { return null } val symbolProvider = session.firSymbolProvider - var qualifierParts = qualifierStack.asReversed().map { it.asString() } + var qualifierParts = qualifierStack.asReversed().map { it.name.asString() } var resolved: PackageOrClass? do { resolved = resolveToPackageOrClass( @@ -80,6 +83,7 @@ class FirQualifiedNameResolver(private val components: BodyResolveComponents) { packageFqName = resolved.packageFqName relativeClassFqName = resolved.relativeClassFqName symbol = resolved.classSymbol + typeArguments.addAll(qualifierStack.take(qualifierParts.size).flatMap { it.typeArguments }) }.apply { resultType = components.typeForQualifier(this) } diff --git a/compiler/testData/diagnostics/tests/callableReference/function/longQualifiedNameGeneric.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/longQualifiedNameGeneric.fir.kt index df53d4d2ccb..155c40387b1 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/longQualifiedNameGeneric.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/longQualifiedNameGeneric.fir.kt @@ -14,5 +14,5 @@ import kotlin.reflect.KFunction3 fun main() { val x = a.b.c.D::foo - checkSubtype, String, Int, a.b.c.D>>(x) + checkSubtype, String, Int, a.b.c.D>>(x) }