FIR resolve: provide synthetic properties scope
At the moment get* and is* functions are supported
This commit is contained in:
committed by
Mikhail Glukhikh
parent
5763b82cdd
commit
fe3afccfc2
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.resolve.defaultType
|
|||||||
import org.jetbrains.kotlin.fir.resolve.scope
|
import org.jetbrains.kotlin.fir.resolve.scope
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
@@ -138,7 +139,10 @@ class MemberScopeTowerLevel(
|
|||||||
output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
|
output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
|
||||||
takeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction
|
takeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
return dispatchReceiver.type.scope(session)?.takeMembers { output.consumeCandidate(it, dispatchReceiver) } ?: ProcessorAction.NEXT
|
val scope = dispatchReceiver.type.scope(session) ?: return ProcessorAction.NEXT
|
||||||
|
if (scope.takeMembers { output.consumeCandidate(it, dispatchReceiver) }.stop()) return ProcessorAction.STOP
|
||||||
|
val withSynthetic = FirSyntheticPropertiesScope(session, scope, ReturnTypeCalculatorWithJump(session))
|
||||||
|
return withSynthetic.takeMembers { output.consumeCandidate(it, dispatchReceiver) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : ConeSymbol> processElementsByName(
|
override fun <T : ConeSymbol> processElementsByName(
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. 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.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberPropertyImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeVariableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class FirSyntheticPropertiesScope(val session: FirSession, val baseScope: FirScope, val typeCalculator: ReturnTypeCalculator) : FirScope {
|
||||||
|
|
||||||
|
val synthetic: MutableMap<ConeCallableSymbol, ConeVariableSymbol> = mutableMapOf()
|
||||||
|
|
||||||
|
|
||||||
|
private fun checkGetAndCreateSynthetic(
|
||||||
|
name: Name,
|
||||||
|
symbol: ConeFunctionSymbol,
|
||||||
|
processor: (ConeVariableSymbol) -> ProcessorAction
|
||||||
|
): ProcessorAction {
|
||||||
|
val fir = symbol.firSafeNullable<FirNamedFunction>() ?: return ProcessorAction.NEXT
|
||||||
|
|
||||||
|
if (fir.typeParameters.isNotEmpty()) return ProcessorAction.NEXT
|
||||||
|
if (fir.valueParameters.isNotEmpty()) return ProcessorAction.NEXT
|
||||||
|
|
||||||
|
val synthetic = FirPropertySymbol(CallableId(symbol.callableId.packageName, symbol.callableId.className, name))
|
||||||
|
|
||||||
|
val returnTypeRef = typeCalculator.tryCalculateReturnType(fir)
|
||||||
|
FirMemberPropertyImpl(
|
||||||
|
session,
|
||||||
|
null,
|
||||||
|
synthetic,
|
||||||
|
name,
|
||||||
|
fir.visibility,
|
||||||
|
fir.modality,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
returnTypeRef,
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility),
|
||||||
|
FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
return processor(synthetic)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processPropertiesByName(name: Name, processor: (ConeVariableSymbol) -> ProcessorAction): ProcessorAction {
|
||||||
|
if (baseScope.processFunctionsByName(Name.guessByFirstCharacter("get${name.identifier.capitalize()}")) {
|
||||||
|
checkGetAndCreateSynthetic(name, it, processor)
|
||||||
|
}.stop()) return ProcessorAction.STOP
|
||||||
|
|
||||||
|
if (name.asString().startsWith("is") && baseScope.processFunctionsByName(name) {
|
||||||
|
checkGetAndCreateSynthetic(name, it, processor)
|
||||||
|
}.stop()) return ProcessorAction.STOP
|
||||||
|
return super.processPropertiesByName(name, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user