FIR IDE: fix not initialized containingClassAttr for copied declaration

This commit is contained in:
Ilya Kirillov
2020-12-31 16:04:32 +01:00
parent a7903c64f1
commit c2866152bf
6 changed files with 33 additions and 27 deletions
@@ -64,23 +64,32 @@ class RawFirBuilder(
return reference.accept(Visitor(), Unit) as FirTypeRef return reference.accept(Visitor(), Unit) as FirTypeRef
} }
fun buildFunctionWithBody(function: KtNamedFunction): FirFunction<*> { fun buildFunctionWithBody(function: KtNamedFunction, original: FirFunction<*>?): FirFunction<*> {
return buildDeclaration(function) as FirFunction<*> return buildDeclaration(function, original) as FirFunction<*>
} }
fun buildSecondaryConstructor(secondaryConstructor: KtSecondaryConstructor): FirConstructor { fun buildSecondaryConstructor(secondaryConstructor: KtSecondaryConstructor, original: FirConstructor?): FirConstructor {
return buildDeclaration(secondaryConstructor) as FirConstructor return buildDeclaration(secondaryConstructor, original) as FirConstructor
} }
fun buildPropertyWithBody(property: KtProperty): FirProperty { fun buildPropertyWithBody(property: KtProperty, original: FirProperty?): FirProperty {
require(!property.isLocal) { "Should not be used to build local properties (variables)" } require(!property.isLocal) { "Should not be used to build local properties (variables)" }
return buildDeclaration(property) as FirProperty return buildDeclaration(property, original) as FirProperty
} }
private fun buildDeclaration(declaration: KtDeclaration): FirDeclaration { private fun buildDeclaration(declaration: KtDeclaration, original: FirDeclaration?): FirDeclaration {
assert(mode == RawFirBuilderMode.NORMAL) { "Building FIR declarations isn't supported in stub or lazy mode mode" } assert(mode == RawFirBuilderMode.NORMAL) { "Building FIR declarations isn't supported in stub or lazy mode mode" }
setupContextForPosition(declaration) setupContextForPosition(declaration,)
return declaration.accept(Visitor(), Unit) as FirDeclaration val firDeclaration = declaration.accept(Visitor(), Unit) as FirDeclaration
original?.let { firDeclaration.copyContainingClassAttrFrom(it) }
return firDeclaration
}
// TODO this is a (temporary) hack, instead we should properly initialize [context]
private fun FirDeclaration.copyContainingClassAttrFrom(from: FirDeclaration) {
(this as? FirCallableMemberDeclaration<*>)?.let {
it.containingClassAttr = (from as? FirCallableMemberDeclaration<*>)?.containingClassAttr
}
} }
private fun setupContextForPosition(position: KtElement) { private fun setupContextForPosition(position: KtElement) {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.builder package org.jetbrains.kotlin.fir.builder
import junit.framework.TestCase
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
@@ -36,17 +35,15 @@ abstract class AbstractPartialRawFirBuilderTestCase : AbstractRawFirBuilderTestC
private fun testFunctionPartialBuilding(filePath: String, nameToFind: String) { private fun testFunctionPartialBuilding(filePath: String, nameToFind: String) {
testPartialBuilding( testPartialBuilding(
filePath, filePath,
{ file -> file.findDescendantOfType<KtNamedFunction> { it.name == nameToFind }!! }, { file -> file.findDescendantOfType<KtNamedFunction> { it.name == nameToFind }!! }
RawFirBuilder::buildFunctionWithBody ) { rawFirBuilder, function -> rawFirBuilder.buildFunctionWithBody(function, original = null) }
)
} }
private fun testPropertyPartialBuilding(filePath: String, nameToFind: String) { private fun testPropertyPartialBuilding(filePath: String, nameToFind: String) {
testPartialBuilding( testPartialBuilding(
filePath, filePath,
{ file -> file.findDescendantOfType<KtProperty> { it.name == nameToFind }!! }, { file -> file.findDescendantOfType<KtProperty> { it.name == nameToFind }!! }
RawFirBuilder::buildPropertyWithBody ) { rawFirBuilder, property -> rawFirBuilder.buildPropertyWithBody(property, original = null) }
)
} }
private fun <T : KtElement> testPartialBuilding( private fun <T : KtElement> testPartialBuilding(
@@ -95,7 +95,7 @@ object LowLevelFirApiFacadeForCompletion {
originalFunction: FirSimpleFunction, originalFunction: FirSimpleFunction,
state: FirModuleResolveState state: FirModuleResolveState
): FirSimpleFunction { ): FirSimpleFunction {
val builtFunction = firIdeProvider.buildFunctionWithBody(element) val builtFunction = firIdeProvider.buildFunctionWithBody(element, originalFunction)
// right now we can't resolve builtFunction header properly, as it built right in air, // right now we can't resolve builtFunction header properly, as it built right in air,
// without file, which is now required for running stages other then body resolve, so we // without file, which is now required for running stages other then body resolve, so we
@@ -115,7 +115,7 @@ object LowLevelFirApiFacadeForCompletion {
originalProperty: FirProperty, originalProperty: FirProperty,
state: FirModuleResolveState state: FirModuleResolveState
): FirProperty { ): FirProperty {
val builtProperty = firIdeProvider.buildPropertyWithBody(element) val builtProperty = firIdeProvider.buildPropertyWithBody(element, originalProperty)
val originalSetter = originalProperty.setter val originalSetter = originalProperty.setter
val builtSetter = builtProperty.setter val builtSetter = builtProperty.setter
@@ -81,8 +81,8 @@ internal class ReanalyzableFunctionStructureElement(
firLazyDeclarationResolver: FirLazyDeclarationResolver, firLazyDeclarationResolver: FirLazyDeclarationResolver,
firIdeProvider: FirIdeProvider, firIdeProvider: FirIdeProvider,
): ReanalyzableFunctionStructureElement { ): ReanalyzableFunctionStructureElement {
val newFunction = firIdeProvider.buildFunctionWithBody(newKtDeclaration) as FirSimpleFunction
val originalFunction = firSymbol.fir as FirSimpleFunction val originalFunction = firSymbol.fir as FirSimpleFunction
val newFunction = firIdeProvider.buildFunctionWithBody(newKtDeclaration, originalFunction) as FirSimpleFunction
return FileStructureUtil.withDeclarationReplaced(firFile, cache, originalFunction, newFunction) { return FileStructureUtil.withDeclarationReplaced(firFile, cache, originalFunction, newFunction) {
firLazyDeclarationResolver.lazyResolveDeclaration( firLazyDeclarationResolver.lazyResolveDeclaration(
@@ -119,8 +119,8 @@ internal class ReanalyzablePropertyStructureElement(
firLazyDeclarationResolver: FirLazyDeclarationResolver, firLazyDeclarationResolver: FirLazyDeclarationResolver,
firIdeProvider: FirIdeProvider, firIdeProvider: FirIdeProvider,
): ReanalyzablePropertyStructureElement { ): ReanalyzablePropertyStructureElement {
val newProperty = firIdeProvider.buildPropertyWithBody(newKtDeclaration)
val originalProperty = firSymbol.fir val originalProperty = firSymbol.fir
val newProperty = firIdeProvider.buildPropertyWithBody(newKtDeclaration, originalProperty)
return FileStructureUtil.withDeclarationReplaced(firFile, cache, originalProperty, newProperty) { return FileStructureUtil.withDeclarationReplaced(firFile, cache, originalProperty, newProperty) {
firLazyDeclarationResolver.lazyResolveDeclaration( firLazyDeclarationResolver.lazyResolveDeclaration(
@@ -32,7 +32,7 @@ internal object FirLazyBodiesCalculator {
fun calculateLazyBodiesForFunction(simpleFunction: FirSimpleFunction) { fun calculateLazyBodiesForFunction(simpleFunction: FirSimpleFunction) {
if (simpleFunction.body !is FirLazyBlock) return if (simpleFunction.body !is FirLazyBlock) return
val rawFirBuilder = createRawFirBuilder(simpleFunction) val rawFirBuilder = createRawFirBuilder(simpleFunction)
val newFunction = rawFirBuilder.buildFunctionWithBody(simpleFunction.psi as KtNamedFunction) as FirSimpleFunction val newFunction = rawFirBuilder.buildFunctionWithBody(simpleFunction.psi as KtNamedFunction, simpleFunction) as FirSimpleFunction
simpleFunction.apply { simpleFunction.apply {
replaceBody(newFunction.body) replaceBody(newFunction.body)
replaceContractDescription(newFunction.contractDescription) replaceContractDescription(newFunction.contractDescription)
@@ -43,7 +43,7 @@ internal object FirLazyBodiesCalculator {
require(!secondaryConstructor.isPrimary) require(!secondaryConstructor.isPrimary)
if (secondaryConstructor.body !is FirLazyBlock) return if (secondaryConstructor.body !is FirLazyBlock) return
val rawFirBuilder = createRawFirBuilder(secondaryConstructor) val rawFirBuilder = createRawFirBuilder(secondaryConstructor)
val newFunction = rawFirBuilder.buildSecondaryConstructor(secondaryConstructor.psi as KtSecondaryConstructor) val newFunction = rawFirBuilder.buildSecondaryConstructor(secondaryConstructor.psi as KtSecondaryConstructor, secondaryConstructor)
secondaryConstructor.apply { secondaryConstructor.apply {
replaceBody(newFunction.body) replaceBody(newFunction.body)
} }
@@ -53,7 +53,7 @@ internal object FirLazyBodiesCalculator {
if (!needCalculatingLazyBodyForProperty(firProperty)) return if (!needCalculatingLazyBodyForProperty(firProperty)) return
val rawFirBuilder = createRawFirBuilder(firProperty) val rawFirBuilder = createRawFirBuilder(firProperty)
val newProperty = rawFirBuilder.buildPropertyWithBody(firProperty.psi as KtProperty) val newProperty = rawFirBuilder.buildPropertyWithBody(firProperty.psi as KtProperty, firProperty)
firProperty.getter?.takeIf { it.body is FirLazyBlock }?.let { getter -> firProperty.getter?.takeIf { it.body is FirLazyBlock }?.let { getter ->
val newGetter = newProperty.getter!! val newGetter = newProperty.getter!!
@@ -95,12 +95,12 @@ internal class FirIdeProvider(
// TODO move out of here // TODO move out of here
// used only for completion // used only for completion
fun buildFunctionWithBody(ktNamedFunction: KtNamedFunction): FirFunction<*> { fun buildFunctionWithBody(ktNamedFunction: KtNamedFunction, original: FirFunction<*>): FirFunction<*> {
return RawFirBuilder(session, kotlinScopeProvider).buildFunctionWithBody(ktNamedFunction) return RawFirBuilder(session, kotlinScopeProvider).buildFunctionWithBody(ktNamedFunction, original)
} }
fun buildPropertyWithBody(ktNamedFunction: KtProperty): FirProperty { fun buildPropertyWithBody(ktNamedFunction: KtProperty, original: FirProperty): FirProperty {
return RawFirBuilder(session, kotlinScopeProvider).buildPropertyWithBody(ktNamedFunction) return RawFirBuilder(session, kotlinScopeProvider).buildPropertyWithBody(ktNamedFunction, original)
} }