Refactoring function translator.
This commit is contained in:
+24
-22
@@ -53,8 +53,6 @@ import static org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator.m
|
|||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//TODO: class has convoluted code. REFACTOR before changing
|
|
||||||
public final class FunctionTranslator extends AbstractTranslator {
|
public final class FunctionTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -63,6 +61,8 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
return new FunctionTranslator(function, context);
|
return new FunctionTranslator(function, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final TranslationContext functionBodyContext;
|
||||||
@Nullable
|
@Nullable
|
||||||
private TemporaryVariable aliasForContaingClassThis = null;
|
private TemporaryVariable aliasForContaingClassThis = null;
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -84,6 +84,8 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
this.functionDeclaration = functionDeclaration;
|
this.functionDeclaration = functionDeclaration;
|
||||||
this.functionObject = context().getFunctionObject(descriptor);
|
this.functionObject = context().getFunctionObject(descriptor);
|
||||||
this.functionBody = functionObject.getBody();
|
this.functionBody = functionObject.getBody();
|
||||||
|
//NOTE: it's important we compute the context before we start the computation
|
||||||
|
this.functionBodyContext = getFunctionBodyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -126,7 +128,7 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public JsFunction translateAsLocalFunction() {
|
public JsFunction translateAsLocalFunction() {
|
||||||
JsName functionName = context().getNameForElement(functionDeclaration);
|
JsName functionName = context().getNameForElement(functionDeclaration);
|
||||||
generateFunctionObject(getFunctionBodyContext());
|
generateFunctionObject();
|
||||||
functionObject.setName(functionName);
|
functionObject.setName(functionName);
|
||||||
return functionObject;
|
return functionObject;
|
||||||
}
|
}
|
||||||
@@ -134,21 +136,20 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public JsPropertyInitializer translateAsMethod() {
|
public JsPropertyInitializer translateAsMethod() {
|
||||||
JsName functionName = context().getNameForElement(functionDeclaration);
|
JsName functionName = context().getNameForElement(functionDeclaration);
|
||||||
generateFunctionObject(getFunctionBodyContext());
|
generateFunctionObject();
|
||||||
return new JsPropertyInitializer(functionName.makeRef(), functionObject);
|
return new JsPropertyInitializer(functionName.makeRef(), functionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression translateAsLiteral() {
|
public JsExpression translateAsLiteral() {
|
||||||
return mayBeWrapInClosureCaptureExpression(doTranslateAsLiteral());
|
assert getExpectedThisDescriptor(descriptor) == null;
|
||||||
|
generateFunctionObject();
|
||||||
|
return mayBeWrapInClosureCaptureExpression(mayBeWrapWithThisAlias());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression doTranslateAsLiteral() {
|
private JsExpression mayBeWrapWithThisAlias() {
|
||||||
assert getExpectedThisDescriptor(descriptor) == null;
|
if (!shouldAliasThisObject()) {
|
||||||
generateFunctionObject(getFunctionBodyContext());
|
|
||||||
boolean shouldAliasThisObject = shouldAliasThisObject();
|
|
||||||
if (!shouldAliasThisObject) {
|
|
||||||
return functionObject;
|
return functionObject;
|
||||||
}
|
}
|
||||||
assert aliasForContaingClassThis != null;
|
assert aliasForContaingClassThis != null;
|
||||||
@@ -185,19 +186,27 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
return dummyFunctionInvocation;
|
return dummyFunctionInvocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateFunctionObject(@NotNull TranslationContext context) {
|
private void generateFunctionObject() {
|
||||||
setParameters(functionObject, translateParameters());
|
setParameters(functionObject, translateParameters());
|
||||||
translateBody(context);
|
translateBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void translateBody(@NotNull TranslationContext context) {
|
private void translateBody() {
|
||||||
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
|
JetExpression jetBodyExpression = functionDeclaration.getBodyExpression();
|
||||||
if (jetBodyExpression == null) {
|
if (jetBodyExpression == null) {
|
||||||
assert descriptor.getModality().equals(Modality.ABSTRACT);
|
assert descriptor.getModality().equals(Modality.ABSTRACT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JsNode realBody = Translation.translateExpression(jetBodyExpression, context);
|
JsNode realBody = Translation.translateExpression(jetBodyExpression, functionBodyContext);
|
||||||
functionBody.getStatements().add(wrapWithReturnIfNeeded(realBody, mustAddReturnToGeneratedFunctionBody()));
|
functionBody.getStatements().add(mayBeWrapWithReturn(realBody));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsBlock mayBeWrapWithReturn(@NotNull JsNode body) {
|
||||||
|
if (!mustAddReturnToGeneratedFunctionBody()) {
|
||||||
|
return convertToBlock(body);
|
||||||
|
}
|
||||||
|
return convertToBlock(lastExpressionReturned(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mustAddReturnToGeneratedFunctionBody() {
|
private boolean mustAddReturnToGeneratedFunctionBody() {
|
||||||
@@ -207,13 +216,6 @@ public final class FunctionTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static JsBlock wrapWithReturnIfNeeded(@NotNull JsNode body, boolean needsReturn) {
|
|
||||||
if (!needsReturn) {
|
|
||||||
return convertToBlock(body);
|
|
||||||
}
|
|
||||||
return convertToBlock(lastExpressionReturned(body));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JsNode lastExpressionReturned(@NotNull JsNode body) {
|
private static JsNode lastExpressionReturned(@NotNull JsNode body) {
|
||||||
return mutateLastExpression(body, new Mutator() {
|
return mutateLastExpression(body, new Mutator() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user