Support inline for simple extension function case.

This commit is contained in:
Pavel V. Talanov
2012-03-28 19:03:54 +04:00
parent b80b7a9050
commit fd1d6e8dfc
3 changed files with 45 additions and 17 deletions
@@ -54,6 +54,14 @@ public final class InlineTest extends SingleFileTranslationTest {
checkFooBoxIsTrueAndFunctionNameIsNotReferenced("methodWithReferenceToThis.kt", "myInlineMethod"); checkFooBoxIsTrueAndFunctionNameIsNotReferenced("methodWithReferenceToThis.kt", "myInlineMethod");
} }
public void testMethodWithIndirectlyReferencedThis() throws Exception {
checkFooBoxIsTrueAndFunctionNameIsNotReferenced("methodWithIndirectlyReferencedThis.kt", "myInlineMethod");
}
public void testExtension() throws Exception {
checkFooBoxIsTrueAndFunctionNameIsNotReferenced("extension.kt", "myInlineExtension");
}
private void checkFooBoxIsTrueAndFunctionNameIsNotReferenced(@NotNull String filename, String funName) throws Exception { private void checkFooBoxIsTrueAndFunctionNameIsNotReferenced(@NotNull String filename, String funName) throws Exception {
checkFooBoxIsTrue(filename); checkFooBoxIsTrue(filename);
String generatedJSFilePath = getOutputFilePath(filename); String generatedJSFilePath = getOutputFilePath(filename);
@@ -23,24 +23,28 @@ import com.google.dart.compiler.backend.js.ast.JsNode;
import com.google.dart.compiler.backend.js.ast.JsReturn; import com.google.dart.compiler.backend.js.ast.JsReturn;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetFunction; import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils; import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator; import org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator;
import org.jetbrains.k2js.translate.utils.mutator.Mutator; import org.jetbrains.k2js.translate.utils.mutator.Mutator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.jetbrains.k2js.translate.reference.CallParametersResolver.resolveCallParameters;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionForDescriptor; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionForDescriptor;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCallForCallExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCallForCallExpression;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedReceiverDescriptor;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedThisDescriptor;
import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody; import static org.jetbrains.k2js.translate.utils.FunctionBodyTranslator.translateFunctionBody;
/** /**
@@ -112,25 +116,32 @@ public final class InlinedCallExpressionTranslator extends AbstractCallExpressio
@NotNull @NotNull
private TranslationContext createContextWithAliasForThisExpression(@NotNull TranslationContext contextForInlining) { private TranslationContext createContextWithAliasForThisExpression(@NotNull TranslationContext contextForInlining) {
ClassDescriptor classDescriptorForMethod = DescriptorUtils.getClassDescriptorForMethod(getFunctionDescriptor());
if (classDescriptorForMethod == null) {
return contextForInlining;
}
TranslationContext contextWithAliasForThisExpression = contextForInlining; TranslationContext contextWithAliasForThisExpression = contextForInlining;
TemporaryVariable aliasForThis = contextWithAliasForThisExpression.declareTemporary(getReceiver()); SimpleFunctionDescriptor functionDescriptor = getFunctionDescriptor();
contextWithAliasForThisExpression = contextForInlining.innerContextWithThisAliased(classDescriptorForMethod, aliasForThis.name()); CallParameters callParameters = resolveCallParameters(receiver, null, functionDescriptor, resolvedCall, contextForInlining);
contextWithAliasForThisExpression.addStatementToCurrentBlock(aliasForThis.assignmentExpression().makeStmt()); JsExpression receiver = callParameters.getReceiver();
if (receiver != null) {
contextWithAliasForThisExpression =
contextWithAlias(contextWithAliasForThisExpression, receiver, getExpectedReceiverDescriptor(functionDescriptor));
}
JsExpression thisObject = callParameters.getThisObject();
if (thisObject != null) {
contextWithAliasForThisExpression =
contextWithAlias(contextWithAliasForThisExpression, thisObject, getExpectedThisDescriptor(functionDescriptor));
}
return contextWithAliasForThisExpression; return contextWithAliasForThisExpression;
} }
@NotNull @NotNull
private JsExpression getReceiver() { private TranslationContext contextWithAlias(@NotNull TranslationContext contextWithAliasForThisExpression,
if (receiver != null) { @NotNull JsExpression aliasExpression, @Nullable DeclarationDescriptor descriptorToAlias) {
return receiver; TranslationContext newContext = contextWithAliasForThisExpression;
} TemporaryVariable aliasForReceiver = context().declareTemporary(aliasExpression);
JsExpression result = TranslationUtils.resolveThisObjectForResolvedCall(resolvedCall, context()); assert descriptorToAlias != null;
assert result != null; newContext =
return result; newContext.innerContextWithThisAliased(descriptorToAlias, aliasForReceiver.name());
newContext.addStatementToCurrentBlock(aliasForReceiver.assignmentExpression().makeStmt());
return newContext;
} }
@NotNull @NotNull
@@ -0,0 +1,9 @@
package foo
class A() {
val a = 5
}
inline fun A.myInlineExtension() = a + 1
fun box() = A().myInlineExtension() == 6