org.jetbrains.kotlin.js.translate.utils.astUtils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.js.translate.utils.jsAstUtils
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.types.expressions.OperatorConventions
fun JsFunction.addStatement(stmt: JsStatement) {
body.statements.add(stmt)
}
fun JsFunction.addParameter(identifier: String, index: Int? = null): JsParameter {
val name = JsScope.declareTemporaryName(identifier)
val parameter = JsParameter(name)
if (index == null) {
parameters.add(parameter)
} else {
parameters.add(index, parameter)
}
return parameter
}
/**
* Tests, if any node containing in receiver's AST matches, [predicate].
*/
fun JsNode.any(predicate: (JsNode) -> Boolean): Boolean {
val visitor = object : RecursiveJsVisitor() {
var matched: Boolean = false
override fun visitElement(node: JsNode) {
matched = matched || predicate(node)
if (!matched) {
super.visitElement(node)
}
}
}
visitor.accept(this)
return visitor.matched
}
fun JsExpression.toInvocationWith(
leadingExtraArgs: List,
parameterCount: Int,
thisExpr: JsExpression
): JsExpression {
val qualifier: JsExpression
fun padArguments(arguments: List) = arguments + (1..(parameterCount - arguments.size))
.map { Namer.getUndefinedExpression() }
return when (this) {
is JsNew -> {
qualifier = Namer.getFunctionCallRef(constructorExpression)
// `new A(a, b, c)` -> `A.call($this, a, b, c)`
JsInvocation(qualifier, listOf(thisExpr) + leadingExtraArgs + arguments).source(source)
}
is JsInvocation -> {
qualifier = getQualifier()
// `A(a, b, c)` -> `A(a, b, c, $this)`
JsInvocation(qualifier, leadingExtraArgs + padArguments(arguments) + thisExpr).source(source)
}
else -> throw IllegalStateException("Unexpected node type: " + this::class.java)
}
}
var JsWhile.test: JsExpression
get() = condition
set(value) { condition = value }
var JsArrayAccess.index: JsExpression
get() = indexExpression
set(value) { indexExpression = value }
var JsArrayAccess.array: JsExpression
get() = arrayExpression
set(value) { arrayExpression = value }
var JsConditional.test: JsExpression
get() = testExpression
set(value) { testExpression = value }
var JsConditional.then: JsExpression
get() = thenExpression
set(value) { thenExpression = value }
var JsConditional.otherwise: JsExpression
get() = elseExpression
set(value) { elseExpression = value }
// Extension functions below produce aliased invocations.
fun TranslationContext.invokeKotlinFunction(functionName: String, vararg arguments: JsExpression)
= JsInvocation(getReferenceToIntrinsic(functionName), arguments.toList())
fun TranslationContext.toByte(expression: JsExpression) = invokeKotlinFunction(OperatorConventions.BYTE.identifier, expression)
fun TranslationContext.toShort(expression: JsExpression) = invokeKotlinFunction(OperatorConventions.SHORT.identifier, expression)
fun TranslationContext.toChar(expression: JsExpression) = invokeKotlinFunction(OperatorConventions.CHAR.identifier, expression)
fun TranslationContext.toLong(expression: JsExpression) = invokeKotlinFunction(OperatorConventions.LONG.identifier, expression)