JS: inline componentN functions

#KT-7294 fixed
This commit is contained in:
Alexey Tsvetkov
2015-04-14 18:02:44 +03:00
parent a9d38e8d22
commit 97a1a13235
6 changed files with 40 additions and 9 deletions
@@ -34,11 +34,11 @@ public class JsVars extends SourceInfoAwareJsNode implements JsStatement, Iterab
}
public JsVars(JsVar var) {
this(Collections.singletonList(var), false);
this(new SmartList<JsVar>(var), false);
}
public JsVars(JsVar... vars) {
this(Arrays.asList(vars), false);
this(new SmartList<JsVar>(vars), false);
}
public boolean isMultiline() {
@@ -23,10 +23,12 @@ import com.google.dart.compiler.backend.js.ast.JsVars;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator;
import org.jetbrains.kotlin.psi.JetMultiDeclaration;
import org.jetbrains.kotlin.psi.JetMultiDeclarationEntry;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -36,6 +38,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.js.translate.utils.UtilsPackage.setInlineCallMetadata;
public class MultiDeclarationTranslator extends AbstractTranslator {
// if multiObjectName was init, initializer must be null
@@ -79,7 +83,10 @@ public class MultiDeclarationTranslator extends AbstractTranslator {
ResolvedCall<FunctionDescriptor> entryInitCall = context().bindingContext().get(BindingContext.COMPONENT_RESOLVED_CALL, entry);
assert entryInitCall != null : "Entry init call must be not null";
JsExpression entryInitializer = CallTranslator.INSTANCE$.translate(context(), entryInitCall, multiObjNameRef);
FunctionDescriptor candidateDescriptor = entryInitCall.getCandidateDescriptor();
if (CallExpressionTranslator.shouldBeInlined(candidateDescriptor)) {
setInlineCallMetadata(entryInitializer, entry, entryInitCall, context());
}
VariableDescriptor descriptor = BindingContextUtils.getNotNull( context().bindingContext(), BindingContext.VARIABLE, entry);
JsName name = context().getNameForDescriptor(descriptor);
jsVars.add(new JsVars.JsVar(name, entryInitializer));
@@ -60,11 +60,11 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
if (isJsCall(resolvedCall)) {
return (new CallExpressionTranslator(expression, receiver, context)).translateJsCode();
}
JsExpression callExpression = (new CallExpressionTranslator(expression, receiver, context)).translate();
if (!resolvedCall.isSafeCall() && shouldBeInlined(expression, context)) {
setInlineCallMetadata(callExpression, expression, context);
setInlineCallMetadata(callExpression, expression, resolvedCall, context);
}
return callExpression;
@@ -146,6 +146,11 @@ public final class PsiUtils {
ResolvedCall<?> resolvedCall = CallUtilPackage.getResolvedCall(expression, context.bindingContext());
assert resolvedCall != null;
return getFunctionDescriptor(resolvedCall);
}
@NotNull
public static CallableDescriptor getFunctionDescriptor(ResolvedCall<?> resolvedCall) {
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
return ((VariableAsFunctionResolvedCall) resolvedCall).getVariableCall().getCandidateDescriptor();
}
@@ -24,7 +24,8 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.js.inline.util.isCallInvocation
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.inline.InlineStrategy
/**
@@ -40,10 +41,11 @@ import org.jetbrains.kotlin.resolve.inline.InlineStrategy
*/
fun setInlineCallMetadata(
expression: JsExpression,
jetCall: JetCallExpression,
psiElement: JetExpression,
resolvedCall: ResolvedCall<*>,
context: TranslationContext
) {
val descriptor = PsiUtils.getFunctionDescriptor(jetCall, context)
val descriptor = PsiUtils.getFunctionDescriptor(resolvedCall)
assert(CallExpressionTranslator.shouldBeInlined(descriptor)) {
"Expected descriptor of callable, that should be inlined, but got: $descriptor"
}
@@ -57,7 +59,7 @@ fun setInlineCallMetadata(
if (name == invocation.name) {
invocation.descriptor = descriptor
invocation.inlineStrategy = InlineStrategy.IN_PLACE
invocation.psiElement = jetCall
invocation.psiElement = psiElement
}
}
}
@@ -0,0 +1,17 @@
package foo
// CHECK_NOT_CALLED: component1
// CHECK_NOT_CALLED: component2
class A(val a: Int, val b: Int)
inline fun A.component1(): Int = a
inline fun A.component2(): Int = b
fun box(): String {
val (a, b) = A(1, 2)
assertEquals(1, a)
assertEquals(2, b)
return "OK"
}