JS: support inlining in new pipeline

This commit is contained in:
Alexey Andreev
2017-02-10 19:31:52 +03:00
parent a414cd64c5
commit 83140bc5f7
15 changed files with 157 additions and 62 deletions
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.resolve.calls.callUtil
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -210,6 +207,15 @@ fun KtExpression.getPropertyResolvedCallWithAssert(context: BindingContext): Res
return resolvedCall as ResolvedCall<out PropertyDescriptor>
}
fun KtExpression.getVariableResolvedCallWithAssert(context: BindingContext): ResolvedCall<out VariableDescriptor> {
val resolvedCall = getResolvedCallWithAssert(context)
assert(resolvedCall.resultingDescriptor is VariableDescriptor) {
"ResolvedCall for this expression must be ResolvedCall<? extends PropertyDescriptor>: ${this.getTextWithLocation()}"
}
@Suppress("UNCHECKED_CAST")
return resolvedCall as ResolvedCall<out VariableDescriptor>
}
fun KtExpression.getType(context: BindingContext): KotlinType? {
val type = context.getType(this)
if (type != null) return type
@@ -17,6 +17,7 @@ public class JsProgramFragment {
private final JsGlobalBlock initializerBlock = new JsGlobalBlock();
private final List<JsNameBinding> nameBindings = new ArrayList<JsNameBinding>();
private final Map<JsName, JsClassModel> classes = new LinkedHashMap<JsName, JsClassModel>();
private final Map<String, JsExpression> inlineModuleMap = new LinkedHashMap<String, JsExpression>();
public JsProgramFragment(@NotNull JsScope scope) {
this.scope = scope;
@@ -61,4 +62,9 @@ public class JsProgramFragment {
public Map<JsName, JsClassModel> getClasses() {
return classes;
}
@NotNull
public Map<String, JsExpression> getInlineModuleMap() {
return inlineModuleMap;
}
}
@@ -27,9 +27,7 @@ import org.jetbrains.kotlin.js.inline.util.IdentitySet
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
import org.jetbrains.kotlin.js.parser.parseFunction
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getModuleName
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.inline.InlineStrategy
@@ -48,7 +46,7 @@ private val JS_IDENTIFIER="[$JS_IDENTIFIER_START][$JS_IDENTIFIER_PART]*"
private val DEFINE_MODULE_PATTERN = ("($JS_IDENTIFIER)\\.defineModule\\(\\s*(['\"])([^'\"]+)\\2\\s*,\\s*(\\w+)\\s*\\)").toRegex().toPattern()
private val DEFINE_MODULE_FIND_PATTERN = ".defineModule("
class FunctionReader(private val context: TranslationContext) {
class FunctionReader(private val config: LibrarySourcesConfig, private val currentModuleName: JsName, fragments: List<JsProgramFragment>) {
/**
* fileContent: .js file content, that contains this module definition.
* One file can contain more than one module definition.
@@ -63,8 +61,12 @@ class FunctionReader(private val context: TranslationContext) {
private val moduleNameToInfo = HashMultimap.create<String, ModuleInfo>()
private val moduleNameMap: Map<String, JsExpression>
init {
val libs = context.config.libraries.map(::File)
val libs = config.libraries.map(::File)
moduleNameMap = buildModuleNameMap(fragments)
JsLibraryUtils.traverseJsLibraries(libs) { fileContent, _ ->
var current = 0
@@ -86,6 +88,13 @@ class FunctionReader(private val context: TranslationContext) {
}
}
// Since we compile each source file in its own context (and we may loose these context when performing incremental compilation)
// we don't use contexts to generate proper names for modules. Instead, we generate all necessary information during
// translation and rely on it here.
private fun buildModuleNameMap(fragments: List<JsProgramFragment>): Map<String, JsExpression> {
return fragments.flatMap { it.inlineModuleMap.entries }.associate { (k, v) -> k to v }
}
private fun rewindToIdentifierStart(text: String, index: Int): Int {
var result = index
while (result > 0 && Character.isJavaIdentifierPart(text[result - 1])) {
@@ -112,7 +121,7 @@ class FunctionReader(private val context: TranslationContext) {
operator fun contains(descriptor: CallableDescriptor): Boolean {
val moduleName = getModuleName(descriptor)
val currentModuleName = context.config.moduleId
val currentModuleName = config.moduleId
return currentModuleName != moduleName && moduleName in moduleNameToInfo.keys()
}
@@ -144,7 +153,7 @@ class FunctionReader(private val context: TranslationContext) {
}
val function = parseFunction(source, offset, ThrowExceptionOnErrorReporter, JsRootScope(JsProgram()))
val moduleReference = context.getModuleExpressionFor(descriptor) ?: getRootPackage()
val moduleReference = moduleNameMap[tag] ?: currentModuleName.makeRef()
val replacements = hashMapOf(info.moduleVariable to moduleReference,
info.kotlinVariable to Namer.kotlinObject())
@@ -152,11 +161,6 @@ class FunctionReader(private val context: TranslationContext) {
function.markInlineArguments(descriptor)
return function
}
private fun getRootPackage(): JsExpression {
val rootName = context.program().rootScope.declareName(Namer.getRootPackageName())
return JsAstUtils.pureFqn(rootName, null)
}
}
private val Char.isWhitespaceOrComma: Boolean
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.backend.ast.metadata.MetadataProperties;
import org.jetbrains.kotlin.js.config.JsConfig;
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig;
import org.jetbrains.kotlin.js.inline.clean.FunctionPostProcessor;
import org.jetbrains.kotlin.js.inline.clean.RemoveUnusedFunctionDefinitionsKt;
import org.jetbrains.kotlin.js.inline.clean.RemoveUnusedLocalFunctionDeclarationsKt;
@@ -37,7 +39,6 @@ import org.jetbrains.kotlin.js.inline.context.NamingContext;
import org.jetbrains.kotlin.js.inline.util.CollectUtilsKt;
import org.jetbrains.kotlin.js.inline.util.CollectionUtilsKt;
import org.jetbrains.kotlin.js.inline.util.NamingUtilsKt;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.resolve.inline.InlineStrategy;
import java.util.*;
@@ -61,15 +62,34 @@ public class JsInliner extends JsVisitorWithContextImpl {
private final Function1<JsNode, Boolean> canBeExtractedByInliner =
node -> node instanceof JsInvocation && hasToBeInlined((JsInvocation) node);
public static JsProgram process(@NotNull TranslationContext context) {
JsProgram program = context.program();
Map<JsName, JsFunction> functions = CollectUtilsKt.collectNamedFunctions(program);
Map<String, JsFunction> accessors = CollectUtilsKt.collectAccessors(program);
new DummyAccessorInvocationTransformer().accept(program);
JsInliner inliner = new JsInliner(functions, accessors, new FunctionReader(context), context.bindingTrace());
inliner.accept(program);
RemoveUnusedFunctionDefinitionsKt.removeUnusedFunctionDefinitions(program, functions);
return program;
public static void process(
@NotNull JsConfig config,
@NotNull DiagnosticSink trace,
@NotNull JsName currentModuleName,
@NotNull List<JsProgramFragment> fragments,
@NotNull List<JsProgramFragment> fragmentsToProcess
) {
Map<JsName, JsFunction> functions = CollectUtilsKt.collectNamedFunctions(fragments);
Map<String, JsFunction> accessors = CollectUtilsKt.collectAccessors(fragments);
DummyAccessorInvocationTransformer accessorInvocationTransformer = new DummyAccessorInvocationTransformer();
for (JsProgramFragment fragment : fragmentsToProcess) {
accessorInvocationTransformer.accept(fragment.getDeclarationBlock());
accessorInvocationTransformer.accept(fragment.getInitializerBlock());
}
FunctionReader functionReader = new FunctionReader((LibrarySourcesConfig) config, currentModuleName, fragments);
JsInliner inliner = new JsInliner(functions, accessors, functionReader, trace);
for (JsProgramFragment fragment : fragmentsToProcess) {
inliner.inliningContexts.push(inliner.new JsInliningContext(null, fragment.getScope()));
inliner.accept(fragment.getDeclarationBlock());
// There can be inlined function in top-level initializers, we need to optimize them as well
JsFunction fakeInitFunction = new JsFunction(JsDynamicScope.INSTANCE, fragment.getInitializerBlock(), "");
inliner.accept(fakeInitFunction);
inliner.inliningContexts.pop();
JsBlock block = new JsBlock(fragment.getDeclarationBlock(), fragment.getInitializerBlock(), fragment.getExportBlock());
RemoveUnusedFunctionDefinitionsKt.removeUnusedFunctionDefinitions(block, functions);
}
}
private JsInliner(
@@ -86,7 +106,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
@Override
public boolean visit(@NotNull JsFunction function, @NotNull JsContext context) {
inliningContexts.push(new JsInliningContext(function));
inliningContexts.push(new JsInliningContext(function, function.getScope()));
assert !inProcessFunctions.contains(function): "Inliner has revisited function";
inProcessFunctions.add(function);
@@ -266,8 +286,8 @@ public class JsInliner extends JsVisitorWithContextImpl {
private class JsInliningContext implements InliningContext {
private final FunctionContext functionContext;
JsInliningContext(@NotNull JsFunction function) {
functionContext = new FunctionContext(function, functionReader) {
JsInliningContext(@NotNull JsScope scope) {
functionContext = new FunctionContext(scope) {
@Nullable
@Override
protected JsFunction lookUpStaticFunction(@Nullable JsName functionName) {
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.js.inline.util.*
import org.jetbrains.kotlin.js.translate.context.Namer
abstract class FunctionContext(
private val function: JsFunction,
private val scope: JsScope,
private val functionReader: FunctionReader
) {
protected abstract fun lookUpStaticFunction(functionName: JsName?): JsFunction?
@@ -40,7 +40,7 @@ abstract class FunctionContext(
}
fun getScope(): JsScope {
return function.scope
return scope
}
/**
@@ -137,6 +137,15 @@ fun collectNamedFunctions(scope: JsNode) = collectNamedFunctionsAndMetadata(scop
fun collectNamedFunctionsOrMetadata(scope: JsNode) = collectNamedFunctionsAndMetadata(scope).mapValues { it.value.second }
fun collectNamedFunctions(fragments: List<JsProgramFragment>): Map<JsName, JsFunction> {
val result = mutableMapOf<JsName, JsFunction>()
for (fragment in fragments) {
result += collectNamedFunctions(fragment.declarationBlock)
result += collectNamedFunctions(fragment.initializerBlock)
}
return result
}
fun collectNamedFunctionsAndMetadata(scope: JsNode): Map<JsName, Pair<JsFunction, JsExpression>> {
val namedFunctions = mutableMapOf<JsName, Pair<JsFunction, JsExpression>>()
@@ -200,6 +209,14 @@ fun collectAccessors(scope: JsNode): Map<String, JsFunction> {
return accessors
}
fun collectAccessors(fragments: List<JsProgramFragment>): Map<String, JsFunction> {
val result = mutableMapOf<String, JsFunction>()
for (fragment in fragments) {
result += collectAccessors(fragment.declarationBlock)
}
return result
}
fun <T : JsNode> collectInstances(klass: Class<T>, scope: JsNode): List<T> {
return with(InstanceCollector(klass, visitNestedDeclarations = false)) {
accept(scope)
@@ -21,12 +21,14 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult;
import org.jetbrains.kotlin.js.backend.ast.JsProgram;
import org.jetbrains.kotlin.js.backend.ast.JsImportedModule;
import org.jetbrains.kotlin.js.config.JsConfig;
import org.jetbrains.kotlin.js.coroutine.CoroutineTransformer;
import org.jetbrains.kotlin.js.facade.exceptions.TranslationException;
import org.jetbrains.kotlin.js.inline.JsInliner;
import org.jetbrains.kotlin.js.inline.clean.RemoveUnusedImportsKt;
import org.jetbrains.kotlin.js.inline.clean.ResolveTemporaryNamesKt;
import org.jetbrains.kotlin.js.translate.general.AstGenerationResult;
import org.jetbrains.kotlin.js.translate.general.Translation;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.psi.KtFile;
@@ -74,18 +76,20 @@ public final class K2JSTranslator {
ModuleDescriptor moduleDescriptor = analysisResult.getModuleDescriptor();
Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics();
JsProgram program = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config);
AstGenerationResult translationResult = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config);
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics);
//JsInliner.process(program);
ResolveTemporaryNamesKt.resolveTemporaryNames(program);
JsInliner.process(config, analysisResult.getBindingTrace(), translationResult.getInnerModuleName(),
translationResult.getFragments(), translationResult.getFragments());
ResolveTemporaryNamesKt.resolveTemporaryNames(translationResult.getProgram());
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics);
CoroutineTransformer coroutineTransformer = new CoroutineTransformer(program);
coroutineTransformer.accept(program);
RemoveUnusedImportsKt.removeUnusedImports(program);
CoroutineTransformer coroutineTransformer = new CoroutineTransformer(translationResult.getProgram());
coroutineTransformer.accept(translationResult.getProgram());
RemoveUnusedImportsKt.removeUnusedImports(translationResult.getProgram());
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics);
@@ -93,10 +97,10 @@ public final class K2JSTranslator {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
List<String> importedModules = new ArrayList<>();
/*for (JsImportedModule module : context.getImportedModules()) {
for (JsImportedModule module : translationResult.getImportedModuleList()) {
importedModules.add(module.getExternalName());
}*/
return new TranslationResult.Success(config, files, program, diagnostics, importedModules, moduleDescriptor,
bindingTrace.getBindingContext());
}
return new TranslationResult.Success(config, files, translationResult.getProgram(), diagnostics, importedModules,
moduleDescriptor, bindingTrace.getBindingContext());
}
}
@@ -34,7 +34,8 @@ internal class DeclarationExporter(val context: StaticContext) {
private val objectLikeKinds = setOf(ClassKind.OBJECT, ClassKind.ENUM_ENTRY)
private val exportedDeclarations = mutableSetOf<MemberDescriptor>()
private val localPackageNames = mutableMapOf<FqName, JsName>()
val statements = mutableListOf<JsStatement>()
private val statements: MutableList<JsStatement>
get() = context.fragment.exportBlock.statements
fun export(descriptor: MemberDescriptor, force: Boolean) {
if (exportedDeclarations.contains(descriptor)) return
@@ -642,7 +642,7 @@ public final class StaticContext {
}
@Nullable
public JsExpression getModuleExpressionFor(@NotNull DeclarationDescriptor descriptor) {
private JsExpression getModuleExpressionFor(@NotNull DeclarationDescriptor descriptor) {
JsName name = getModuleInnerName(descriptor);
return name != null ? JsAstUtils.pureFqn(name, null) : null;
}
@@ -748,6 +748,11 @@ public final class StaticContext {
return currentModule;
}
public void addInlineCall(@NotNull CallableDescriptor descriptor) {
String tag = Namer.getFunctionTag(descriptor);
fragment.getInlineModuleMap().put(tag, getModuleExpressionFor(descriptor));
}
/*public void postProcess() {
addInterfaceDefaultMethods();
rootFunction.getBody().getStatements().addAll(importStatements);
@@ -625,9 +625,8 @@ public class TranslationContext {
callSites.add(new DeferredCallSite(constructor, invocationArgs, this));
}
@Nullable
public JsExpression getModuleExpressionFor(@NotNull DeclarationDescriptor descriptor) {
return staticContext.getModuleExpressionFor(descriptor);
public void addInlineCall(@NotNull CallableDescriptor descriptor) {
staticContext.addInlineCall(descriptor);
}
public void addDeclarationStatement(@NotNull JsStatement statement) {
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2017 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.js.translate.general
import org.jetbrains.kotlin.js.backend.ast.JsImportedModule
import org.jetbrains.kotlin.js.backend.ast.JsName
import org.jetbrains.kotlin.js.backend.ast.JsProgram
import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment
class AstGenerationResult(
val program: JsProgram,
val innerModuleName: JsName,
val fragments: List<JsProgramFragment>,
val importedModuleList: List<JsImportedModule>
)
@@ -16,12 +16,13 @@
package org.jetbrains.kotlin.js.translate.general
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.backend.ast.metadata.coroutineMetadata
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
class Merger(private val rootFunction: JsFunction, val internalModuleName: JsName) {
class Merger(private val rootFunction: JsFunction, val internalModuleName: JsName, val module: ModuleDescriptor) {
// Maps unique signature (see generateSignature) to names
private val nameTable = mutableMapOf<String, JsName>()
private val importedModuleTable = mutableMapOf<JsImportedModuleKey, JsName>()
@@ -114,6 +115,7 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
this += importBlock.statements
addClassPrototypes(this)
this += declarationBlock.statements
this += exportBlock.statements
this += initializerBlock.statements
}
}
@@ -234,7 +234,7 @@ public final class Translation {
}
@NotNull
public static JsProgram generateAst(
public static AstGenerationResult generateAst(
@NotNull BindingTrace bindingTrace,
@NotNull Collection<KtFile> files,
@NotNull MainCallParameters mainCallParameters,
@@ -253,7 +253,7 @@ public final class Translation {
}
@NotNull
private static JsProgram doGenerateAst(
private static AstGenerationResult doGenerateAst(
@NotNull BindingTrace bindingTrace,
@NotNull Collection<KtFile> files,
@NotNull MainCallParameters mainCallParameters,
@@ -263,7 +263,7 @@ public final class Translation {
JsProgram program = new JsProgram();
JsFunction rootFunction = new JsFunction(program.getRootScope(), new JsBlock(), "root function");
JsName internalModuleName = program.getScope().declareName("_");
Merger merger = new Merger(rootFunction, internalModuleName);
Merger merger = new Merger(rootFunction, internalModuleName, moduleDescriptor);
List<JsProgramFragment> fragments = new ArrayList<JsProgramFragment>();
for (KtFile file : files) {
@@ -280,15 +280,13 @@ public final class Translation {
List<JsStatement> statements = rootBlock.getStatements();
//staticContext.postProcess();
statements.add(0, program.getStringLiteral("use strict").makeStmt());
if (!isBuiltinModule(fragments)) {
defineModule(program, statements, config.getModuleId());
}
//mayBeGenerateTests(files, rootBlock, context);
JsName rootPackageName = program.getScope().declareName(Namer.getRootPackageName());
rootFunction.getParameters().add(new JsParameter((rootPackageName)));
rootFunction.getParameters().add(new JsParameter(internalModuleName));
// Invoke function passing modules as arguments
// This should help minifier tool to recognize references to these modules as local variables and make them shorter.
@@ -307,13 +305,13 @@ public final class Translation {
}
*/
statements.add(new JsReturn(rootPackageName.makeRef()));
statements.add(new JsReturn(internalModuleName.makeRef()));
JsBlock block = program.getGlobalBlock();
block.getStatements().addAll(wrapIfNecessary(config.getModuleId(), rootFunction, importedModuleList, program,
config.getModuleKind()));
return program;
return new AstGenerationResult(program, internalModuleName, fragments, importedModuleList);
}
private static boolean isBuiltinModule(@NotNull List<JsProgramFragment> fragments) {
@@ -39,13 +39,12 @@ public class VariableAccessTranslator extends AbstractTranslator implements Acce
@NotNull KtReferenceExpression referenceExpression,
@Nullable JsExpression receiver
) {
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(referenceExpression, context.bindingContext());
ResolvedCall<? extends VariableDescriptor> resolvedCall =
CallUtilKt.getVariableResolvedCallWithAssert(referenceExpression, context.bindingContext());
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
resolvedCall = ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall();
}
assert resolvedCall.getResultingDescriptor() instanceof VariableDescriptor;
return new VariableAccessTranslator(context, referenceExpression, (ResolvedCall<? extends VariableDescriptor>) resolvedCall,
receiver);
return new VariableAccessTranslator(context, referenceExpression, resolvedCall, receiver);
}
@@ -75,7 +74,7 @@ public class VariableAccessTranslator extends AbstractTranslator implements Acce
if (InlineUtil.isInline(getter)) {
if (e instanceof JsNameRef) {
// Get was translated as a name reference
setInlineCallMetadata((JsNameRef) e, referenceExpression, getter);
setInlineCallMetadata((JsNameRef) e, referenceExpression, getter, context());
} else {
setInlineCallMetadata(e, referenceExpression, getter, context());
}
@@ -94,7 +93,7 @@ public class VariableAccessTranslator extends AbstractTranslator implements Acce
if (InlineUtil.isInline(setter)) {
if (e instanceof JsBinaryOperation && ((JsBinaryOperation) e).getOperator().isAssignment()) {
// Set was translated as an assignment
setInlineCallMetadata((JsNameRef) (((JsBinaryOperation) e).getArg1()), referenceExpression, setter);
setInlineCallMetadata((JsNameRef) (((JsBinaryOperation) e).getArg1()), referenceExpression, setter, context());
} else {
setInlineCallMetadata(e, referenceExpression, setter, context());
}
@@ -64,6 +64,8 @@ fun setInlineCallMetadata(
}
visitor.accept(expression)
context.addInlineCall(descriptor)
}
fun setInlineCallMetadata(
@@ -76,11 +78,14 @@ fun setInlineCallMetadata(
fun setInlineCallMetadata(
nameRef: JsNameRef,
psiElement: KtExpression,
descriptor: CallableDescriptor
descriptor: CallableDescriptor,
context: TranslationContext
) {
nameRef.descriptor = descriptor
nameRef.inlineStrategy = InlineStrategy.IN_PLACE
nameRef.psiElement = psiElement
context.addInlineCall(descriptor)
}
fun TranslationContext.aliasedName(descriptor: CallableDescriptor): JsName {