Use local aliases for Kotlin runtime functions in JS BE
This commit is contained in:
@@ -359,6 +359,7 @@ class Analyzer(private val context: Context) : JsVisitor() {
|
||||
private fun enterFunction(function: JsFunction, arguments: List<JsExpression>) {
|
||||
functionsToEnter += function
|
||||
context.addNodesForLocalVars(function.collectLocalVariables())
|
||||
context.markSpecialFunctions(function.body)
|
||||
|
||||
for ((param, arg) in function.parameters.zip(arguments)) {
|
||||
if (arg is JsFunction && arg.name == null && isProperFunctionalParameter(arg.body, param)) {
|
||||
@@ -377,6 +378,7 @@ class Analyzer(private val context: Context) : JsVisitor() {
|
||||
private fun enterFunctionWithGivenNodes(function: JsFunction, arguments: List<Node>) {
|
||||
functionsToEnter += function
|
||||
context.addNodesForLocalVars(function.collectLocalVariables())
|
||||
context.markSpecialFunctions(function.body)
|
||||
|
||||
for ((param, arg) in function.parameters.zip(arguments)) {
|
||||
val paramNode = context.nodes[param.name]!!
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package org.jetbrains.kotlin.js.dce
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SpecialFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.specialFunction
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.array
|
||||
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.index
|
||||
|
||||
@@ -32,6 +35,45 @@ class Context {
|
||||
nodes += names.filter { it !in nodes }.associate { it to Node(it) }
|
||||
}
|
||||
|
||||
fun markSpecialFunctions(root: JsNode) {
|
||||
val candidates = mutableMapOf<JsName, SpecialFunction>()
|
||||
val unsuitableNames = mutableSetOf<JsName>()
|
||||
val assignedNames = mutableSetOf<JsName>()
|
||||
root.accept(object : RecursiveJsVisitor() {
|
||||
override fun visit(x: JsVars.JsVar) {
|
||||
val name = x.name
|
||||
if (!assignedNames.add(name)) {
|
||||
unsuitableNames += name
|
||||
}
|
||||
|
||||
val initializer = x.initExpression
|
||||
if (initializer != null) {
|
||||
val specialName = when {
|
||||
isDefineInlineFunction(initializer) -> SpecialFunction.DEFINE_INLINE_FUNCTION
|
||||
isWrapFunction(initializer) -> SpecialFunction.WRAP_FUNCTION
|
||||
else -> null
|
||||
}
|
||||
specialName?.let { candidates[name] = specialName }
|
||||
}
|
||||
super.visit(x)
|
||||
}
|
||||
|
||||
override fun visitBinaryExpression(x: JsBinaryOperation) {
|
||||
JsAstUtils.decomposeAssignmentToVariable(x)?.let { (left, _) -> unsuitableNames += left }
|
||||
}
|
||||
|
||||
override fun visitFunction(x: JsFunction) {
|
||||
x.name?.let { unsuitableNames += it }
|
||||
}
|
||||
})
|
||||
|
||||
for ((name, function) in candidates) {
|
||||
if (name !in unsuitableNames) {
|
||||
name.specialFunction = function
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun extractNode(expression: JsExpression): Node? {
|
||||
val node = extractNodeImpl(expression)?.original
|
||||
return if (node != null && moduleExportsNode in generateSequence(node) { it.qualifier?.parent }) {
|
||||
|
||||
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.js.dce
|
||||
|
||||
import com.google.gwt.dev.js.rhino.CodePosition
|
||||
import com.google.gwt.dev.js.rhino.ErrorReporter
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsBlock
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNode
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsProgram
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.dce.Context.Node
|
||||
import org.jetbrains.kotlin.js.inline.util.collectDefinedNames
|
||||
import org.jetbrains.kotlin.js.inline.util.fixForwardNameReferences
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.kotlin.js.dce
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SpecialFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.specialFunction
|
||||
import org.jetbrains.kotlin.js.dce.Context.Node
|
||||
|
||||
fun Context.isObjectDefineProperty(function: JsExpression) = isObjectFunction(function, "defineProperty")
|
||||
@@ -25,9 +27,11 @@ fun Context.isObjectGetOwnPropertyDescriptor(function: JsExpression) = isObjectF
|
||||
|
||||
fun Context.isDefineModule(function: JsExpression): Boolean = isKotlinFunction(function, "defineModule")
|
||||
|
||||
fun Context.isDefineInlineFunction(function: JsExpression): Boolean = isKotlinFunction(function, "defineInlineFunction")
|
||||
fun Context.isDefineInlineFunction(function: JsExpression): Boolean =
|
||||
isKotlinFunction(function, "defineInlineFunction") || isSpecialFunction(function, SpecialFunction.DEFINE_INLINE_FUNCTION)
|
||||
|
||||
fun Context.isWrapFunction(function: JsExpression): Boolean = isKotlinFunction(function, "wrapFunction")
|
||||
fun Context.isWrapFunction(function: JsExpression): Boolean =
|
||||
isKotlinFunction(function, "wrapFunction") || isSpecialFunction(function, SpecialFunction.WRAP_FUNCTION)
|
||||
|
||||
fun Context.isObjectFunction(function: JsExpression, functionName: String): Boolean {
|
||||
if (function !is JsNameRef) return false
|
||||
@@ -45,6 +49,9 @@ fun Context.isKotlinFunction(function: JsExpression, name: String): Boolean {
|
||||
return receiver in nodes && receiver.ident.toLowerCase() == "kotlin"
|
||||
}
|
||||
|
||||
fun isSpecialFunction(expr: JsExpression, specialFunction: SpecialFunction): Boolean =
|
||||
expr is JsNameRef && expr.qualifier == null && expr.name?.specialFunction == specialFunction
|
||||
|
||||
fun Context.isAmdDefine(function: JsExpression): Boolean = isTopLevelFunction(function, "define")
|
||||
|
||||
fun Context.isTopLevelFunction(function: JsExpression, name: String): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user