switched to using dartc.jar

deleted module js.ast
This commit is contained in:
pTalanov
2012-02-27 18:49:54 +04:00
parent 8d6525f23f
commit 8bfa313ad4
136 changed files with 574 additions and 9370 deletions
@@ -17,9 +17,11 @@
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.addVarDeclaration;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
public class DynamicContext {
@NotNull
@@ -66,8 +68,8 @@ public class DynamicContext {
@NotNull
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
JsName temporaryName = blockScope.declareTemporary();
JsVars temporaryDeclaration = AstUtil.newVar(temporaryName, null);
jsBlock().addVarDeclaration(temporaryDeclaration);
JsVars temporaryDeclaration = newVar(temporaryName, /*no init expression in var statement*/ null);
addVarDeclaration(jsBlock(), temporaryDeclaration);
return new TemporaryVariable(temporaryName, initExpression);
}
@@ -22,6 +22,8 @@ import com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel Talanov
* <p/>
@@ -71,7 +73,8 @@ public final class Namer {
public static String getNameForAccessor(@NotNull String propertyName, boolean isGetter) {
if (isGetter) {
return getNameForGetter(propertyName);
} else {
}
else {
return getNameForSetter(propertyName);
}
}
@@ -139,17 +142,17 @@ public final class Namer {
}
@NotNull
private JsNameRef createMethodReference(@NotNull JsName name) {
private static JsNameRef createMethodReference(@NotNull JsName name) {
JsNameRef qualifier = name.makeRef();
JsNameRef reference = AstUtil.newQualifiedNameRef("create");
AstUtil.setQualifier(reference, qualifier);
setQualifier(reference, qualifier);
return reference;
}
@NotNull
private JsNameRef kotlin(@NotNull JsNameRef reference) {
JsNameRef kotlinReference = kotlinName.makeRef();
AstUtil.setQualifier(reference, kotlinReference);
setQualifier(reference, kotlinReference);
return reference;
}
@@ -20,6 +20,8 @@ import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
/**
* @author Pavel Talanov
* <p/>
@@ -42,7 +44,7 @@ public final class NamingScope {
@NotNull
public NamingScope innerScope(@NotNull String scopeName) {
JsScope innerJsScope = new JsScope(jsScope(), scopeName);
return new NamingScope(innerJsScope);
return innerScope(innerJsScope);
}
@NotNull
@@ -71,13 +73,14 @@ public final class NamingScope {
return doObfuscate(name);
}
//TODO: refactor
@NotNull
private String doObfuscate(@NotNull String name) {
int obfuscate = 0;
String result = name;
while (true) {
JsName existingNameWithSameIdent = scope.findExistingName(result);
boolean isDuplicate = (existingNameWithSameIdent != null) && (scope.ownsName(existingNameWithSameIdent));
boolean isDuplicate = (existingNameWithSameIdent != null) && ownsName(scope, existingNameWithSameIdent);
if (!isDuplicate) break;
@@ -87,6 +90,19 @@ public final class NamingScope {
return result;
}
//TODO: util?
private static boolean ownsName(@NotNull JsScope scope, @NotNull JsName name) {
Iterator<JsName> nameIterator = scope.getAllNames();
while (nameIterator.hasNext()) {
if (nameIterator.next() == name) {
return true;
}
}
return false;
}
@NotNull
public JsName declareTemporary() {
return scope.declareTemporary();
}
@@ -16,10 +16,8 @@
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.backend.js.ast.JsProgram;
import com.google.dart.compiler.backend.js.ast.JsRootScope;
import com.google.common.collect.Maps;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -31,6 +29,7 @@ import org.jetbrains.k2js.translate.context.generator.Rule;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*;
@@ -54,7 +53,7 @@ public final class StaticContext {
StandardClasses standardClasses =
StandardClasses.bindImplementations(namer.getKotlinScope());
return new StaticContext(program, bindingContext, aliaser,
namer, intrinsics, standardClasses, scope);
namer, intrinsics, standardClasses, scope);
}
@NotNull
@@ -87,6 +86,9 @@ public final class StaticContext {
@NotNull
private final Generator<Boolean> qualifierIsNull = new QualifierIsNullGenerator();
@NotNull
private final Map<NamingScope, JsFunction> scopeToFunction = Maps.newHashMap();
//TODO: too many parameters in constructor
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
@@ -144,6 +146,14 @@ public final class StaticContext {
return namingScope;
}
@NotNull
public JsFunction getFunctionWithScope(@NotNull CallableDescriptor descriptor) {
NamingScope scope = getScopeForDescriptor(descriptor);
JsFunction function = scopeToFunction.get(scope);
assert scope.jsScope().equals(function.getScope()) : "Inconsistency.";
return function;
}
@NotNull
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
JsName name = names.get(descriptor.getOriginal());
@@ -216,7 +226,8 @@ public final class StaticContext {
if (annotation != null) {
name = AnnotationsUtils.getAnnotationStringParameter(descriptor, LIBRARY_ANNOTATION_FQNAME);
name = (!name.isEmpty()) ? name : descriptor.getName();
} else {
}
else {
ClassDescriptor containingClass = getContainingClass(descriptor);
if (containingClass == null) return null;
if (getAnnotationByName(containingClass, LIBRARY_ANNOTATION_FQNAME) != null) {
@@ -264,7 +275,8 @@ public final class StaticContext {
if (annotation != null) {
name = AnnotationsUtils.getAnnotationStringParameter(descriptor, NATIVE_ANNOTATION_FQNAME);
name = (!name.isEmpty()) ? name : descriptor.getName();
} else {
}
else {
ClassDescriptor containingClass = getContainingClass(descriptor);
if (containingClass == null) return null;
if (getAnnotationByName(containingClass, NATIVE_ANNOTATION_FQNAME) != null) {
@@ -286,7 +298,8 @@ public final class StaticContext {
Set<? extends FunctionDescriptor> overriddenDescriptors = ((FunctionDescriptor) descriptor).getOverriddenDescriptors();
if (overriddenDescriptors.isEmpty()) {
return null;
} else {
}
else {
//assert overriddenDescriptors.size() == 1;
//TODO: for now translator can't deal with multiple inheritance good enough
for (FunctionDescriptor overriddenDescriptor : overriddenDescriptors) {
@@ -360,6 +373,20 @@ public final class StaticContext {
return enclosingScope.innerScope("Scope for member " + descriptor.getName());
}
};
Rule<NamingScope> createFunctionObjectsForCallableDescriptors = new Rule<NamingScope>() {
@Override
public NamingScope apply(@NotNull DeclarationDescriptor descriptor) {
if (!(descriptor instanceof CallableDescriptor)) {
return null;
}
NamingScope enclosingScope = getEnclosingScope(descriptor);
JsFunction correspondingFunction = new JsFunction(enclosingScope.jsScope());
NamingScope newScope = enclosingScope.innerScope(correspondingFunction.getScope());
scopeToFunction.put(newScope, correspondingFunction);
return newScope;
}
};
addRule(createFunctionObjectsForCallableDescriptors);
addRule(generateNewScopesForClassesWithNoAncestors);
addRule(generateInnerScopesForDerivedClasses);
addRule(generateNewScopesForNamespaceDescriptors);
@@ -439,7 +466,7 @@ public final class StaticContext {
}
}
private class QualifierIsNullGenerator extends Generator<Boolean> {
private static class QualifierIsNullGenerator extends Generator<Boolean> {
private QualifierIsNullGenerator() {
Rule<Boolean> propertiesHaveNoQualifiers = new Rule<Boolean>() {
@@ -16,7 +16,6 @@
package org.jetbrains.k2js.translate.context;
import com.google.common.collect.Maps;
import com.google.dart.compiler.backend.js.ast.*;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
@@ -26,8 +25,6 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import java.util.Map;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForElement;
/**
@@ -41,15 +38,13 @@ public final class TranslationContext {
private final DynamicContext dynamicContext;
@NotNull
private final StaticContext staticContext;
@NotNull
private final Map<JsScope, JsFunction> scopeToFunction = Maps.newHashMap();
@NotNull
public static TranslationContext rootContext(@NotNull StaticContext staticContext) {
JsProgram program = staticContext.getProgram();
JsBlock globalBlock = program.getGlobalBlock();
return new TranslationContext(staticContext,
DynamicContext.rootContext(staticContext.getRootScope(), globalBlock));
DynamicContext.rootContext(staticContext.getRootScope(), globalBlock));
}
private TranslationContext(@NotNull StaticContext staticContext, @NotNull DynamicContext dynamicContext) {
@@ -155,6 +150,11 @@ public final class TranslationContext {
return dynamicContext.jsScope();
}
@NotNull
public JsFunction getFunctionObject(@NotNull CallableDescriptor descriptor) {
return staticContext.getFunctionWithScope(descriptor);
}
public void addStatementToCurrentBlock(@NotNull JsStatement statement) {
dynamicContext.jsBlock().getStatements().add(statement);
}
@@ -36,6 +36,7 @@ import java.util.List;
import java.util.Map;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getAllClassesDefinedInNamespace;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
/**
* @author Pavel Talanov
@@ -49,7 +50,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
@NotNull
private final Map<JsName, JsName> localToGlobalClassName;
@NotNull
private final JsScope dummyFunctionScope;
private final JsFunction dummyFunction;
@Nullable
private JsName declarationsObject = null;
@Nullable
@@ -60,14 +61,14 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
super(context);
this.descriptors = descriptors;
this.localToGlobalClassName = new HashMap<JsName, JsName>();
this.dummyFunctionScope = new JsScope(context().jsScope(), "class declaration function");
this.dummyFunction = new JsFunction(context.jsScope());
}
public void generateDeclarations() {
declarationsObject = context().jsScope().declareName(Namer.nameForClassesVariable());
assert declarationsObject != null;
declarationsStatement =
AstUtil.newVar(declarationsObject, generateDummyFunctionInvocation());
newVar(declarationsObject, generateDummyFunctionInvocation());
}
@NotNull
@@ -84,10 +85,9 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
@NotNull
private JsInvocation generateDummyFunctionInvocation() {
JsFunction dummyFunction = JsFunction.getAnonymousFunctionWithScope(dummyFunctionScope);
List<JsStatement> classDeclarations = generateClassDeclarationStatements();
classDeclarations.add(new JsReturn(generateReturnedObjectLiteral()));
dummyFunction.setBody(AstUtil.newBlock(classDeclarations));
dummyFunction.setBody(newBlock(classDeclarations));
return AstUtil.newInvocation(dummyFunction);
}
@@ -136,13 +136,13 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
JsName localClassName = generateLocalAlias(declaration);
JsInvocation classDeclarationExpression =
Translation.translateClassDeclaration(declaration, context());
return AstUtil.newVar(localClassName, classDeclarationExpression);
return newVar(localClassName, classDeclarationExpression);
}
@NotNull
private JsName generateLocalAlias(@NotNull JetClass declaration) {
JsName globalClassName = context().getNameForElement(declaration);
JsName localAlias = dummyFunctionScope.declareTemporary();
JsName localAlias = dummyFunction.getScope().declareTemporary();
localToGlobalClassName.put(localAlias, globalClassName);
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(bindingContext(), declaration);
aliaser().setAliasForDescriptor(descriptor, localAlias);
@@ -161,7 +161,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator {
@NotNull
private JsPropertyInitializer getClassNameToClassObject(@NotNull ClassDescriptor classDescriptor) {
JsName className = context().getNameForDescriptor(classDescriptor);
JsNameRef alreadyDefinedClassReferernce = AstUtil.qualified(className, getDeclarationsObjectName().makeRef());
JsNameRef alreadyDefinedClassReferernce = qualified(className, getDeclarationsObjectName().makeRef());
return new JsPropertyInitializer(className.makeRef(), alreadyDefinedClassReferernce);
}
}
@@ -86,9 +86,11 @@ public final class ClassTranslator extends AbstractTranslator {
private JsInvocation classCreateMethodInvocation() {
if (isObject()) {
return AstUtil.newInvocation(context().namer().objectCreationMethodReference());
} else if (isTrait()) {
}
else if (isTrait()) {
return AstUtil.newInvocation(context().namer().traitCreationMethodReference());
} else {
}
else {
return AstUtil.newInvocation(context().namer().classCreationMethodReference());
}
}
@@ -163,7 +165,10 @@ public final class ClassTranslator extends AbstractTranslator {
}
propertyList.addAll(translatePropertiesAsConstructorParameters());
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, context()));
return new JsObjectLiteral(propertyList);
//TODO: util?
JsObjectLiteral jsObjectLiteral = new JsObjectLiteral();
jsObjectLiteral.getPropertyInitializers().addAll(propertyList);
return jsObjectLiteral;
}
@NotNull
@@ -29,6 +29,9 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel.Talanov
* <p/>
@@ -62,7 +65,7 @@ public final class NamespaceTranslator extends AbstractTranslator {
@NotNull
public JsStatement getInitializeStatement() {
JsNameRef initializeMethodReference = Namer.initializeMethodReference();
AstUtil.setQualifier(initializeMethodReference, namespaceName.makeRef());
setQualifier(initializeMethodReference, namespaceName.makeRef());
return AstUtil.newInvocation(initializeMethodReference).makeStmt();
}
@@ -76,7 +79,7 @@ public final class NamespaceTranslator extends AbstractTranslator {
JsInvocation namespaceDeclaration = namespaceCreateMethodInvocation();
addMemberDeclarations(namespaceDeclaration);
addClassesDeclarations(namespaceDeclaration);
return AstUtil.newVar(namespaceName, namespaceDeclaration);
return newVar(namespaceName, namespaceDeclaration);
}
private void addClassesDeclarations(@NotNull JsInvocation namespaceDeclaration) {
@@ -93,6 +96,9 @@ public final class NamespaceTranslator extends AbstractTranslator {
List<JsPropertyInitializer> propertyList = new ArrayList<JsPropertyInitializer>();
propertyList.add(Translation.generateNamespaceInitializerMethod(descriptor, context()));
propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(descriptor, context()));
return new JsObjectLiteral(propertyList);
//TODO: make util, search for dups
JsObjectLiteral jsObjectLiteral = new JsObjectLiteral();
jsObjectLiteral.getPropertyInitializers().addAll(propertyList);
return jsObjectLiteral;
}
}
@@ -17,7 +17,6 @@
package org.jetbrains.k2js.translate.declaration;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
@@ -31,10 +30,11 @@ import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
/**
* @author Pavel Talanov
@@ -74,7 +74,8 @@ public final class PropertyTranslator extends AbstractTranslator {
private void addGetter() {
if (hasCustomGetter()) {
accessors.add(translateCustomAccessor(getCustomGetterDeclaration()));
} else {
}
else {
accessors.add(generateDefaultGetter());
}
}
@@ -82,7 +83,8 @@ public final class PropertyTranslator extends AbstractTranslator {
private void addSetter() {
if (hasCustomSetter()) {
accessors.add(translateCustomAccessor(getCustomSetterDeclaration()));
} else {
}
else {
accessors.add(generateDefaultSetter());
}
}
@@ -115,15 +117,15 @@ public final class PropertyTranslator extends AbstractTranslator {
private JsPropertyInitializer generateDefaultGetter() {
PropertyGetterDescriptor getterDescriptor = property.getGetter();
assert getterDescriptor != null : "Getter descriptor should not be null";
return AstUtil.newNamedMethod(context().getNameForDescriptor(getterDescriptor),
generateDefaultGetterFunction(getterDescriptor));
return newNamedMethod(context().getNameForDescriptor(getterDescriptor),
generateDefaultGetterFunction(getterDescriptor));
}
@NotNull
private JsFunction generateDefaultGetterFunction(@NotNull PropertyGetterDescriptor descriptor) {
JsReturn returnExpression = new JsReturn(backingFieldReference(context(), property));
JsFunction getterFunction = functionWithScope(context().getScopeForDescriptor(descriptor));
getterFunction.setBody(AstUtil.convertToBlock(returnExpression));
JsFunction getterFunction = context().getFunctionObject(descriptor);
getterFunction.setBody(convertToBlock(returnExpression));
return getterFunction;
}
@@ -131,18 +133,18 @@ public final class PropertyTranslator extends AbstractTranslator {
private JsPropertyInitializer generateDefaultSetter() {
PropertySetterDescriptor setterDescriptor = property.getSetter();
assert setterDescriptor != null : "Setter descriptor should not be null";
return AstUtil.newNamedMethod(context().getNameForDescriptor(setterDescriptor),
generateDefaultSetterFunction(setterDescriptor));
return newNamedMethod(context().getNameForDescriptor(setterDescriptor),
generateDefaultSetterFunction(setterDescriptor));
}
@NotNull
private JsFunction generateDefaultSetterFunction(@NotNull PropertySetterDescriptor propertySetterDescriptor) {
JsFunction result = functionWithScope(context().getScopeForDescriptor(propertySetterDescriptor));
JsFunction result = context().getFunctionObject(propertySetterDescriptor);
JsParameter defaultParameter =
new JsParameter(propertyAccessContext(propertySetterDescriptor).jsScope().declareTemporary());
JsStatement assignment = assignmentToBackingField(context(), property, defaultParameter.getName().makeRef());
result.setParameters(Arrays.asList(defaultParameter));
result.setBody(AstUtil.convertToBlock(assignment));
setParameters(result, defaultParameter);
result.setBody(convertToBlock(assignment));
return result;
}
@@ -17,7 +17,6 @@
package org.jetbrains.k2js.translate.expression;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -36,11 +35,13 @@ import org.jetbrains.k2js.translate.operation.IncrementTranslator;
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
import org.jetbrains.k2js.translate.reference.*;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationName;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateInitializerForProperty;
@@ -52,7 +53,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
private JsExpression translateAsExpression(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
return AstUtil.convertToExpression(expression.accept(this, context));
return convertToExpression(expression.accept(this, context));
}
@Override
@@ -98,9 +99,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
TranslationContext blockContext = context.innerBlock(jsBlock);
for (JetElement statement : statements) {
assert statement instanceof JetExpression : "Elements in JetBlockExpression " +
"should be of type JetExpression";
"should be of type JetExpression";
JsNode jsNode = statement.accept(this, blockContext);
jsBlock.addStatement(AstUtil.convertToStatement(jsNode));
jsBlock.getStatements().add(convertToStatement(jsNode));
}
return jsBlock;
}
@@ -142,7 +143,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), expression);
JsName jsPropertyName = context.getNameForDescriptor(descriptor);
JsExpression jsInitExpression = translateInitializerForProperty(expression, context);
return AstUtil.newVar(jsPropertyName, jsInitExpression);
return newVar(jsPropertyName, jsInitExpression);
}
@Override
@@ -160,11 +161,11 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
return ifStatement;
}
TemporaryVariable result = context.declareTemporary(context.program().getNullLiteral());
AstUtil.SaveLastExpressionMutator saveResultToTemporaryMutator =
new AstUtil.SaveLastExpressionMutator(result.reference());
JsNode mutatedIfStatement = AstUtil.mutateLastExpression(ifStatement,
saveResultToTemporaryMutator);
JsStatement resultingStatement = AstUtil.convertToStatement(mutatedIfStatement);
JsAstUtils.SaveLastExpressionMutator saveResultToTemporaryMutator =
new JsAstUtils.SaveLastExpressionMutator(result.reference());
JsNode mutatedIfStatement = mutateLastExpression(ifStatement,
saveResultToTemporaryMutator);
JsStatement resultingStatement = convertToStatement(mutatedIfStatement);
context.addStatementToCurrentBlock(resultingStatement);
return result.reference();
}
@@ -194,7 +195,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
if (jetElse == null) {
return null;
}
return AstUtil.convertToStatement(jetElse.accept(this, context));
return convertToStatement(jetElse.accept(this, context));
}
@NotNull
@@ -203,7 +204,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
if (nullableExpression == null) {
return context.program().getEmptyStmt();
}
return AstUtil.convertToStatement(nullableExpression.accept(this, context));
return convertToStatement(nullableExpression.accept(this, context));
}
@NotNull
@@ -211,7 +212,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull TranslationContext context) {
JsExpression jsCondition = translateNullableExpression(expression, context);
assert (jsCondition != null) : "Condition should not be empty";
return AstUtil.convertToExpression(jsCondition);
return convertToExpression(jsCondition);
}
@Nullable
@@ -253,14 +254,14 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
}
@NotNull
private JsNode resolveAsTemplate(@NotNull JetStringTemplateExpression expression,
@NotNull TranslationContext context) {
private static JsNode resolveAsTemplate(@NotNull JetStringTemplateExpression expression,
@NotNull TranslationContext context) {
return StringTemplateTranslator.translate(expression, context);
}
@Nullable
private JsStringLiteral resolveAsStringConstant(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
private static JsStringLiteral resolveAsStringConstant(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
Object value = getCompileTimeValue(context.bindingContext(), expression);
if (value == null) {
return null;
@@ -408,7 +409,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), objectDeclarationName);
JsName propertyName = context.getNameForDescriptor(descriptor);
JsExpression value = ClassTranslator.generateClassCreationExpression(expression, context);
return AstUtil.newVar(propertyName, value);
return newVar(propertyName, value);
}
@Override
@@ -30,13 +30,16 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.newAliasForThis;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.removeAliasForThis;
/**
@@ -108,7 +111,7 @@ public final class FunctionTranslator extends AbstractTranslator {
@NotNull
private JsFunction generateFunctionObject() {
functionObject.setParameters(translateParameters());
setParameters(functionObject, translateParameters());
translateBody();
functionObject.setBody(functionBody);
restoreContext();
@@ -126,7 +129,7 @@ public final class FunctionTranslator extends AbstractTranslator {
@NotNull
private JsFunction createFunctionObject() {
if (isDeclaration()) {
return functionWithScope(context().getScopeForDescriptor(descriptor));
return context().getFunctionObject(descriptor);
}
if (isLiteral()) {
//TODO: changing this piece of code to more natural "same as for declaration" results in life test failing
@@ -143,7 +146,7 @@ public final class FunctionTranslator extends AbstractTranslator {
return;
}
JsNode realBody = Translation.translateExpression(jetBodyExpression, functionBodyContext);
functionBody.addStatement(wrapWithReturnIfNeeded(realBody, mustAddReturnToGeneratedFunctionBody()));
functionBody.getStatements().add(wrapWithReturnIfNeeded(realBody, mustAddReturnToGeneratedFunctionBody()));
}
private boolean mustAddReturnToGeneratedFunctionBody() {
@@ -153,15 +156,15 @@ public final class FunctionTranslator extends AbstractTranslator {
}
@NotNull
private JsBlock wrapWithReturnIfNeeded(@NotNull JsNode body, boolean needsReturn) {
private static JsBlock wrapWithReturnIfNeeded(@NotNull JsNode body, boolean needsReturn) {
if (!needsReturn) {
return AstUtil.convertToBlock(body);
return convertToBlock(body);
}
return AstUtil.convertToBlock(lastExpressionReturned(body));
return convertToBlock(lastExpressionReturned(body));
}
private JsNode lastExpressionReturned(@NotNull JsNode body) {
return AstUtil.mutateLastExpression(body, new AstUtil.Mutator() {
private static JsNode lastExpressionReturned(@NotNull JsNode body) {
return mutateLastExpression(body, new JsAstUtils.Mutator() {
@Override
@NotNull
public JsNode mutate(@NotNull JsNode node) {
@@ -177,7 +180,8 @@ public final class FunctionTranslator extends AbstractTranslator {
private TranslationContext functionBodyContext() {
if (isLiteral()) {
return context().innerJsScope(functionObject.getScope());
} else {
}
else {
return context().newDeclaration(functionDeclaration);
}
}
@@ -218,6 +222,6 @@ public final class FunctionTranslator extends AbstractTranslator {
private boolean isDeclaration() {
return (functionDeclaration instanceof JetNamedFunction) ||
(functionDeclaration instanceof JetPropertyAccessor);
(functionDeclaration instanceof JetPropertyAccessor);
}
}
@@ -28,8 +28,11 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
/**
* @author Pavel Talanov
*/
@@ -50,11 +53,12 @@ public final class PatternTranslator extends AbstractTranslator {
JetPattern pattern = getPattern(expression);
JsExpression resultingExpression = translatePattern(pattern, left);
if (expression.isNegated()) {
return AstUtil.negated(resultingExpression);
return negated(resultingExpression);
}
return resultingExpression;
}
//TODO: inspection
@NotNull
private JetPattern getPattern(@NotNull JetIsExpression expression) {
JetPattern pattern = expression.getPattern();
@@ -79,14 +83,14 @@ public final class PatternTranslator extends AbstractTranslator {
//TODO: look into using intrinsics or other mechanisms to implement this logic
JsName className = getClassReference(pattern).getName();
if (className.getIdent().equals("String")) {
return AstUtil.typeof(expressionToMatch, program().getStringLiteral("string"));
return typeof(expressionToMatch, program().getStringLiteral("string"));
}
if (className.getIdent().equals("Int")) {
return AstUtil.typeof(expressionToMatch, program().getStringLiteral("number"));
return typeof(expressionToMatch, program().getStringLiteral("number"));
}
JsInvocation isCheck = AstUtil.newInvocation(context().namer().isOperationReference(),
expressionToMatch, getClassReference(pattern));
expressionToMatch, getClassReference(pattern));
if (isNullable(pattern)) {
return addNullCheck(expressionToMatch, isCheck);
}
@@ -95,12 +99,12 @@ public final class PatternTranslator extends AbstractTranslator {
@NotNull
private JsExpression addNullCheck(@NotNull JsExpression expressionToMatch, @NotNull JsInvocation isCheck) {
return AstUtil.or(TranslationUtils.isNullCheck(context(), expressionToMatch), isCheck);
return or(TranslationUtils.isNullCheck(context(), expressionToMatch), isCheck);
}
private boolean isNullable(JetTypePattern pattern) {
return BindingUtils.getTypeByReference(bindingContext(),
getTypeReference(pattern)).isNullable();
getTypeReference(pattern)).isNullable();
}
@NotNull
@@ -109,6 +113,7 @@ public final class PatternTranslator extends AbstractTranslator {
return getClassNameReferenceForTypeReference(typeReference);
}
//TODO: inspection: util?
@NotNull
private JetTypeReference getTypeReference(@NotNull JetTypePattern pattern) {
JetTypeReference typeReference = pattern.getTypeReference();
@@ -129,6 +134,6 @@ public final class PatternTranslator extends AbstractTranslator {
assert patternExpression != null : "Expression patter should have an expression.";
JsExpression expressionToMatchAgainst =
Translation.translateAsExpression(patternExpression, context());
return AstUtil.equals(expressionToMatch, expressionToMatchAgainst);
return JsAstUtils.equals(expressionToMatch, expressionToMatchAgainst);
}
}
@@ -25,7 +25,8 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import static com.google.dart.compiler.util.AstUtil.sum;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.sum;
/**
* @author Pavel Talanov
@@ -66,7 +67,8 @@ public final class StringTemplateTranslator extends AbstractTranslator {
void append(@NotNull JsExpression expression) {
if (resultingExpression == null) {
resultingExpression = expression;
} else {
}
else {
resultingExpression = sum(resultingExpression, expression);
}
}
@@ -30,7 +30,7 @@ import org.jetbrains.k2js.translate.general.Translation;
import java.util.ArrayList;
import java.util.List;
import static com.google.dart.compiler.util.AstUtil.convertToBlock;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
/**
* @author Pavel Talanov
@@ -25,10 +25,13 @@ import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
/**
* @author Pavel Talanov
*/
@@ -63,7 +66,7 @@ public class WhenTranslator extends AbstractTranslator {
JsNode translate() {
JsFor resultingFor = generateDummyFor();
List<JsStatement> entries = translateEntries();
resultingFor.setBody(AstUtil.newBlock(entries));
resultingFor.setBody(newBlock(entries));
context().addStatementToCurrentBlock(resultingFor);
return result.reference();
}
@@ -80,7 +83,7 @@ public class WhenTranslator extends AbstractTranslator {
@NotNull
private JsStatement surroundWithDummyIf(@NotNull JsStatement entryStatement) {
JsExpression stepNumberEqualsCurrentEntryNumber = new JsBinaryOperation(JsBinaryOperator.EQ,
dummyCounter.reference(), program().getNumberLiteral(currentEntryNumber));
dummyCounter.reference(), program().getNumberLiteral(currentEntryNumber));
currentEntryNumber++;
return new JsIf(stepNumberEqualsCurrentEntryNumber, entryStatement, null);
}
@@ -118,8 +121,8 @@ public class WhenTranslator extends AbstractTranslator {
@NotNull
JsStatement withReturnValueCaptured(@NotNull JsNode node) {
return AstUtil.convertToStatement(AstUtil.mutateLastExpression(node,
new AstUtil.SaveLastExpressionMutator(result.reference())));
return convertToStatement(mutateLastExpression(node,
new JsAstUtils.SaveLastExpressionMutator(result.reference())));
}
@NotNull
@@ -139,7 +142,7 @@ public class WhenTranslator extends AbstractTranslator {
}
@NotNull
private JsExpression anyOfThemIsTrue(List<JsExpression> conditions) {
private static JsExpression anyOfThemIsTrue(List<JsExpression> conditions) {
assert !conditions.isEmpty() : "When entry (not else) should have at least one condition";
JsExpression current = null;
for (JsExpression condition : conditions) {
@@ -150,11 +153,12 @@ public class WhenTranslator extends AbstractTranslator {
}
@NotNull
private JsExpression addCaseCondition(@Nullable JsExpression current, @NotNull JsExpression condition) {
private static JsExpression addCaseCondition(@Nullable JsExpression current, @NotNull JsExpression condition) {
if (current == null) {
return condition;
} else {
return AstUtil.or(current, condition);
}
else {
return or(current, condition);
}
}
@@ -167,7 +171,7 @@ public class WhenTranslator extends AbstractTranslator {
}
@NotNull
private JsBlock addDummyBreak(@NotNull JsStatement statement) {
private static JsBlock addDummyBreak(@NotNull JsStatement statement) {
return AstUtil.newBlock(statement, new JsBreak());
}
@@ -176,12 +180,12 @@ public class WhenTranslator extends AbstractTranslator {
JsExpression patternMatchExpression = Translation.patternTranslator(context()).
translatePattern(getPattern(condition), expressionToMatch);
if (isNegated(condition)) {
return AstUtil.negated(patternMatchExpression);
return negated(patternMatchExpression);
}
return patternMatchExpression;
}
private boolean isNegated(@NotNull JetWhenCondition condition) {
private static boolean isNegated(@NotNull JetWhenCondition condition) {
if (condition instanceof JetWhenConditionIsPattern) {
return ((JetWhenConditionIsPattern) condition).isNegated();
}
@@ -189,13 +193,15 @@ public class WhenTranslator extends AbstractTranslator {
}
@NotNull
private JetPattern getPattern(@NotNull JetWhenCondition condition) {
private static JetPattern getPattern(@NotNull JetWhenCondition condition) {
JetPattern pattern;
if (condition instanceof JetWhenConditionIsPattern) {
pattern = ((JetWhenConditionIsPattern) condition).getPattern();
} else if (condition instanceof JetWhenConditionWithExpression) {
}
else if (condition instanceof JetWhenConditionWithExpression) {
pattern = ((JetWhenConditionWithExpression) condition).getPattern();
} else {
}
else {
throw new AssertionError("Wrong type of JetWhenCondition");
}
assert pattern != null : "Condition should have a non null pattern.";
@@ -33,6 +33,7 @@ import java.util.List;
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
@@ -54,7 +55,7 @@ public final class ArrayForTranslator extends ForTranslator {
//TODO: better check
//TODO: IMPORTANT!
return getClassDescriptorForType(rangeType).getName().equals("Array")
|| getClassDescriptorForType(rangeType).getName().equals("IntArray");
|| getClassDescriptorForType(rangeType).getName().equals("IntArray");
}
@NotNull
@@ -78,7 +79,7 @@ public final class ArrayForTranslator extends ForTranslator {
private JsBlock translate() {
List<JsStatement> blockStatements = temporariesInitialization(loopRange, end);
blockStatements.add(generateForExpression());
return AstUtil.newBlock(blockStatements);
return newBlock(blockStatements);
}
@NotNull
@@ -94,19 +95,19 @@ public final class ArrayForTranslator extends ForTranslator {
@NotNull
private JsStatement getBody() {
JsArrayAccess arrayAccess = new JsArrayAccess(loopRange.reference(), index.reference());
JsStatement currentVar = AstUtil.newVar(parameterName, arrayAccess);
JsStatement currentVar = newVar(parameterName, arrayAccess);
JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context());
return AstUtil.newBlock(currentVar, realBody);
}
@NotNull
private JsVars initExpression() {
return AstUtil.newVar(index.name(), program().getNumberLiteral(0));
return newVar(index.name(), program().getNumberLiteral(0));
}
@NotNull
private JsExpression getCondition() {
return AstUtil.notEqual(index.reference(), end.reference());
return notEqual(index.reference(), end.reference());
}
@NotNull
@@ -30,6 +30,8 @@ import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.reference.CallBuilder;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
@@ -62,10 +64,10 @@ public final class IteratorForTranslator extends ForTranslator {
@NotNull
private JsBlock generateCycleBody() {
JsBlock cycleBody = new JsBlock();
JsStatement parameterAssignment = AstUtil.newVar(parameterName, nextMethodInvocation());
JsStatement parameterAssignment = newVar(parameterName, nextMethodInvocation());
JsNode originalBody = Translation.translateExpression(getLoopBody(expression), context().innerBlock(cycleBody));
cycleBody.addStatement(parameterAssignment);
cycleBody.addStatement(AstUtil.convertToBlock(originalBody));
cycleBody.getStatements().add(parameterAssignment);
cycleBody.getStatements().add(convertToBlock(originalBody));
return cycleBody;
}
@@ -31,6 +31,7 @@ import java.util.List;
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
@@ -39,6 +40,7 @@ import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
*/
public final class RangeForTranslator extends ForTranslator {
//TODO: inspection
@NotNull
public static JsStatement translate(@NotNull JetForExpression expression,
@NotNull TranslationContext context) {
@@ -67,8 +69,8 @@ public final class RangeForTranslator extends ForTranslator {
rangeExpression = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
JsExpression isReversed = callFunction("get_reversed");
JsConditional incrVarValue = new JsConditional(isReversed,
program().getNumberLiteral(-1),
program().getNumberLiteral(1));
program().getNumberLiteral(-1),
program().getNumberLiteral(1));
incrVar = context().declareTemporary(incrVarValue);
start = context().declareTemporary(callFunction("get_start"));
end = context().declareTemporary(new JsBinaryOperation(JsBinaryOperator.ADD, callFunction("get_end"), incrVar.reference()));
@@ -78,7 +80,7 @@ public final class RangeForTranslator extends ForTranslator {
private JsBlock translate() {
List<JsStatement> blockStatements = temporariesInitialization(rangeExpression, incrVar, start, end);
blockStatements.add(generateForExpression());
return AstUtil.newBlock(blockStatements);
return newBlock(blockStatements);
}
@NotNull
@@ -93,12 +95,12 @@ public final class RangeForTranslator extends ForTranslator {
@NotNull
private JsVars initExpression() {
return AstUtil.newVar(parameterName, start.reference());
return newVar(parameterName, start.reference());
}
@NotNull
private JsExpression getCondition() {
return AstUtil.notEqual(parameterName.makeRef(), end.reference());
return notEqual(parameterName.makeRef(), end.reference());
}
@NotNull
@@ -109,7 +111,7 @@ public final class RangeForTranslator extends ForTranslator {
@NotNull
private JsExpression getField(@NotNull String fieldName) {
JsNameRef nameRef = AstUtil.newQualifiedNameRef(fieldName);
AstUtil.setQualifier(nameRef, rangeExpression.reference());
setQualifier(nameRef, rangeExpression.reference());
return nameRef;
}
@@ -16,9 +16,7 @@
package org.jetbrains.k2js.translate.expression.foreach;
import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
@@ -30,6 +28,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import java.util.List;
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
@@ -82,7 +81,7 @@ public final class RangeLiteralForTranslator extends ForTranslator {
private JsBlock translate() {
List<JsStatement> blockStatements = temporariesInitialization(rangeEnd);
blockStatements.add(generateForExpression());
return AstUtil.newBlock(blockStatements);
return newBlock(blockStatements);
}
@NotNull
@@ -97,12 +96,12 @@ public final class RangeLiteralForTranslator extends ForTranslator {
@NotNull
private JsVars initExpression() {
return AstUtil.newVar(parameterName, rangeStart);
return newVar(parameterName, rangeStart);
}
@NotNull
private JsExpression getCondition() {
return AstUtil.notEqual(parameterName.makeRef(), rangeEnd.reference());
return notEqual(parameterName.makeRef(), rangeEnd.reference());
}
@NotNull
@@ -19,7 +19,6 @@ package org.jetbrains.k2js.translate.general;
import com.google.dart.compiler.backend.js.JsNamer;
import com.google.dart.compiler.backend.js.JsPrettyNamer;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.*;
@@ -38,6 +37,9 @@ import org.jetbrains.k2js.translate.initializer.NamespaceInitializerTranslator;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToExpression;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement;
/**
* @author Pavel Talanov
* <p/>
@@ -46,6 +48,9 @@ import java.util.List;
*/
public final class Translation {
private Translation() {
}
@NotNull
public static FunctionTranslator functionTranslator(@NotNull JetDeclarationWithBody function,
@NotNull TranslationContext context) {
@@ -76,13 +81,13 @@ public final class Translation {
@NotNull
public static JsExpression translateAsExpression(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
return AstUtil.convertToExpression(translateExpression(expression, context));
return convertToExpression(translateExpression(expression, context));
}
@NotNull
public static JsStatement translateAsStatement(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
return AstUtil.convertToStatement(translateExpression(expression, context));
return convertToStatement(translateExpression(expression, context));
}
@NotNull
@@ -17,7 +17,6 @@
package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -35,8 +34,8 @@ import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
/**
* @author Pavel Talanov
@@ -57,10 +56,11 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
@Override
@NotNull
protected JsFunction generateInitializerFunction() {
JsFunction result = functionWithScope(initializerMethodScope);
//TODO: look for duplication of this code
JsFunction result = new JsFunction(initializerMethodScope.jsScope());
//NOTE: that while we translateAsLocalNameReference constructor parameters we also add property initializer statements
// for properties declared as constructor parameters
result.setParameters(translatePrimaryConstructorParameters());
setParameters(result, translatePrimaryConstructorParameters());
mayBeAddCallToSuperMethod();
result.setBody(generateInitializerMethodBody());
return result;
@@ -69,7 +69,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
@NotNull
private JsBlock generateInitializerMethodBody() {
initializerStatements.addAll(translateClassInitializers(classDeclaration));
return AstUtil.newBlock(initializerStatements);
return newBlock(initializerStatements);
}
private void mayBeAddCallToSuperMethod() {
@@ -84,8 +84,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
//TODO: look into
JsName superMethodName = initializerMethodScope.jsScope().declareName(Namer.superMethodName());
List<JsExpression> arguments = translateArguments(superCall);
initializerStatements.add(AstUtil.convertToStatement
(AstUtil.newInvocation(AstUtil.thisQualifiedReference(superMethodName), arguments)));
initializerStatements.add(convertToStatement(newInvocation(thisQualifiedReference(superMethodName), arguments)));
}
@NotNull
@@ -17,12 +17,11 @@
package org.jetbrains.k2js.translate.initializer;
import com.google.dart.compiler.backend.js.ast.JsFunction;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.functionWithScope;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newBlock;
/**
* @author Pavel Talanov
@@ -41,8 +40,8 @@ public final class NamespaceInitializerTranslator extends AbstractInitializerTra
@Override
@NotNull
protected JsFunction generateInitializerFunction() {
JsFunction result = functionWithScope(initializerMethodScope);
result.setBody(AstUtil.newBlock(translateNamespaceInitializers(namespace)));
JsFunction result = new JsFunction(initializerMethodScope.jsScope());
result.setBody(newBlock(translateNamespaceInitializers(namespace)));
return result;
}
@@ -26,6 +26,8 @@ import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
/**
* @author Pavel Talanov
*/
@@ -43,6 +45,6 @@ public enum ArrayFunctionConstructorIntrinsic implements FunctionIntrinsic {
assert arguments.size() == 2;
//TODO: provide better mechanism
JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef("Kotlin.arrayFromFun");
return AstUtil.newInvocation(iteratorFunName, arguments);
return newInvocation(iteratorFunName, arguments);
}
}
@@ -26,6 +26,8 @@ import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
/**
* @author Pavel Talanov
*/
@@ -42,6 +44,6 @@ public enum ArrayNullConstructorIntrinsic implements FunctionIntrinsic {
assert arguments.size() == 1;
//TODO: provide better mechanism
JsNameRef nullArrayFunName = AstUtil.newQualifiedNameRef("Kotlin.nullArray");
return AstUtil.newInvocation(nullArrayFunName, arguments);
return newInvocation(nullArrayFunName, arguments);
}
}
@@ -26,6 +26,8 @@ import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel Talanov
*/
@@ -42,7 +44,7 @@ public enum ArraySizeIntrinsic implements FunctionIntrinsic {
assert arguments.isEmpty() : "Length expression must have zero arguments.";
//TODO: provide better way
JsNameRef lengthProperty = AstUtil.newQualifiedNameRef("length");
AstUtil.setQualifier(lengthProperty, receiver);
setQualifier(lengthProperty, receiver);
return lengthProperty;
}
}
@@ -17,14 +17,16 @@
package org.jetbrains.k2js.translate.intrinsic.primitive;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.notEqual;
/**
* @author Pavel Talanov
*/
@@ -42,10 +44,12 @@ public final class PrimitiveEqualsIntrinsic extends EqualsIntrinsic {
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
@NotNull TranslationContext context) {
assert arguments.size() == 1 : "Equals operation should have one argument";
assert receiver != null;
if (isNegated()) {
return AstUtil.notEqual(receiver, arguments.get(0));
} else {
return AstUtil.equals(receiver, arguments.get(0));
return notEqual(receiver, arguments.get(0));
}
else {
return JsAstUtils.equals(receiver, arguments.get(0));
}
}
@@ -26,9 +26,10 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
import java.util.Arrays;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
/**
* @author Pavel Talanov
*/
@@ -48,14 +49,14 @@ public final class PrimitiveRangeToIntrinsic implements FunctionIntrinsic {
@NotNull TranslationContext context) {
assert arguments.size() == 1 : "RangeTo must have one argument.";
JsExpression rangeEnd = arguments.get(0);
JsBinaryOperation rangeSize = AstUtil.sum(AstUtil.subtract(rangeEnd, rangeStart),
context.program().getNumberLiteral(1));
JsBinaryOperation rangeSize = sum(subtract(rangeEnd, rangeStart),
context.program().getNumberLiteral(1));
//TODO: provide a way not to hard code this value
JsNew numberRangeConstructorInvocation
= new JsNew(AstUtil.newQualifiedNameRef("Kotlin.NumberRange"));
//TODO: add tests and correct expression for reversed ranges.
JsBooleanLiteral isRangeReversed = context.program().getFalseLiteral();
numberRangeConstructorInvocation.setArguments(Arrays.asList(rangeStart, rangeSize, isRangeReversed));
setArguments(numberRangeConstructorInvocation, rangeStart, rangeSize, isRangeReversed);
return numberRangeConstructorInvocation;
}
}
@@ -26,6 +26,9 @@ import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel Talanov
*/
@@ -41,7 +44,7 @@ public enum CharAtIntrinsic implements FunctionIntrinsic {
assert arguments.size() == 1 : "get Char expression must have 1 arguments.";
//TODO: provide better way
JsNameRef charAtReference = AstUtil.newQualifiedNameRef("charAt");
AstUtil.setQualifier(charAtReference, receiver);
return AstUtil.newInvocation(charAtReference, arguments);
setQualifier(charAtReference, receiver);
return newInvocation(charAtReference, arguments);
}
}
@@ -27,6 +27,8 @@ import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
/**
* @author Pavel Talanov
*/
@@ -42,7 +44,7 @@ public enum LengthIntrinsic implements FunctionIntrinsic {
assert arguments.isEmpty() : "Length expression must have zero arguments.";
//TODO: provide better way
JsNameRef lengthProperty = AstUtil.newQualifiedNameRef("length");
AstUtil.setQualifier(lengthProperty, receiver);
setQualifier(lengthProperty, receiver);
return lengthProperty;
}
}
@@ -35,12 +35,12 @@ import org.jetbrains.k2js.translate.reference.CallType;
import java.util.Arrays;
import static com.google.dart.compiler.util.AstUtil.not;
import static org.jetbrains.k2js.translate.operation.AssignmentTranslator.isAssignmentOperator;
import static org.jetbrains.k2js.translate.operation.CompareToTranslator.isCompareToCall;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isEquals;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.not;
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
@@ -140,7 +140,8 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
if (isInOrNotInOperation(expression)) {
return callBuilder.receiver(rightExpression).args(leftExpression);
} else {
}
else {
return callBuilder.receiver(leftExpression).args(rightExpression);
}
}
@@ -149,7 +150,8 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
private JsExpression mayBeWrapWithNegation(@NotNull JsExpression result) {
if (isNotInOperation(expression)) {
return not(result);
} else {
}
else {
return result;
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMethodReferenceForOverloadedOperation;
/**
@@ -60,7 +61,7 @@ public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
@NotNull
private JsExpression overloadedMethodInvocation() {
AstUtil.setQualifier(operationReference, accessTranslator.translateAsGet());
setQualifier(operationReference, accessTranslator.translateAsGet());
return AstUtil.newInvocation(operationReference, right);
}
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMethodReferenceForOverloadedOperation;
/**
@@ -47,14 +48,14 @@ public final class OverloadedIncrementTranslator extends IncrementTranslator {
}
@NotNull
protected JsExpression translate() {
private JsExpression translate() {
return translateAsMethodCall();
}
@Override
@NotNull
protected JsExpression operationExpression(@NotNull JsExpression receiver) {
AstUtil.setQualifier(operationReference, receiver);
setQualifier(operationReference, receiver);
return AstUtil.newInvocation(operationReference);
}
@@ -37,6 +37,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getThisObject;
/**
@@ -134,7 +135,7 @@ public final class CallTranslator extends AbstractTranslator {
private JsExpression constructorCall() {
JsExpression constructorReference = translateAsFunctionWithNoThisObject(descriptor);
JsNew constructorCall = new JsNew(constructorReference);
constructorCall.setArguments(arguments);
setArguments(constructorCall, arguments);
return constructorCall;
}
@@ -149,7 +150,7 @@ public final class CallTranslator extends AbstractTranslator {
private boolean isExtensionFunctionLiteral() {
boolean isLiteral = descriptor instanceof VariableAsFunctionDescriptor
|| descriptor instanceof ExpressionAsFunctionDescriptor;
|| descriptor instanceof ExpressionAsFunctionDescriptor;
return isExtensionFunction() && isLiteral;
}
@@ -170,7 +171,7 @@ public final class CallTranslator extends AbstractTranslator {
private JsExpression constructExtensionLiteralCall(@NotNull JsExpression realReceiver) {
List<JsExpression> callArguments = generateExtensionCallArgumentList(realReceiver);
JsInvocation callMethodInvocation = generateCallMethodInvocation();
callMethodInvocation.setArguments(callArguments);
setArguments(callMethodInvocation, callArguments);
return callMethodInvocation;
}
@@ -179,7 +180,7 @@ public final class CallTranslator extends AbstractTranslator {
JsNameRef callMethodNameRef = AstUtil.newQualifiedNameRef("call");
JsInvocation callMethodInvocation = new JsInvocation();
callMethodInvocation.setQualifier(callMethodNameRef);
AstUtil.setQualifier(callMethodInvocation, callParameters().functionReference);
setQualifier(callMethodInvocation, callParameters().functionReference);
return callMethodInvocation;
}
@@ -219,8 +220,8 @@ public final class CallTranslator extends AbstractTranslator {
private JsExpression constructExtensionFunctionCall(@NotNull JsExpression receiver) {
List<JsExpression> argumentList = generateExtensionCallArgumentList(receiver);
JsExpression functionReference = callParameters().functionReference;
AstUtil.setQualifier(functionReference, callParameters().receiver);
return AstUtil.newInvocation(functionReference, argumentList);
setQualifier(functionReference, callParameters().receiver);
return newInvocation(functionReference, argumentList);
}
@NotNull
@@ -241,9 +242,9 @@ public final class CallTranslator extends AbstractTranslator {
public JsExpression construct(@Nullable JsExpression receiver) {
JsExpression functionReference = callParameters.functionReference;
if (receiver != null) {
AstUtil.setQualifier(functionReference, receiver);
setQualifier(functionReference, receiver);
}
return AstUtil.newInvocation(functionReference, arguments);
return newInvocation(functionReference, arguments);
}
}, context());
}
@@ -20,7 +20,6 @@ import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsConditional;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNullLiteral;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression;
@@ -30,6 +29,7 @@ import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static com.google.dart.compiler.util.AstUtil.newSequence;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.notEqual;
/**
* @author Pavel Talanov
@@ -44,7 +44,7 @@ public enum CallType {
TemporaryVariable temporaryVariable = context.declareTemporary(receiver);
JsNullLiteral nullLiteral = context.program().getNullLiteral();
//TODO: find similar not null checks
JsBinaryOperation notNullCheck = AstUtil.notEqual(temporaryVariable.reference(), nullLiteral);
JsBinaryOperation notNullCheck = notEqual(temporaryVariable.reference(), nullLiteral);
JsConditional callMethodIfNotNullElseNull =
new JsConditional(notNullCheck, constructor.construct(temporaryVariable.reference()), nullLiteral);
return newSequence(temporaryVariable.assignmentExpression(), callMethodIfNotNullElseNull);
@@ -18,7 +18,6 @@ package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -27,6 +26,8 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedThisDescriptor;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.qualified;
/**
* @author Pavel Talanov
@@ -57,8 +58,9 @@ public final class NativePropertyAccessTranslator extends PropertyAccessTranslat
JsName nativePropertyName = context().getNameForDescriptor(propertyDescriptor);
JsExpression realQualifier = getQualifier();
if (realQualifier != null) {
return AstUtil.qualified(nativePropertyName, realQualifier);
} else {
return qualified(nativePropertyName, realQualifier);
}
else {
return nativePropertyName.makeRef();
}
}
@@ -66,7 +68,7 @@ public final class NativePropertyAccessTranslator extends PropertyAccessTranslat
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression setTo) {
return AstUtil.assignment(translateAsGet(), setTo);
return assignment(translateAsGet(), setTo);
}
@Nullable
@@ -18,19 +18,22 @@ package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.qualified;
/**
* @author Pavel Talanov
*/
public final class ReferenceTranslator {
private ReferenceTranslator() {
}
@NotNull
public static JsExpression translateSimpleName(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
@@ -50,7 +53,7 @@ public final class ReferenceTranslator {
return translateAsLocalNameReference(referencedDescriptor, context);
}
JsName referencedName = context.getNameForDescriptor(referencedDescriptor);
return AstUtil.qualified(referencedName, qualifier);
return qualified(referencedName, qualifier);
}
@NotNull
@@ -0,0 +1,288 @@
/*
* Copyright 2000-2012 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.k2js.translate.utils;
import com.google.common.collect.Lists;
import com.google.dart.compiler.backend.js.ast.*;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* @author Pavel Talanov
*/
public final class JsAstUtils {
private JsAstUtils() {
}
@NotNull
public static JsPropertyInitializer newNamedMethod(@NotNull JsName name, @NotNull JsFunction function) {
JsNameRef methodName = name.makeRef();
return new JsPropertyInitializer(methodName, function);
}
@NotNull
public static JsStatement convertToStatement(@NotNull JsNode jsNode) {
assert (jsNode instanceof JsExpression) || (jsNode instanceof JsStatement)
: "Unexpected node of type: " + jsNode.getClass().toString();
if (jsNode instanceof JsExpression) {
return new JsExprStmt((JsExpression) jsNode);
}
return (JsStatement) jsNode;
}
@NotNull
public static JsBlock convertToBlock(@NotNull JsNode jsNode) {
if (jsNode instanceof JsBlock) {
return (JsBlock) jsNode;
}
JsStatement jsStatement = convertToStatement(jsNode);
return new JsBlock(jsStatement);
}
@NotNull
public static JsExpression convertToExpression(@NotNull JsNode jsNode) {
assert jsNode instanceof JsExpression : "Unexpected node of type: " + jsNode.getClass().toString();
return (JsExpression) jsNode;
}
public static JsNameRef thisQualifiedReference(@NotNull JsName name) {
JsNameRef result = name.makeRef();
result.setQualifier(new JsThisRef());
return result;
}
@NotNull
public static JsBlock newBlock(List<JsStatement> statements) {
JsBlock result = new JsBlock();
setStatements(result, statements);
return result;
}
@NotNull
public static JsPrefixOperation negated(@NotNull JsExpression expression) {
return new JsPrefixOperation(JsUnaryOperator.NOT, expression);
}
@NotNull
public static JsStatement newAssignmentStatement(@NotNull JsNameRef nameRef, @NotNull JsExpression expr) {
return convertToStatement(new JsBinaryOperation(JsBinaryOperator.ASG, nameRef, expr));
}
@NotNull
public static JsExpression extractExpressionFromStatement(@NotNull JsStatement statement) {
assert statement instanceof JsExprStmt : "Cannot extract expression from statement: " + statement;
return (((JsExprStmt) statement).getExpression());
}
@NotNull
public static JsBinaryOperation and(@NotNull JsExpression op1, @NotNull JsExpression op2) {
return new JsBinaryOperation(JsBinaryOperator.AND, op1, op2);
}
@NotNull
public static JsBinaryOperation or(@NotNull JsExpression op1, @NotNull JsExpression op2) {
return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2);
}
//TODO refactor
public static void setQualifier(@NotNull JsExpression selector, @Nullable JsExpression receiver) {
if (selector instanceof JsInvocation) {
setQualifier(((JsInvocation) selector).getQualifier(), receiver);
return;
}
if (selector instanceof JsNameRef) {
JsNameRef nameRef = (JsNameRef) selector;
JsExpression qualifier = nameRef.getQualifier();
if (qualifier == null) {
nameRef.setQualifier(receiver);
}
else {
setQualifier(qualifier, receiver);
}
return;
}
throw new AssertionError("Set qualifier should be applied only to JsInvocation or JsNameRef instances");
}
public static JsNameRef qualified(@NotNull JsName selector, @Nullable JsExpression qualifier) {
JsNameRef reference = selector.makeRef();
setQualifier(reference, qualifier);
return reference;
}
@NotNull
public static JsBinaryOperation equals(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
return new JsBinaryOperation(JsBinaryOperator.EQ, arg1, arg2);
}
@NotNull
public static JsBinaryOperation notEqual(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
return new JsBinaryOperation(JsBinaryOperator.NEQ, arg1, arg2);
}
@NotNull
public static JsExpression equalsTrue(@NotNull JsExpression expression, @NotNull JsProgram program) {
return equals(expression, program.getTrueLiteral());
}
@NotNull
public static JsExpression assignment(@NotNull JsExpression left, @NotNull JsExpression right) {
return new JsBinaryOperation(JsBinaryOperator.ASG, left, right);
}
@NotNull
public static JsBinaryOperation sum(@NotNull JsExpression left, @NotNull JsExpression right) {
return new JsBinaryOperation(JsBinaryOperator.ADD, left, right);
}
@NotNull
public static JsBinaryOperation subtract(@NotNull JsExpression left, @NotNull JsExpression right) {
return new JsBinaryOperation(JsBinaryOperator.SUB, left, right);
}
@NotNull
public static JsPrefixOperation not(@NotNull JsExpression expression) {
return new JsPrefixOperation(JsUnaryOperator.NOT, expression);
}
@NotNull
public static JsBinaryOperation typeof(@NotNull JsExpression expression, @NotNull JsStringLiteral string) {
return equals(new JsPrefixOperation(JsUnaryOperator.TYPEOF, expression), string);
}
public interface Mutator {
JsNode mutate(JsNode node);
}
//TODO: move somewhere
//TODO: refactor and review
public static JsNode mutateLastExpression(@NotNull JsNode node, @NotNull Mutator mutator) {
if (node instanceof JsBlock) {
JsBlock block = (JsBlock) node;
List<JsStatement> statements = block.getStatements();
if (statements.isEmpty()) return block;
int size = statements.size();
statements.set(size - 1,
convertToStatement(mutateLastExpression(statements.get(size - 1), mutator)));
return block;
}
if (node instanceof JsIf) {
JsIf ifExpr = (JsIf) node;
ifExpr.setThenStmt(convertToStatement(mutateLastExpression(ifExpr.getThenStmt(), mutator)));
JsStatement elseStmt = ifExpr.getElseStmt();
if (elseStmt != null) {
ifExpr.setElseStmt(convertToStatement(mutateLastExpression(elseStmt, mutator)));
}
return ifExpr;
}
if (node instanceof JsExprStmt) {
return convertToStatement(mutateLastExpression(((JsExprStmt) node).getExpression(), mutator));
}
return mutator.mutate(node);
}
public static final class SaveLastExpressionMutator implements Mutator {
@NotNull
private final JsExpression toAssign;
public SaveLastExpressionMutator(@NotNull JsExpression toAssign) {
this.toAssign = toAssign;
}
@Override
public JsNode mutate(JsNode node) {
if (!(node instanceof JsExpression)) {
return node;
}
return assignment(toAssign, (JsExpression) node);
}
}
@NotNull
public static JsVars newVar(@NotNull JsName name, @Nullable JsExpression expr) {
JsVars.JsVar var = new JsVars.JsVar(name);
if (expr != null) {
var.setInitExpr(expr);
}
JsVars vars = new JsVars();
vars.add(var);
return vars;
}
public static void addVarDeclaration(@NotNull JsBlock block, @NotNull JsVars vars) {
LinkedList<JsStatement> statementLinkedList = Lists.newLinkedList(block.getStatements());
statementLinkedList.offer(vars);
setStatements(block, statementLinkedList);
}
public static void setStatements(@NotNull JsBlock block, @NotNull List<JsStatement> statements) {
List<JsStatement> statementList = block.getStatements();
statementList.clear();
statementList.addAll(statements);
}
public static void setArguments(@NotNull JsInvocation invocation, @NotNull List<JsExpression> newArgs) {
List<JsExpression> arguments = invocation.getArguments();
assert arguments.isEmpty() : "Arguments already set.";
arguments.addAll(newArgs);
}
public static void setArguments(@NotNull JsInvocation invocation, JsExpression... arguments) {
setArguments(invocation, Arrays.asList(arguments));
}
public static void setArguments(@NotNull JsNew invocation, @NotNull List<JsExpression> newArgs) {
List<JsExpression> arguments = invocation.getArguments();
assert arguments.isEmpty() : "Arguments already set.";
arguments.addAll(newArgs);
}
public static void setArguments(@NotNull JsNew invocation, JsExpression... arguments) {
setArguments(invocation, Arrays.asList(arguments));
}
public static void setParameters(@NotNull JsFunction function, @NotNull List<JsParameter> newParams) {
List<JsParameter> parameters = function.getParameters();
assert parameters.isEmpty() : "Arguments already set.";
parameters.addAll(newParams);
}
public static void setParameters(@NotNull JsFunction function, JsParameter... arguments) {
setParameters(function, Arrays.asList(arguments));
}
@NotNull
public static JsInvocation newInvocation(@NotNull JsExpression target, List<JsExpression> params) {
JsInvocation invoke = new JsInvocation();
invoke.setQualifier(target);
for (JsExpression expr : params) {
invoke.getArguments().add(expr);
}
return invoke;
}
}