JS: inline stdlib functions
This commit is contained in:
@@ -92,6 +92,19 @@ public class FunctionReader(private val context: TranslationContext) {
|
||||
}
|
||||
}
|
||||
|
||||
private val functionCache = object : SLRUCache<CallableDescriptor, JsFunction>(50, 50) {
|
||||
override fun createValue(descriptor: CallableDescriptor): JsFunction =
|
||||
requireNotNull(readFunction(descriptor), "Could not read function: $descriptor")
|
||||
}
|
||||
|
||||
public fun contains(descriptor: CallableDescriptor): Boolean {
|
||||
val moduleName = getExternalModuleName(descriptor)
|
||||
val currentModuleName = context.getConfig().getModuleId()
|
||||
return currentModuleName != moduleName && moduleName in moduleJsDefinition
|
||||
}
|
||||
|
||||
public fun get(descriptor: CallableDescriptor): JsFunction = functionCache.get(descriptor)
|
||||
|
||||
private fun readFunction(descriptor: CallableDescriptor): JsFunction? {
|
||||
if (descriptor !in this) return null
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.InlineStrategy;
|
||||
import org.jetbrains.kotlin.js.inline.context.*;
|
||||
import org.jetbrains.kotlin.js.inline.exception.InlineRecursionException;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Set;
|
||||
@@ -40,6 +41,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
||||
private final Stack<JsInliningContext> inliningContexts = new Stack<JsInliningContext>();
|
||||
private final Set<JsFunction> processedFunctions = IdentitySet();
|
||||
private final Set<JsFunction> inProcessFunctions = IdentitySet();
|
||||
private final FunctionReader functionReader;
|
||||
|
||||
/**
|
||||
* A statement can contain more, than one inlineable sub-expressions.
|
||||
@@ -71,16 +73,21 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
||||
*/
|
||||
private boolean lastStatementWasShifted = false;
|
||||
|
||||
public static JsProgram process(JsProgram program) {
|
||||
public static JsProgram process(@NotNull TranslationContext context) {
|
||||
JsProgram program = context.program();
|
||||
IdentityHashMap<JsName, JsFunction> functions = collectNamedFunctions(program);
|
||||
JsInliner inliner = new JsInliner(functions);
|
||||
JsInliner inliner = new JsInliner(functions, new FunctionReader(context));
|
||||
inliner.accept(program);
|
||||
removeUnusedFunctionDefinitions(program, functions);
|
||||
return program;
|
||||
}
|
||||
|
||||
JsInliner(IdentityHashMap<JsName, JsFunction> functions) {
|
||||
private JsInliner(
|
||||
@NotNull IdentityHashMap<JsName, JsFunction> functions,
|
||||
@NotNull FunctionReader functionReader
|
||||
) {
|
||||
this.functions = functions;
|
||||
this.functionReader = functionReader;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +198,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
||||
private final FunctionContext functionContext;
|
||||
|
||||
JsInliningContext(JsFunction function) {
|
||||
functionContext = new FunctionContext(function, this) {
|
||||
functionContext = new FunctionContext(function, this, functionReader) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected JsFunction lookUpStaticFunction(@Nullable JsName functionName) {
|
||||
|
||||
@@ -27,10 +27,13 @@ import org.jetbrains.kotlin.js.inline.util.isFunctionCreator
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import java.util.IdentityHashMap
|
||||
import org.jetbrains.kotlin.js.inline.FunctionReader
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.descriptor
|
||||
|
||||
abstract class FunctionContext(
|
||||
private val function: JsFunction,
|
||||
private val inliningContext: InliningContext
|
||||
private val inliningContext: InliningContext,
|
||||
private val functionReader: FunctionReader
|
||||
) {
|
||||
/**
|
||||
* Caches function with captured arguments applied.
|
||||
@@ -109,6 +112,9 @@ abstract class FunctionContext(
|
||||
* in case of local function with closure.
|
||||
*/
|
||||
private fun getFunctionDefinitionImpl(call: JsInvocation): JsFunction? {
|
||||
val descriptor = call.descriptor
|
||||
if (descriptor != null && descriptor in functionReader) return functionReader[descriptor]
|
||||
|
||||
/** remove ending `()` */
|
||||
var callQualifier = call.getQualifier()
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.js.inline.JsInliner;
|
||||
import org.jetbrains.kotlin.js.sourceMap.JsSourceGenerationVisitor;
|
||||
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder;
|
||||
import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilder;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
@@ -82,12 +83,12 @@ public final class K2JSTranslator {
|
||||
BindingTrace bindingTrace = analysisResult.getBindingTrace();
|
||||
TopDownAnalyzerFacadeForJS.checkForErrors(Config.withJsLibAdded(files, config), bindingTrace.getBindingContext());
|
||||
ModuleDescriptor moduleDescriptor = analysisResult.getModuleDescriptor();
|
||||
JsProgram program = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config);
|
||||
TranslationContext context = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config);
|
||||
Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics();
|
||||
|
||||
if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics);
|
||||
|
||||
program = JsInliner.process(program);
|
||||
JsProgram program = JsInliner.process(context);
|
||||
return new TranslationResult.Success(config, files, program, diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public final class Translation {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsProgram generateAst(@NotNull BindingTrace bindingTrace,
|
||||
public static TranslationContext generateAst(@NotNull BindingTrace bindingTrace,
|
||||
@NotNull Collection<JetFile> files, @NotNull MainCallParameters mainCallParameters,
|
||||
@NotNull ModuleDescriptor moduleDescriptor,
|
||||
@NotNull Config config)
|
||||
@@ -179,7 +179,7 @@ public final class Translation {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsProgram doGenerateAst(@NotNull BindingTrace bindingTrace, @NotNull Collection<JetFile> files,
|
||||
private static TranslationContext doGenerateAst(@NotNull BindingTrace bindingTrace, @NotNull Collection<JetFile> files,
|
||||
@NotNull MainCallParameters mainCallParameters,
|
||||
@NotNull ModuleDescriptor moduleDescriptor,
|
||||
@NotNull Config config) throws MainFunctionNotFoundException {
|
||||
@@ -203,7 +203,7 @@ public final class Translation {
|
||||
}
|
||||
}
|
||||
mayBeGenerateTests(files, config, rootBlock, context);
|
||||
return context.program();
|
||||
return context;
|
||||
}
|
||||
|
||||
private static void defineModule(@NotNull TranslationContext context, @NotNull List<JsStatement> statements, @NotNull String moduleId) {
|
||||
|
||||
Reference in New Issue
Block a user