a bunch or refactoring and TODO fixes

This commit is contained in:
Pavel Talanov
2012-02-05 17:10:44 +04:00
parent f5dd688746
commit 534375f975
9 changed files with 49 additions and 35 deletions
@@ -16,10 +16,13 @@ public class DynamicContext {
return new DynamicContext(scope, scope, new JsBlock()); return new DynamicContext(scope, scope, new JsBlock());
} }
//TODO: current/block scope logic unclear. is it necessary?
@NotNull @NotNull
private NamingScope currentScope; private NamingScope currentScope;
@NotNull @NotNull
private NamingScope blockScope; private NamingScope blockScope;
@NotNull @NotNull
private JsBlock currentBlock; private JsBlock currentBlock;
@@ -34,6 +37,11 @@ public class DynamicContext {
return new DynamicContext(currentScope.innerScope(scope), blockScope, currentBlock); return new DynamicContext(currentScope.innerScope(scope), blockScope, currentBlock);
} }
@NotNull
public NamingScope getScope() {
return blockScope;
}
@NotNull @NotNull
public DynamicContext innerBlock(@NotNull JsBlock block) { public DynamicContext innerBlock(@NotNull JsBlock block) {
return new DynamicContext(currentScope, currentScope, block); return new DynamicContext(currentScope, currentScope, block);
@@ -47,6 +55,7 @@ public class DynamicContext {
return new TemporaryVariable(temporaryName, initExpression); return new TemporaryVariable(temporaryName, initExpression);
} }
@NotNull @NotNull
public JsScope jsScope() { public JsScope jsScope() {
return currentScope.jsScope(); return currentScope.jsScope();
@@ -24,6 +24,12 @@ public final class Namer {
private static final String SUPER_METHOD_NAME = "super_init"; private static final String SUPER_METHOD_NAME = "super_init";
private static final String KOTLIN_OBJECT_NAME = "Kotlin"; private static final String KOTLIN_OBJECT_NAME = "Kotlin";
private static final String ANONYMOUS_NAMESPACE = "Anonymous"; private static final String ANONYMOUS_NAMESPACE = "Anonymous";
private static final String RECEIVER_PARAMETER_NAME = "receiver";
@NotNull
public static String getReceiverParameterName() {
return RECEIVER_PARAMETER_NAME;
}
@NotNull @NotNull
public static String getAnonymousNamespaceName() { public static String getAnonymousNamespaceName() {
@@ -123,13 +123,17 @@ public final class TranslationContext {
return staticContext.getStandardClasses(); return staticContext.getStandardClasses();
} }
@NotNull
public NamingScope getScope() {
return dynamicContext.getScope();
}
@NotNull @NotNull
public JsScope jsScope() { public JsScope jsScope() {
return dynamicContext.jsScope(); return dynamicContext.jsScope();
} }
@NotNull public void addStatementToCurrentBlock(@NotNull JsStatement statement) {
public JsBlock jsBlock() { dynamicContext.jsBlock().addStatement(statement);
return dynamicContext.jsBlock();
} }
} }
@@ -5,7 +5,6 @@ import com.google.dart.compiler.util.AstUtil;
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.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.Namer;
@@ -20,14 +19,11 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDeclarationsForNamespace;
/** /**
* @author Pavel Talanov * @author Pavel Talanov
* <p/> * <p/>
* Generates a big block where are all the classes(objects representing them) are created. * Generates a big block where are all the classes(objects representing them) are created.
*/ */
//TODO: declaration translator receives NamespaceDescriptor while actually should receive all declarations in namespace
public final class ClassDeclarationTranslator extends AbstractTranslator { public final class ClassDeclarationTranslator extends AbstractTranslator {
@NotNull @NotNull
@@ -41,9 +37,9 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
@Nullable @Nullable
private JsStatement declarationsStatement = null; private JsStatement declarationsStatement = null;
public ClassDeclarationTranslator(@NotNull TranslationContext context, @NotNull NamespaceDescriptor namespace) { public ClassDeclarationTranslator(@NotNull TranslationContext context, @NotNull List<JetDeclaration> declarationList) {
super(context); super(context);
this.namespaceDeclarations = getDeclarationsForNamespace(context.bindingContext(), namespace); this.namespaceDeclarations = declarationList;
this.localToGlobalClassName = new HashMap<JsName, JsName>(); this.localToGlobalClassName = new HashMap<JsName, JsName>();
this.dummyFunctionScope = new JsScope(context().jsScope(), "class declaration function"); this.dummyFunctionScope = new JsScope(context().jsScope(), "class declaration function");
} }
@@ -4,6 +4,7 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil; import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator;
@@ -12,6 +13,8 @@ import org.jetbrains.k2js.translate.general.Translation;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDeclarationsForNamespace;
/** /**
* @author Pavel.Talanov * @author Pavel.Talanov
* <p/> * <p/>
@@ -35,7 +38,8 @@ public final class NamespaceTranslator extends AbstractTranslator {
super(context.newDeclaration(namespace)); super(context.newDeclaration(namespace));
this.namespace = namespace; this.namespace = namespace;
this.namespaceName = context.getNameForDescriptor(namespace); this.namespaceName = context.getNameForDescriptor(namespace);
this.classDeclarationTranslator = new ClassDeclarationTranslator(context(), namespace); List<JetDeclaration> namespaceDeclarations = getDeclarationsForNamespace(context.bindingContext(), namespace);
this.classDeclarationTranslator = new ClassDeclarationTranslator(context(), namespaceDeclarations);
} }
@NotNull @NotNull
@@ -26,6 +26,7 @@ import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.List; import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*; import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationName;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateInitializerForProperty; import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateInitializerForProperty;
/** /**
@@ -149,7 +150,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
JsNode mutatedIfStatement = AstUtil.mutateLastExpression(ifStatement, JsNode mutatedIfStatement = AstUtil.mutateLastExpression(ifStatement,
saveResultToTemporaryMutator); saveResultToTemporaryMutator);
JsStatement resultingStatement = AstUtil.convertToStatement(mutatedIfStatement); JsStatement resultingStatement = AstUtil.convertToStatement(mutatedIfStatement);
context.jsBlock().addStatement(resultingStatement); context.addStatementToCurrentBlock(resultingStatement);
return result.nameReference(); return result.nameReference();
} }
@@ -388,11 +389,8 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull @NotNull
public JsNode visitObjectDeclaration(@NotNull JetObjectDeclaration expression, public JsNode visitObjectDeclaration(@NotNull JetObjectDeclaration expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
//TODO: util JetObjectDeclarationName objectDeclarationName = getObjectDeclarationName(expression);
JetObjectDeclarationName nameAsDeclaration = expression.getNameAsDeclaration(); DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), objectDeclarationName);
assert nameAsDeclaration != null;
DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(),
nameAsDeclaration);
JsName propertyName = context.getNameForDescriptor(descriptor); JsName propertyName = context.getNameForDescriptor(descriptor);
JsExpression value = ClassTranslator.generateClassCreationExpression(expression, context); JsExpression value = ClassTranslator.generateClassCreationExpression(expression, context);
return AstUtil.newVar(propertyName, value); return AstUtil.newVar(propertyName, value);
@@ -8,6 +8,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.k2js.translate.context.Namer;
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.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator;
@@ -34,9 +35,6 @@ public final class FunctionTranslator extends AbstractTranslator {
} }
//TODO: implement more generic and safe way //TODO: implement more generic and safe way
@NotNull
private static final String RECEIVER_PARAMETER_NAME = "receiver";
@NotNull @NotNull
private final JetDeclarationWithBody functionDeclaration; private final JetDeclarationWithBody functionDeclaration;
@NotNull @NotNull
@@ -105,7 +103,7 @@ public final class FunctionTranslator extends AbstractTranslator {
@NotNull @NotNull
private JsFunction createFunctionObject() { private JsFunction createFunctionObject() {
if (isDeclaration()) { if (isDeclaration()) {
return functionWithScope(context().getScopeForElement((JetDeclaration) functionDeclaration)); return functionWithScope(context().getScopeForElement(functionDeclaration));
} }
if (isLiteral()) { if (isLiteral()) {
//TODO: look into //TODO: look into
@@ -130,25 +128,16 @@ public final class FunctionTranslator extends AbstractTranslator {
return (!functionDeclaration.hasBlockBody()) && (!JetStandardClasses.isUnit(functionReturnType)); return (!functionDeclaration.hasBlockBody()) && (!JetStandardClasses.isUnit(functionReturnType));
} }
//TODO: refactor
@NotNull @NotNull
private JsBlock wrapWithReturnIfNeeded(@NotNull JsNode body, boolean needsReturn) { private JsBlock wrapWithReturnIfNeeded(@NotNull JsNode body, boolean needsReturn) {
if (!needsReturn) { if (!needsReturn) {
return AstUtil.convertToBlock(body); return AstUtil.convertToBlock(body);
} }
if (body instanceof JsExpression) { return AstUtil.convertToBlock(lastExpressionReturned(body));
return AstUtil.convertToBlock(new JsReturn(AstUtil.convertToExpression(body)));
}
if (body instanceof JsBlock) {
JsBlock bodyBlock = (JsBlock) body;
addReturnToBlockStatement(bodyBlock);
return bodyBlock;
}
throw new AssertionError("Invalid node as functionDeclaration body");
} }
private void addReturnToBlockStatement(@NotNull JsBlock bodyBlock) { private JsNode lastExpressionReturned(@NotNull JsNode body) {
AstUtil.mutateLastExpression(bodyBlock, new AstUtil.Mutator() { return AstUtil.mutateLastExpression(body, new AstUtil.Mutator() {
@Override @Override
@NotNull @NotNull
public JsNode mutate(@NotNull JsNode node) { public JsNode mutate(@NotNull JsNode node) {
@@ -187,8 +176,8 @@ public final class FunctionTranslator extends AbstractTranslator {
private void mayBeAddThisParameterForExtensionFunction(@NotNull List<JsParameter> jsParameters) { private void mayBeAddThisParameterForExtensionFunction(@NotNull List<JsParameter> jsParameters) {
if (isExtensionFunction()) { if (isExtensionFunction()) {
//TODO: dont do this //TODO: don't do this
JsName receiver = functionBodyContext.jsScope().declareName(RECEIVER_PARAMETER_NAME); JsName receiver = functionBodyContext.jsScope().declareName(Namer.getReceiverParameterName());
DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor); DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(descriptor);
assert expectedReceiverDescriptor != null; assert expectedReceiverDescriptor != null;
context().aliaser().setAliasForThis(expectedReceiverDescriptor, receiver); context().aliaser().setAliasForThis(expectedReceiverDescriptor, receiver);
@@ -48,7 +48,7 @@ public class WhenTranslator extends AbstractTranslator {
JsFor resultingFor = generateDummyFor(); JsFor resultingFor = generateDummyFor();
List<JsStatement> entries = translateEntries(); List<JsStatement> entries = translateEntries();
resultingFor.setBody(AstUtil.newBlock(entries)); resultingFor.setBody(AstUtil.newBlock(entries));
context().jsBlock().addStatement(resultingFor); context().addStatementToCurrentBlock(resultingFor);
return result.nameReference(); return result.nameReference();
} }
@@ -119,6 +119,14 @@ public final class PsiUtils {
return (JetObjectDeclaration) parent; return (JetObjectDeclaration) parent;
} }
@NotNull
public static JetObjectDeclarationName getObjectDeclarationName(@NotNull JetObjectDeclaration objectDeclaration) {
//TODO: util
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
assert nameAsDeclaration != null;
return nameAsDeclaration;
}
@NotNull @NotNull
public static String getNamespaceName(@NotNull JetFile psiFile) { public static String getNamespaceName(@NotNull JetFile psiFile) {
JetNamespaceHeader namespaceHeader = psiFile.getNamespaceHeader(); JetNamespaceHeader namespaceHeader = psiFile.getNamespaceHeader();