[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 {
|
||||
return JsBreak(jump.label?.let(::JsNameRef))
|
||||
return JsBreak(context.getNameForLoop(jump.loop)?.makeRef())
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -79,11 +79,15 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
|
||||
override fun visitWhileLoop(loop: IrWhileLoop, context: JsGenerationContext): JsStatement {
|
||||
//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 {
|
||||
//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.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
|
||||
@@ -42,4 +43,5 @@ class JsGenerationContext {
|
||||
}
|
||||
|
||||
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.transformers.irToJs.JsIntrinsicTransformers
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsClassModel
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
||||
@@ -25,4 +26,5 @@ class JsStaticContext(
|
||||
val classModels = mutableMapOf<JsName, JsClassModel>()
|
||||
|
||||
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
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
|
||||
interface NameGenerator {
|
||||
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.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
import org.jetbrains.kotlin.js.naming.isES5IdentifierPart
|
||||
@@ -18,8 +19,13 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
class SimpleNameGenerator : NameGenerator {
|
||||
|
||||
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 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 =
|
||||
nameCache.getOrPut(descriptor) {
|
||||
|
||||
Reference in New Issue
Block a user