From 43315fd61d4b6934bf5ea896714b158a9a0c0137 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 7 Mar 2019 18:18:14 +0300 Subject: [PATCH] FIR: Preparation for resolve to classifiers --- .../kotlin/fir/symbols/ConeLookupTags.kt | 9 +++- .../transformers/FirBodyResolveTransformer.kt | 53 ++++++++++++------- .../jetbrains/kotlin/fir/scopes/FirScope.kt | 17 ++++++ 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt index 93290c475ff..4e7c4e46168 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/ConeLookupTags.kt @@ -8,18 +8,23 @@ package org.jetbrains.kotlin.fir.symbols import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -interface ConeClassifierLookupTag +interface ConeClassifierLookupTag { + val name: Name +} interface ConeClassifierLookupTagWithFixedSymbol { val symbol: ConeClassifierSymbol } interface ConeTypeParameterLookupTag : ConeClassifierLookupTag { - val name: Name + override val name: Name } interface ConeClassLikeLookupTag : ConeClassifierLookupTag { val classId: ClassId + + override val name: Name + get() = classId.shortClassName } interface ConeTypeAliasLookupTag : ConeClassLikeLookupTag diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt index d7b818eb9f3..4f46f84957f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -16,10 +16,8 @@ import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.* -import org.jetbrains.kotlin.fir.scopes.lookupSuperTypes import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult @@ -181,7 +179,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( abstract class ApplicabilityChecker { val groupNumbers = mutableListOf() - val candidates = mutableListOf() + val candidates = mutableListOf() var currentApplicability = CandidateApplicability.HIDDEN @@ -205,7 +203,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( } - protected open fun getApplicability(group: Int, symbol: ConeCallableSymbol): CandidateApplicability { + protected open fun getApplicability(group: Int, symbol: ConeSymbol): CandidateApplicability { val declaration = (symbol as? FirBasedSymbol<*>)?.fir ?: return CandidateApplicability.HIDDEN declaration as FirDeclaration @@ -217,7 +215,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( return CandidateApplicability.RESOLVED } - open fun consumeCandidate(group: Int, symbol: ConeCallableSymbol) { + open fun consumeCandidate(group: Int, symbol: ConeSymbol) { val applicability = getApplicability(group, symbol) if (applicability > currentApplicability) { @@ -235,13 +233,13 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( abstract fun updateNames(names: LinkedHashSet) - open fun isSuccessful(index: Int, candidate: ConeCallableSymbol): Boolean { + open fun isSuccessful(index: Int, candidate: ConeSymbol): Boolean { return true } - open fun successCandidates(): List { + open fun successCandidates(): List { if (groupNumbers.isEmpty()) return emptyList() - val result = mutableListOf() + val result = mutableListOf() var bestGroup = groupNumbers.first() for ((index, candidate) in candidates.withIndex()) { val group = groupNumbers[index] @@ -263,7 +261,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( names.add(name) } - override fun consumeCandidate(group: Int, symbol: ConeCallableSymbol) { + override fun consumeCandidate(group: Int, symbol: ConeSymbol) { if (symbol !is ConeVariableSymbol) return if (symbol.callableId.callableName != name) return super.consumeCandidate(group, symbol) @@ -273,7 +271,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( inner class VariableInvokeApplicabilityChecker(val variableName: Name) : FunctionApplicabilityChecker(invoke) { val variableChecker = object : VariableApplicabilityChecker(variableName) { - override fun isSuccessful(index: Int, candidate: ConeCallableSymbol): Boolean { + override fun isSuccessful(index: Int, candidate: ConeSymbol): Boolean { return matchedProperties[index] } } @@ -287,12 +285,13 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( } } - private fun isInvokeApplicableOn(propertySymbol: ConeCallableSymbol, invokeSymbol: ConeCallableSymbol): Boolean { + private fun isInvokeApplicableOn(propertySymbol: ConeSymbol, invokeSymbol: ConeCallableSymbol): Boolean { return true //TODO: Actual type-check here } - override fun getApplicability(group: Int, symbol: ConeCallableSymbol): CandidateApplicability { + override fun getApplicability(group: Int, symbol: ConeSymbol): CandidateApplicability { + symbol as ConeCallableSymbol val declaration = (symbol as? FirBasedSymbol<*>)?.fir ?: return CandidateApplicability.HIDDEN declaration as FirDeclaration @@ -303,7 +302,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( var applicable = false - fun processCandidates(candidates: Iterable>) { + fun processCandidates(candidates: Iterable>) { for ((index, candidate) in candidates) { val invokeApplicableOn = isInvokeApplicableOn(candidate, symbol) if (invokeApplicableOn) { @@ -330,8 +329,8 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( return currentApplicability == CandidateApplicability.RESOLVED } - override fun consumeCandidate(group: Int, symbol: ConeCallableSymbol) { - if (symbol.callableId.callableName == variableName) { + override fun consumeCandidate(group: Int, symbol: ConeSymbol) { + if (symbol is ConeVariableSymbol && symbol.callableId.callableName == variableName) { variableChecker.consumeCandidate(group, symbol) val lastCandidate = variableChecker.candidates.lastOrNull() @@ -369,6 +368,19 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( val invoke = Name.identifier("invoke") } + class ClassifierApplicabilityChecker(val name: Name) : ApplicabilityChecker() { + override fun updateNames(names: LinkedHashSet) { + names.add(name) + } + + override fun consumeCandidate(group: Int, symbol: ConeSymbol) { + if (symbol !is ConeClassifierSymbol) return + if (symbol.toLookupTag().name != name) return + super.consumeCandidate(group, symbol) + } + + } + open class FunctionApplicabilityChecker(val name: Name) : ApplicabilityChecker() { var parameterCount = 0 @@ -377,7 +389,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( names.add(name) } - override fun getApplicability(group: Int, symbol: ConeCallableSymbol): CandidateApplicability { + override fun getApplicability(group: Int, symbol: ConeSymbol): CandidateApplicability { val declaration = (symbol as FirBasedSymbol<*>).fir if (declaration is FirFunction) { @@ -386,7 +398,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( return super.getApplicability(group, symbol) } - override fun consumeCandidate(group: Int, symbol: ConeCallableSymbol) { + override fun consumeCandidate(group: Int, symbol: ConeSymbol) { if (symbol !is ConeFunctionSymbol) return if (symbol.callableId.callableName != name) return super.consumeCandidate(group, symbol) @@ -413,13 +425,14 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( processedScopes.add(scope) names.forEach { name -> - fun process(symbol: ConeCallableSymbol): ProcessorAction { + fun process(symbol: ConeSymbol): ProcessorAction { for (checker in checkers) { checker.consumeCandidate(index, symbol) } return ProcessorAction.NEXT } + scope.processClassifiersByNameWithAction(name, FirPosition.OTHER, ::process) scope.processPropertiesByName(name, ::process) scope.processFunctionsByName(name, ::process) } @@ -515,7 +528,7 @@ class FirBodyResolveTransformer(val session: FirSession) : FirTransformer( FirQualifiedAccessExpressionImpl(functionCall.session, functionCall.calleeReference.psi, functionCall.safe).apply { calleeReference = createResolvedNamedReference( functionCall.calleeReference, - result.variableChecker.successCandidates() + result.variableChecker.successCandidates() as List ) explicitReceiver = functionCall.explicitReceiver } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt index a7bd2c28670..a54475f81bf 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt @@ -6,12 +6,17 @@ package org.jetbrains.kotlin.fir.scopes import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT +import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP import org.jetbrains.kotlin.fir.symbols.ConeClassifierSymbol import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol import org.jetbrains.kotlin.fir.symbols.ConeVariableSymbol import org.jetbrains.kotlin.name.Name interface FirScope { + @Deprecated( + "obsolete", + replaceWith = ReplaceWith("processClassifiersByNameWithAction(name, position) { if (processor()) ProcessorAction.NEXT else ProcessorAction.STOP }.next()") + ) fun processClassifiersByName( name: Name, position: FirPosition, @@ -29,6 +34,18 @@ interface FirScope { ): ProcessorAction = NEXT } + +inline fun FirScope.processClassifiersByNameWithAction( + name: Name, + position: FirPosition, + crossinline processor: (ConeClassifierSymbol) -> ProcessorAction +): ProcessorAction { + val result = processClassifiersByName(name, position) { + processor(it).next() + } + return if (result) NEXT else STOP +} + enum class FirPosition(val allowTypeParameters: Boolean = true) { SUPER_TYPE_OR_EXPANSION(allowTypeParameters = false), OTHER