[JS IR BE] Implement labeled loops
This commit is contained in:
+8
-4
@@ -40,11 +40,11 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBreak(jump: IrBreak, context: JsGenerationContext): JsStatement {
|
override fun visitBreak(jump: IrBreak, context: JsGenerationContext): JsStatement {
|
||||||
return JsBreak(jump.label?.let(::JsNameRef))
|
return JsBreak(context.getNameForLoop(jump.loop)?.makeRef())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitContinue(jump: IrContinue, context: JsGenerationContext): JsStatement {
|
override fun visitContinue(jump: IrContinue, context: JsGenerationContext): JsStatement {
|
||||||
return JsContinue(jump.label?.let(::JsNameRef))
|
return JsContinue(context.getNameForLoop(jump.loop)?.makeRef())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReturn(expression: IrReturn, context: JsGenerationContext): JsStatement {
|
override fun visitReturn(expression: IrReturn, context: JsGenerationContext): JsStatement {
|
||||||
@@ -79,11 +79,15 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
|||||||
|
|
||||||
override fun visitWhileLoop(loop: IrWhileLoop, context: JsGenerationContext): JsStatement {
|
override fun visitWhileLoop(loop: IrWhileLoop, context: JsGenerationContext): JsStatement {
|
||||||
//TODO what if body null?
|
//TODO what if body null?
|
||||||
return JsWhile(loop.condition.accept(IrElementToJsExpressionTransformer(), context), loop.body?.accept(this, context))
|
val label = context.getNameForLoop(loop)
|
||||||
|
val loopStatement = JsWhile(loop.condition.accept(IrElementToJsExpressionTransformer(), context), loop.body?.accept(this, context))
|
||||||
|
return label?.let { JsLabel(it, loopStatement) } ?: loopStatement
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDoWhileLoop(loop: IrDoWhileLoop, context: JsGenerationContext): JsStatement {
|
override fun visitDoWhileLoop(loop: IrDoWhileLoop, context: JsGenerationContext): JsStatement {
|
||||||
//TODO what if body null?
|
//TODO what if body null?
|
||||||
return JsDoWhile(loop.condition.accept(IrElementToJsExpressionTransformer(), context), loop.body?.accept(this, context))
|
val label = context.getNameForLoop(loop)
|
||||||
|
val loopStatement = JsDoWhile(loop.condition.accept(IrElementToJsExpressionTransformer(), context), loop.body?.accept(this, context))
|
||||||
|
return label?.let { JsLabel(it, loopStatement) } ?: loopStatement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.utils
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
|
|
||||||
@@ -42,4 +43,5 @@ class JsGenerationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getNameForSymbol(symbol: IrSymbol): JsName = staticContext.getNameForSymbol(symbol, this)
|
fun getNameForSymbol(symbol: IrSymbol): JsName = staticContext.getNameForSymbol(symbol, this)
|
||||||
|
fun getNameForLoop(loop: IrLoop): JsName? = staticContext.getNameForLoop(loop, this)
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.utils
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIntrinsicTransformers
|
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIntrinsicTransformers
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsClassModel
|
import org.jetbrains.kotlin.js.backend.ast.JsClassModel
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
||||||
@@ -25,4 +26,5 @@ class JsStaticContext(
|
|||||||
val classModels = mutableMapOf<JsName, JsClassModel>()
|
val classModels = mutableMapOf<JsName, JsClassModel>()
|
||||||
|
|
||||||
fun getNameForSymbol(irSymbol: IrSymbol, context: JsGenerationContext) = nameGenerator.getNameForSymbol(irSymbol, context)
|
fun getNameForSymbol(irSymbol: IrSymbol, context: JsGenerationContext) = nameGenerator.getNameForSymbol(irSymbol, context)
|
||||||
|
fun getNameForLoop(loop: IrLoop, context: JsGenerationContext) = nameGenerator.getNameForLoop(loop, context)
|
||||||
}
|
}
|
||||||
@@ -5,9 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.utils
|
package org.jetbrains.kotlin.ir.backend.js.utils
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||||
|
|
||||||
interface NameGenerator {
|
interface NameGenerator {
|
||||||
fun getNameForSymbol(symbol: IrSymbol, context: JsGenerationContext): JsName
|
fun getNameForSymbol(symbol: IrSymbol, context: JsGenerationContext): JsName
|
||||||
|
fun getNameForLoop(loop: IrLoop, context: JsGenerationContext): JsName?
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.utils
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||||
import org.jetbrains.kotlin.js.naming.isES5IdentifierPart
|
import org.jetbrains.kotlin.js.naming.isES5IdentifierPart
|
||||||
@@ -18,8 +19,13 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
|||||||
class SimpleNameGenerator : NameGenerator {
|
class SimpleNameGenerator : NameGenerator {
|
||||||
|
|
||||||
private val nameCache = mutableMapOf<DeclarationDescriptor, JsName>()
|
private val nameCache = mutableMapOf<DeclarationDescriptor, JsName>()
|
||||||
|
private val loopCache = mutableMapOf<IrLoop, JsName>()
|
||||||
|
|
||||||
override fun getNameForSymbol(symbol: IrSymbol, context: JsGenerationContext): JsName = getNameForDescriptor(symbol.descriptor, context)
|
override fun getNameForSymbol(symbol: IrSymbol, context: JsGenerationContext): JsName = getNameForDescriptor(symbol.descriptor, context)
|
||||||
|
override fun getNameForLoop(loop: IrLoop, context: JsGenerationContext): JsName? = loop.label?.let {
|
||||||
|
loopCache.getOrPut(loop) { context.currentScope.declareFreshName(sanitizeName(loop.label!!)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getNameForDescriptor(descriptor: DeclarationDescriptor, context: JsGenerationContext): JsName =
|
private fun getNameForDescriptor(descriptor: DeclarationDescriptor, context: JsGenerationContext): JsName =
|
||||||
nameCache.getOrPut(descriptor) {
|
nameCache.getOrPut(descriptor) {
|
||||||
|
|||||||
Reference in New Issue
Block a user