diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/PossiblyFirFakeOverrideSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/PossiblyFirFakeOverrideSymbol.kt new file mode 100644 index 00000000000..49a5c50a653 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/PossiblyFirFakeOverrideSymbol.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.symbols + +import org.jetbrains.kotlin.fir.FirSymbolOwner +import org.jetbrains.kotlin.fir.declarations.FirDeclaration + +interface PossiblyFirFakeOverrideSymbol> : FirBasedSymbol where E : FirSymbolOwner, E : FirDeclaration { + // contract isFakeOverride == true <=> overriddenSymbol != null + val isFakeOverride: Boolean + val overriddenSymbol: S? +} \ No newline at end of file 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 0b61003367a..1013e0dc2e3 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 @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.symbols.impl import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.symbols.AccessorSymbol import org.jetbrains.kotlin.fir.symbols.CallableId +import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -23,10 +24,10 @@ sealed class FirFunctionSymbol>( open class FirNamedFunctionSymbol( callableId: CallableId, - val isFakeOverride: Boolean = false, + override val isFakeOverride: Boolean = false, // Actual for fake override only override val overriddenSymbol: FirNamedFunctionSymbol? = null -) : FirFunctionSymbol(callableId) +) : FirFunctionSymbol(callableId), PossiblyFirFakeOverrideSymbol class FirConstructorSymbol( callableId: CallableId, diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt index 365f1d54c50..50e81a356a3 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.CallableId +import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -22,10 +23,10 @@ open class FirVariableSymbol>(override val callableId: Callab open class FirPropertySymbol( callableId: CallableId, - val isFakeOverride: Boolean = false, + override val isFakeOverride: Boolean = false, // Actual for fake override only override val overriddenSymbol: FirPropertySymbol? = null -) : FirVariableSymbol(callableId) { +) : FirVariableSymbol(callableId), PossiblyFirFakeOverrideSymbol { // TODO: should we use this constructor for local variables? constructor(name: Name) : this(CallableId(name)) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt index 730ab705291..bfc0d6a5966 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt @@ -46,9 +46,15 @@ constructor( internal val firSession get() = LowLevelFirApiFacade.getSessionFor(element, firResolveState) + private val typeCheckerContext = ConeTypeCheckerContext( + isErrorTypeEqualsToAnything = true, + isStubTypeEqualsToAnything = true, + firSession + ) + internal val firSymbolBuilder = KtSymbolByFirBuilder( firSession.firSymbolProvider, - ConeTypeCheckerContext(isErrorTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true, firSession), + typeCheckerContext, element.project, validityToken ) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt index eda11879e5b..3eab7fdcc91 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt @@ -11,7 +11,6 @@ import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl -import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag @@ -38,6 +37,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil import org.jetbrains.kotlin.name.FqName /** @@ -87,7 +87,10 @@ internal class KtSymbolByFirBuilder( fun buildFirConstructorParameter(fir: FirValueParameterImpl) = symbolsCache.cache(fir) { KtFirConstructorValueParameterSymbol(fir, token, this) } - fun buildFunctionSymbol(fir: FirSimpleFunction) = symbolsCache.cache(fir) { KtFirFunctionSymbol(fir, token, this) } + fun buildFunctionSymbol(fir: FirSimpleFunction, forcedOrigin: FirDeclarationOrigin? = null) = symbolsCache.cache(fir) { + KtFirFunctionSymbol(fir, token, this, forcedOrigin) + } + fun buildConstructorSymbol(fir: FirConstructor) = symbolsCache.cache(fir) { KtFirConstructorSymbol(fir, token, this) } fun buildTypeParameterSymbol(fir: FirTypeParameter) = symbolsCache.cache(fir) { KtFirTypeParameterSymbol(fir, token) } @@ -96,10 +99,10 @@ internal class KtSymbolByFirBuilder( fun buildFieldSymbol(fir: FirField) = symbolsCache.cache(fir) { KtFirJavaFieldSymbol(fir, token, this) } fun buildAnonymousFunctionSymbol(fir: FirAnonymousFunction) = symbolsCache.cache(fir) { KtFirAnonymousFunctionSymbol(fir, token, this) } - fun buildVariableSymbol(fir: FirProperty): KtVariableSymbol = symbolsCache.cache(fir) { + fun buildVariableSymbol(fir: FirProperty, forcedOrigin: FirDeclarationOrigin? = null): KtVariableSymbol = symbolsCache.cache(fir) { when { fir.isLocal -> KtFirLocalVariableSymbol(fir, token, this) - else -> KtFirPropertySymbol(fir, token, this) + else -> KtFirPropertySymbol(fir, token, this, forcedOrigin) } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDelegatingScope.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDelegatingScope.kt index d5ff6352535..26ae774ef78 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDelegatingScope.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/scopes/KtFirDelegatingScope.kt @@ -6,17 +6,20 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.scopes import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.processClassifiersByName +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.PossiblyFirFakeOverrideSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder -import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScope import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.KtClass internal abstract class KtFirDelegatingScope(private val builder: KtSymbolByFirBuilder) : KtScope { abstract val firScope: FirScope @@ -51,11 +54,17 @@ internal abstract class KtFirDelegatingScope(private val builder: KtSymbolByFirB val callables = mutableListOf() firScope.processFunctionsByName(name) { firSymbol -> (firSymbol.fir as? FirSimpleFunction)?.let { fir -> - callables.add(builder.buildFunctionSymbol(fir)) + callables.add(builder.buildFunctionSymbol(fir, firSymbol.realDeclarationOrigin())) } } firScope.processPropertiesByName(name) { firSymbol -> - callables.add(builder.buildSymbol(firSymbol.fir)) + val symbol = when { + firSymbol is FirPropertySymbol && firSymbol.isFakeOverride -> { + builder.buildVariableSymbol(firSymbol.fir, firSymbol.realDeclarationOrigin()) + } + else -> builder.buildSymbol(firSymbol.fir) + } + callables.add(symbol) } yieldAll(callables) } @@ -79,4 +88,15 @@ internal abstract class KtFirDelegatingScope(private val builder: KtSymbolByFirB override fun containsName(name: Name): Boolean = withValidityAssertion { name in getAllNames() } + + companion object { + private fun FirBasedSymbol<*>.realDeclarationOrigin(): FirDeclarationOrigin? { + if (this !is PossiblyFirFakeOverrideSymbol<*, *> || !isFakeOverride) return null + var current: FirBasedSymbol<*>? = this.overriddenSymbol + while (current is PossiblyFirFakeOverrideSymbol<*, *> && current.isFakeOverride) { + current = current.overriddenSymbol + } + return (current?.fir as? FirDeclaration)?.origin + } + } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt index 04ca61ffde9..38a84fb74de 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirFunctionSymbol.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -25,6 +26,7 @@ internal class KtFirFunctionSymbol( fir: FirSimpleFunction, override val token: ValidityOwner, private val builder: KtSymbolByFirBuilder, + private val forcedOrigin: FirDeclarationOrigin? = null ) : KtFunctionSymbol(), KtFirSymbol { override val fir: FirSimpleFunction by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } @@ -41,6 +43,7 @@ internal class KtFirFunctionSymbol( builder.buildTypeParameterSymbol(typeParameter.symbol.fir) } } + override val origin: KtSymbolOrigin get() = withValidityAssertion { forcedOrigin?.asKtSymbolOrigin() ?: super.origin } override val isSuspend: Boolean get() = withValidityAssertion { fir.isSuspend } override val receiverType: KtType? by cached { fir.receiverTypeRef?.let(builder::buildKtType) } override val isOperator: Boolean get() = withValidityAssertion { fir.isOperator } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt index c444d91fd54..9610055efbb 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirPropertySymbol.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.modality import org.jetbrains.kotlin.idea.fir.findPsi @@ -17,6 +18,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -24,7 +26,8 @@ import org.jetbrains.kotlin.name.Name internal class KtFirPropertySymbol( fir: FirProperty, override val token: ValidityOwner, - private val builder: KtSymbolByFirBuilder + private val builder: KtSymbolByFirBuilder, + private val forcedOrigin: FirDeclarationOrigin? ) : KtPropertySymbol(), KtFirSymbol { init { assert(!fir.isLocal) @@ -33,6 +36,8 @@ internal class KtFirPropertySymbol( override val fir: FirProperty by weakRef(fir) override val psi: PsiElement? by cached { fir.findPsi(fir.session) } + override val origin: KtSymbolOrigin get() = withValidityAssertion { forcedOrigin?.asKtSymbolOrigin() ?: super.origin } + override val fqName: FqName get() = withValidityAssertion { fir.symbol.callableId.asFqNameForDebugInfo() } override val isVal: Boolean get() = withValidityAssertion { fir.isVal } override val name: Name get() = withValidityAssertion { fir.name } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt index ecf466008fb..fa100005291 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/symbols/KtFirSymbol.kt @@ -17,7 +17,7 @@ internal interface KtFirSymbol : KtSymbol, ValidityOwnerByVa override val origin: KtSymbolOrigin get() = withValidityAssertion { fir.origin.asKtSymbolOrigin() } } -private fun FirDeclarationOrigin.asKtSymbolOrigin() = when (this) { +internal fun FirDeclarationOrigin.asKtSymbolOrigin() = when (this) { FirDeclarationOrigin.Source -> KtSymbolOrigin.SOURCE FirDeclarationOrigin.Library -> KtSymbolOrigin.LIBRARY FirDeclarationOrigin.Java -> KtSymbolOrigin.JAVA @@ -26,7 +26,7 @@ private fun FirDeclarationOrigin.asKtSymbolOrigin() = when (this) { FirDeclarationOrigin.FakeOverride -> throw InvalidFirDeclarationOriginForSymbol(this) FirDeclarationOrigin.ImportedFromObject -> throw InvalidFirDeclarationOriginForSymbol(this) FirDeclarationOrigin.IntersectionOverride -> throw InvalidFirDeclarationOriginForSymbol(this) - FirDeclarationOrigin.Enhancement -> throw InvalidFirDeclarationOriginForSymbol(this) + FirDeclarationOrigin.Enhancement -> KtSymbolOrigin.JAVA // TODO is FirDeclarationOrigin.Plugin -> throw InvalidFirDeclarationOriginForSymbol(this) }