JS inline: use dfs processing order, as it is independent of declaration order
This commit is contained in:
committed by
Zalim Bashorov
parent
a5688440a1
commit
da817e7ed2
@@ -19,14 +19,17 @@ package org.jetbrains.k2js.inline;
|
|||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.k2js.inline.exception.InlineRecursionException;
|
||||||
|
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.inline.clean.CleanPackage.removeUnusedLocalFunctionInstances;
|
import static org.jetbrains.k2js.inline.clean.CleanPackage.removeUnusedLocalFunctionInstances;
|
||||||
import static org.jetbrains.k2js.inline.clean.CleanPackage.removeUnusedLocalFunctions;
|
import static org.jetbrains.k2js.inline.clean.CleanPackage.removeUnusedLocalFunctions;
|
||||||
import static org.jetbrains.k2js.inline.FunctionInlineMutator.getInlineableCallReplacement;
|
import static org.jetbrains.k2js.inline.FunctionInlineMutator.getInlineableCallReplacement;
|
||||||
|
import static org.jetbrains.k2js.inline.util.UtilPackage.IdentitySet;
|
||||||
|
|
||||||
public class JsInliner extends JsVisitorWithContextImpl {
|
public class JsInliner extends JsVisitorWithContextImpl {
|
||||||
|
|
||||||
@@ -113,6 +116,8 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
|||||||
|
|
||||||
private final IdentityHashMap<JsName, JsFunction> functions;
|
private final IdentityHashMap<JsName, JsFunction> functions;
|
||||||
private final Stack<JsInliningContext> inliningContexts = new Stack<JsInliningContext>();
|
private final Stack<JsInliningContext> inliningContexts = new Stack<JsInliningContext>();
|
||||||
|
private final Set<JsFunction> processedFunctions = IdentitySet();
|
||||||
|
private final Set<JsFunction> inProcessFunctions = IdentitySet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A statement can contain more, than one inlineable sub-expressions.
|
* A statement can contain more, than one inlineable sub-expressions.
|
||||||
@@ -159,6 +164,10 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
|||||||
@Override
|
@Override
|
||||||
public boolean visit(JsFunction function, JsContext context) {
|
public boolean visit(JsFunction function, JsContext context) {
|
||||||
inliningContexts.push(new JsInliningContext(function));
|
inliningContexts.push(new JsInliningContext(function));
|
||||||
|
|
||||||
|
if (inProcessFunctions.contains(function)) throw new InlineRecursionException();
|
||||||
|
inProcessFunctions.add(function);
|
||||||
|
|
||||||
return super.visit(function, context);
|
return super.visit(function, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,6 +175,11 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
|||||||
public void endVisit(JsFunction function, JsContext context) {
|
public void endVisit(JsFunction function, JsContext context) {
|
||||||
super.endVisit(function, context);
|
super.endVisit(function, context);
|
||||||
removeUnusedLocalFunctionInstances(function);
|
removeUnusedLocalFunctionInstances(function);
|
||||||
|
processedFunctions.add(function);
|
||||||
|
|
||||||
|
assert inProcessFunctions.contains(function);
|
||||||
|
inProcessFunctions.remove(function);
|
||||||
|
|
||||||
inliningContexts.pop();
|
inliningContexts.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,6 +190,11 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shouldInline(call) && canInline(call)) {
|
if (shouldInline(call) && canInline(call)) {
|
||||||
|
JsFunction definition = getFunctionContext().getFunctionDefinition(call);
|
||||||
|
if (!processedFunctions.contains(definition)) {
|
||||||
|
accept(definition);
|
||||||
|
}
|
||||||
|
|
||||||
inline(call, context);
|
inline(call, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user