Skip to content

Commit 9570b64

Browse files
committed
Add 'parent' to IrDeclaration, initialize it with a hack (for migration)
1 parent 24622c0 commit 9570b64

File tree

9 files changed

+104
-22
lines changed

9 files changed

+104
-22
lines changed

compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir
1919
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
2020
import org.jetbrains.kotlin.ir.IrElement
2121
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
22+
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
2223
import org.jetbrains.kotlin.psi.KtFile
2324
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
2425
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
@@ -55,5 +56,7 @@ class Psi2IrTranslator(val configuration: Psi2IrConfiguration = Psi2IrConfigurat
5556
insertImplicitCasts(context.builtIns, irElement)
5657

5758
postprocessingSteps.forEach { it.postprocess(context, irElement) }
59+
60+
irElement.patchDeclarationParents()
5861
}
5962
}

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ interface IrDeclaration : IrStatement {
3131
val declarationKind: IrDeclarationKind
3232
val origin: IrDeclarationOrigin
3333

34+
val parent: IrDeclarationParent
35+
3436
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrStatement =
3537
accept(transformer, data) as IrStatement
3638
}

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclarationContainer.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.jetbrains.kotlin.ir.declarations
1818

19-
interface IrDeclarationContainer {
19+
interface IrDeclarationParent
20+
21+
interface IrDeclarationContainer : IrDeclarationParent {
2022
val declarations: MutableList<IrDeclaration>
2123
}

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
2424
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
2525
import org.jetbrains.kotlin.types.KotlinType
2626

27-
interface IrFunction : IrDeclaration, IrTypeParametersContainer, IrSymbolOwner {
27+
interface IrFunction : IrDeclaration, IrTypeParametersContainer, IrSymbolOwner, IrDeclarationParent {
2828
override val descriptor: FunctionDescriptor
2929
override val symbol: IrFunctionSymbol
3030

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrDeclarationBase.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ package org.jetbrains.kotlin.ir.declarations.impl
1919
import org.jetbrains.kotlin.ir.IrElementBase
2020
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
2121
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
22+
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
2223

2324
abstract class IrDeclarationBase(
2425
startOffset: Int,
2526
endOffset: Int,
2627
override val origin: IrDeclarationOrigin
27-
) : IrElementBase(startOffset, endOffset), IrDeclaration
28+
) : IrElementBase(startOffset, endOffset),
29+
IrDeclaration {
30+
31+
override lateinit var parent: IrDeclarationParent
32+
}

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTree.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
3131
import org.jetbrains.kotlin.types.KotlinType
3232
import java.util.*
3333

34-
inline fun <reified T : IrElement> T.deepCopyOld() =
35-
transform(DeepCopyIrTree(), null) as T
34+
inline fun <reified T : IrElement> T.deepCopyOld(): T =
35+
transform(DeepCopyIrTree(), null).patchDeclarationParents() as T
3636

3737
@Deprecated("Creates unbound symbols")
3838
open class DeepCopyIrTree : IrElementTransformerVoid() {

compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import java.util.*
3232
inline fun <reified T : IrElement> T.deepCopyWithSymbols(): T {
3333
val remapper = DeepCopySymbolsRemapper()
3434
acceptVoid(remapper)
35-
return transform(DeepCopyIrTreeWithSymbols(remapper), null) as T
35+
return transform(DeepCopyIrTreeWithSymbols(remapper), null).patchDeclarationParents() as T
3636
}
3737

3838

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
3+
* that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package org.jetbrains.kotlin.ir.util
7+
8+
import org.jetbrains.kotlin.ir.IrElement
9+
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
10+
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
11+
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
12+
import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase
13+
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
14+
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
15+
import org.jetbrains.kotlin.ir.visitors.acceptVoid
16+
import java.util.*
17+
18+
fun <T : IrElement> T.patchDeclarationParents() =
19+
apply {
20+
acceptVoid(PatchDeclarationParentsVisitor())
21+
}
22+
23+
class PatchDeclarationParentsVisitor : IrElementVisitorVoid {
24+
25+
private val declarationParentsStack = ArrayDeque<IrDeclarationParent>()
26+
27+
override fun visitElement(element: IrElement) {
28+
element.acceptChildrenVoid(this)
29+
}
30+
31+
override fun visitPackageFragment(declaration: IrPackageFragment) {
32+
declarationParentsStack.push(declaration)
33+
super.visitPackageFragment(declaration)
34+
declarationParentsStack.pop()
35+
}
36+
37+
override fun visitDeclaration(declaration: IrDeclaration) {
38+
patchParent(declaration)
39+
40+
if (declaration is IrDeclarationParent) {
41+
declarationParentsStack.push(declaration)
42+
}
43+
44+
super.visitDeclaration(declaration)
45+
46+
if (declaration is IrDeclarationParent) {
47+
declarationParentsStack.pop()
48+
}
49+
}
50+
51+
private fun patchParent(declaration: IrDeclaration) {
52+
(declaration as IrDeclarationBase).parent = declarationParentsStack.peekFirst()
53+
}
54+
}

compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrTextTestCase.kt

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
115115
errors.add(message)
116116
}
117117

118+
private inline fun require(condition: Boolean, message: () -> String) {
119+
if (!condition) {
120+
errors.add(message())
121+
}
122+
}
123+
118124
fun verifyWithAssert(irFile: IrFile) {
119125
irFile.acceptChildrenVoid(this)
120126
TestCase.assertFalse(errorsAsMessage + "\n\n\n" + irFile.dump(), hasErrors)
@@ -128,8 +134,20 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
128134
if (declaration is IrSymbolOwner) {
129135
declaration.symbol.checkBinding("decl", declaration)
130136

131-
if (declaration.symbol.owner != declaration) {
132-
error("Symbol is not bound to declaration: ${declaration.render()}")
137+
require(declaration.symbol.owner == declaration) {
138+
"Symbol is not bound to declaration: ${declaration.render()}"
139+
}
140+
}
141+
142+
val containingDeclarationDescriptor = declaration.descriptor.containingDeclaration
143+
if (containingDeclarationDescriptor != null) {
144+
val parent = declaration.parent
145+
if (parent is IrDeclaration) {
146+
require(parent.descriptor == containingDeclarationDescriptor) {
147+
"In declaration ${declaration.descriptor}: " +
148+
"Mismatching parent descriptor (${parent.descriptor}) " +
149+
"and containing declaration descriptor ($containingDeclarationDescriptor)"
150+
}
133151
}
134152
}
135153
}
@@ -143,20 +161,18 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
143161

144162
val expectedDispatchReceiver = functionDescriptor.dispatchReceiverParameter
145163
val actualDispatchReceiver = declaration.dispatchReceiverParameter?.descriptor
146-
if (expectedDispatchReceiver != actualDispatchReceiver) {
147-
error(
148-
"$functionDescriptor: Dispatch receiver parameter mismatch: " +
149-
"expected $expectedDispatchReceiver, actual $actualDispatchReceiver"
150-
)
164+
require(expectedDispatchReceiver == actualDispatchReceiver) {
165+
"$functionDescriptor: Dispatch receiver parameter mismatch: " +
166+
"expected $expectedDispatchReceiver, actual $actualDispatchReceiver"
167+
151168
}
152169

153170
val expectedExtensionReceiver = functionDescriptor.extensionReceiverParameter
154171
val actualExtensionReceiver = declaration.extensionReceiverParameter?.descriptor
155-
if (expectedExtensionReceiver != actualExtensionReceiver) {
156-
error(
157-
"$functionDescriptor: Extension receiver parameter mismatch: " +
158-
"expected $expectedExtensionReceiver, actual $actualExtensionReceiver"
159-
)
172+
require(expectedExtensionReceiver == actualExtensionReceiver) {
173+
"$functionDescriptor: Extension receiver parameter mismatch: " +
174+
"expected $expectedExtensionReceiver, actual $actualExtensionReceiver"
175+
160176
}
161177

162178
val declaredValueParameters = declaration.valueParameters.map { it.descriptor }
@@ -165,8 +181,8 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
165181
error("$functionDescriptor: Value parameters mismatch: $declaredValueParameters != $actualValueParameters")
166182
} else {
167183
declaredValueParameters.zip(actualValueParameters).forEach { (declaredValueParameter, actualValueParameter) ->
168-
if (declaredValueParameter != actualValueParameter) {
169-
error("$functionDescriptor: Value parameters mismatch: $declaredValueParameter != $actualValueParameter")
184+
require(declaredValueParameter == actualValueParameter) {
185+
"$functionDescriptor: Value parameters mismatch: $declaredValueParameter != $actualValueParameter"
170186
}
171187
}
172188
}
@@ -220,8 +236,8 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
220236
error("$descriptor: Type parameters mismatch: $declaredTypeParameters != $expectedTypeParameters")
221237
} else {
222238
declaredTypeParameters.zip(expectedTypeParameters).forEach { (declaredTypeParameter, expectedTypeParameter) ->
223-
if (declaredTypeParameter != expectedTypeParameter) {
224-
error("$descriptor: Type parameters mismatch: $declaredTypeParameter != $expectedTypeParameter")
239+
require(declaredTypeParameter == expectedTypeParameter) {
240+
"$descriptor: Type parameters mismatch: $declaredTypeParameter != $expectedTypeParameter"
225241
}
226242
}
227243
}

0 commit comments

Comments
 (0)