FIR: implement qualifier resolver

This commit is contained in:
Simon Ogorodnik
2019-05-17 17:32:14 +03:00
committed by Mikhail Glukhikh
parent d3cc0e6ce9
commit cef108a5ae
43 changed files with 572 additions and 136 deletions
@@ -22,9 +22,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirUncheckedNotNullCastImpl
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.directExpansionType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.withNullability
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.symbols.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
@@ -1167,6 +1165,20 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
keyword("class")
}
private fun FlowContent.generate(resolvedQualifier: FirResolvedQualifier) {
resolved {
val symbolProvider = session.service<FirSymbolProvider>()
val classId = resolvedQualifier.classId
if (classId != null) {
symbolRef(symbolProvider.getClassLikeSymbolByFqName(classId)) {
fqn(classId.relativeClassName)
}
} else {
fqn(resolvedQualifier.packageFqName)
}
}
}
private fun FlowContent.generate(expression: FirExpression) {
exprType(expression.typeRef) {
when (expression) {
@@ -1195,6 +1207,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
is FirFunctionCall -> {
generate(expression)
}
is FirResolvedQualifier -> generate(expression)
is FirQualifiedAccessExpression -> generate(expression)
is FirNamedArgumentExpression -> {
simpleName(expression.name)
@@ -21,6 +21,9 @@ import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
@@ -1160,4 +1163,19 @@ internal class Fir2IrVisitor(
)
}
}
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Any?): IrElement {
val classId = resolvedQualifier.classId
if (classId != null) {
val classSymbol = ConeClassLikeLookupTagImpl(classId).toSymbol(session)!!
return resolvedQualifier.convertWithOffsets { startOffset, endOffset ->
IrGetObjectValueImpl(
startOffset, endOffset,
resolvedQualifier.typeRef.toIrType(session, declarationStorage),
classSymbol.toIrSymbol(session, declarationStorage) as IrClassSymbol
)
}
}
return super.visitResolvedQualifier(resolvedQualifier, data)
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.java.topLevelName
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
@@ -146,7 +147,7 @@ class KotlinDeserializedJvmSymbolsProvider(
): FirScope? {
val symbol = this.getClassLikeSymbolByFqName(classId) ?: return null
return symbol.firUnsafe<FirRegularClass>().buildDefaultUseSiteScope(session, scopeSession)
return symbol.firSafeNullable<FirRegularClass>()?.buildDefaultUseSiteScope(session, scopeSession)
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
@@ -29,10 +29,7 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
// For ConeClassLikeType they might be a type alias instead of a regular class
// TODO: support that case and switch back to `firUnsafe` instead of `firSafeNullable`
val fir = this.lookupTag.toSymbol(useSiteSession)?.firSafeNullable<FirRegularClass>() ?: return null
val companionScope = fir.companionObject?.buildUseSiteScope(useSiteSession, scopeSession)
val ownScope = wrapSubstitutionScopeIfNeed(useSiteSession, fir.buildUseSiteScope(useSiteSession, scopeSession)!!, scopeSession)
if (companionScope != null) FirCompositeScope(mutableListOf(ownScope, companionScope)) else ownScope
wrapSubstitutionScopeIfNeed(useSiteSession, fir.buildUseSiteScope(useSiteSession, scopeSession)!!, scopeSession)
}
is ConeTypeParameterType -> {
// TODO: support LibraryTypeParameterSymbol or get rid of it
@@ -8,16 +8,21 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
import org.jetbrains.kotlin.fir.scopes.FirPosition
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
import org.jetbrains.kotlin.fir.scopes.processClassifiersByNameWithAction
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.*
@@ -25,6 +30,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
@@ -253,6 +259,84 @@ class ScopeTowerLevel(
}
/**
* Handles only statics and top-levels, DOES NOT handle objects/companions members
*/
class QualifiedReceiverTowerLevel(session: FirSession) : SessionBasedTowerLevel(session) {
override fun <T : ConeSymbol> processElementsByName(
token: TowerScopeLevel.Token<T>,
name: Name,
explicitReceiver: ExpressionReceiverValue?,
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
): ProcessorAction {
val qualifiedReceiver = explicitReceiver?.explicitReceiverExpression as FirResolvedQualifier
val scope = FirExplicitSimpleImportingScope(
listOf(
FirResolvedImportImpl(
session,
FirImportImpl(session, null, FqName.topLevel(name), false, null),
qualifiedReceiver.packageFqName,
qualifiedReceiver.relativeClassFqName
)
), session
)
return if (token == TowerScopeLevel.Token.Objects) {
scope.processClassifiersByNameWithAction(name, FirPosition.OTHER) {
processor.consumeCandidate(it as T, null)
}
} else {
scope.processCallables(name, token.cast()) {
val fir = it.firUnsafe<FirCallableMemberDeclaration>()
if (fir.isStatic || it.callableId.classId == null) {
processor.consumeCandidate(it as T, null)
} else {
ProcessorAction.NEXT
}
}
}
}
}
class QualifiedReceiverTowerDataConsumer<T : ConeSymbol>(
val session: FirSession,
val name: Name,
val token: TowerScopeLevel.Token<T>,
val explicitReceiver: ExpressionReceiverValue,
val candidateFactory: CandidateFactory
) : TowerDataConsumer() {
override fun consume(
kind: TowerDataKind,
towerScopeLevel: TowerScopeLevel,
resultCollector: CandidateCollector,
group: Int
): ProcessorAction {
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
if (kind != TowerDataKind.EMPTY) return ProcessorAction.NEXT
return QualifiedReceiverTowerLevel(session).processElementsByName(
token,
name,
explicitReceiver,
processor = object : TowerScopeLevel.TowerScopeLevelProcessor<T> {
override fun consumeCandidate(symbol: T, dispatchReceiverValue: ClassDispatchReceiverValue?): ProcessorAction {
assert(dispatchReceiverValue == null)
resultCollector.consumeCandidate(
group,
candidateFactory.createCandidate(
symbol,
null,
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
)
)
return ProcessorAction.NEXT
}
}
)
}
}
abstract class TowerDataConsumer {
abstract fun consume(
@@ -321,14 +405,25 @@ fun createSimpleConsumer(
inferenceComponents: InferenceComponents
): TowerDataConsumer {
val factory = CandidateFactory(inferenceComponents, callInfo)
return if (callInfo.explicitReceiver != null) {
ExplicitReceiverTowerDataConsumer(
session,
name,
token,
ExpressionReceiverValue(callInfo.explicitReceiver, callInfo.typeProvider),
factory
)
val explicitReceiver = callInfo.explicitReceiver
return if (explicitReceiver != null) {
val receiverValue = ExpressionReceiverValue(explicitReceiver, callInfo.typeProvider)
if (explicitReceiver is FirResolvedQualifier) {
val qualified =
QualifiedReceiverTowerDataConsumer(session, name, token, receiverValue, factory)
if (explicitReceiver.classId != null) {
PrioritizedTowerDataConsumer(
qualified,
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory)
)
} else {
qualified
}
} else {
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory)
}
} else {
NoExplicitReceiverTowerDataConsumer(session, name, token, factory)
}
@@ -24,7 +24,7 @@ class ClassDispatchReceiverValue(val klassSymbol: FirClassSymbol) : ReceiverValu
}
class ExpressionReceiverValue(
private val explicitReceiverExpression: FirExpression,
val explicitReceiverExpression: FirExpression,
val typeProvider: (FirExpression) -> FirTypeRef?
) : ReceiverValue {
override val type: ConeKotlinType
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
@@ -39,7 +40,8 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() {
// TODO: add invoke cases
when (receiverKind) {
NO_EXPLICIT_RECEIVER -> {
if (explicitReceiver != null) return sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier)
return sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
}
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
if (explicitReceiver == null) return sink.reportApplicability(CandidateApplicability.WRONG_RECEIVER)
@@ -6,10 +6,12 @@
package org.jetbrains.kotlin.fir.resolve.transformers
import com.google.common.collect.LinkedHashMultimap
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.*
@@ -123,6 +125,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
primaryConstructorParametersScope = null
val type = regularClass.defaultType()
scopes.addIfNotNull(type.scope(session, scopeSession))
val companionObject = regularClass.companionObject
if (companionObject != null) {
scopes.addIfNotNull(symbolProvider.getClassUseSiteMemberScope(companionObject.classId, session, scopeSession))
}
val result = withLabelAndReceiverType(regularClass.name, regularClass, type) {
super.transformRegularClass(regularClass, data)
}
@@ -159,10 +165,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
}
FirOperation.SAFE_AS -> {
resolved.resultType =
resolved.conversionTypeRef.withReplacedConeType(
session,
resolved.conversionTypeRef.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
)
resolved.conversionTypeRef.withReplacedConeType(
session,
resolved.conversionTypeRef.coneTypeUnsafe<ConeKotlinType>().withNullability(ConeNullability.NULLABLE)
)
}
else -> error("Unknown type operator")
}
@@ -251,10 +257,79 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
}
}, session)
private fun <T : FirQualifiedAccess> transformCallee(qualifiedAccess: T): T {
private var qualifierStack = mutableListOf<Name>()
private var qualifierPartsToDrop = 0
private fun tryResolveAsQualifier(): FirStatement? {
val symbolProvider = session.service<FirSymbolProvider>()
var qualifierParts = qualifierStack.asReversed().map { it.asString() }
var resolved: PackageOrClass?
do {
resolved = resolveToPackageOrClass(
symbolProvider,
FqName.fromSegments(qualifierParts)
)
if (resolved == null)
qualifierParts = qualifierParts.dropLast(1)
} while (resolved == null && qualifierParts.isNotEmpty())
if (resolved != null) {
qualifierPartsToDrop = qualifierParts.size - 1
return FirResolvedQualifierImpl(session, null /* TODO */, resolved.packageFqName, resolved.relativeClassFqName)
.apply { resultType = typeForQualifier(this) }
}
return null
}
private fun typeForQualifier(resolvedQualifier: FirResolvedQualifier): FirTypeRef {
val classId = resolvedQualifier.classId
val resultType = resolvedQualifier.resultType
if (classId != null) {
val classSymbol = symbolProvider.getClassLikeSymbolByFqName(classId)!!
val declaration = classSymbol.firUnsafe<FirClassLikeDeclaration>()
if (declaration is FirClass) {
if (declaration.classKind == ClassKind.OBJECT) {
return resultType.resolvedTypeFromPrototype(
classSymbol.constructType(emptyArray(), false)
)
} else if (declaration.classKind == ClassKind.ENUM_ENTRY) {
val enumClassSymbol = symbolProvider.getClassLikeSymbolByFqName(classSymbol.classId.outerClassId!!)!!
return resultType.resolvedTypeFromPrototype(
enumClassSymbol.constructType(emptyArray(), false)
)
} else {
if (declaration is FirRegularClass) {
val companionObject = declaration.companionObject
if (companionObject != null) {
return resultType.resolvedTypeFromPrototype(
companionObject.symbol.constructType(emptyArray(), false)
)
}
}
}
}
}
// TODO: Handle no value type here
return resultType.resolvedTypeFromPrototype(
StandardClassIds.Unit(symbolProvider).constructType(emptyArray(), isNullable = false)
)
}
private fun <T : FirQualifiedAccess> transformCallee(qualifiedAccess: T): FirStatement {
val callee = qualifiedAccess.calleeReference as? FirSimpleNamedReference ?: return qualifiedAccess
if (qualifiedAccess.safe || callee.name.isSpecial) {
qualifierStack.clear()
} else {
qualifierStack.add(callee.name)
}
val qualifiedAccess = qualifiedAccess.transformExplicitReceiver(this, noExpectedType)
if (qualifierPartsToDrop > 0) {
qualifierPartsToDrop--
return qualifiedAccess.explicitReceiver ?: qualifiedAccess
}
val info = CallInfo(
CallKind.VariableAccess,
@@ -277,12 +352,32 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
)
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
val candidates = result.bestCandidates()
val nameReference = createResolvedNamedReference(
callee,
result.bestCandidates(),
candidates,
result.currentApplicability
)
if (qualifiedAccess.explicitReceiver == null &&
(candidates.size <= 1 && result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED)
) {
tryResolveAsQualifier()?.let { return it }
}
if (nameReference is FirResolvedCallableReference) {
val symbol = nameReference.coneSymbol as? ConeClassLikeSymbol
if (symbol != null) {
return FirResolvedQualifierImpl(session, nameReference.psi, symbol.classId).apply {
resultType = typeForQualifier(this)
}
}
}
if (qualifiedAccess.explicitReceiver == null) {
qualifierStack.clear()
}
val resultExpression =
qualifiedAccess.transformCalleeReference(StoreNameReference, nameReference) as T
if (resultExpression is FirExpression) storeTypeFromCallee(resultExpression)
@@ -304,15 +399,15 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
}
is FirSuperReference -> {
qualifiedAccessExpression.resultType =
callee.superTypeRef as? FirResolvedTypeRef ?:
implicitReceiverStack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull()
callee.superTypeRef as? FirResolvedTypeRef
?: implicitReceiverStack.filterIsInstance<ImplicitDispatchReceiverValue>().lastOrNull()
?.boundSymbol?.fir?.superTypeRefs?.firstOrNull()
?: FirErrorTypeRefImpl(session, qualifiedAccessExpression.psi, "No super type")
?: FirErrorTypeRefImpl(session, qualifiedAccessExpression.psi, "No super type")
}
is FirResolvedCallableReference -> {
if (qualifiedAccessExpression.typeRef !is FirResolvedTypeRef) {
qualifiedAccessExpression.resultType =
jump.tryCalculateReturnType(callee.coneSymbol.firUnsafe<FirCallableDeclaration>())
jump.tryCalculateReturnType(callee.coneSymbol.firUnsafe<FirCallableDeclaration>())
}
}
}
@@ -365,6 +460,8 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
private fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall, expectedTypeRef: FirTypeRef?): FirFunctionCall {
qualifierStack.clear()
val functionCall =
(functionCall.transformExplicitReceiver(this, noExpectedType) as FirFunctionCall)
.transformArguments(this, null) as FirFunctionCall
@@ -795,13 +892,33 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult<FirStatement> {
val transformedGetClassCall = super.transformGetClassCall(getClassCall, data).single as FirGetClassCall
val kClassSymbol = ClassId.fromString("kotlin/reflect/KClass")(session.service())
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
is FirResolvedQualifier -> {
val classId = lhs.classId
if (classId != null) {
val symbol = symbolProvider.getClassLikeSymbolByFqName(classId)!!
// TODO: Unify logic?
symbol.constructType(
Array(symbol.firUnsafe<FirClassLikeDeclaration>().typeParameters.size) {
ConeStarProjection
},
isNullable = false
)
} else {
lhs.resultType.coneTypeUnsafe<ConeKotlinType>()
}
}
else -> lhs.resultType.coneTypeUnsafe<ConeKotlinType>()
}
transformedGetClassCall.resultType =
FirResolvedTypeRefImpl(
session,
null,
kClassSymbol.constructType(arrayOf(transformedGetClassCall.argument.resultType.coneTypeUnsafe()), false),
emptyList()
)
FirResolvedTypeRefImpl(
session,
null,
kClassSymbol.constructType(arrayOf(typeOfExpression), false),
emptyList()
)
return transformedGetClassCall.compose()
}
}
@@ -49,32 +49,34 @@ class FirImportResolveTransformer() : FirAbstractTreeTransformer() {
}
private fun transformImportForFqName(fqName: FqName, delegate: FirImport): CompositeTransformResult<FirImport> {
val (packageFqName, relativeClassFqName) = resolveToPackageOrClass(fqName) ?: return delegate.compose()
val (packageFqName, relativeClassFqName) = resolveToPackageOrClass(symbolProvider, fqName) ?: return delegate.compose()
return FirResolvedImportImpl(session, delegate, packageFqName, relativeClassFqName).compose()
}
private fun resolveToPackageOrClass(fqName: FqName): PackageOrClass? {
var currentPackage = fqName
val pathSegments = fqName.pathSegments()
var prefixSize = pathSegments.size
while (!currentPackage.isRoot) {
if (symbolProvider.getPackage(currentPackage) != null) {
break
}
currentPackage = currentPackage.parent()
prefixSize--
}
fun resolveToPackageOrClass(symbolProvider: FirSymbolProvider, fqName: FqName): PackageOrClass? {
var currentPackage = fqName
val pathSegments = fqName.pathSegments()
var prefixSize = pathSegments.size
while (!currentPackage.isRoot && prefixSize > 0) {
if (symbolProvider.getPackage(currentPackage) != null) {
break
}
if (currentPackage == fqName) return PackageOrClass(currentPackage, null)
val relativeClassFqName =
FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
val classId = ClassId(currentPackage, relativeClassFqName, false)
if (symbolProvider.getClassLikeSymbolByFqName(classId) == null) return null
return PackageOrClass(currentPackage, relativeClassFqName)
currentPackage = currentPackage.parent()
prefixSize--
}
private data class PackageOrClass(val packageFqName: FqName, val relativeClassFqName: FqName?)
if (currentPackage == fqName) return PackageOrClass(currentPackage, null)
val relativeClassFqName =
FqName.fromSegments((prefixSize until pathSegments.size).map { pathSegments[it].asString() })
val classId = ClassId(currentPackage, relativeClassFqName, false)
if (symbolProvider.getClassLikeSymbolByFqName(classId) == null) return null
return PackageOrClass(currentPackage, relativeClassFqName)
}
data class PackageOrClass(val packageFqName: FqName, val relativeClassFqName: FqName?)
@@ -7,8 +7,13 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.TowerScopeLevel
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.processConstructors
import org.jetbrains.kotlin.fir.symbols.*
@@ -21,7 +26,23 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
protected val scopeCache = ScopeSession()
fun <T : ConeCallableSymbol> processCallables(
private fun getStaticsScope(classId: ClassId): FirScope? {
provider.getClassUseSiteMemberScope(classId, session, scopeCache)?.let { return it }
val symbol = provider.getClassLikeSymbolByFqName(classId) ?: error("No scope/symbol for $classId")
if (symbol is ConeTypeAliasSymbol) {
val expansionSymbol = symbol.firUnsafe<FirTypeAlias>().expandedConeType?.lookupTag?.toSymbol(session)
if (expansionSymbol as? ConeClassLikeSymbol != null) {
return getStaticsScope(expansionSymbol.classId)
}
}
return null
}
protected fun <T : ConeCallableSymbol> processCallables(
import: FirResolvedImport,
name: Name,
token: TowerScopeLevel.Token<T>,
@@ -31,9 +52,8 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
val classId = import.resolvedClassId
if (classId != null) {
val scope = getStaticsScope(classId) ?: return ProcessorAction.NEXT
val scope =
provider.getClassUseSiteMemberScope(classId, session, scopeCache) ?: error("No scope for $classId")
val action = when (token) {
TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(
@@ -75,7 +95,7 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
return ProcessorAction.NEXT
}
protected abstract fun <T : ConeCallableSymbol> processCallables(
abstract fun <T : ConeCallableSymbol> processCallables(
name: Name,
token: TowerScopeLevel.Token<T>,
processor: (ConeCallableSymbol) -> ProcessorAction
+3 -3
View File
@@ -23,7 +23,7 @@ FILE: enum.kt
public final enum entry FIRST : R|SomeEnum| {
public constructor(): R|SomeEnum.FIRST| {
super<R|SomeEnum|>(R|/O1|)
super<R|SomeEnum|>(Q|O1|)
}
public final override fun check(y: R|Some|): R|kotlin/Boolean| {
@@ -34,11 +34,11 @@ FILE: enum.kt
public final enum entry SECOND : R|SomeEnum| {
public constructor(): R|SomeEnum.SECOND| {
super<R|SomeEnum|>(R|/O2|)
super<R|SomeEnum|>(Q|O2|)
}
public final override fun check(y: R|Some|): R|kotlin/Boolean| {
^check ==(R|<local>/y|, R|/O2|)
^check ==(R|<local>/y|, Q|O2|)
}
}
@@ -42,10 +42,10 @@ FILE: companion.kt
}
public final fun test(): R|kotlin/Unit| {
R|/A|.R|/A.Companion.foo|()
R|/B|.<Inapplicable(WRONG_RECEIVER): [/A.bar]>#()
R|/B|.R|/B.Companion.baz|()
lval x: R|kotlin/String| = R|/A|.R|/A.Companion.D|
lval y: R|kotlin/String| = R|/B|.R|/B.Companion.C|
lval z: <ERROR TYPE REF: Unresolved name: D> = R|/B|.<Unresolved name: D>#
Q|A|.R|/A.Companion.foo|()
Q|B|.R|/A.bar|()
Q|B|.R|/B.Companion.baz|()
lval x: R|kotlin/String| = Q|A|.R|/A.Companion.D|
lval y: R|kotlin/String| = Q|B|.R|/B.Companion.C|
lval z: <ERROR TYPE REF: Unresolved name: D> = Q|B|.<Unresolved name: D>#
}
@@ -10,8 +10,8 @@ FILE: objects.kt
}
public final fun use(): R|A| {
^use R|/A|
^use Q|A|
}
public final fun bar(): R|A| {
^bar R|/A|.R|/A.foo|()
^bar Q|A|.R|/A.foo|()
}
@@ -0,0 +1,33 @@
package a.b
class C {
object D {
fun foo() {}
}
companion object {
fun foo() {}
}
fun foo() {}
}
enum class E {
entry
}
fun foo() {}
val f = 10
fun main() {
a.b.foo()
a.b.C.foo()
a.b.C.D.foo()
val x = a.b.f
C.foo()
C().foo()
val e = a.b.E.entry
val e1 = E.entry
}
@@ -0,0 +1,57 @@
FILE: qualifiedExpressions.kt
public final class C : R|kotlin/Any| {
public constructor(): R|a/b/C| {
super<R|kotlin/Any|>()
}
public final object D : R|kotlin/Any| {
private constructor(): R|a/b/C.D| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
}
}
public final companion object Companion : R|kotlin/Any| {
private constructor(): R|a/b/C.Companion| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
}
}
public final fun foo(): R|kotlin/Unit| {
}
}
public final enum class E : R|kotlin/Enum| {
private constructor(): R|a/b/E| {
super<R|kotlin/Enum|>()
}
public final enum entry entry : R|kotlin/Any| {
public constructor(): R|a/b/E.entry| {
super<R|kotlin/Any|>()
}
}
}
public final fun foo(): R|kotlin/Unit| {
}
public final val f: R|kotlin/Int| = Int(10)
public get(): R|kotlin/Int|
public final fun main(): R|kotlin/Unit| {
Q|a/b|.R|a/b/foo|()
Q|a/b/C|.R|a/b/C.Companion.foo|()
Q|a/b/C.D|.R|a/b/C.D.foo|()
lval x: R|kotlin/Int| = Q|a/b|.R|a/b/f|
Q|a/b/C|.R|a/b/C.Companion.foo|()
R|a/b/C.C|().R|a/b/C.foo|()
lval e: R|a/b/E| = Q|a/b/E.entry|
lval e1: R|a/b/E| = Q|a/b/E.entry|
}
+2 -2
View File
@@ -41,8 +41,8 @@ FILE: inner.kt
public final fun test(): R|kotlin/Unit| {
lval o: R|Owner| = R|/Owner.Owner|()
R|<local>/o|.R|/Owner.foo|()
lval err: R|Owner.Inner| = R|/Owner|.R|/Owner.Inner.Inner|()
R|<local>/err|.R|/Owner.Inner.baz|()
lval err: <ERROR TYPE REF: Unresolved name: Inner> = Q|Owner|.<Unresolved name: Inner>#()
R|<local>/err|.<Unresolved name: baz>#()
lval i: R|Owner.Inner| = R|<local>/o|.R|/Owner.Inner.Inner|()
R|<local>/i|.R|/Owner.Inner.gau|()
}
+2 -2
View File
@@ -40,6 +40,6 @@ FILE: simple.kt
public final fun test(): R|kotlin/Unit| {
lval o: R|Owner| = R|/Owner.Owner|()
R|<local>/o|.R|/Owner.foo|()
lval n: R|Owner.Nested| = R|/Owner|.R|/Owner.Nested.Nested|()
R|<local>/n|.R|/Owner.Nested.baz|()
lval n: <ERROR TYPE REF: Unresolved name: Nested> = Q|Owner|.<Unresolved name: Nested>#()
R|<local>/n|.<Unresolved name: baz>#()
}
@@ -1,4 +1,4 @@
FILE: companionLoad.kt
public final fun main(): R|kotlin/Unit| {
lval y: R|kotlin/Int| = R|kotlin/Int|.R|kotlin/Int.Companion.MAX_VALUE|
lval y: R|kotlin/Int| = Q|kotlin/Int|.R|kotlin/Int.Companion.MAX_VALUE|
}
@@ -1,5 +1,5 @@
FILE: reflectionClass.kt
public final val javaClass: R|java/lang/Class<kotlin/String>| = <getClass>(R|kotlin/String|).R|kotlin/jvm/java|
public final val javaClass: R|java/lang/Class<kotlin/String>| = <getClass>(Q|kotlin/String|).R|kotlin/jvm/java|
public get(): R|java/lang/Class<kotlin/String>|
public final val kotlinClass: R|kotlin/reflect/KClass<kotlin/String>| = <getClass>(R|kotlin/String|)
public final val kotlinClass: R|kotlin/reflect/KClass<kotlin/String>| = <getClass>(Q|kotlin/String|)
public get(): R|kotlin/reflect/KClass<kotlin/String>|
@@ -257,6 +257,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt");
}
@TestMetadata("qualifiedExpressions.kt")
public void testQualifiedExpressions() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/qualifiedExpressions.kt");
}
@TestMetadata("receiverConsistency.kt")
public void testReceiverConsistency() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.kt");
@@ -930,4 +930,15 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
uncheckedNotNullCast.expression.accept(this)
print("!")
}
override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier) {
print("Q|")
val classId = resolvedQualifier.classId
if (classId != null) {
print(classId.asString())
} else {
print(resolvedQualifier.packageFqName.asString().replace(".", "/"))
}
print("|")
}
}
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2019 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.expressions
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
interface FirResolvedQualifier : FirExpression {
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedQualifier(this, data)
val packageFqName: FqName
val relativeClassFqName: FqName?
val classId
get() = relativeClassFqName?.let {
ClassId(packageFqName, it, false)
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2019 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.expressions.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
class FirResolvedQualifierImpl(
session: FirSession,
psi: PsiElement?,
override val packageFqName: FqName,
override val relativeClassFqName: FqName?
) : FirResolvedQualifier, FirAbstractExpression(session, psi) {
constructor(session: FirSession, psi: PsiElement?, classId: ClassId) : this(
session,
psi,
classId.packageFqName,
classId.relativeClassName
)
}
@@ -268,6 +268,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformJump(returnExpression, data)
}
open fun transformResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: D): CompositeTransformResult<FirStatement> {
return transformExpression(resolvedQualifier, data)
}
open fun transformThrowExpression(throwExpression: FirThrowExpression, data: D): CompositeTransformResult<FirStatement> {
return transformExpression(throwExpression, data)
}
@@ -664,6 +668,10 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformResolvedImport(resolvedImport, data)
}
final override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: D): CompositeTransformResult<FirElement> {
return transformResolvedQualifier(resolvedQualifier, data)
}
final override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: D): CompositeTransformResult<FirElement> {
return transformResolvedTypeRef(resolvedTypeRef, data)
}
@@ -268,6 +268,10 @@ abstract class FirVisitor<out R, in D> {
return visitJump(returnExpression, data)
}
open fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: D): R {
return visitExpression(resolvedQualifier, data)
}
open fun visitThrowExpression(throwExpression: FirThrowExpression, data: D): R {
return visitExpression(throwExpression, data)
}
@@ -268,6 +268,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitJump(returnExpression, null)
}
open fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier) {
visitExpression(resolvedQualifier, null)
}
open fun visitThrowExpression(throwExpression: FirThrowExpression) {
visitExpression(throwExpression, null)
}
@@ -664,6 +668,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitResolvedImport(resolvedImport)
}
final override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Nothing?) {
visitResolvedQualifier(resolvedQualifier)
}
final override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: Nothing?) {
visitResolvedTypeRef(resolvedTypeRef)
}
+2 -2
View File
@@ -279,7 +279,7 @@ FILE fqName:<root> fileName:/enum.kt
$this: VALUE_PARAMETER name:<this> type:<root>.TestEnum4.TEST1
BLOCK_BODY
CALL 'public final fun println (message: kotlin.Any?): kotlin.Unit [inline] declared in kotlin.io' type=kotlin.Unit origin=null
message: ERROR_CALL 'Unresolved reference: R|/TestEnum4.TEST1|' type=<root>.TestEnum4
message: GET_OBJECT 'CLASS ENUM_ENTRY name:TEST1 modality:FINAL visibility:public superTypes:[<root>.TestEnum4]' type=<root>.TestEnum4
FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Any
overridden:
protected final fun clone (): kotlin.Any declared in kotlin.Enum
@@ -326,7 +326,7 @@ FILE fqName:<root> fileName:/enum.kt
$this: VALUE_PARAMETER name:<this> type:<root>.TestEnum4.TEST2
BLOCK_BODY
CALL 'public final fun println (message: kotlin.Any?): kotlin.Unit [inline] declared in kotlin.io' type=kotlin.Unit origin=null
message: ERROR_CALL 'Unresolved reference: R|/TestEnum4.TEST2|' type=<root>.TestEnum4
message: GET_OBJECT 'CLASS ENUM_ENTRY name:TEST2 modality:FINAL visibility:public superTypes:[<root>.TestEnum4]' type=<root>.TestEnum4
FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Any
overridden:
protected final fun clone (): kotlin.Any declared in kotlin.Enum
@@ -47,7 +47,7 @@ FILE fqName:test fileName:/callableReferenceToImportedFromObject.kt
FIELD PROPERTY_BACKING_FIELD name:test1a type:kotlin.String visibility:public [final,static]
EXPRESSION_BODY
CALL 'public final fun <get-a> (): kotlin.String declared in test.Foo' type=kotlin.String origin=null
$this: ERROR_CALL 'Unresolved reference: R|test/Foo|' type=test.Foo
$this: GET_OBJECT 'CLASS OBJECT name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=test.Foo
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1a> visibility:public modality:FINAL <> () returnType:kotlin.String
correspondingProperty: PROPERTY name:test1a visibility:public modality:FINAL [val]
BLOCK_BODY
@@ -21,7 +21,7 @@ FILE fqName:<root> fileName:/classReference.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
GET_OBJECT 'CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.A' type=<root>.A origin=null
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<T of <uninitialized parent>>
@@ -144,21 +144,21 @@ FILE fqName:<root> fileName:/complexAugmentedAssignment.kt
BLOCK_BODY
VAR name:<unary> type:kotlin.Int [val]
CALL 'public final fun <get-x1> (): kotlin.Int declared in <root>.X1' type=kotlin.Int origin=null
$this: ERROR_CALL 'Unresolved reference: R|/X1|' type=<root>.X1
$this: GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x1 type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CALL 'public final fun inc (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
VAR name:<unary> type:kotlin.Int [val]
CALL 'public final fun <get-x2> (): kotlin.Int declared in <root>.X1.X2' type=kotlin.Int origin=null
$this: ERROR_CALL 'Unresolved reference: R|/X1.X2|' type=<root>.X1.X2
$this: GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x2 type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CALL 'public final fun inc (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
VAR name:<unary> type:kotlin.Int [val]
CALL 'public final fun <get-x3> (): kotlin.Int declared in <root>.X1.X2.X3' type=kotlin.Int origin=null
$this: ERROR_CALL 'Unresolved reference: R|/X1.X2.X3|' type=<root>.X1.X2.X3
$this: GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2.X3
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x3 type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CALL 'public final fun inc (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null
$this: GET_VAR 'val <unary>: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
@@ -50,7 +50,7 @@ FILE fqName:<root> fileName:/destructuring1.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR name:<destruct> type:<root>.A [val]
ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR name:x type:kotlin.Int [val]
CALL 'public final fun component1 (): kotlin.Int declared in <root>.B' type=kotlin.Int origin=null
$this: GET_VAR 'val <destruct>: <root>.A [val] declared in <root>.test' type=<root>.A origin=null
@@ -55,7 +55,7 @@ FILE fqName:<root> fileName:/destructuringWithUnderscore.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR name:<destruct> type:<root>.A [val]
ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
VAR name:x type:kotlin.Int [val]
CALL 'public final fun component1 (): kotlin.Int declared in <root>.B' type=kotlin.Int origin=null
$this: GET_VAR 'val <destruct>: <root>.A [val] declared in <root>.test' type=<root>.A origin=null
@@ -97,7 +97,7 @@ FILE fqName:<root> fileName:/forWithImplicitReceivers.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
VAR name:<range> type:<root>.FiveTimes [val]
ERROR_CALL 'Unresolved reference: R|/FiveTimes|' type=<root>.FiveTimes
GET_OBJECT 'CLASS OBJECT name:FiveTimes modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.FiveTimes
VAR name:<iterator> type:<root>.IntCell [val]
CALL 'public open fun iterator (): <root>.IntCell declared in <root>.IReceiver' type=<root>.IntCell origin=null
$this: GET_VAR 'val <range>: <root>.FiveTimes [val] declared in <root>.test' type=<root>.FiveTimes origin=null
@@ -89,7 +89,7 @@ FILE fqName:<root> fileName:/objectAsCallable.kt
PROPERTY name:test2 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test2 type:IrErrorType visibility:public [final,static]
EXPRESSION_BODY
ERROR_CALL 'Unresolved reference: <Inapplicable(PARAMETER_MAPPING_ERROR): [/En.X.X]>#' type=IrErrorType
ERROR_CALL 'Unresolved reference: <Unresolved name: X>#' type=IrErrorType
CONST Int type=kotlin.Int value=42
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:IrErrorType
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
@@ -21,6 +21,6 @@ FILE fqName:<root> fileName:/objectClassReference.kt
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
ERROR_CALL 'No getter found for R|kotlin/jvm/java|' type=java.lang.Class<T of <uninitialized parent>>
@@ -36,7 +36,7 @@ FILE fqName:<root> fileName:/objectReference.kt
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CONST Int type=kotlin.Int value=1
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
$this: ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
$this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
CLASS CLASS name:Nested modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Z.Nested
CONSTRUCTOR visibility:public <> () returnType:<root>.Z.Nested [primary]
@@ -51,7 +51,7 @@ FILE fqName:<root> fileName:/objectReference.kt
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CONST Int type=kotlin.Int value=1
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
$this: ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
$this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
FUN name:test visibility:public modality:FINAL <> ($this:<root>.Z.Nested) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Z.Nested
BLOCK_BODY
@@ -61,7 +61,7 @@ FILE fqName:<root> fileName:/objectReference.kt
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CONST Int type=kotlin.Int value=1
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
$this: ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
$this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
@@ -88,7 +88,7 @@ FILE fqName:<root> fileName:/objectReference.kt
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CONST Int type=kotlin.Int value=1
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
$this: ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
$this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
FUNCTION_REFERENCE 'local final fun <anonymous> (): IrErrorType declared in <root>.Z.aLambda' type=IrErrorType origin=LAMBDA
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-aLambda> visibility:public modality:FINAL <> ($this:<root>.Z) returnType:IrErrorType
correspondingProperty: PROPERTY name:aLambda visibility:public modality:FINAL [val]
@@ -115,7 +115,7 @@ FILE fqName:<root> fileName:/objectReference.kt
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CONST Int type=kotlin.Int value=1
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
$this: ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
$this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
FUN name:test visibility:public modality:FINAL <> ($this:<root>.Z.anObject.<no name provided>) returnType:kotlin.Unit
$this: VALUE_PARAMETER name:<this> type:<root>.Z.anObject.<no name provided>
BLOCK_BODY
@@ -125,7 +125,7 @@ FILE fqName:<root> fileName:/objectReference.kt
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CONST Int type=kotlin.Int value=1
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
$this: ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
$this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
CONSTRUCTOR_CALL 'private constructor <init> () [primary] declared in <root>.Z.anObject.<no name provided>' type=<root>.Z.anObject.<no name provided> origin=null
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-anObject> visibility:public modality:FINAL <> ($this:<root>.Z) returnType:kotlin.Any
correspondingProperty: PROPERTY name:anObject visibility:public modality:FINAL [val]
@@ -155,4 +155,4 @@ FILE fqName:<root> fileName:/objectReference.kt
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:counter type:kotlin.Int visibility:public ' type=kotlin.Int origin=null
value: CONST Int type=kotlin.Int value=1
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Z' type=kotlin.Unit origin=null
$this: ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
$this: GET_OBJECT 'CLASS OBJECT name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z
@@ -254,23 +254,20 @@ FILE fqName:<root> fileName:/propertyReferences.kt
RETURN type=kotlin.Nothing from='public final fun <get-test_J_nonConst> (): kotlin.Int declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
PROPERTY name:test_varWithPrivateSet visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test_varWithPrivateSet type:kotlin.Int visibility:public [final,static]
FIELD PROPERTY_BACKING_FIELD name:test_varWithPrivateSet type:IrErrorType visibility:public [final,static]
EXPRESSION_BODY
CALL 'public final fun <get-varWithPrivateSet> (): kotlin.Int declared in <root>.C' type=kotlin.Int origin=null
$this: ERROR_CALL 'Unresolved reference: R|/C|' type=<root>.C
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_varWithPrivateSet> visibility:public modality:FINAL <> () returnType:kotlin.Int
ERROR_CALL 'Unresolved reference: <Unresolved name: varWithPrivateSet>#' type=IrErrorType
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_varWithPrivateSet> visibility:public modality:FINAL <> () returnType:IrErrorType
correspondingProperty: PROPERTY name:test_varWithPrivateSet visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test_varWithPrivateSet> (): kotlin.Int declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_varWithPrivateSet type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
RETURN type=kotlin.Nothing from='public final fun <get-test_varWithPrivateSet> (): IrErrorType declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_varWithPrivateSet type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
PROPERTY name:test_varWithProtectedSet visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test_varWithProtectedSet type:kotlin.Int visibility:public [final,static]
FIELD PROPERTY_BACKING_FIELD name:test_varWithProtectedSet type:IrErrorType visibility:public [final,static]
EXPRESSION_BODY
CALL 'public final fun <get-varWithProtectedSet> (): kotlin.Int declared in <root>.C' type=kotlin.Int origin=null
$this: ERROR_CALL 'Unresolved reference: R|/C|' type=<root>.C
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_varWithProtectedSet> visibility:public modality:FINAL <> () returnType:kotlin.Int
ERROR_CALL 'Unresolved reference: <Unresolved name: varWithProtectedSet>#' type=IrErrorType
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_varWithProtectedSet> visibility:public modality:FINAL <> () returnType:IrErrorType
correspondingProperty: PROPERTY name:test_varWithProtectedSet visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test_varWithProtectedSet> (): kotlin.Int declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_varWithProtectedSet type:kotlin.Int visibility:public [final,static] ' type=kotlin.Int origin=null
RETURN type=kotlin.Nothing from='public final fun <get-test_varWithProtectedSet> (): IrErrorType declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test_varWithProtectedSet type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
@@ -36,7 +36,7 @@ FILE fqName:<root> fileName:/reflectionLiterals.kt
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.reflect.KClass<<root>.A> visibility:public [final,static]
EXPRESSION_BODY
GET_CLASS type=kotlin.reflect.KClass<<root>.A>
ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
GET_OBJECT 'CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KClass<<root>.A>
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val]
BLOCK_BODY
@@ -62,14 +62,14 @@ FILE fqName:<root> fileName:/reflectionLiterals.kt
RETURN type=kotlin.Nothing from='public final fun <get-test3> (): IrErrorType declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test3 type:IrErrorType visibility:public [final,static] ' type=IrErrorType origin=null
PROPERTY name:test4 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test4 type:<root>.A visibility:public [final,static]
FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Unit visibility:public [final,static]
EXPRESSION_BODY
ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test4> visibility:public modality:FINAL <> () returnType:<root>.A
GET_OBJECT 'CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test4> visibility:public modality:FINAL <> () returnType:kotlin.Unit
correspondingProperty: PROPERTY name:test4 visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test4> (): <root>.A declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test4 type:<root>.A visibility:public [final,static] ' type=<root>.A origin=null
RETURN type=kotlin.Nothing from='public final fun <get-test4> (): kotlin.Unit declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Unit visibility:public [final,static] ' type=kotlin.Unit origin=null
PROPERTY name:test5 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test5 type:IrErrorType visibility:public [final,static]
EXPRESSION_BODY
+9 -7
View File
@@ -63,18 +63,20 @@ FILE fqName:<root> fileName:/safeCalls.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1 (x: kotlin.String?): kotlin.Int? declared in <root>'
ERROR_CALL 'No getter found for R|kotlin/String.length|' type=kotlin.Int?
FUN name:test2 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:IrErrorType
FUN name:test2 visibility:public modality:FINAL <> (x:kotlin.String?) returnType:kotlin.Int
VALUE_PARAMETER name:x index:0 type:kotlin.String?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2 (x: kotlin.String?): IrErrorType declared in <root>'
ERROR_CALL 'Unresolved reference: <Ambiguity: hashCode, [kotlin/Any.hashCode, kotlin/Any.hashCode]>#' type=IrErrorType
FUN name:test3 visibility:public modality:FINAL <> (x:kotlin.String?, y:kotlin.Any?) returnType:IrErrorType
RETURN type=kotlin.Nothing from='public final fun test2 (x: kotlin.String?): kotlin.Int declared in <root>'
CALL 'public open fun hashCode (): kotlin.Int declared in kotlin.Any' type=kotlin.Int origin=null
$this: GET_VAR 'x: kotlin.String? declared in <root>.test2' type=kotlin.String? origin=null
FUN name:test3 visibility:public modality:FINAL <> (x:kotlin.String?, y:kotlin.Any?) returnType:kotlin.Boolean
VALUE_PARAMETER name:x index:0 type:kotlin.String?
VALUE_PARAMETER name:y index:1 type:kotlin.Any?
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3 (x: kotlin.String?, y: kotlin.Any?): IrErrorType declared in <root>'
ERROR_CALL 'Unresolved reference: <Ambiguity: equals, [kotlin/Any.equals, kotlin/Any.equals]>#' type=IrErrorType
GET_VAR 'y: kotlin.Any? declared in <root>.test3' type=kotlin.Any? origin=null
RETURN type=kotlin.Nothing from='public final fun test3 (x: kotlin.String?, y: kotlin.Any?): kotlin.Boolean declared in <root>'
CALL 'public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any' type=kotlin.Boolean origin=null
$this: GET_VAR 'x: kotlin.String? declared in <root>.test3' type=kotlin.String? origin=null
other: GET_VAR 'y: kotlin.Any? declared in <root>.test3' type=kotlin.Any? origin=null
FUN name:test4 visibility:public modality:FINAL <> (x:<root>.Ref?) returnType:kotlin.Unit
VALUE_PARAMETER name:x index:0 type:<root>.Ref?
BLOCK_BODY
@@ -18,8 +18,7 @@ FILE fqName:<root> fileName:/thisReferenceBeforeClassDeclared.kt
CONSTRUCTOR visibility:private <> () returnType:<root>.WithCompanion [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> (a: <root>.WithCompanion.Companion) [primary] declared in <root>.WithCompanion'
a: CALL 'public final fun foo (): <root>.WithCompanion.Companion declared in <root>.WithCompanion.Companion' type=<root>.WithCompanion.Companion origin=null
$this: ERROR_CALL 'Unresolved reference: this#' type=<root>.WithCompanion
a: ERROR_CALL 'Unresolved reference: <Unresolved name: foo>#' type=IrErrorType
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:<no name provided> modality:FINAL visibility:local superTypes:[<root>.WithCompanion]'
CONSTRUCTOR_CALL 'private constructor <init> () [primary] declared in <root>.test.<no name provided>' type=<root>.test.<no name provided> origin=null
CLASS CLASS name:WithCompanion modality:OPEN visibility:public superTypes:[kotlin.Any]
+7 -8
View File
@@ -113,20 +113,19 @@ FILE fqName:<root> fileName:/values.kt
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Any
FUN name:test1 visibility:public modality:FINAL <> () returnType:<root>.Enum
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test1 (): kotlin.Any declared in <root>'
ERROR_CALL 'Unresolved reference: R|/Enum.A|' type=kotlin.Any
RETURN type=kotlin.Nothing from='public final fun test1 (): <root>.Enum declared in <root>'
GET_OBJECT 'CLASS ENUM_ENTRY name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Enum
FUN name:test2 visibility:public modality:FINAL <> () returnType:<root>.A
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test2 (): <root>.A declared in <root>'
ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test3 (): kotlin.Int declared in <root>'
CALL 'public final fun <get-a> (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
FUN name:test4 visibility:public modality:FINAL <> () returnType:<root>.Z
FUN name:test4 visibility:public modality:FINAL <> () returnType:<root>.Z.Companion
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun test4 (): <root>.Z declared in <root>'
ERROR_CALL 'Unresolved reference: R|/Z|' type=<root>.Z
RETURN type=kotlin.Nothing from='public final fun test4 (): <root>.Z.Companion declared in <root>'
GET_OBJECT 'CLASS CLASS name:Z modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.Z.Companion
+2 -2
View File
@@ -33,7 +33,7 @@ FILE fqName:<root> fileName:/when.kt
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp0_subject: kotlin.Any? [val] declared in <root>.testWithSubject' type=kotlin.Any? origin=null
arg1: ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
arg1: GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
then: CONST String type=kotlin.String value="A"
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String
@@ -63,7 +63,7 @@ FILE fqName:<root> fileName:/when.kt
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'x: kotlin.Any? declared in <root>.test' type=kotlin.Any? origin=null
arg1: ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
arg1: GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
then: CONST String type=kotlin.String value="A"
BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.String
@@ -45,7 +45,7 @@ FILE fqName:<root> fileName:/multipleImplicitReceivers.kt
$this: VALUE_PARAMETER name:<this> type:<root>.IFoo
BLOCK_BODY
RETURN type=kotlin.Nothing from='public open fun <get-foo> (): <root>.B declared in <root>.IFoo'
ERROR_CALL 'Unresolved reference: R|/B|' type=<root>.B
GET_OBJECT 'CLASS OBJECT name:B modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.B
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
@@ -84,7 +84,7 @@ FILE fqName:<root> fileName:/multipleImplicitReceivers.kt
VALUE_PARAMETER name:invokeImpl index:1 type:<root>.IInvoke
BLOCK_BODY
CALL 'public final fun with (receiver: T of <uninitialized parent>, block: kotlin.Function1<T of <uninitialized parent>, R of <uninitialized parent>>): R of <uninitialized parent> [inline] declared in kotlin' type=kotlin.Nothing origin=null
receiver: ERROR_CALL 'Unresolved reference: R|/A|' type=<root>.A
receiver: GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
block: BLOCK type=IrErrorType origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:<root>.A) returnType:kotlin.Nothing
VALUE_PARAMETER name:it index:0 type:<root>.A