From 0e3fecf614712cede76808868b917dff1ba5fa4a Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 31 Jan 2019 19:34:52 +0300 Subject: [PATCH] Implement fake override mapping for functions Related to KT-29636 --- .../jetbrains/kotlin/fir/types/ConeTypes.kt | 13 +- .../FirAccessResolveTransformer.kt | 34 +++- .../scopes/impl/FirClassSubstitutionScope.kt | 149 ++++++++++++++++++ .../resolve/overrides/simpleFakeOverride.kt | 15 ++ .../resolve/overrides/simpleFakeOverride.txt | 21 +++ .../fir/FirResolveTestCaseGenerated.java | 5 + .../org/jetbrains/kotlin/fir/FirRenderer.kt | 9 ++ .../impl/FirAbstractCallableMember.kt | 50 ++++-- .../impl/FirAbstractMemberDeclaration.kt | 36 +++-- .../impl/FirMemberFunctionImpl.kt | 56 ++++--- .../fir/symbols/impl/FirFunctionSymbol.kt | 5 +- 11 files changed, 330 insertions(+), 63 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt create mode 100644 compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.kt create mode 100644 compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index b6899ccc2fe..bc86a72f400 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -26,23 +26,30 @@ object StarProjection : ConeKotlinTypeProjection() { get() = ProjectionKind.STAR } -class ConeKotlinTypeProjectionIn(val type: ConeKotlinType) : ConeKotlinTypeProjection() { +interface ConeTypedProjection { + val type: ConeKotlinType +} + +class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection(), ConeTypedProjection { override val kind: ProjectionKind get() = ProjectionKind.IN } -class ConeKotlinTypeProjectionOut(val type: ConeKotlinType) : ConeKotlinTypeProjection() { +class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : ConeKotlinTypeProjection(), ConeTypedProjection { override val kind: ProjectionKind get() = ProjectionKind.OUT } // We assume type IS an invariant type projection to prevent additional wrapper here // (more exactly, invariant type projection contains type) -sealed class ConeKotlinType : ConeKotlinTypeProjection() { +sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection { override val kind: ProjectionKind get() = ProjectionKind.INVARIANT abstract val typeArguments: Array + + override val type: ConeKotlinType + get() = this } class ConeKotlinErrorType(val reason: String) : ConeKotlinType() { 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 14ec3666f5f..67f3f503928 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,15 +14,17 @@ 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.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT -import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope -import org.jetbrains.kotlin.fir.scopes.impl.FirClassUseSiteScope -import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope -import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope +import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol +import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.types.ConeClassErrorType +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.ConeTypedProjection import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose @@ -35,6 +37,21 @@ class FirAccessResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(rev } } + private fun ConeClassLikeType.buildSubstitutionScope( + useSiteSession: FirSession, + unsubstituted: FirScope, + regularClass: FirRegularClass + ): FirClassSubstitutionScope? { + if (this.typeArguments.isEmpty()) return null + + @Suppress("UNCHECKED_CAST") + 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) @@ -43,7 +60,8 @@ class FirAccessResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(rev if (useSiteSuperType is ConeClassErrorType) return@mapNotNullTo null val symbol = useSiteSuperType.symbol if (symbol is FirClassSymbol) { - symbol.fir.buildUseSiteScope(useSiteSession) + val scope = symbol.fir.buildUseSiteScope(useSiteSession) + useSiteSuperType.buildSubstitutionScope(useSiteSession, scope, symbol.fir) ?: scope } else { null } @@ -58,10 +76,10 @@ class FirAccessResolveTransformer : FirAbstractTreeTransformerWithSuperTypes(rev } } - var lookupFunctions = false - var lookupProperties = false + private var lookupFunctions = false + private var lookupProperties = false - inline fun withNewSettings(block: () -> T): T { + private inline fun withNewSettings(block: () -> T): T { val prevFunctions = lookupFunctions val prevProperties = lookupProperties val result = block() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt new file mode 100644 index 00000000000..cd2179e6d84 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -0,0 +1,149 @@ +/* + * 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.FirNamedFunction +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirMemberFunctionImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.symbols.* +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.ConeAbbreviatedTypeImpl +import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl +import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeImpl +import org.jetbrains.kotlin.name.Name + +class FirClassSubstitutionScope( + session: FirSession, + private val unsubstituted: FirScope, + private val substitution: Map, + lookupInFir: Boolean +) : FirAbstractProviderBasedScope(session, lookupInFir) { + + val fakeOverrides = mutableMapOf() + + private fun wrapProjection(old: ConeKotlinTypeProjection, newType: ConeKotlinType): ConeKotlinTypeProjection { + return when (old) { + is StarProjection -> old + is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(newType) + is ConeKotlinTypeProjectionOut -> ConeKotlinTypeProjectionOut(newType) + is ConeKotlinType -> newType + else -> old + } + } + + private fun ConeKotlinType.substitute(): ConeKotlinType? { + if (this is ConeTypeParameterType) return substitution[this] + + val newArguments by lazy { arrayOfNulls(typeArguments.size) } + var initialized = false + for ((index, typeArgument) in this.typeArguments.withIndex()) { + val type = (typeArgument as? ConeTypedProjection)?.type ?: continue + val newType = type.substitute() + if (newType != null) { + initialized = true + newArguments[index] = wrapProjection(typeArgument, newType) + } + } + + if (initialized) { + for ((index, typeArgument) in this.typeArguments.withIndex()) { + if (newArguments[index] == null) { + newArguments[index] = typeArgument + } + } + @Suppress("UNCHECKED_CAST") + return when (this) { + is ConeKotlinErrorType -> error("Trying to substitute arguments for error type") + is ConeTypeParameterType -> error("Trying to substitute arguments for type parameter") + is ConeClassTypeImpl -> ConeClassTypeImpl(symbol, newArguments as Array) + is ConeAbbreviatedTypeImpl -> ConeAbbreviatedTypeImpl( + abbreviationSymbol, + newArguments as Array, + directExpansion.substitute() as? ConeClassLikeType ?: directExpansion + ) + is ConeFunctionType -> TODO("Substitute function type properly") + is ConeClassLikeType -> error("Unknown class-like type to substitute: $this, ${this::class}") + } + } + return null + } + + + override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction { + unsubstituted.processFunctionsByName(name) process@{ original -> + + val function = fakeOverrides.getOrPut(original) { createFakeOverride(original, name) } + processor(function as ConeFunctionSymbol) + } + + + return super.processFunctionsByName(name, processor) + } + + override fun processPropertiesByName(name: Name, processor: (ConePropertySymbol) -> ProcessorAction): ProcessorAction { + return unsubstituted.processPropertiesByName(name, processor) + } + + private fun createFakeOverride( + original: ConeFunctionSymbol, + name: Name + ): FirFunctionSymbol { + val member = (original as FirBasedSymbol<*>).fir as? FirNamedFunction ?: error("Can't fake override for $original") + val receiverType = member.receiverType?.coneTypeUnsafe() + val newReceiverType = receiverType?.substitute() + + val returnType = member.returnType.coneTypeUnsafe() + val newReturnType = returnType.substitute() + + val newParameterTypes = member.valueParameters.map { + it.returnType.coneTypeUnsafe().substitute() + } + + val symbol = FirFunctionSymbol(original.callableId, true) + with(member) { + // TODO: consider using here some light-weight functions instead of pseudo-real FirMemberFunctionImpl + // As second alternative, we can invent some light-weight kind of FirRegularClass + FirMemberFunctionImpl( + session, + psi, + symbol, + name, + member.receiverType?.withReplacedConeType(newReceiverType), + member.returnType.withReplacedConeType(newReturnType) + ).apply { + status = member.status as FirDeclarationStatusImpl + valueParameters += member.valueParameters.zip(newParameterTypes) { valueParameter, newType -> + with(valueParameter) { + FirValueParameterImpl( + session, psi, + name, this.returnType.withReplacedConeType(newType), + defaultValue, isCrossinline, isNoinline, isVararg + ) + } + } + } + } + return symbol + } +} + + +fun FirType.withReplacedConeType(newType: ConeKotlinType?): FirResolvedType { + require(this is FirResolvedType) + if (newType == null) return this + + return FirResolvedTypeImpl( + session, psi, newType, + isNullable, + annotations + ) + +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.kt b/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.kt new file mode 100644 index 00000000000..531c52cd28b --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.kt @@ -0,0 +1,15 @@ + +open class A { + fun foo(t: T): T { + return t + } +} + +class Some + +class B : A() { + fun test() { + foo(Some()) + } +} + diff --git a/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt b/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt new file mode 100644 index 00000000000..cd972cd3685 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.txt @@ -0,0 +1,21 @@ +FILE: simpleFakeOverride.kt + public open class A { + public constructor(): super() + + public final function foo(t: R|T|): R|T| { + return@@@foo # + } + + } + public final class Some { + public constructor(): super() + + } + public final class B : R|A| { + public constructor(): super|>() + + public final function test(): R|kotlin/Unit| { + R|FakeOverride|(#()) + } + + } 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 607677b1157..c64a96956cc 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirResolveTestCaseGenerated.java @@ -259,6 +259,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase { public void testSimple() throws Exception { runTest("compiler/fir/resolve/testData/resolve/overrides/simple.kt"); } + + @TestMetadata("simpleFakeOverride.kt") + public void testSimpleFakeOverride() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/overrides/simpleFakeOverride.kt"); + } } @TestMetadata("compiler/fir/resolve/testData/resolve/references") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 768c6f34aab..31ee36a8c7c 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.ConeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinType @@ -697,7 +698,15 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() { override fun visitResolvedCallableReference(resolvedCallableReference: FirResolvedCallableReference) { print("R|") + val isFakeOverride = (resolvedCallableReference.callableSymbol as? FirFunctionSymbol)?.isFakeOverride == true + + if (isFakeOverride) { + print("FakeOverride<") + } print(resolvedCallableReference.callableSymbol.callableId) + if (isFakeOverride) { + print(">") + } print("|") } 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 6b246643f07..170d4936548 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 @@ -17,25 +17,47 @@ import org.jetbrains.kotlin.fir.types.FirType import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.name.Name -abstract class FirAbstractCallableMember( - session: FirSession, - psi: PsiElement?, - final override val symbol: FirBasedSymbol, - name: Name, - visibility: Visibility, - modality: Modality?, - isExpect: Boolean, - isActual: Boolean, - isOverride: Boolean, - final override var receiverType: FirType?, - final override var returnType: FirType -) : FirAbstractMemberDeclaration(session, psi, name, visibility, modality, isExpect, isActual), FirCallableMember { +abstract class FirAbstractCallableMember : FirAbstractMemberDeclaration, FirCallableMember { - init { + final override val symbol: FirBasedSymbol + final override var receiverType: FirType? + final override var returnType: FirType + + constructor( + session: FirSession, + psi: PsiElement?, + symbol: FirBasedSymbol, + name: Name, + receiverType: FirType?, + returnType: FirType + ) : super(session, psi, name) { + this.symbol = symbol symbol.bind(this) + this.receiverType = receiverType + this.returnType = returnType + } + + constructor( + session: FirSession, + psi: PsiElement?, + symbol: FirBasedSymbol, + name: Name, + visibility: Visibility, + modality: Modality?, + isExpect: Boolean, + isActual: Boolean, + isOverride: Boolean, + receiverType: FirType?, + returnType: FirType + ) : super(session, psi, name, visibility, modality, isExpect, isActual) { + this.symbol = symbol + symbol.bind(this) + this.receiverType = receiverType + this.returnType = returnType status.isOverride = isOverride } + override fun transformChildren(transformer: FirTransformer, data: D): FirElement { receiverType = receiverType?.transformSingle(transformer, data) returnType = returnType.transformSingle(transformer, data) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractMemberDeclaration.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractMemberDeclaration.kt index 7c1b2230632..3064d1967d6 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractMemberDeclaration.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirAbstractMemberDeclaration.kt @@ -20,23 +20,31 @@ import org.jetbrains.kotlin.name.Name abstract class FirAbstractMemberDeclaration( session: FirSession, psi: PsiElement?, - name: Name, - visibility: Visibility, - modality: Modality?, - isExpect: Boolean, - isActual: Boolean + name: Name ) : FirAbstractNamedAnnotatedDeclaration(session, psi, name), FirMemberDeclaration { - final override val typeParameters = mutableListOf() - - final override var status = FirDeclarationStatusImpl( - session, - visibility, - modality - ).apply { - this.isExpect = isExpect - this.isActual = isActual + constructor( + session: FirSession, + psi: PsiElement?, + name: Name, + visibility: Visibility, + modality: Modality?, + isExpect: Boolean, + isActual: Boolean + ) : this(session, psi, name) { + this.status = FirDeclarationStatusImpl( + session, + visibility, + modality + ).apply { + this.isExpect = isExpect + this.isActual = isActual + } } + final override val typeParameters: MutableList = mutableListOf() + + final override lateinit var status: FirDeclarationStatusImpl + override fun transformChildren(transformer: FirTransformer, data: D): FirElement { typeParameters.transformInplace(transformer, data) status = status.transformSingle(transformer, data) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirMemberFunctionImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirMemberFunctionImpl.kt index 912123e83fd..8442af909b0 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirMemberFunctionImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirMemberFunctionImpl.kt @@ -20,29 +20,39 @@ import org.jetbrains.kotlin.fir.types.FirType import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.name.Name -class FirMemberFunctionImpl( - session: FirSession, - psi: PsiElement?, - symbol: FirFunctionSymbol, - name: Name, - visibility: Visibility, - modality: Modality?, - isExpect: Boolean, - isActual: Boolean, - isOverride: Boolean, - isOperator: Boolean, - isInfix: Boolean, - isInline: Boolean, - isTailRec: Boolean, - isExternal: Boolean, - isSuspend: Boolean, - receiverType: FirType?, - returnType: FirType -) : FirAbstractCallableMember( - session, psi, symbol, name, visibility, modality, - isExpect, isActual, isOverride, receiverType, returnType -), FirNamedFunction, FirModifiableFunction { - init { +class FirMemberFunctionImpl : FirAbstractCallableMember, FirNamedFunction, FirModifiableFunction { + + constructor( + session: FirSession, + psi: PsiElement?, + symbol: FirFunctionSymbol, + name: Name, + receiverType: FirType?, + returnType: FirType + ) : super(session, psi, symbol, name, receiverType, returnType) + + constructor( + session: FirSession, + psi: PsiElement?, + symbol: FirFunctionSymbol, + name: Name, + visibility: Visibility, + modality: Modality?, + isExpect: Boolean, + isActual: Boolean, + isOverride: Boolean, + isOperator: Boolean, + isInfix: Boolean, + isInline: Boolean, + isTailRec: Boolean, + isExternal: Boolean, + isSuspend: Boolean, + receiverType: FirType?, + returnType: FirType + ) : super( + session, psi, symbol, name, visibility, modality, + isExpect, isActual, isOverride, receiverType, returnType + ) { status.isOperator = isOperator status.isInfix = isInfix status.isInline = isInline diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt index abc65997b6a..953e7209429 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirFunctionSymbol.kt @@ -11,7 +11,10 @@ import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType -class FirFunctionSymbol(override val callableId: CallableId) : ConeFunctionSymbol, AbstractFirBasedSymbol() { +class FirFunctionSymbol( + override val callableId: CallableId, + val isFakeOverride: Boolean = false +) : ConeFunctionSymbol, AbstractFirBasedSymbol() { override val parameters: List get() = emptyList() } \ No newline at end of file