Skip to content

Commit

Permalink
[JS IR] Use a backing field initializer for js() code folding
Browse files Browse the repository at this point in the history
 During a translation of the code from js() call to statement list,
 the compiler folds the code string. For that it uses property bodies.
 However the bodies can not be loaded in an incremental rebuild.
 The patch uses the backing field initializers of constant properties.
 The initializers are always loaded.

^KT-57002 Fixed
  • Loading branch information
AlexK0 authored and qodana-bot committed Mar 8, 2023
1 parent c91ef60 commit f82d3e6
Show file tree
Hide file tree
Showing 20 changed files with 129 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferen
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
Expand Down Expand Up @@ -131,6 +132,11 @@ internal class ICHasher {
}
}
(symbol.owner as? IrAnnotationContainer)?.let(hashCalculator::updateAnnotationContainer)
(symbol.owner as? IrProperty)?.let { irProperty ->
if (irProperty.isConst) {
irProperty.backingField?.initializer?.let(hashCalculator::update)
}
}
return hashCalculator.finalize()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private fun translateJsCodeIntoStatementList(
return parseExpressionOrStatement(jsCode, ThrowExceptionOnErrorReporter, currentScope, CodePosition(startLine, offset), fileName)
}

fun foldString(expression: IrExpression, context: JsIrBackendContext?): String? {
private fun foldString(expression: IrExpression, context: JsIrBackendContext?): String? {
val builder = StringBuilder()
var foldingFailed = false
expression.acceptVoid(object : IrElementVisitorVoid {
Expand Down Expand Up @@ -92,15 +92,25 @@ fun foldString(expression: IrExpression, context: JsIrBackendContext?): String?

override fun visitCall(expression: IrCall) {
val owner = expression.symbol.owner
val propertySymbol = owner.correspondingPropertySymbol
return when {
expression.origin == IrStatementOrigin.PLUS ->
expression.acceptChildrenVoid(this)
expression.origin == PropertyLazyInitLowering.Companion.PROPERTY_INIT_FUN_CALL -> {
owner.body?.acceptChildrenVoid(InitFunVisitor(context))
expression.acceptChildrenVoid(this)
}
owner == owner.correspondingPropertySymbol?.owner?.getter -> {
owner.body?.acceptChildrenVoid(this)
propertySymbol != null && owner == propertySymbol.owner.getter -> {
if (propertySymbol.owner.isConst) {
val initializer = propertySymbol.owner.backingField?.initializer
if (initializer != null) {
initializer.acceptChildrenVoid(this)
} else {
foldingFailed = true
}
} else {
owner.body?.acceptChildrenVoid(this)
}
expression.acceptChildrenVoid(this)
}
else -> super.visitCall(expression)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ STEP 0:
added file: l2.kt
STEP 1:
dependencies: lib1
updated imports: l2.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ STEP 0:
dirty js: lib1, lib2, main
STEP 1:
libs: lib1, lib2, main
dirty js: lib1
dirty js: lib1, lib2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fun test() : dynamic {
return js("var testObj = { $constKey: 0 }; testObj.$constKey")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fun test() : dynamic {
return js("var testObj = { $constKey: 1 }; testObj.$constKey")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fun test() : dynamic {
return js("var testObj = { $constKey: $constVal }; testObj.$constKey")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fun test() : dynamic {
return js("var testObj = { ${constKey1}__bar: $constVal + 1 }; testObj.foo__$constKey2")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
internal const val constKey = "foo"

internal const val constVal = "2"

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
internal const val constKey1 = "foo"
internal const val constKey2 = "bar"

internal const val constKey = constKey1 + "_" + constKey2

internal const val constVal = "3"

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
internal const val constKey1 = "foo"
internal const val constKey2 = "bar"

internal const val constKey = constKey1 + "__" + constKey2

internal const val constVal = "4"

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
internal const val constKey1 = "foo"
internal const val constKey2 = "bar"

internal const val constKey = constKey1 + "__" + constKey2

internal const val constVal = 5

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
STEP 0:
modifications:
U : l1.0.kt -> l1.kt
U : js.0.kt -> js.kt
U : test.0.kt -> test.kt
added file: l1.kt, js.kt, test.kt
STEP 1:
modifications:
U : js.1.kt -> js.kt
modified ir: js.kt
STEP 2:
modifications:
U : js.2.kt -> js.kt
modified ir: js.kt
updated exports: l1.kt
STEP 3:
modifications:
U : l1.3.kt -> l1.kt
modified ir: l1.kt
updated imports: js.kt
STEP 4:
modifications:
U : test.4.kt -> test.kt
modified ir: test.kt
STEP 5:
modifications:
U : l1.5.kt -> l1.kt
modified ir: l1.kt
updated imports: js.kt
STEP 6:
modifications:
U : js.6.kt -> js.kt
modified ir: js.kt
updated exports: l1.kt
STEP 7:
modifications:
U : l1.7.kt -> l1.kt
modified ir: l1.kt, js.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fun doTest() = test()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fun doTest() = test() + 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fun box(stepId: Int): String {
val x = doTest()
when (stepId) {
in 0..7 -> if (x != stepId) return "Fail, got $x"
else -> return "Unknown"
}
return "OK"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
STEP 0:
dependencies: lib1
added file: m.kt
STEP 1..7:
dependencies: lib1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
MODULES: lib1, main

STEP 0:
libs: lib1, main
dirty js: lib1, main
STEP 1..7:
libs: lib1, main
dirty js: lib1

0 comments on commit f82d3e6

Please sign in to comment.