[FIR] Use static & qualified scopes to access qualified callables

This commit provides more correct logic for creating scopes based
on FirResolvedQualifier & eliminates QualifiedReceiverTowerDataConsumer
This commit is contained in:
Mikhail Glukhikh
2020-01-13 17:43:52 +03:00
parent 6bbfb2ffe9
commit f0ced642d9
29 changed files with 250 additions and 221 deletions
@@ -29,6 +29,7 @@ internal fun FirScope.processFunctionsAndConstructorsByName(
name: Name, name: Name,
session: FirSession, session: FirSession,
bodyResolveComponents: BodyResolveComponents, bodyResolveComponents: BodyResolveComponents,
noInnerConstructors: Boolean = false,
processor: (FirCallableSymbol<*>) -> ProcessorAction processor: (FirCallableSymbol<*>) -> ProcessorAction
): ProcessorAction { ): ProcessorAction {
val matchedClassSymbol = getFirstClassifierOrNull(name) as? FirClassLikeSymbol<*> val matchedClassSymbol = getFirstClassifierOrNull(name) as? FirClassLikeSymbol<*>
@@ -38,7 +39,8 @@ internal fun FirScope.processFunctionsAndConstructorsByName(
processor, processor,
session, session,
bodyResolveComponents.scopeSession, bodyResolveComponents.scopeSession,
name name,
noInnerConstructors
).stop() ).stop()
) { ) {
return ProcessorAction.STOP return ProcessorAction.STOP
@@ -133,7 +135,8 @@ private fun processConstructors(
processor: (FirFunctionSymbol<*>) -> ProcessorAction, processor: (FirFunctionSymbol<*>) -> ProcessorAction,
session: FirSession, session: FirSession,
scopeSession: ScopeSession, scopeSession: ScopeSession,
name: Name name: Name,
noInner: Boolean
): ProcessorAction { ): ProcessorAction {
try { try {
if (matchedSymbol != null) { if (matchedSymbol != null) {
@@ -157,10 +160,13 @@ private fun processConstructors(
} }
//TODO: why don't we use declared member scope at this point? //TODO: why don't we use declared member scope at this point?
if (scope != null && scope.processFunctionsByName( if (scope != null && scope.processFunctionsByName(constructorName) {
constructorName, if (!noInner || (it as? FirConstructorSymbol)?.fir?.isInner != true) {
processor processor(it)
) == ProcessorAction.STOP } else {
ProcessorAction.NEXT
}
} == ProcessorAction.STOP
) { ) {
return ProcessorAction.STOP return ProcessorAction.STOP
} }
@@ -279,7 +285,7 @@ private fun <F : FirMemberFunction<F>> prepareSubstitutorForTypeAliasConstructor
val substitutor = substitutorByMap( val substitutor = substitutorByMap(
expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap() expandedClass.typeParameters.map { it.symbol }.zip(resultingTypeArguments).toMap()
); )
return TypeAliasConstructorsSubstitutor(typeAliasSymbol, substitutor, copyFactory) return TypeAliasConstructorsSubstitutor(typeAliasSymbol, substitutor, copyFactory)
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -104,24 +103,7 @@ fun createSimpleConsumer(
val factory = CandidateFactory(bodyResolveComponents, callInfo) val factory = CandidateFactory(bodyResolveComponents, callInfo)
val explicitReceiver = callInfo.explicitReceiver val explicitReceiver = callInfo.explicitReceiver
return if (explicitReceiver != null) { return if (explicitReceiver != null) {
val receiverValue = ExpressionReceiverValue(explicitReceiver) ExplicitReceiverTowerDataConsumer(session, name, token, ExpressionReceiverValue(explicitReceiver), factory, resultCollector)
if (explicitReceiver is FirResolvedQualifier) {
val qualified =
QualifiedReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
if (explicitReceiver.classId != null) {
PrioritizedTowerDataConsumer(
resultCollector,
qualified,
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
)
} else {
qualified
}
} else {
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
}
} else { } else {
NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector) NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector)
} }
@@ -5,23 +5,29 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirSealedClassImpl
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl
import org.jetbrains.kotlin.fir.references.impl.FirImplicitThisReference import org.jetbrains.kotlin.fir.references.impl.FirImplicitThisReference
import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.scopes.scope import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
import org.jetbrains.kotlin.name.ClassId
interface ReceiverValue { interface ReceiverValue {
val type: ConeKotlinType val type: ConeKotlinType
@@ -37,7 +43,7 @@ private fun receiverExpression(symbol: AbstractFirBasedSymbol<*>, type: ConeKotl
typeRef = FirResolvedTypeRefImpl(null, type) typeRef = FirResolvedTypeRefImpl(null, type)
} }
class ClassDispatchReceiverValue(val klassSymbol: FirClassSymbol<*>) : ReceiverValue { class ClassDispatchReceiverValue(klassSymbol: FirClassSymbol<*>) : ReceiverValue {
override val type: ConeKotlinType = ConeClassLikeTypeImpl( override val type: ConeKotlinType = ConeClassLikeTypeImpl(
klassSymbol.toLookupTag(), klassSymbol.toLookupTag(),
(klassSymbol.fir as? FirTypeParametersOwner)?.typeParameters?.map { ConeStarProjection }?.toTypedArray().orEmpty(), (klassSymbol.fir as? FirTypeParametersOwner)?.typeParameters?.map { ConeStarProjection }?.toTypedArray().orEmpty(),
@@ -56,6 +62,60 @@ class ExpressionReceiverValue(
override val receiverExpression: FirExpression override val receiverExpression: FirExpression
get() = explicitReceiverExpression get() = explicitReceiverExpression
private fun getClassSymbolWithCallablesScope(
classId: ClassId,
useSiteSession: FirSession,
scopeSession: ScopeSession
): Pair<FirClassSymbol<*>?, FirScope?> {
val symbol = useSiteSession.firSymbolProvider.getClassLikeSymbolByFqName(classId) ?: return null to null
if (symbol is FirTypeAliasSymbol) {
val expansionSymbol = symbol.fir.expandedConeType?.lookupTag?.toSymbol(useSiteSession)
if (expansionSymbol != null) {
return getClassSymbolWithCallablesScope(expansionSymbol.classId, useSiteSession, scopeSession)
}
} else {
return (symbol as? FirClassSymbol<*>)?.let { klassSymbol ->
klassSymbol to when (val klass = klassSymbol.fir) {
is FirClassImpl -> {
when (klass.classKind) {
ClassKind.ENUM_CLASS -> FirStaticScope(declaredMemberScope(klass))
ClassKind.OBJECT -> klass.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession)
else -> null
}
}
is FirSealedClassImpl -> null
else -> /* Java */ FirStaticScope(klass.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession))
}
} ?: (null to null)
}
return null to null
}
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
val qualifiedReceiver = explicitReceiverExpression as? FirResolvedQualifier
?: return super.scope(useSiteSession, scopeSession)
val classId = qualifiedReceiver.classId ?: return null
val (classSymbol, callablesScope) = getClassSymbolWithCallablesScope(classId, useSiteSession, scopeSession)
if (classSymbol != null) {
val klass = classSymbol.fir
val classifierScope = if (klass is FirClassImpl || klass is FirSealedClassImpl) {
nestedClassifierScope(klass)
} else {
useSiteSession.firSymbolProvider.getNestedClassifierScope(classId)
}
val qualifierScope = FirQualifierScope(callablesScope, classifierScope)
if ((klass as? FirRegularClass)?.companionObject == null) {
return qualifierScope
}
val companionScope = super.scope(useSiteSession, scopeSession) ?: return qualifierScope
return FirCompositeScope(qualifierScope, companionScope)
}
return super.scope(useSiteSession, scopeSession)
}
} }
abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>( abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
@@ -38,48 +38,6 @@ abstract class TowerDataConsumer {
} }
} }
class QualifiedReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
val session: FirSession,
val name: Name,
val token: TowerScopeLevel.Token<T>,
val explicitReceiver: ExpressionReceiverValue,
val candidateFactory: CandidateFactory,
override val resultCollector: CandidateCollector
) : TowerDataConsumer() {
override fun consume(
kind: TowerDataKind,
towerScopeLevel: TowerScopeLevel,
group: Int
): ProcessorAction {
if (skipGroup(group)) return ProcessorAction.NEXT
if (kind != TowerDataKind.EMPTY) return ProcessorAction.NEXT
return QualifiedReceiverTowerLevel(session, candidateFactory.bodyResolveComponents).processElementsByName(
token,
name,
explicitReceiver,
processor = TowerLevelProcessorImpl(group)
)
}
private inner class TowerLevelProcessorImpl(val group: Int) : TowerScopeLevel.TowerScopeLevelProcessor<T> {
override fun consumeCandidate(
symbol: T,
dispatchReceiverValue: ReceiverValue?,
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
builtInExtensionFunctionReceiverValue: ReceiverValue?
): ProcessorAction {
assert(dispatchReceiverValue == null)
resultCollector.consumeCandidate(
group,
candidateFactory.createCandidate(symbol, explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER)
)
return ProcessorAction.NEXT
}
}
}
class PrioritizedTowerDataConsumer( class PrioritizedTowerDataConsumer(
override val resultCollector: CandidateCollector, override val resultCollector: CandidateCollector,
private vararg val consumers: TowerDataConsumer private vararg val consumers: TowerDataConsumer
@@ -6,29 +6,24 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.isStatic
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
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
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
import org.jetbrains.kotlin.fir.scopes.scope
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeNullability import org.jetbrains.kotlin.fir.types.ConeNullability
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.cast
@@ -159,12 +154,14 @@ class MemberScopeTowerLevel(
return ProcessorAction.NEXT return ProcessorAction.NEXT
} }
val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver
val noInnerConstructors =
dispatchReceiver is ExpressionReceiverValue && dispatchReceiver.explicitReceiverExpression is FirResolvedQualifier
return when (token) { return when (token) {
TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol -> TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol ->
this.processPropertiesByName(name, symbol.cast()) this.processPropertiesByName(name, symbol.cast())
} }
TowerScopeLevel.Token.Functions -> processMembers(processor, explicitExtensionReceiver) { symbol -> TowerScopeLevel.Token.Functions -> processMembers(processor, explicitExtensionReceiver) { symbol ->
this.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents, symbol.cast()) this.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents, noInnerConstructors, symbol.cast())
} }
TowerScopeLevel.Token.Objects -> processMembers(processor, explicitExtensionReceiver) { symbol -> TowerScopeLevel.Token.Objects -> processMembers(processor, explicitExtensionReceiver) { symbol ->
this.processClassifiersByName(name, symbol.cast()) this.processClassifiersByName(name, symbol.cast())
@@ -241,72 +238,6 @@ class ScopeTowerLevel(
} }
} }
/**
* Handles only statics and top-levels, DOES NOT handle objects/companions members
*/
class QualifiedReceiverTowerLevel(
session: FirSession,
private val bodyResolveComponents: BodyResolveComponents
) : SessionBasedTowerLevel(session) {
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
token: TowerScopeLevel.Token<T>,
name: Name,
explicitReceiver: ExpressionReceiverValue?,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): ProcessorAction {
val qualifiedReceiver = explicitReceiver?.explicitReceiverExpression as FirResolvedQualifier
val classId = qualifiedReceiver.classId
val scope = when {
token == TowerScopeLevel.Token.Objects || classId == null -> {
FirExplicitSimpleImportingScope(
listOf(
FirResolvedImportImpl(
FirImportImpl(null, FqName.topLevel(name), false, null),
qualifiedReceiver.packageFqName,
qualifiedReceiver.relativeClassFqName
)
), session, bodyResolveComponents.scopeSession
)
}
else -> {
val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId) ?: return ProcessorAction.NEXT
when (symbol) {
is FirClassSymbol<*> -> symbol.fir.scope(ConeSubstitutor.Empty, session, bodyResolveComponents.scopeSession)
is FirTypeAliasSymbol ->
symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeKotlinType>()
.scope(session, bodyResolveComponents.scopeSession) ?: return ProcessorAction.NEXT
}
}
}
val processorForCallables: (FirCallableSymbol<*>) -> ProcessorAction = {
val fir = it.fir
if (fir is FirCallableMemberDeclaration<*> && fir.isStatic ||
it.callableId.classId == null ||
fir is FirConstructor && !fir.isInner
) {
@Suppress("UNCHECKED_CAST")
processor.consumeCandidate(it as T, null, null, null)
} else {
ProcessorAction.NEXT
}
}
return when (token) {
TowerScopeLevel.Token.Objects -> scope.processClassifiersByName(name) {
@Suppress("UNCHECKED_CAST")
processor.consumeCandidate(it as T, null, null, null)
}
TowerScopeLevel.Token.Functions -> {
scope.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents, processorForCallables)
}
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name, processorForCallables)
}
}
}
class NotNullableReceiverValue(val value: ReceiverValue) : ReceiverValue { class NotNullableReceiverValue(val value: ReceiverValue) : ReceiverValue {
override val type: ConeKotlinType override val type: ConeKotlinType
get() = value.type.withNullability(ConeNullability.NOT_NULL) get() = value.type.withNullability(ConeNullability.NOT_NULL)
@@ -18,6 +18,8 @@ class FirCompositeScope(
val scopes: MutableList<FirScope>, val scopes: MutableList<FirScope>,
private val reversedPriority: Boolean = false private val reversedPriority: Boolean = false
) : FirScope() { ) : FirScope() {
constructor(vararg scopes: FirScope) : this(scopes.toMutableList())
override fun processClassifiersByName( override fun processClassifiersByName(
name: Name, name: Name,
processor: (FirClassifierSymbol<*>) -> ProcessorAction processor: (FirClassifierSymbol<*>) -> ProcessorAction
@@ -0,0 +1,46 @@
/*
* 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.fir.scopes.impl
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.name.Name
class FirQualifierScope(
private val delegateCallablesScope: FirScope?,
private val delegateClassifiersScope: FirScope?
) : FirScope() {
override fun processClassifiersByName(
name: Name,
processor: (FirClassifierSymbol<*>) -> ProcessorAction
): ProcessorAction {
return delegateClassifiersScope?.processClassifiersByName(name) {
if (it is FirRegularClassSymbol) {
processor(it)
} else {
ProcessorAction.NEXT
}
} ?: ProcessorAction.NEXT
}
override fun processFunctionsByName(
name: Name,
processor: (FirFunctionSymbol<*>) -> ProcessorAction
): ProcessorAction {
return delegateCallablesScope?.processFunctionsByName(name, processor) ?: ProcessorAction.NEXT
}
override fun processPropertiesByName(
name: Name,
processor: (FirCallableSymbol<*>) -> ProcessorAction
): ProcessorAction {
return delegateCallablesScope?.processPropertiesByName(name, processor) ?: ProcessorAction.NEXT
}
}
@@ -0,0 +1,44 @@
/*
* 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.fir.scopes.impl
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.isStatic
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.name.Name
class FirStaticScope(private val delegateScope: FirScope) : FirScope() {
override fun processFunctionsByName(
name: Name,
processor: (FirFunctionSymbol<*>) -> ProcessorAction
): ProcessorAction {
return delegateScope.processFunctionsByName(name) {
if ((it.fir as? FirSimpleFunction)?.isStatic == true) {
processor(it)
} else {
ProcessorAction.NEXT
}
}
}
override fun processPropertiesByName(
name: Name,
processor: (FirCallableSymbol<*>) -> ProcessorAction
): ProcessorAction {
return delegateScope.processPropertiesByName(name) {
if ((it.fir as? FirCallableMemberDeclaration<*>)?.isStatic == true) {
processor(it)
} else {
ProcessorAction.NEXT
}
}
}
}
@@ -20,6 +20,6 @@ fun test() {
JavaClass.bar() JavaClass.bar()
val errC = BB.<!UNRESOLVED_REFERENCE!>C<!> val errC = BB.<!UNRESOLVED_REFERENCE!>C<!>
val errBarViaBB = BB.bar() val errBarViaBB = BB.<!UNRESOLVED_REFERENCE!>bar<!>()
val errBarViaAA = AA.bar() val errBarViaAA = AA.<!UNRESOLVED_REFERENCE!>bar<!>()
} }
@@ -30,6 +30,6 @@ FILE: Test.kt
lval aac: R|AA.C| = Q|AA.C| lval aac: R|AA.C| = Q|AA.C|
Q|JavaClass|.R|/JavaClass.bar|() Q|JavaClass|.R|/JavaClass.bar|()
lval errC: <ERROR TYPE REF: Unresolved name: C> = Q|BB|.<Unresolved name: C># lval errC: <ERROR TYPE REF: Unresolved name: C> = Q|BB|.<Unresolved name: C>#
lval errBarViaBB: R|kotlin/Unit| = Q|BB|.R|/JavaClass.bar|() lval errBarViaBB: <ERROR TYPE REF: Unresolved name: bar> = Q|BB|.<Unresolved name: bar>#()
lval errBarViaAA: R|kotlin/Unit| = Q|AA|.R|/JavaClass.bar|() lval errBarViaAA: <ERROR TYPE REF: Unresolved name: bar> = Q|AA|.<Unresolved name: bar>#()
} }
@@ -32,9 +32,9 @@ fun main() {
foo2(KotlinClass::baz) foo2(KotlinClass::baz)
<!AMBIGUITY!>foo3<!>(KotlinClass::baz) <!AMBIGUITY!>foo3<!>(KotlinClass::baz)
foo1(KotlinClass::bar) <!INAPPLICABLE_CANDIDATE!>foo1<!>(KotlinClass::bar)
foo2(KotlinClass::bar) foo2(KotlinClass::bar)
<!AMBIGUITY!>foo3<!>(KotlinClass::bar) foo3(KotlinClass::bar)
foo1(KotlinClass2::bar) foo1(KotlinClass2::bar)
<!INAPPLICABLE_CANDIDATE!>foo2<!>(KotlinClass2::bar) <!INAPPLICABLE_CANDIDATE!>foo2<!>(KotlinClass2::bar)
@@ -53,10 +53,10 @@ FILE: main.kt
R|/foo1|(Q|KotlinClass|::R|/KotlinClass.Companion.baz|) R|/foo1|(Q|KotlinClass|::R|/KotlinClass.Companion.baz|)
R|/foo2|(Q|KotlinClass|::R|/KotlinClass.baz|) R|/foo2|(Q|KotlinClass|::R|/KotlinClass.baz|)
<Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/KotlinClass.baz|) <Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/KotlinClass.baz|)
R|/foo1|(Q|KotlinClass|::R|/JavaClass.bar|) <Inapplicable(INAPPLICABLE): [/foo1]>#(Q|KotlinClass|::R|/JavaClass.bar|)
R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|) R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|)
<Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/JavaClass.bar|) R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|)
R|/foo1|(Q|KotlinClass2|::R|/JavaClass.bar|) R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
<Inapplicable(INAPPLICABLE): [/foo2]>#(Q|KotlinClass2|::R|/JavaClass.bar|) <Inapplicable(INAPPLICABLE): [/foo2]>#(Q|KotlinClass2|::R|/JavaClass.bar|)
R|/foo3|(Q|KotlinClass2|::R|/JavaClass.bar|) R|/foo3|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
} }
@@ -47,18 +47,18 @@ fun test() {
val ic: I.NC = I.NC() val ic: I.NC = I.NC()
val ii: I.NI? = null val ii: I.NI? = null
val bc: B.NC = B.NC() val bc: B.NC = B.<!UNRESOLVED_REFERENCE!>NC<!>()
val bic: B.IC = B().IC() val bic: B.IC = B().IC()
val bi: B.NI? = null val bi: B.NI? = null
val cc: C.NC = C.NC() val cc: C.NC = C.<!UNRESOLVED_REFERENCE!>NC<!>()
val ci: C.NI? = null val ci: C.NI? = null
val dc: D.NC = D.NC() val dc: D.NC = D.<!UNRESOLVED_REFERENCE!>NC<!>()
val dic: D.IC = D().IC() val dic: D.IC = D().IC()
val di: D.NI? = null val di: D.NI? = null
val kc: K.NC = K.NC() val kc: K.NC = K.<!UNRESOLVED_REFERENCE!>NC<!>()
val kic: K.IC = K().IC() val kic: K.IC = K().IC()
val ki: K.NI? = null val ki: K.NI? = null
} }
@@ -31,14 +31,14 @@ fun test() {
val ic: I.NC = I.NC() val ic: I.NC = I.NC()
val ii: I.NI? = null val ii: I.NI? = null
val bc: B.NC = B.NC() val bc: B.NC = B.<!UNRESOLVED_REFERENCE!>NC<!>()
val bic: B.IC = B().IC() val bic: B.IC = B().IC()
val bi: B.NI? = null val bi: B.NI? = null
val cc: C.NC = C.NC() val cc: C.NC = C.<!UNRESOLVED_REFERENCE!>NC<!>()
val ci: C.NI? = null val ci: C.NI? = null
val dc: D.NC = D.NC() val dc: D.NC = D.<!UNRESOLVED_REFERENCE!>NC<!>()
val dic: D.IC = D().IC() val dic: D.IC = D().IC()
val di: D.NI? = null val di: D.NI? = null
} }
@@ -25,8 +25,8 @@ fun main() {
C.foo() C.foo()
C.bar() C.bar()
K.a K.<!UNRESOLVED_REFERENCE!>a<!>
K.b K.<!UNRESOLVED_REFERENCE!>b<!>
K.foo() K.<!UNRESOLVED_REFERENCE!>foo<!>()
K.bar() K.<!UNRESOLVED_REFERENCE!>bar<!>()
} }
@@ -28,7 +28,7 @@ class X: A {
init { init {
A_S() A_S()
A.A_S() A.A_S()
X.A_S() X.<!UNRESOLVED_REFERENCE!>A_S<!>()
} }
object xD { object xD {
@@ -51,7 +51,7 @@ class Y: B() {
B_S() B_S()
B.B_S() B.B_S()
Y.B_S() Y.<!UNRESOLVED_REFERENCE!>B_S<!>()
} }
object X { object X {
@@ -43,20 +43,20 @@ class X: D() {
A_S() A_S()
A.A_S() A.A_S()
C.A_S() C.<!UNRESOLVED_REFERENCE!>A_S<!>()
D.A_S() D.<!UNRESOLVED_REFERENCE!>A_S<!>()
X.A_S() X.<!UNRESOLVED_REFERENCE!>A_S<!>()
B_S() B_S()
B.B_S() B.B_S()
C.B_S() C.<!UNRESOLVED_REFERENCE!>B_S<!>()
D.B_S() D.<!UNRESOLVED_REFERENCE!>B_S<!>()
X.B_S() X.<!UNRESOLVED_REFERENCE!>B_S<!>()
E_S() E_S()
E.E_S() E.E_S()
D.E_S() D.<!UNRESOLVED_REFERENCE!>E_S<!>()
X.E_S() X.<!UNRESOLVED_REFERENCE!>E_S<!>()
} }
} }
@@ -68,15 +68,15 @@ class Y: F() {
Y.<!UNRESOLVED_REFERENCE!>B_<!>() Y.<!UNRESOLVED_REFERENCE!>B_<!>()
A_S() A_S()
F.A_S() F.<!UNRESOLVED_REFERENCE!>A_S<!>()
Y.A_S() Y.<!UNRESOLVED_REFERENCE!>A_S<!>()
B_S() B_S()
F.B_S() F.<!UNRESOLVED_REFERENCE!>B_S<!>()
Y.B_S() Y.<!UNRESOLVED_REFERENCE!>B_S<!>()
E_S() E_S()
F.E_S() F.<!UNRESOLVED_REFERENCE!>E_S<!>()
Y.E_S() Y.<!UNRESOLVED_REFERENCE!>E_S<!>()
} }
} }
@@ -31,9 +31,9 @@ fun test() {
C.b C.b
C.bar() C.bar()
K.a K.<!UNRESOLVED_REFERENCE!>a<!>
K.b K.<!UNRESOLVED_REFERENCE!>b<!>
K.bar() K.<!UNRESOLVED_REFERENCE!>bar<!>()
D.a D.a
D.b D.b
@@ -37,9 +37,9 @@ fun test() {
C.b C.b
C.bar() C.bar()
K.a K.<!UNRESOLVED_REFERENCE!>a<!>
K.b K.<!UNRESOLVED_REFERENCE!>b<!>
K.bar() K.<!UNRESOLVED_REFERENCE!>bar<!>()
D.a D.a
D.b D.b
@@ -31,8 +31,8 @@ class XN: X() {
init { init {
foo() foo()
A.foo() A.foo()
X.foo() X.<!UNRESOLVED_REFERENCE!>foo<!>()
XN.foo() XN.<!UNRESOLVED_REFERENCE!>foo<!>()
} }
} }
@@ -40,12 +40,12 @@ class YN: Y() {
init { init {
foo() foo()
A.foo() A.foo()
Y.foo() Y.<!UNRESOLVED_REFERENCE!>foo<!>()
YN.foo() YN.<!UNRESOLVED_REFERENCE!>foo<!>()
bar() bar()
B.bar() B.bar()
Y.bar() Y.<!UNRESOLVED_REFERENCE!>bar<!>()
YN.bar() YN.<!UNRESOLVED_REFERENCE!>bar<!>()
} }
} }
@@ -16,12 +16,12 @@ class D: C() {
init { init {
foo() foo()
A.foo() A.foo()
B.foo() B.<!UNRESOLVED_REFERENCE!>foo<!>()
C.foo() C.foo()
D.foo() D.<!UNRESOLVED_REFERENCE!>foo<!>()
bar() bar()
C.bar() C.bar()
D.bar() D.<!UNRESOLVED_REFERENCE!>bar<!>()
} }
} }
@@ -47,8 +47,8 @@ fun test(a: KotlinClass, b: KotlinClass2) {
JavaClass.<!INAPPLICABLE_CANDIDATE!>bar1<!>() JavaClass.<!INAPPLICABLE_CANDIDATE!>bar1<!>()
JavaClass.<!INAPPLICABLE_CANDIDATE!>CONST1<!> JavaClass.<!INAPPLICABLE_CANDIDATE!>CONST1<!>
KotlinClass.<!INAPPLICABLE_CANDIDATE!>bar1<!>() // Currently it's unresolved, but it should be prohibited even in case it would be resolved KotlinClass.<!UNRESOLVED_REFERENCE!>bar1<!>() // Currently it's unresolved, but it should be prohibited even in case it would be resolved
KotlinClass.<!INAPPLICABLE_CANDIDATE!>CONST1<!> KotlinClass.<!UNRESOLVED_REFERENCE!>CONST1<!>
JavaClassSamePackage.<!INAPPLICABLE_CANDIDATE!>bar1<!>() JavaClassSamePackage.<!INAPPLICABLE_CANDIDATE!>bar1<!>()
JavaClassSamePackage.bar2() JavaClassSamePackage.bar2()
@@ -10,6 +10,6 @@ class C {
typealias CA = C typealias CA = C
val test1 = CA val test1 = CA
val test2 = CA.<!UNRESOLVED_REFERENCE!>Companion<!> val test2 = CA.Companion
val test3 = CA.<!UNRESOLVED_REFERENCE!>x<!> val test3 = CA.<!UNRESOLVED_REFERENCE!>x<!>
val test4 = CA.<!UNRESOLVED_REFERENCE!>Companion<!>.<!UNRESOLVED_REFERENCE!>x<!> val test4 = CA.Companion.x
@@ -8,4 +8,4 @@ object Since_1_1 {
typealias Since_1_1_Alias = Since_1_1 typealias Since_1_1_Alias = Since_1_1
val test1 = Since_1_1_Alias val test1 = Since_1_1_Alias
val test2 = Since_1_1_Alias.<!UNRESOLVED_REFERENCE!>x<!> val test2 = Since_1_1_Alias.x
@@ -7,8 +7,8 @@ typealias GenericTestObject<T> = AnObject
val test11: AnObject = GenericTestObject val test11: AnObject = GenericTestObject
val test12: GenericTestObject<*> = GenericTestObject val test12: GenericTestObject<*> = GenericTestObject
val test13: String = GenericTestObject.<!UNRESOLVED_REFERENCE!>ok<!> val test13: String = GenericTestObject.ok
val test14: String = GenericTestObject.<!UNRESOLVED_REFERENCE!>foo<!>() val test14: String = GenericTestObject.foo()
class GenericClassWithCompanion<T> { class GenericClassWithCompanion<T> {
companion object { companion object {
@@ -33,7 +33,7 @@ val seeAlsoDerivedFoo: String = JDerived.foo()
// Referencing nested classes via type alias should be prohibited // Referencing nested classes via type alias should be prohibited
// (in type position and in expression position) // (in type position and in expression position)
val testNested1: JT.Nested = JT.Nested() val testNested1: JT.Nested = JT.<!UNRESOLVED_REFERENCE!>Nested<!>()
val testNested2: KT.Nested = KT.Nested() val testNested2: KT.Nested = KT.Nested()
val testNested3: IT.Nested = IT.Nested() val testNested3: IT.Nested = IT.Nested()
val testInner1: JT.Inner = JT.<!UNRESOLVED_REFERENCE!>Inner<!>() val testInner1: JT.Inner = JT.<!UNRESOLVED_REFERENCE!>Inner<!>()
@@ -13,9 +13,9 @@ class C {
} }
} }
val c = C.Self.<!UNRESOLVED_REFERENCE!>Self<!>() val c = C.<!UNRESOLVED_REFERENCE!>Self<!>.<!UNRESOLVED_REFERENCE!>Self<!>()
val n = C.Self.Nested() val n = C.<!UNRESOLVED_REFERENCE!>Self<!>.<!UNRESOLVED_REFERENCE!>Nested<!>()
val x = C.Self.<!UNRESOLVED_REFERENCE!>X<!> val x = C.<!UNRESOLVED_REFERENCE!>Self<!>.<!UNRESOLVED_REFERENCE!>X<!>
val n2 = C.Nested.Root.<!UNRESOLVED_REFERENCE!>Nested<!>.<!UNRESOLVED_REFERENCE!>N2<!>() val n2 = C.Nested.<!UNRESOLVED_REFERENCE!>Root<!>.<!UNRESOLVED_REFERENCE!>Nested<!>.<!UNRESOLVED_REFERENCE!>N2<!>()
val ic = C.Self.<!UNRESOLVED_REFERENCE!>InCompanion<!>() val ic = C.<!UNRESOLVED_REFERENCE!>Self<!>.<!UNRESOLVED_REFERENCE!>InCompanion<!>()
val ok = C.Self.<!UNRESOLVED_REFERENCE!>ok<!> val ok = C.<!UNRESOLVED_REFERENCE!>Self<!>.<!UNRESOLVED_REFERENCE!>ok<!>
@@ -7,15 +7,15 @@ typealias TestObject = AnObject
val test11: AnObject = TestObject val test11: AnObject = TestObject
val test12: TestObject = TestObject val test12: TestObject = TestObject
val test13: String = TestObject.<!UNRESOLVED_REFERENCE!>ok<!> val test13: String = TestObject.ok
val test14: String = TestObject.<!UNRESOLVED_REFERENCE!>foo<!>() val test14: String = TestObject.foo()
typealias TestObject2 = TestObject typealias TestObject2 = TestObject
val test21: AnObject = TestObject2 val test21: AnObject = TestObject2
val test22: TestObject2 = TestObject2 val test22: TestObject2 = TestObject2
val test23: String = TestObject2.<!UNRESOLVED_REFERENCE!>ok<!> val test23: String = TestObject2.ok
val test24: String = TestObject2.<!UNRESOLVED_REFERENCE!>foo<!>() val test24: String = TestObject2.foo()
class ClassWithCompanion { class ClassWithCompanion {
companion object { companion object {
@@ -53,7 +53,7 @@ fun foo(
test.ClassAlias::func test.ClassAlias::func
test.ClassSample.Nested::func test.ClassSample.Nested::func
test.ClassAlias.<!UNRESOLVED_REFERENCE!>Nested<!>::func test.ClassAlias.Nested::func
test.ObjectSample::Nested test.ObjectSample::Nested
test.ObjectAlias::Nested test.ObjectAlias::Nested
@@ -62,7 +62,7 @@ fun foo(
test.ObjectAlias::func test.ObjectAlias::func
test.ObjectSample.Nested::func test.ObjectSample.Nested::func
test.ObjectAlias.<!UNRESOLVED_REFERENCE!>Nested<!>::func test.ObjectAlias.Nested::func
test.EnumSample::Nested test.EnumSample::Nested
test.EnumAlias::Nested test.EnumAlias::Nested
@@ -71,5 +71,5 @@ fun foo(
test.EnumAlias::func test.EnumAlias::func
test.EnumSample.Nested::func test.EnumSample.Nested::func
test.EnumAlias.<!UNRESOLVED_REFERENCE!>Nested<!>::func test.EnumAlias.Nested::func
} }