From 099f98f8170e54c6b04457f6d0f94d615487377e Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 28 Feb 2019 18:27:44 +0300 Subject: [PATCH] FIR: Expression typing and simple call resolver --- .../kotlin/fir/symbols/StandardClassIds.kt | 33 ++ .../fir/resolve/impl/FirTypeResolverImpl.kt | 2 +- .../FirAccessResolveTransformer.kt | 105 +---- .../transformers/FirBodyResolveTransformer.kt | 392 ++++++++++++++++++ .../FirSpecificTypeResolverTransformer.kt | 9 +- .../FirTotalResolveTransformer.kt | 3 +- .../transformers/FirTypeResolveTransformer.kt | 8 + .../kotlin/fir/scopes/impl/FirLocalScope.kt | 42 ++ .../kotlin/fir/symbols/StandardTypes.kt | 18 + .../testData/resolve/expresssions/access.kt | 6 + .../testData/resolve/expresssions/access.txt | 12 + .../testData/resolve/expresssions/simple.kt | 9 + .../testData/resolve/expresssions/simple.txt | 10 + .../testData/resolve/expresssions/when.kt | 1 + .../testData/resolve/expresssions/when.txt | 12 + .../testData/resolve/fromBuilder/enums.txt | 4 +- .../resolve/fromBuilder/simpleClass.txt | 4 +- .../testData/resolve/references/simple.txt | 4 +- .../resolve/testData/resolve/simpleClass.txt | 4 +- .../fir/FirResolveTestCaseGenerated.java | 28 ++ .../fir/declarations/FirTypedDeclaration.kt | 3 + .../impl/FirAbstractCallableMember.kt | 4 + .../impl/FirAnonymousFunctionImpl.kt | 4 + .../impl/FirDefaultPropertyAccessor.kt | 6 + .../impl/FirDefaultSetterValueParameter.kt | 4 + .../impl/FirPropertyAccessorImpl.kt | 4 + .../impl/FirValueParameterImpl.kt | 4 + .../fir/declarations/impl/FirVariableImpl.kt | 4 + .../fir/expressions/FirQualifiedAccess.kt | 3 + .../impl/FirAbstractQualifiedAccess.kt | 6 + .../expressions/impl/FirFunctionCallImpl.kt | 6 + 31 files changed, 637 insertions(+), 117 deletions(-) create mode 100644 compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/symbols/StandardTypes.kt create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/access.kt create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/access.txt create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/simple.kt create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/simple.txt create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/when.kt create mode 100644 compiler/fir/resolve/testData/resolve/expresssions/when.txt diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt new file mode 100644 index 00000000000..6463edddba8 --- /dev/null +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.symbols + +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name + +object StandardClassIds { + + private val BASE_KOTLIN_PACKAGE = FqName("kotlin") + private fun String.baseId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier(this)) + + val Nothing = "Nothing".baseId() + val Any = "Any".baseId() + + val Boolean = "Boolean".baseId() + val Char = "Char".baseId() + val Byte = "Byte".baseId() + val Short = "Short".baseId() + + val Int = "Int".baseId() + val Long = "Long".baseId() + + val String = "String".baseId() + + val Float = "Float".baseId() + val Double = "Double".baseId() + +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt index 75ad8491d9f..b36c510e97a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/impl/FirTypeResolverImpl.kt @@ -109,7 +109,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver { is FirImplicitBuiltinTypeRef -> { resolveToSymbol(typeRef, scope, position)!!.constructType(emptyList(), isNullable = false) } - is FirDynamicTypeRef, is FirImplicitTypeRef, is FirDelegatedTypeRef -> { + is FirDynamicTypeRef, is FirDelegatedTypeRef -> { ConeKotlinErrorType("Not supported: ${typeRef::class.simpleName}") } else -> error("!") diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAccessResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAccessResolveTransformer.kt index 5237debbf12..e7287e860a0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAccessResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAccessResolveTransformer.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl -import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope +import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope @@ -24,105 +24,4 @@ import org.jetbrains.kotlin.fir.visitors.compose class FirAccessResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority = true) { - private lateinit var session: FirSession - - override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult { - session = file.fileSession - return withScopeCleanup { - towerScope.scopes += FirTopLevelDeclaredMemberScope(file, session) - super.transformFile(file, data) - } - } - - override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): CompositeTransformResult { - return withScopeCleanup { - towerScope.scopes += regularClass.buildUseSiteScope(session) - super.transformRegularClass(regularClass, data) - } - } - - private var lookupFunctions = false - private var lookupProperties = false - - private inline fun withNewSettings(block: () -> T): T { - val prevFunctions = lookupFunctions - val prevProperties = lookupProperties - val result = block() - - lookupFunctions = prevFunctions - lookupProperties = prevProperties - return result - } - - - override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult { - - return withNewSettings { - lookupFunctions = true - lookupProperties = false - super.transformFunctionCall(functionCall, data) - } - } - - - override fun transformQualifiedAccessExpression( - qualifiedAccessExpression: FirQualifiedAccessExpression, - data: Nothing? - ): CompositeTransformResult { - return withNewSettings { - lookupProperties = true - lookupFunctions = false - super.transformQualifiedAccessExpression(qualifiedAccessExpression, data) - } - } - - override fun transformCallableReferenceAccess( - callableReferenceAccess: FirCallableReferenceAccess, - data: Nothing? - ): CompositeTransformResult { - return withNewSettings { - lookupProperties = true - lookupFunctions = true - super.transformCallableReferenceAccess(callableReferenceAccess, data) - } - } - - - override fun transformAssignment(assignment: FirAssignment, data: Nothing?): CompositeTransformResult { - return withNewSettings { - lookupProperties = true - lookupFunctions = false - super.transformAssignment(assignment, data) - } - } - - - override fun transformNamedReference(namedReference: FirNamedReference, data: Nothing?): CompositeTransformResult { - if (namedReference is FirResolvedCallableReference) return namedReference.compose() - val name = namedReference.name - val referents = mutableListOf() - fun collect(it: ConeCallableSymbol): ProcessorAction { - referents.add(it) - return NEXT - } - - if (lookupFunctions) - towerScope.processFunctionsByName(name, ::collect) - if (lookupProperties) - towerScope.processPropertiesByName(name, ::collect) - - return when (referents.size) { - 0 -> FirErrorNamedReference( - session, namedReference.psi, "Unresolved name: $name" - ).compose() - 1 -> FirResolvedCallableReferenceImpl( - session, namedReference.psi, - name, referents.single() - ).compose() - else -> FirErrorNamedReference( - session, namedReference.psi, "Ambiguity: $name, ${referents.map { it.callableId }}" - ).compose() - } - - } -} +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt new file mode 100644 index 00000000000..33011ce54a5 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -0,0 +1,392 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.transformers + +import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.references.FirErrorNamedReference +import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl +import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.impl.* +import org.jetbrains.kotlin.fir.scopes.lookupSuperTypes +import org.jetbrains.kotlin.fir.symbols.* +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult +import org.jetbrains.kotlin.fir.visitors.FirTransformer +import org.jetbrains.kotlin.fir.visitors.compose +import org.jetbrains.kotlin.ir.expressions.IrConstKind +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl +import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl +import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl +import org.jetbrains.kotlin.utils.addIfNotNull + +class FirBodyResolveTransformer(val session: FirSession) : FirTransformer() { + + val symbolProvider = session.service() + + override fun transformElement(element: E, data: Any?): CompositeTransformResult { + @Suppress("UNCHECKED_CAST") + return (element.transformChildren(this, data) as E).compose() + } + + override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Any?): CompositeTransformResult { + if (data == null) + return implicitTypeRef.compose() + require(data is FirTypeRef) + return data.compose() + } + + + private fun ConeClassLikeType.buildSubstitutionScope( + useSiteSession: FirSession, + unsubstituted: FirScope, + regularClass: FirRegularClass + ): FirClassSubstitutionScope? { + if (this.typeArguments.isEmpty()) return null + + val substitution = regularClass.typeParameters.zip(this.typeArguments) { typeParameter, typeArgument -> + typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type + }.filter { (_, type) -> type != null }.toMap() as Map + + return FirClassSubstitutionScope(useSiteSession, unsubstituted, substitution, true) + } + + private fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession = session): FirClassUseSiteScope { + val superTypeScope = FirCompositeScope(mutableListOf()) + val declaredScope = FirClassDeclaredMemberScope(this, useSiteSession) + lookupSuperTypes(this, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession) + .mapNotNullTo(superTypeScope.scopes) { useSiteSuperType -> + if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null + val symbol = useSiteSuperType.symbol + if (symbol is FirClassSymbol) { + val scope = symbol.fir.buildUseSiteScope(useSiteSession) + useSiteSuperType.buildSubstitutionScope(useSiteSession, scope, symbol.fir) ?: scope + } else { + null + } + } + return FirClassUseSiteScope(useSiteSession, superTypeScope, declaredScope, true) + } + + fun ConeKotlinType.scope(useSiteSession: FirSession): FirScope { + when (this) { + is ConeClassTypeImpl -> return (this.symbol as FirBasedSymbol).fir.buildUseSiteScope(useSiteSession) + else -> error("Failed type ${this}") + } + } + + override fun transformRegularClass(regularClass: FirRegularClass, data: Any?): CompositeTransformResult { + return withScopeCleanup { + scopes += regularClass.buildUseSiteScope() + super.transformRegularClass(regularClass, data) + } + } + + + protected inline fun withScopeCleanup(crossinline l: () -> T): T { + val sizeBefore = scopes.size + val result = l() + val size = scopes.size + assert(size >= sizeBefore) + repeat(size - sizeBefore) { + scopes.let { it.removeAt(it.size - 1) } + } + return result + } + + val scopes = mutableListOf() + + enum class CandidateApplicability { + HIDDEN, + PARAMETER_MAPPING_ERROR, + SYNTHETIC_RESOLVED, + RESOLVED + } + + inner class ApplicabilityChecker { + + var groupCounter = 0 + val groupNumbers = mutableListOf() + val candidates = mutableListOf() + + + var currentApplicability = CandidateApplicability.HIDDEN + + + var expectedType: FirTypeRef? = null + var explicitReceiverType: FirTypeRef? = null + + fun newDataSet() { + groupNumbers.clear() + candidates.clear() + groupCounter = 0 + expectedType = null + currentApplicability = CandidateApplicability.HIDDEN + } + + fun newGroup() { + groupCounter++ + } + + + fun isSubtypeOf(superType: FirTypeRef?, subType: FirTypeRef?): Boolean { + if (superType == null && subType == null) return true + if (superType != null && subType != null) return true + return false + } + + + private fun getApplicability(symbol: ConeCallableSymbol): CandidateApplicability { + val declaration = (symbol as? FirBasedSymbol)?.fir + ?: return CandidateApplicability.HIDDEN + + if (!isSubtypeOf(declaration.receiverTypeRef, explicitReceiverType)) return CandidateApplicability.PARAMETER_MAPPING_ERROR + return CandidateApplicability.RESOLVED + } + + fun consumeCandidate(symbol: ConeCallableSymbol) { + val applicability = getApplicability(symbol) + + if (applicability > currentApplicability) { + groupNumbers.clear() + candidates.clear() + currentApplicability = applicability + } + + + if (applicability == currentApplicability) { + candidates.add(symbol) + groupNumbers.add(groupCounter) + } + } + } + + override fun transformQualifiedAccessExpression( + qualifiedAccessExpression: FirQualifiedAccessExpression, + data: Any? + ): CompositeTransformResult { + qualifiedAccessExpression.explicitReceiver?.visitNoTransform(this, null) + val callee = qualifiedAccessExpression.calleeReference as? FirNamedReference ?: return qualifiedAccessExpression.compose() + + with(ApplicabilityChecker()) { + expectedType = data as FirTypeRef? + explicitReceiverType = qualifiedAccessExpression.explicitReceiver?.resultType + newDataSet() + + for (scope in scopes.asReversed()) { + newGroup() + val name = callee.name + scope.processPropertiesByName(name) { + consumeCandidate(symbol = it) + ProcessorAction.NEXT + } + if (currentApplicability == CandidateApplicability.RESOLVED) { + break + } + } + + val result = candidates + qualifiedAccessExpression.transformCalleeReference(this@FirBodyResolveTransformer, result) + + bindingContext[qualifiedAccessExpression] = + when (val newCallee = qualifiedAccessExpression.calleeReference) { + is FirErrorNamedReference -> + FirErrorTypeRefImpl(session, qualifiedAccessExpression.psi, newCallee.errorReason) + is FirResolvedCallableReference -> + (newCallee.callableSymbol as FirBasedSymbol).fir.returnTypeRef + else -> error("WTF!") + } + } + return qualifiedAccessExpression.compose() + } + + override fun transformNamedReference(namedReference: FirNamedReference, data: Any?): CompositeTransformResult { + if (namedReference is FirResolvedCallableReference) return namedReference.compose() + val name = namedReference.name + val referents = data as? List ?: return namedReference.compose() + return when (referents.size) { + 0 -> FirErrorNamedReference( + namedReference.session, namedReference.psi, "Unresolved name: $name" + ).compose() + 1 -> FirResolvedCallableReferenceImpl( + namedReference.session, namedReference.psi, + name, referents.single() + ).compose() + else -> FirErrorNamedReference( + namedReference.session, namedReference.psi, "Ambiguity: $name, ${referents.map { it.callableId }}" + ).compose() + } + } + +// +// override fun transformAssignment(assignment: FirAssignment, data: Any?): CompositeTransformResult { +// return withNewSettings { +// lookupProperties = true +// lookupFunctions = false +// super.transformAssignment(assignment, data) +// } +// } + +// +// override fun transformNamedReference(namedReference: FirNamedReference, data: Any?): CompositeTransformResult { +// if (namedReference is FirResolvedCallableReference) return namedReference.compose() +// val name = namedReference.name +// val referents = mutableListOf() +// fun collect(it: ConeCallableSymbol): ProcessorAction { +// referents.add(it) +// return ProcessorAction.NEXT +// } +// +// if (lookupFunctions) +// towerScope.processFunctionsByName(name, ::collect) +// if (lookupProperties) +// towerScope.processPropertiesByName(name, ::collect) +// +// return when (referents.size) { +// 0 -> FirErrorNamedReference( +// namedReference.session, namedReference.psi, "Unresolved name: $name" +// ).compose() +// 1 -> FirResolvedCallableReferenceImpl( +// namedReference.session, namedReference.psi, +// name, referents.single() +// ).compose() +// else -> FirErrorNamedReference( +// namedReference.session, namedReference.psi, "Ambiguity: $name, ${referents.map { it.callableId }}" +// ).compose() +// } +// +// } +// +// override fun transformQualifiedAccessExpression( +// qualifiedAccessExpression: FirQualifiedAccessExpression, +// data: Any? +// ): CompositeTransformResult { +// +// +// +// return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data) +// } + + + override fun transformBlock(block: FirBlock, data: Any?): CompositeTransformResult { + + block.transformChildren(this, data) + val statement = block.statements.lastOrNull() + + val resultExpression = when (statement) { + is FirReturnExpression -> statement.result + is FirExpression -> statement + else -> null + } + resultExpression?.resultType?.let { bindingContext[block] = it } + return super.transformBlock(block, data) + } + + private fun commonSuperType(types: List): FirTypeRef { + return types.first() + } + + override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): CompositeTransformResult { + + val type = commonSuperType(whenExpression.branches.mapNotNull { + it.result.visitNoTransform(this, data) + it.result.resultType + }) + bindingContext[whenExpression] = type + return super.transformWhenExpression(whenExpression, data) + } + + override fun transformConstExpression(constExpression: FirConstExpression, data: Any?): CompositeTransformResult { + if (data == null) return constExpression.compose() + val expectedType = data as FirTypeRef + + if (expectedType is FirImplicitTypeRef) { + + val symbol = when (constExpression.kind) { + IrConstKind.Null -> StandardClassIds.Nothing(symbolProvider) + IrConstKind.Boolean -> StandardClassIds.Boolean(symbolProvider) + IrConstKind.Char -> StandardClassIds.Char(symbolProvider) + IrConstKind.Byte -> StandardClassIds.Byte(symbolProvider) + IrConstKind.Short -> StandardClassIds.Short(symbolProvider) + IrConstKind.Int -> StandardClassIds.Int(symbolProvider) + IrConstKind.Long -> StandardClassIds.Long(symbolProvider) + IrConstKind.String -> StandardClassIds.String(symbolProvider) + IrConstKind.Float -> StandardClassIds.Float(symbolProvider) + IrConstKind.Double -> StandardClassIds.Double(symbolProvider) + } + + val type = ConeClassTypeImpl(symbol, emptyArray(), isNullable = constExpression.kind == IrConstKind.Null) + + bindingContext[constExpression] = FirResolvedTypeRefImpl(session, null, type, false, emptyList()) + } else { + bindingContext[constExpression] = expectedType + } + + + return super.transformConstExpression(constExpression, data) + } + + @Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")")) + val bindingContext = mutableMapOf() + + val FirExpression.resultType: FirTypeRef? get() = bindingContext[this] + + + override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult { + + return withScopeCleanup { + scopes.addIfNotNull(namedFunction.receiverTypeRef?.coneTypeSafe()?.scope(session)) + val body = namedFunction.body + if (namedFunction.returnTypeRef is FirImplicitTypeRef && body != null) { + body.visitNoTransform(this, namedFunction.returnTypeRef) + namedFunction.transformReturnTypeRef(this, body.resultType) + } + + super.transformNamedFunction(namedFunction, data) + } + + } + + override fun transformVariable(variable: FirVariable, data: Any?): CompositeTransformResult { + val initializer = variable.initializer + initializer?.visitNoTransform(this, variable.returnTypeRef) + if (variable.returnTypeRef is FirImplicitTypeRef) { + when { + variable.delegate != null -> TODO("!?") + initializer != null -> { + variable.transformReturnTypeRef(this, initializer.resultType) + } + } + } + return super.transformVariable(variable, data) + } + + override fun transformProperty(property: FirProperty, data: Any?): CompositeTransformResult { + return transformVariable(property, data) + } + + private fun FirElement.visitNoTransform(transformer: FirTransformer, data: D) { + val result = this.transform(transformer, data) + require(result.single === this) + } +} + + +@Deprecated("It is temp", level = DeprecationLevel.WARNING, replaceWith = ReplaceWith("TODO(\"что-то нормальное\")")) +class FirBodyResolveTransformerAdapter : FirTransformer() { + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + return element.compose() + } + + override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult { + val transformer = FirBodyResolveTransformer(file.session) + return file.transform(transformer, null) + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt index e80991d3ef2..27a19acbc64 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt @@ -11,10 +11,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.resolve.FirTypeResolver import org.jetbrains.kotlin.fir.scopes.FirPosition import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirResolvedFunctionTypeRefImpl import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult @@ -59,4 +56,8 @@ class FirSpecificTypeResolverTransformer( override fun transformResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: Nothing?): CompositeTransformResult { return resolvedTypeRef.compose() } + + override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Nothing?): CompositeTransformResult { + return implicitTypeRef.compose() + } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveTransformer.kt index d05bd80e232..bc93046e707 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveTransformer.kt @@ -15,7 +15,8 @@ class FirTotalResolveTransformer { FirSupertypeResolverTransformer(), FirTypeResolveTransformer(), FirStatusResolveTransformer(), - FirAccessResolveTransformer() + FirAccessResolveTransformer(), + FirBodyResolveTransformerAdapter() ) fun processFiles(files: List) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 5ad8958dd87..5e8648c737a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -13,8 +13,11 @@ import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.scopes.FirPosition import org.jetbrains.kotlin.fir.scopes.addImportingScopes import org.jetbrains.kotlin.fir.scopes.impl.* +import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult +import org.jetbrains.kotlin.fir.visitors.compose open class FirTypeResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(reversedScopePriority = true) { private lateinit var session: FirSession @@ -76,6 +79,11 @@ open class FirTypeResolveTransformer : FirAbstractTreeTransformerWithSuperTypes( } } + override fun transformImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: Nothing?): CompositeTransformResult { + if (implicitTypeRef is FirImplicitBuiltinTypeRef) return super.transformImplicitTypeRef(implicitTypeRef, data) + return implicitTypeRef.compose() + } + override fun transformTypeRef(typeRef: FirTypeRef, data: Nothing?): CompositeTransformResult { return FirSpecificTypeResolverTransformer(towerScope, FirPosition.OTHER, session).transformTypeRef(typeRef, data) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt new file mode 100644 index 00000000000..939d9b54c49 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.scopes.impl + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirNamedDeclaration +import org.jetbrains.kotlin.fir.declarations.FirNamedFunction +import org.jetbrains.kotlin.fir.expressions.FirVariable +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol +import org.jetbrains.kotlin.name.Name + +//class FirLocalScope : FirScope { +// +// val properties = mutableMapOf() +// val functions = mutableMapOf() +// +// fun storeDeclaration(declaration: FirNamedDeclaration) { +// when (declaration) { +// is FirVariable -> properties[declaration.name] = declaration +// is FirNamedFunction -> functions[declaration.name] = declaration +// +// } +// } +// +// override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction { +// return super.processFunctionsByName(name, processor) +// } +// +// override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction { +// val prop = properties[name] +// if (prop != null) { +// return processor() +// } +// return ProcessorAction.NEXT +// } +//} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/symbols/StandardTypes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/symbols/StandardTypes.kt new file mode 100644 index 00000000000..548f4532bfe --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/symbols/StandardTypes.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.symbols + +import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider +import org.jetbrains.kotlin.name.ClassId + + +val FirSymbolProvider.Any: ConeClassLikeSymbol get() = this.getClassLikeSymbolByFqName(StandardClassIds.Any)!! +val FirSymbolProvider.Nothing: ConeClassLikeSymbol get() = this.getClassLikeSymbolByFqName(StandardClassIds.Nothing)!! + + +operator fun ClassId.invoke(symbolProvider: FirSymbolProvider): ConeClassLikeSymbol { + return symbolProvider.getClassLikeSymbolByFqName(this)!! +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/access.kt b/compiler/fir/resolve/testData/resolve/expresssions/access.kt new file mode 100644 index 00000000000..70966b37958 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/access.kt @@ -0,0 +1,6 @@ + +class Foo { + val x = 1 + + fun abc() = x +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/access.txt b/compiler/fir/resolve/testData/resolve/expresssions/access.txt new file mode 100644 index 00000000000..488099d7967 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/access.txt @@ -0,0 +1,12 @@ +FILE: access.kt + public final class Foo { + public constructor(): super() + + public final property x(val): R|kotlin/Int| = Int(1) + public get(): + + public final function abc(): R|kotlin/Int| { + return@@@abc R|/Foo.x| + } + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/simple.kt b/compiler/fir/resolve/testData/resolve/expresssions/simple.kt new file mode 100644 index 00000000000..9b1486d66f6 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/simple.kt @@ -0,0 +1,9 @@ +fun foo() { + val x = 1 +} + +val bar = "" + +val n = null + +val g: String? = null \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/simple.txt b/compiler/fir/resolve/testData/resolve/expresssions/simple.txt new file mode 100644 index 00000000000..e68c8994699 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/simple.txt @@ -0,0 +1,10 @@ +FILE: simple.kt + public final function foo(): R|kotlin/Unit| { + val x: R|kotlin/Int| = Int(1) + } + public final property bar(val): R|kotlin/String| = String() + public get(): + public final property n(val): R|kotlin/Nothing|? = Null(null) + public get(): + public final property g(val): R|kotlin/String|? = Null(null) + public get(): R|kotlin/String|? diff --git a/compiler/fir/resolve/testData/resolve/expresssions/when.kt b/compiler/fir/resolve/testData/resolve/expresssions/when.kt new file mode 100644 index 00000000000..06e1c6cf959 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/when.kt @@ -0,0 +1 @@ +fun foo() = if (true) 1 else 0 \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/when.txt b/compiler/fir/resolve/testData/resolve/expresssions/when.txt new file mode 100644 index 00000000000..a96cf5b3a74 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/when.txt @@ -0,0 +1,12 @@ +FILE: when.kt + public final function foo(): R|kotlin/Int| { + return@@@foo when () { + Boolean(true) -> { + Int(1) + } + else -> { + Int(0) + } + } + + } diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt index 17b7b376f09..89666052ce2 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt @@ -62,8 +62,8 @@ FILE: enums.kt public final companion object Companion { public constructor(): super() - public final const property G(val): R|error: Not supported: FirImplicitTypeRefImpl| = Double(6.67E-11) - public get(): R|error: Not supported: FirImplicitTypeRefImpl| + public final const property G(val): R|kotlin/Double| = Double(6.67E-11) + public get(): } diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt index 7f99ea9aa38..e0312912cd5 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/simpleClass.txt @@ -9,8 +9,8 @@ FILE: simpleClass.kt public final class SomeClass : R|SomeInterface| { public constructor(): super() - private final property baz(val): R|error: Not supported: FirImplicitTypeRefImpl| = Int(42) - private get(): R|error: Not supported: FirImplicitTypeRefImpl| + private final property baz(val): R|kotlin/Int| = Int(42) + private get(): public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| { return@@@foo #(#(#, #), R|/SomeClass.baz|) diff --git a/compiler/fir/resolve/testData/resolve/references/simple.txt b/compiler/fir/resolve/testData/resolve/references/simple.txt index 8c326396d4a..786f1b20165 100644 --- a/compiler/fir/resolve/testData/resolve/references/simple.txt +++ b/compiler/fir/resolve/testData/resolve/references/simple.txt @@ -1,7 +1,7 @@ FILE: simple.kt - public final function foo(): R|error: Not supported: FirImplicitTypeRefImpl| { + public final function foo(): R|kotlin/Int| { return@@@foo Int(1) } - public final function bar(): R|error: Not supported: FirImplicitTypeRefImpl| { + public final function bar(): { return@@@bar R|/foo|() } diff --git a/compiler/fir/resolve/testData/resolve/simpleClass.txt b/compiler/fir/resolve/testData/resolve/simpleClass.txt index 39c83005547..8fc085d7fea 100644 --- a/compiler/fir/resolve/testData/resolve/simpleClass.txt +++ b/compiler/fir/resolve/testData/resolve/simpleClass.txt @@ -9,8 +9,8 @@ FILE: simpleClass.kt public final class SomeClass : R|SomeInterface| { public constructor(): super() - private final property baz(val): R|error: Not supported: FirImplicitTypeRefImpl| = Int(42) - private get(): R|error: Not supported: FirImplicitTypeRefImpl| + private final property baz(val): R|kotlin/Int| = Int(42) + private get(): public final override function foo(x: R|kotlin/Int|, y: R|kotlin/String|): R|kotlin/String| { return@@@foo #(#(#, #), R|/SomeClass.baz|) diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java index 49df3f9c9e5..ebcd1d3b291 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java @@ -142,6 +142,34 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase { } } + @TestMetadata("compiler/fir/resolve/testData/resolve/expresssions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Expresssions extends AbstractFirResolveTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + @TestMetadata("access.kt") + public void testAccess() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/access.kt"); + } + + public void testAllFilesPresentInExpresssions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/expresssions"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/simple.kt"); + } + + @TestMetadata("when.kt") + public void testWhen() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/when.kt"); + } + } + @TestMetadata("compiler/fir/resolve/testData/resolve/fromBuilder") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirTypedDeclaration.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirTypedDeclaration.kt index b0b4e0e2c2a..a13c1f130af 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirTypedDeclaration.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirTypedDeclaration.kt @@ -7,11 +7,14 @@ package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirVisitor interface FirTypedDeclaration : FirDeclaration, FirAnnotationContainer { val returnTypeRef: FirTypeRef + fun transformReturnTypeRef(transformer: FirTransformer, data: D) + override fun accept(visitor: FirVisitor, data: D): R = visitor.visitTypedDeclaration(this, data) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractCallableMember.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractCallableMember.kt index a725011b2ff..15a768c90ca 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractCallableMember.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractCallableMember.kt @@ -23,6 +23,10 @@ abstract class FirAbstractCallableMember : FirAbstractMemberDeclaration, FirCall final override var receiverTypeRef: FirTypeRef? final override var returnTypeRef: FirTypeRef + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } + constructor( session: FirSession, psi: PsiElement?, diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt index db51a7e2d99..1681fe91064 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt @@ -28,4 +28,8 @@ class FirAnonymousFunctionImpl( label = label?.transformSingle(transformer, data) return super.transformChildren(transformer, data) } + + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultPropertyAccessor.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultPropertyAccessor.kt index 2410f237f9f..733e858108e 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultPropertyAccessor.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultPropertyAccessor.kt @@ -32,6 +32,12 @@ abstract class FirDefaultPropertyAccessor( final override val annotations: List get() = emptyList() + + abstract override var returnTypeRef: FirTypeRef + + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } } class FirDefaultPropertyGetter( diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt index 13bf92f8b8e..3e9fe33ce85 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt @@ -34,6 +34,10 @@ class FirDefaultSetterValueParameter( return super.transformChildren(transformer, data) } + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } + companion object { val name = Name.identifier("value") } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt index acc0a12268f..3bf8bea889b 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt @@ -32,4 +32,8 @@ class FirPropertyAccessorImpl( return super.transformChildren(transformer, data) } + + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt index 2b2bb81dc2e..64b919941ac 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt @@ -31,4 +31,8 @@ open class FirValueParameterImpl( return super.transformChildren(transformer, data) } + + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirVariableImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirVariableImpl.kt index 79efcfbbea0..65b445f448a 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirVariableImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirVariableImpl.kt @@ -31,4 +31,8 @@ class FirVariableImpl( return super.transformChildren(transformer, data) } + + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirQualifiedAccess.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirQualifiedAccess.kt index ac87f85edab..3b8a0f18bb3 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirQualifiedAccess.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirQualifiedAccess.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.expressions import org.jetbrains.kotlin.fir.FirReference +import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirVisitor interface FirQualifiedAccess : FirStatement { @@ -15,6 +16,8 @@ interface FirQualifiedAccess : FirStatement { val explicitReceiver: FirExpression? get() = null + fun transformCalleeReference(transformer: FirTransformer, data: D): FirQualifiedAccess + override fun accept(visitor: FirVisitor, data: D): R = visitor.visitQualifiedAccess(this, data) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirAbstractQualifiedAccess.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirAbstractQualifiedAccess.kt index b35fad87a79..9aff0dcf666 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirAbstractQualifiedAccess.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirAbstractQualifiedAccess.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.expressions.impl import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.visitors.FirTransformer abstract class FirAbstractQualifiedAccess( @@ -24,4 +25,9 @@ abstract class FirAbstractQualifiedAccess( explicitReceiver = explicitReceiver?.transformSingle(transformer, data) return super.transformChildren(transformer, data) } + + override fun transformCalleeReference(transformer: FirTransformer, data: D): FirQualifiedAccess { + calleeReference = calleeReference.transformSingle(transformer, data) + return this + } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt index a04bad697d7..d2d64a7700d 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt @@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirFunctionCall +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.visitors.FirTransformer @@ -29,4 +30,9 @@ class FirFunctionCallImpl( explicitReceiver = explicitReceiver?.transformSingle(transformer, data) return super.transformChildren(transformer, data) } + + override fun transformCalleeReference(transformer: FirTransformer, data: D): FirQualifiedAccess { + calleeReference = calleeReference.transformSingle(transformer, data) + return this + } } \ No newline at end of file