JS/Inlining: minor simplifications after code review
This commit is contained in:
@@ -339,7 +339,6 @@ internal class ExpressionDecomposer private constructor(
|
||||
|
||||
fun assign(value: JsExpression): JsStatement {
|
||||
val statement = JsExpressionStatement(assignment(nameRef, value)).apply { synthetic = true }
|
||||
name.staticRef = value
|
||||
return statement
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.js.inline.util.rewriters.ReturnReplacingVisitor
|
||||
class FunctionInlineMutator
|
||||
private constructor(
|
||||
private val call: JsInvocation,
|
||||
inliningContext: InliningContext
|
||||
private val inliningContext: InliningContext
|
||||
) {
|
||||
private val invokedFunction: JsFunction
|
||||
private val namingContext: NamingContext
|
||||
@@ -85,9 +85,7 @@ private constructor(
|
||||
}
|
||||
|
||||
private fun applyCapturedArgs(call: JsInvocation, inner: JsFunction, outer: JsFunction) {
|
||||
// We want statements that introduce temporary variables to be added immediately after applying renamings,
|
||||
// so that further processing that involves detection of inlineable function had a chance to recognize them.
|
||||
val namingContext = NamingContext(inner.scope) { inner.body.statements.addAll(0, it) }
|
||||
val namingContext = inliningContext.newNamingContext()
|
||||
val arguments = call.arguments
|
||||
val parameters = outer.parameters
|
||||
aliasArgumentsIfNeeded(namingContext, arguments, parameters)
|
||||
@@ -108,11 +106,7 @@ private constructor(
|
||||
}
|
||||
|
||||
private fun processReturns() {
|
||||
val resultReference = getResultReference()
|
||||
if (resultReference != null) {
|
||||
resultExpr = resultReference
|
||||
}
|
||||
assert(resultExpr == null || resultExpr is JsNameRef)
|
||||
resultExpr = getResultReference()
|
||||
|
||||
val breakName = namingContext.getFreshName(getBreakLabel())
|
||||
this.breakLabel = JsLabel(breakName).apply { synthetic = true }
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.js.inline;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -194,18 +193,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
resultExpression = accept(resultExpression);
|
||||
JsStatement currentStatement = statementContext.getCurrentNode();
|
||||
|
||||
if (currentStatement instanceof JsExpressionStatement &&
|
||||
((JsExpressionStatement) currentStatement).getExpression() == call &&
|
||||
resultExpression == null
|
||||
) {
|
||||
statementContext.removeMe();
|
||||
}
|
||||
else {
|
||||
context.replaceMe(resultExpression);
|
||||
}
|
||||
context.replaceMe(accept(resultExpression));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -267,13 +255,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
||||
@Override
|
||||
public NamingContext newNamingContext() {
|
||||
JsScope scope = getFunctionContext().getScope();
|
||||
return new NamingContext(scope, new Function1<List<? extends JsStatement>, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(List<? extends JsStatement> statements) {
|
||||
getStatementContext().addPrevious(statements);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return new NamingContext(scope, getStatementContext());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -34,14 +34,14 @@ internal class ReferenceTracker<in Reference, RemoveCandidate : JsNode> {
|
||||
}
|
||||
|
||||
fun addCandidateForRemoval(reference: Reference, candidate: RemoveCandidate) {
|
||||
assert(!isKnown(reference)) { "Candidate for removal cannot be reassigned: $candidate" }
|
||||
assert(!isReferenceToRemovableCandidate(reference)) { "Candidate for removal cannot be reassigned: $candidate" }
|
||||
|
||||
removableCandidates.put(reference, candidate)
|
||||
reachable.put(reference, false)
|
||||
}
|
||||
|
||||
fun addRemovableReference(referrer: Reference, referenced: Reference) {
|
||||
if (!isKnown(referenced)) return
|
||||
if (!isReferenceToRemovableCandidate(referenced)) return
|
||||
|
||||
getReferencedBy(referrer).add(referenced)
|
||||
|
||||
@@ -51,12 +51,12 @@ internal class ReferenceTracker<in Reference, RemoveCandidate : JsNode> {
|
||||
}
|
||||
|
||||
fun markReachable(reference: Reference) {
|
||||
if (!isKnown(reference)) return
|
||||
if (!isReferenceToRemovableCandidate(reference)) return
|
||||
|
||||
visited.add(reference)
|
||||
getReferencedBy(reference)
|
||||
.filterNot { it in visited }
|
||||
.filter { isKnown(it) && !isReachable(it) }
|
||||
.filter { isReferenceToRemovableCandidate(it) && !isReachable(it) }
|
||||
.forEach { markReachable(it) }
|
||||
|
||||
visited.remove(reference)
|
||||
@@ -67,7 +67,7 @@ internal class ReferenceTracker<in Reference, RemoveCandidate : JsNode> {
|
||||
return referenceFromTo.getOrPut(referrer, { IdentitySet<Reference>() })
|
||||
}
|
||||
|
||||
fun isKnown(ref: Reference): Boolean {
|
||||
fun isReferenceToRemovableCandidate(ref: Reference): Boolean {
|
||||
return removableCandidates.containsKey(ref)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ private class UnusedInstanceCollector : JsVisitorWithContextImpl() {
|
||||
// For the case like this: `b = a; c = b;`, where `a` is a function. In this case we should remove both declaration,
|
||||
// although second one contains 'usage' of `b`.
|
||||
// see `inlineEvaluationOrder/cases/lambdaWithClosure.kt`.
|
||||
if (expr is JsNameRef && (expr.name?.let { tracker.isKnown(it) } ?: false)) return true
|
||||
if (expr is JsNameRef && (expr.name?.let { tracker.isReferenceToRemovableCandidate(it) } ?: false)) return true
|
||||
|
||||
val staticRef = name?.staticRef
|
||||
return staticRef != null && staticRef == expr && isFunctionReference(expr)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.js.inline.util.replaceNames
|
||||
|
||||
class NamingContext(
|
||||
private val scope: JsScope,
|
||||
private val statementConsumer: (List<JsStatement>) -> Unit
|
||||
private val statementContext: JsContext<JsStatement>
|
||||
) {
|
||||
private val renamings = IdentityHashMap<JsName, JsExpression>()
|
||||
private val declarations = ArrayList<JsVars>()
|
||||
@@ -35,7 +35,7 @@ class NamingContext(
|
||||
|
||||
fun applyRenameTo(target: JsNode): JsNode {
|
||||
if (!addedDeclarations) {
|
||||
statementConsumer(declarations)
|
||||
statementContext.addPrevious(declarations)
|
||||
addedDeclarations = true
|
||||
}
|
||||
|
||||
|
||||
@@ -132,8 +132,7 @@ val JsExpression.transitiveStaticRef: JsExpression
|
||||
get() {
|
||||
var qualifier = this
|
||||
while (qualifier is JsNameRef) {
|
||||
val staticRef = qualifier.name?.staticRef as? JsExpression ?: break
|
||||
qualifier = staticRef
|
||||
qualifier = qualifier.name?.staticRef as? JsExpression ?: break
|
||||
}
|
||||
return qualifier
|
||||
}
|
||||
@@ -32,15 +32,10 @@ fun aliasArgumentsIfNeeded(
|
||||
for ((arg, param) in arguments.zip(parameters)) {
|
||||
val paramName = param.name
|
||||
|
||||
val replacement: JsExpression = if (arg is JsFunction && isFunctionCreator(arg)) {
|
||||
arg
|
||||
}
|
||||
else {
|
||||
val freshName = context.getFreshName(paramName).apply { staticRef = arg }
|
||||
context.newVar(freshName, arg)
|
||||
val freshNameRef = freshName.makeRef()
|
||||
freshNameRef
|
||||
}
|
||||
val replacement = context.getFreshName(paramName).apply {
|
||||
staticRef = arg
|
||||
context.newVar(this, arg)
|
||||
}.makeRef()
|
||||
|
||||
context.replaceName(paramName, replacement)
|
||||
}
|
||||
|
||||
+2
-4
@@ -55,12 +55,10 @@ class ReturnReplacingVisitor(
|
||||
|
||||
private fun getReturnReplacement(returnExpression: JsExpression?): JsExpression? {
|
||||
return if (returnExpression != null) {
|
||||
if (resultRef != null) {
|
||||
val assignment = resultRef?.let {
|
||||
JsAstUtils.assignment(resultRef, returnExpression).apply { synthetic = true }
|
||||
}
|
||||
else {
|
||||
returnExpression
|
||||
}
|
||||
assignment ?: returnExpression
|
||||
}
|
||||
else {
|
||||
null
|
||||
|
||||
@@ -28,8 +28,7 @@ fun JsExpression.canHaveOwnSideEffect(vars: Set<JsName>) = when (this) {
|
||||
is JsConditional,
|
||||
is JsLiteral -> false
|
||||
is JsBinaryOperation -> operator.isAssignment
|
||||
is JsNameRef -> !(qualifier == null && name in vars) && sideEffects
|
||||
is JsInvocation -> !isFunctionCreatorInvocation(this) && sideEffects
|
||||
is JsNameRef -> name !in vars && sideEffects
|
||||
is HasMetadata -> sideEffects
|
||||
else -> true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user