All Downloads are FREE. Search and download functionalities are using the official Maven repository.

.kotlin.kotlin-compiler.1.3.11.source-code.jsCode.kt Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
 * that can be found in the license/LICENSE.txt file.
 */

package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs

import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.parser.parse


fun translateJsCode(call: IrCall, scope: JsScope): JsNode {
    //TODO check non simple compile time constants (expressions)

    fun foldString(expression: IrExpression): String {
        val builder = StringBuilder()
        expression.acceptVoid(object : IrElementVisitorVoid {
            override fun visitElement(element: IrElement) = error("Parameter of js function must be compile time String constant")

            override fun  visitConst(expression: IrConst) {
                builder.append(expression.kind.valueOf(expression))
            }

            override fun visitStringConcatenation(expression: IrStringConcatenation) = expression.acceptChildrenVoid(this)
        })

        return builder.toString()
    }

    val code = call.getValueArgument(0)!!
    val statements = parseJsCode(code.run(::foldString), JsFunctionScope(scope, "")).orEmpty()
    val size = statements.size

    return when (size) {
        0 -> JsEmpty
        1 -> statements[0].let { (it as? JsExpressionStatement)?.expression ?: it }
        else -> JsBlock(statements)
    }
}

private fun parseJsCode(jsCode: String, currentScope: JsScope): List? {
    // Parser can change local or global scope.
    // In case of js we want to keep new local names,
    // but no new global ones.
    assert(currentScope is JsFunctionScope) { "Usage of js outside of function is unexpected" }
    val temporaryRootScope = JsRootScope(JsProgram())
    val scope = DelegatingJsFunctionScopeWithTemporaryParent(currentScope as JsFunctionScope, temporaryRootScope)

    // TODO write debug info, see how it's done in CallExpressionTranslator.parseJsCode

    return parse(jsCode, ThrowExceptionOnErrorReporter, scope, "")
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy