JS inline: inline function calls

This commit is contained in:
Alexey Tsvetkov
2014-08-22 18:57:10 +04:00
committed by Zalim Bashorov
parent 3c7677e73e
commit 3c4125c233
@@ -18,6 +18,7 @@ package org.jetbrains.k2js.inline;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.IdentityHashMap;
import java.util.Stack;
@@ -53,6 +54,19 @@ public class JsInliner extends JsVisitorWithContextImpl {
scopeStack.pop();
}
@Override
public void endVisit(JsInvocation call, JsContext context) {
super.endVisit(call, context);
if (call == null) {
return;
}
if (shouldInline(call) && canInline(call)) {
inline(call, context);
}
}
private JsProgram process() {
return this.accept(program);
}
@@ -61,4 +75,56 @@ public class JsInliner extends JsVisitorWithContextImpl {
assert !scopeStack.isEmpty();
return scopeStack.peek();
}
private void inline(@NotNull JsInvocation call, @NotNull JsContext context) {
JsFunction functionToInline = findDeclaration(call);
assert functionToInline != null;
JsContext statementLevelContext = getLastStatementLevelContext();
assert statementLevelContext != null;
JsScope currentScope = getCurrentFunctionScope();
InlineableResult inlineableResult = getInlineableCallReplacement(call, currentScope, functionToInline);
JsStatement inlineableBody = inlineableResult.getInlineableBody();
JsExpression resultExpression = inlineableResult.getResultExpression();
statementLevelContext.insertAfter(statementLevelContext.getCurrentNode());
statementLevelContext.insertAfter(inlineableBody);
statementLevelContext.replaceMe(program.getEmptyStatement());
context.replaceMe(resultExpression);
}
@Nullable
private JsFunction findDeclaration(@NotNull JsInvocation call) {
JsName name = getFunctionName(call);
if (functions.containsKey(name)) {
return functions.get(name);
}
if (name.getStaticRef() != null && name.getStaticRef() instanceof JsFunction) {
return (JsFunction) name.getStaticRef();
}
return null;
}
private boolean canInline(@NotNull JsInvocation call) {
return findDeclaration(call) != null;
}
private static boolean shouldInline(@NotNull JsInvocation call) {
return call.getInlineStrategy().isInline();
}
@NotNull
private static JsName getFunctionName(@NotNull JsInvocation call) {
JsExpression qualifier = call.getQualifier();
assert qualifier instanceof JsNameRef;
JsName name = ((JsNameRef) qualifier).getName();
assert name != null;
return name;
}
}