From e9682952a1fae23ee83cd4256df9cff3c3c53307 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Fri, 25 Nov 2011 15:17:27 +0400 Subject: [PATCH] Refactoring. --- .idea/workspace.xml | 599 ++++++++---------- .../k2js/translate/AbstractTranslator.java | 2 +- .../translate/BinaryOperationTranslator.java | 6 +- .../k2js/translate/BindingUtils.java | 22 +- .../translate/DeclarationBodyVisitor.java | 166 ----- .../k2js/translate/ExpressionTranslator.java | 2 +- .../k2js/translate/ExpressionVisitor.java | 2 +- .../k2js/translate/FunctionTranslator.java | 14 +- .../k2js/translate/OperationTranslator.java | 12 +- .../k2js/translate/PatternTranslator.java | 14 +- .../translate/PropertyAccessTranslator.java | 12 +- .../k2js/translate/ReferenceTranslator.java | 12 +- .../jetbrains/k2js/translate/Translation.java | 2 + .../k2js/translate/TranslationContext.java | 2 +- .../k2js/translate/TranslationUtils.java | 38 ++ .../k2js/translate/TranslatorVisitor.java | 28 - .../translate/UnaryOperationTranslator.java | 8 +- .../k2js/translate/WhenTranslator.java | 14 +- .../ClassDeclarationTranslator.java | 16 +- .../{ => declaration}/ClassTranslator.java | 20 +- .../declaration/DeclarationBodyVisitor.java | 74 +++ .../NamespaceTranslator.java | 12 +- .../declaration/PropertyTranslator.java | 161 +++++ .../AbstractInitializerTranslator.java | 4 +- .../ClassInitializerTranslator.java | 4 +- .../initializer/InitializerVisitor.java | 4 +- 26 files changed, 642 insertions(+), 608 deletions(-) delete mode 100644 translator/src/org/jetbrains/k2js/translate/DeclarationBodyVisitor.java rename translator/src/org/jetbrains/k2js/translate/{ => declaration}/ClassDeclarationTranslator.java (85%) rename translator/src/org/jetbrains/k2js/translate/{ => declaration}/ClassTranslator.java (88%) create mode 100644 translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java rename translator/src/org/jetbrains/k2js/translate/{ => declaration}/NamespaceTranslator.java (88%) create mode 100644 translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 904c85c1d44..c6fbc6658eb 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -8,25 +8,31 @@ - - - - - - - + + + + + + - - - + + - + + + + + - + + + + + @@ -58,7 +64,7 @@ - + + + @@ -139,7 +158,7 @@ - + @@ -167,75 +186,19 @@ - - + + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -244,16 +207,73 @@ - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -280,22 +300,22 @@ @@ -404,6 +424,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -840,6 +696,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + localhost @@ -1000,21 +920,21 @@ - + - + - + - + - + @@ -1058,7 +978,7 @@ @@ -1105,122 +1025,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java b/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java index a53032a4ad7..42ee19733e8 100644 --- a/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/AbstractTranslator.java @@ -21,7 +21,7 @@ public abstract class AbstractTranslator { } @NotNull - protected TranslationContext translationContext() { + protected TranslationContext context() { return context; } } diff --git a/translator/src/org/jetbrains/k2js/translate/BinaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/BinaryOperationTranslator.java index c2da93681a1..1b0f6cd872b 100644 --- a/translator/src/org/jetbrains/k2js/translate/BinaryOperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/BinaryOperationTranslator.java @@ -119,7 +119,7 @@ public final class BinaryOperationTranslator extends OperationTranslator { } private JsExpression translateLeftExpression() { - return Translation.translateAsExpression(expression.getLeft(), translationContext()); + return Translation.translateAsExpression(expression.getLeft(), context()); } @NotNull @@ -132,7 +132,7 @@ public final class BinaryOperationTranslator extends OperationTranslator { private JsExpression translateRightExpression() { JetExpression rightExpression = expression.getRight(); assert rightExpression != null : "Binary expression should have a right expression"; - return Translation.translateAsExpression(rightExpression, translationContext()); + return Translation.translateAsExpression(rightExpression, context()); } @NotNull @@ -142,7 +142,7 @@ public final class BinaryOperationTranslator extends OperationTranslator { @NotNull public JsInvocation setterCall(@NotNull JsExpression assignTo) { - PropertyAccessTranslator propertyAccessTranslator = Translation.propertyAccessTranslator(translationContext()); + PropertyAccessTranslator propertyAccessTranslator = Translation.propertyAccessTranslator(context()); JsInvocation setterCall = propertyAccessTranslator.translateAsPropertySetterCall(expression.getLeft()); setterCall.setArguments(assignTo); return setterCall; diff --git a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java index 3a97c3b2184..f13e1a0e41f 100644 --- a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java @@ -141,6 +141,22 @@ public final class BindingUtils { return getClassDescriptorForType(getTypeByReference(context, typeReference)); } + @Nullable + static public PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context, + @NotNull JetParameter parameter) { + return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); + } + + @Nullable + static public JetProperty getPropertyForDescriptor(@NotNull BindingContext context, + @NotNull PropertyDescriptor property) { + PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, property); + if (!(result instanceof JetProperty)) { + return null; + } + return (JetProperty) result; + } + @Nullable static public DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context, @NotNull JetReferenceExpression reference) { @@ -164,7 +180,11 @@ public final class BindingUtils { } static public boolean belongsToNamespace(@NotNull BindingContext context, @NotNull JetProperty property) { - return getPropertyDescriptor(context, property).getContainingDeclaration() instanceof NamespaceDescriptor; + return belongsToNamespace(context, getPropertyDescriptor(context, property)); + } + + static public boolean belongsToNamespace(@NotNull BindingContext context, @NotNull PropertyDescriptor descriptor) { + return descriptor.getContainingDeclaration() instanceof NamespaceDescriptor; } @Nullable diff --git a/translator/src/org/jetbrains/k2js/translate/DeclarationBodyVisitor.java b/translator/src/org/jetbrains/k2js/translate/DeclarationBodyVisitor.java deleted file mode 100644 index 9506dbba43c..00000000000 --- a/translator/src/org/jetbrains/k2js/translate/DeclarationBodyVisitor.java +++ /dev/null @@ -1,166 +0,0 @@ -package org.jetbrains.k2js.translate; - -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.PropertyGetterDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor; -import org.jetbrains.jet.lang.psi.*; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * @author Talanov Pavel - */ -public final class DeclarationBodyVisitor extends TranslatorVisitor> { - - - @NotNull - public List traverseClass(@NotNull JetClass expression, - @NotNull TranslationContext context) { - List properties = new ArrayList(); - for (JetDeclaration declaration : expression.getDeclarations()) { - properties.addAll(declaration.accept(this, context)); - } - return properties; - } - - @NotNull - public List traverseNamespace(@NotNull JetNamespace expression, - @NotNull TranslationContext context) { - List properties = new ArrayList(); - for (JetDeclaration declaration : expression.getDeclarations()) { - properties.addAll(declaration.accept(this, context)); - } - return properties; - } - - @Override - @NotNull - public List visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) { - //TODO: - return Collections.emptyList(); - } - - @Override - @NotNull - public List visitNamedFunction(@NotNull JetNamedFunction expression, @NotNull TranslationContext context) { - return Arrays.asList(Translation.functionTranslator(context).translateAsMethod(expression)); - } - - @Override - @NotNull - public List visitProperty(@NotNull JetProperty expression, @NotNull TranslationContext context) { - List methods = new ArrayList(); - addSetterToMethods(expression, context, methods); - addGetterToMethods(expression, context, methods); - return methods; - } - - private void addGetterToMethods(@NotNull JetProperty expression, @NotNull TranslationContext context, - @NotNull List methods) { - JetPropertyAccessor getter = expression.getGetter(); - if (getter != null) { - methods.addAll(getter.accept(this, context)); - } else { - methods.add(generateDefaultGetter(expression, context)); - } - } - - private void addSetterToMethods(@NotNull JetProperty expression, @NotNull TranslationContext context, - @NotNull List methods) { - JetPropertyAccessor setter = expression.getSetter(); - if (setter != null) { - methods.addAll(setter.accept(this, context)); - } else { - if (expression.isVar()) { - methods.add(generateDefaultSetter(expression, context)); - } - } - } - - @NotNull - private JsPropertyInitializer generateDefaultGetter - (@NotNull JetProperty expression, @NotNull TranslationContext context) { - PropertyGetterDescriptor getterDescriptor = - BindingUtils.getPropertyGetterDescriptorForProperty(context.bindingContext(), expression); - return AstUtil.newNamedMethod(context.getNameForDescriptor(getterDescriptor), - generateDefaultGetterFunction(expression, context.newPropertyAccess(getterDescriptor))); - } - - @NotNull - private JsFunction generateDefaultGetterFunction(@NotNull JetProperty expression, - @NotNull TranslationContext context) { - JsReturn returnExpression = new JsReturn(backingFieldReference(expression, context)); - return AstUtil.newFunction - (context.enclosingScope(), null, new ArrayList(), AstUtil.convertToBlock(returnExpression)); - } - - @NotNull - private JsPropertyInitializer generateDefaultSetter(@NotNull JetProperty expression, - @NotNull TranslationContext context) { - PropertySetterDescriptor setterDescriptor = - BindingUtils.getPropertySetterDescriptorForProperty(context.bindingContext(), expression); - return AstUtil.newNamedMethod(context.getNameForDescriptor(setterDescriptor), - generateDefaultSetterFunction(expression, context.newPropertyAccess(setterDescriptor))); - } - - @NotNull - private JsFunction generateDefaultSetterFunction(@NotNull JetProperty expression, - @NotNull TranslationContext context) { - JsFunction result = new JsFunction(context.enclosingScope()); - JsParameter defaultParameter = new JsParameter(context.enclosingScope().declareTemporary()); - JsBinaryOperation assignment = assignmentToBackingFieldFromDefaultParameter - (expression, context, defaultParameter); - result.setParameters(Arrays.asList(defaultParameter)); - result.setBody(AstUtil.convertToBlock(assignment)); - return result; - } - - @NotNull - private JsBinaryOperation assignmentToBackingFieldFromDefaultParameter - (@NotNull JetProperty expression, @NotNull TranslationContext context, - @NotNull JsParameter defaultParameter) { - return AstUtil.newAssignment(backingFieldReference(expression, context), defaultParameter.getName().makeRef()); - } - - @Override - @NotNull - public List visitPropertyAccessor(@NotNull JetPropertyAccessor expression, - @NotNull TranslationContext context) { - List methods = new ArrayList(); - methods.add(generateMethodForAccessor(expression, context)); - return methods; - } - - @NotNull - private JsPropertyInitializer generateMethodForAccessor(@NotNull JetPropertyAccessor expression, - @NotNull TranslationContext context) { - JsFunction methodBody = translateAccessorBody(expression, context); - // we know that custom getters and setters always have their descriptors - return AstUtil.newNamedMethod(context.getNameForElement(expression), methodBody); - } - - @NotNull - private JsFunction translateAccessorBody(@NotNull JetPropertyAccessor expression, - @NotNull TranslationContext context) { - JsFunction methodBody = JsFunction.getAnonymousFunctionWithScope(context.getScopeForElement(expression)); - JetExpression bodyExpression = expression.getBodyExpression(); - assert bodyExpression != null : "Custom accessor should have a body."; - JsBlock methodBodyBlock = AstUtil.convertToBlock( - Translation.translateExpression(bodyExpression, context.newPropertyAccess(expression))); - methodBody.setBody(methodBodyBlock); - return methodBody; - } - - @Override - @NotNull - public List visitAnonymousInitializer(@NotNull JetClassInitializer expression, - @NotNull TranslationContext context) { - // parsed it in initializer visitor => no additional actions are needed - return Collections.emptyList(); - } -} diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java b/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java index db6423619d3..25c5e6bdc56 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionTranslator.java @@ -22,6 +22,6 @@ public final class ExpressionTranslator extends AbstractTranslator { @NotNull public JsNode translate(@NotNull JetExpression jetExpression) { - return jetExpression.accept(visitor, translationContext()); + return jetExpression.accept(visitor, context()); } } diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java index 05220de493f..778c7e8edfc 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java @@ -94,7 +94,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull // assume it is a local variable declaration public JsNode visitProperty(@NotNull JetProperty expression, @NotNull TranslationContext context) { - JsName jsPropertyName = context.declareLocalName(getPropertyName(expression)); + JsName jsPropertyName = context.declareLocalName(TranslationUtils.getPropertyName(expression)); JsExpression jsInitExpression = translateInitializerForProperty(expression, context); return AstUtil.newVar(jsPropertyName, jsInitExpression); } diff --git a/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java b/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java index 4765575d6bf..edd1fd8964a 100644 --- a/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/FunctionTranslator.java @@ -23,14 +23,14 @@ public final class FunctionTranslator extends AbstractTranslator { } @NotNull - JsPropertyInitializer translateAsMethod(@NotNull JetNamedFunction expression) { - JsName functionName = translationContext().getNameForElement(expression); + public JsPropertyInitializer translateAsMethod(@NotNull JetNamedFunction expression) { + JsName functionName = context().getNameForElement(expression); JsFunction function = generateFunctionObject(expression); return new JsPropertyInitializer(functionName.makeRef(), function); } @NotNull - JsFunction translateAsLiteral(@NotNull JetFunctionLiteral expression) { + public JsFunction translateAsLiteral(@NotNull JetFunctionLiteral expression) { return generateFunctionObject(expression); } @@ -45,10 +45,10 @@ public final class FunctionTranslator extends AbstractTranslator { private JsFunction createFunctionObject(JetFunction function) { if (function instanceof JetNamedFunction) { return JsFunction.getAnonymousFunctionWithScope - (translationContext().getScopeForElement(function)); + (context().getScopeForElement(function)); } if (function instanceof JetFunctionLiteral) { - return new JsFunction(translationContext().enclosingScope()); + return new JsFunction(context().enclosingScope()); } throw new AssertionError("Unsupported type of function."); } @@ -90,10 +90,10 @@ public final class FunctionTranslator extends AbstractTranslator { private TranslationContext functionBodyContext(@NotNull JetFunction function, @NotNull JsScope functionScope) { if (function instanceof JetNamedFunction) { - return translationContext().newFunctionDeclaration((JetNamedFunction) function); + return context().newFunctionDeclaration((JetNamedFunction) function); } if (function instanceof JetFunctionLiteral) { - return translationContext().newFunctionLiteral(functionScope); + return context().newFunctionLiteral(functionScope); } throw new AssertionError("Unsupported type of function."); } diff --git a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java index 040bf12c914..c9992580437 100644 --- a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java @@ -25,26 +25,26 @@ public class OperationTranslator extends AbstractTranslator { if (operationDescriptor == null) { return null; } - if (!translationContext().isDeclared(operationDescriptor)) { + if (!context().isDeclared(operationDescriptor)) { return null; } - return translationContext().getNameForDescriptor(operationDescriptor).makeRef(); + return context().getNameForDescriptor(operationDescriptor).makeRef(); } @Nullable private DeclarationDescriptor getOperationDescriptor(@NotNull JetSimpleNameExpression expression) { return BindingUtils.getDescriptorForReferenceExpression - (translationContext().bindingContext(), expression); + (context().bindingContext(), expression); } protected boolean isPropertyAccess(@NotNull JetExpression expression) { - return Translation.propertyAccessTranslator(translationContext()).canBePropertyAccess(expression); + return Translation.propertyAccessTranslator(context()).canBePropertyAccess(expression); } protected boolean isVariableReassignment(@NotNull JetExpression expression) { return BindingUtils.isVariableReassignment - (translationContext().bindingContext(), expression); + (context().bindingContext(), expression); } @@ -56,7 +56,7 @@ public class OperationTranslator extends AbstractTranslator { private final JsName variableName; private TemporaryVariable(@NotNull JsExpression initExpression) { - this.variableName = translationContext().enclosingScope().declareTemporary(); + this.variableName = context().enclosingScope().declareTemporary(); this.assignmentExpression = AstUtil.newAssignment(variableName.makeRef(), initExpression); } diff --git a/translator/src/org/jetbrains/k2js/translate/PatternTranslator.java b/translator/src/org/jetbrains/k2js/translate/PatternTranslator.java index e7eac5f991e..5e30360a24b 100644 --- a/translator/src/org/jetbrains/k2js/translate/PatternTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/PatternTranslator.java @@ -25,7 +25,7 @@ public final class PatternTranslator extends AbstractTranslator { @NotNull public JsExpression translateIsExpression(@NotNull JetIsExpression expression) { - JsExpression left = Translation.translateAsExpression(expression.getLeftHandSide(), translationContext()); + JsExpression left = Translation.translateAsExpression(expression.getLeftHandSide(), context()); JetPattern pattern = getPattern(expression); JsExpression resultingExpression = translatePattern(pattern, left); if (expression.isNegated()) { @@ -66,11 +66,11 @@ public final class PatternTranslator extends AbstractTranslator { @NotNull private JsExpression addNullCheck(@NotNull JsExpression expressionToMatch, @NotNull JsInvocation isCheck) { - return AstUtil.or(TranslationUtils.isNullCheck(translationContext(), expressionToMatch), isCheck); + return AstUtil.or(TranslationUtils.isNullCheck(context(), expressionToMatch), isCheck); } private boolean isNullable(JetTypePattern pattern) { - return BindingUtils.getTypeByReference(translationContext().bindingContext(), + return BindingUtils.getTypeByReference(context().bindingContext(), getTypeReference(pattern)).isNullable(); } @@ -90,10 +90,10 @@ public final class PatternTranslator extends AbstractTranslator { @NotNull private JsNameRef getClassNameReferenceForTypeReference(@NotNull JetTypeReference typeReference) { ClassDescriptor referencedClass = BindingUtils.getClassDescriptorForTypeReference - (translationContext().bindingContext(), typeReference); + (context().bindingContext(), typeReference); //TODO should reference class by full name here - JsName className = translationContext().getNameForDescriptor(referencedClass); - return translationContext().getNamespaceQualifiedReference(className); + JsName className = context().getNameForDescriptor(referencedClass); + return context().getNamespaceQualifiedReference(className); } @NotNull @@ -101,7 +101,7 @@ public final class PatternTranslator extends AbstractTranslator { JetExpression patternExpression = pattern.getExpression(); assert patternExpression != null : "Expression patter should have an expression."; JsExpression expressionToMatchAgainst = - Translation.translateAsExpression(patternExpression, translationContext()); + Translation.translateAsExpression(patternExpression, context()); return AstUtil.equals(expressionToMatch, expressionToMatchAgainst); } } diff --git a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java index 6ad3fc4bf4a..737fce75042 100644 --- a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java @@ -89,7 +89,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator { @NotNull private JsInvocation resolveAsPropertyGet(@NotNull JetSimpleNameExpression expression) { JsName getterName = getNotNullGetterName(expression); - JsNameRef getterReference = TranslationUtils.getReference(translationContext(), expression, getterName); + JsNameRef getterReference = TranslationUtils.getReference(context(), expression, getterName); return AstUtil.newInvocation(getterReference); } @@ -113,7 +113,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator { @NotNull private JsInvocation resolveAsPropertySet(@NotNull JetSimpleNameExpression expression) { JsName setterName = getNotNullSetterName(expression); - JsNameRef setterReference = Translation.generateCorrectReference(translationContext(), expression, setterName); + JsNameRef setterReference = Translation.generateCorrectReference(context(), expression, setterName); return AstUtil.newInvocation(setterReference); } @@ -121,7 +121,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator { private JsInvocation translateReceiverAndReturnAccessorInvocation (@NotNull JetQualifiedExpression qualifiedExpression, @NotNull JsName accessorName) { JsExpression qualifier = Translation.translateAsExpression - (qualifiedExpression.getReceiverExpression(), translationContext()); + (qualifiedExpression.getReceiverExpression(), context()); JsNameRef result = accessorName.makeRef(); AstUtil.setQualifier(result, qualifier); return AstUtil.newInvocation(result); @@ -162,7 +162,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator { if (getter == null) { return null; } - return translationContext().getNameForDescriptor(getter); + return context().getNameForDescriptor(getter); } @@ -183,13 +183,13 @@ public final class PropertyAccessTranslator extends AbstractTranslator { if (setter == null) { return null; } - return translationContext().getNameForDescriptor(setter); + return context().getNameForDescriptor(setter); } @Nullable private PropertyDescriptor getPropertyDescriptor(@NotNull JetSimpleNameExpression expression) { ResolvedCall resolvedCall = - BindingUtils.getResolvedCall(translationContext().bindingContext(), expression); + BindingUtils.getResolvedCall(context().bindingContext(), expression); if (resolvedCall != null) { DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor(); if (descriptor instanceof PropertyDescriptor) { diff --git a/translator/src/org/jetbrains/k2js/translate/ReferenceTranslator.java b/translator/src/org/jetbrains/k2js/translate/ReferenceTranslator.java index 9f69645da31..b0c4a3b49ea 100644 --- a/translator/src/org/jetbrains/k2js/translate/ReferenceTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/ReferenceTranslator.java @@ -44,7 +44,7 @@ public class ReferenceTranslator extends AbstractTranslator { @Nullable private JsInvocation resolveAsPropertyAccess(@NotNull JetSimpleNameExpression expression) { - PropertyAccessTranslator propertyAccessTranslator = Translation.propertyAccessTranslator(translationContext()); + PropertyAccessTranslator propertyAccessTranslator = Translation.propertyAccessTranslator(context()); if (propertyAccessTranslator.canBePropertyGetterCall(expression)) { return propertyAccessTranslator.translateAsPropertyGetterCall(expression); } @@ -54,15 +54,15 @@ public class ReferenceTranslator extends AbstractTranslator { @Nullable private JsExpression resolveAsGlobalReference(@NotNull JetSimpleNameExpression expression) { DeclarationDescriptor referencedDescriptor = - BindingUtils.getDescriptorForReferenceExpression(translationContext().bindingContext(), expression); + BindingUtils.getDescriptorForReferenceExpression(context().bindingContext(), expression); if (referencedDescriptor == null) { return null; } - if (!translationContext().isDeclared(referencedDescriptor)) { + if (!context().isDeclared(referencedDescriptor)) { return null; } - JsName referencedName = translationContext().getNameForDescriptor(referencedDescriptor); - return TranslationUtils.getReference(translationContext(), expression, referencedName); + JsName referencedName = context().getNameForDescriptor(referencedDescriptor); + return TranslationUtils.getReference(context(), expression, referencedName); } @Nullable @@ -70,7 +70,7 @@ public class ReferenceTranslator extends AbstractTranslator { String name = expression.getReferencedName(); assert name != null : "SimpleNameExpression should reference a name"; JsName localReferencedName = TranslationUtils.getLocalReferencedName - (translationContext(), name); + (context(), name); if (localReferencedName == null) { return null; } diff --git a/translator/src/org/jetbrains/k2js/translate/Translation.java b/translator/src/org/jetbrains/k2js/translate/Translation.java index 3616fcb8473..53146a35a00 100644 --- a/translator/src/org/jetbrains/k2js/translate/Translation.java +++ b/translator/src/org/jetbrains/k2js/translate/Translation.java @@ -6,6 +6,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.k2js.declarations.Declarations; +import org.jetbrains.k2js.translate.declaration.ClassTranslator; +import org.jetbrains.k2js.translate.declaration.NamespaceTranslator; import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator; import org.jetbrains.k2js.translate.initializer.NamespaceInitializerTranslator; diff --git a/translator/src/org/jetbrains/k2js/translate/TranslationContext.java b/translator/src/org/jetbrains/k2js/translate/TranslationContext.java index 938935d5f2b..8a3cbd57582 100644 --- a/translator/src/org/jetbrains/k2js/translate/TranslationContext.java +++ b/translator/src/org/jetbrains/k2js/translate/TranslationContext.java @@ -186,7 +186,7 @@ public final class TranslationContext { } @NotNull - JsName getNameForElement(@NotNull JetElement element) { + public JsName getNameForElement(@NotNull JetElement element) { DeclarationDescriptor descriptor = getDescriptorForElement(element); return getNameForDescriptor(descriptor); } diff --git a/translator/src/org/jetbrains/k2js/translate/TranslationUtils.java b/translator/src/org/jetbrains/k2js/translate/TranslationUtils.java index 4b87abde5ad..8faec01e465 100644 --- a/translator/src/org/jetbrains/k2js/translate/TranslationUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/TranslationUtils.java @@ -4,7 +4,9 @@ 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; import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.psi.ValueArgument; @@ -64,5 +66,41 @@ public final class TranslationUtils { return Translation.translateAsExpression(jetExpression, context); } + //TODO: refactor + @NotNull + static public JsNameRef backingFieldReference(@NotNull TranslationContext context, + @NotNull JetProperty expression) { + JsName backingFieldName = getBackingFieldName(getPropertyName(expression), context); + if (BindingUtils.belongsToNamespace(context.bindingContext(), expression)) { + return context.getNamespaceQualifiedReference(backingFieldName); + } + return AstUtil.thisQualifiedReference(backingFieldName); + } + + @NotNull + static public JsNameRef backingFieldReference(@NotNull TranslationContext context, + @NotNull PropertyDescriptor descriptor) { + JsName backingFieldName = getBackingFieldName(descriptor.getName(), context); + if (BindingUtils.belongsToNamespace(context.bindingContext(), descriptor)) { + return context.getNamespaceQualifiedReference(backingFieldName); + } + return AstUtil.thisQualifiedReference(backingFieldName); + } + + @NotNull + static public String getPropertyName(@NotNull JetProperty expression) { + String propertyName = expression.getName(); + if (propertyName == null) { + throw new AssertionError("Property with no name encountered!"); + } + return propertyName; + } + + @NotNull + static private JsName getBackingFieldName(@NotNull String propertyName, @NotNull TranslationContext context) { + String backingFieldName = Namer.getKotlinBackingFieldName(propertyName); + return context.enclosingScope().findExistingName(backingFieldName); + } + } diff --git a/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java b/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java index b2560bd85ec..e69485051b6 100644 --- a/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java @@ -1,9 +1,6 @@ package org.jetbrains.k2js.translate; import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetElement; @@ -24,31 +21,6 @@ public class TranslatorVisitor extends JetVisitor { throw new RuntimeException("Unsupported expression encountered:" + expression.toString()); } - @NotNull - protected JsNameRef backingFieldReference(@NotNull JetProperty expression, @NotNull TranslationContext context) { - JsName backingFieldName = getBackingFieldName(getPropertyName(expression), context); - if (BindingUtils.belongsToNamespace(context.bindingContext(), expression)) { - return context.getNamespaceQualifiedReference(backingFieldName); - } - return AstUtil.thisQualifiedReference(backingFieldName); - } - - @NotNull - protected String getPropertyName(@NotNull JetProperty expression) { - String propertyName = expression.getName(); - if (propertyName == null) { - throw new AssertionError("Property with no name encountered!"); - } - return propertyName; - } - - @NotNull - private JsName getBackingFieldName(@NotNull String propertyName, @NotNull TranslationContext context) { - String backingFieldName = Namer.getKotlinBackingFieldName(propertyName); - return context.enclosingScope().findExistingName(backingFieldName); - } - - @Nullable protected JsExpression translateInitializerForProperty(@NotNull JetProperty declaration, @NotNull TranslationContext context) { diff --git a/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java index aff3c5ddaef..2606605eab9 100644 --- a/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java @@ -45,7 +45,7 @@ public final class UnaryOperationTranslator extends OperationTranslator { this.expression = expression; this.isPrefix = isPrefix; this.isVariableReassignment = isVariableReassignment(expression); - this.isStatement = BindingUtils.isStatement(translationContext().bindingContext(), expression); + this.isStatement = BindingUtils.isStatement(context().bindingContext(), expression); this.baseExpression = translateBaseExpression(); this.isPropertyAccess = isPropertyAccess(getBaseExpression()); this.operationReference = getOverloadedOperationReference(expression.getOperationSign()); @@ -120,7 +120,7 @@ public final class UnaryOperationTranslator extends OperationTranslator { @NotNull private JsExpression propertyReassignment(@NotNull JsExpression toCallMethodUpon) { JetExpression jetBaseExpression = getBaseExpression(); - PropertyAccessTranslator propertyAccessTranslator = Translation.propertyAccessTranslator(translationContext()); + PropertyAccessTranslator propertyAccessTranslator = Translation.propertyAccessTranslator(context()); JsInvocation setterCall = propertyAccessTranslator.translateAsPropertySetterCall(jetBaseExpression); assert propertyAccessTranslator.canBePropertyGetterCall(jetBaseExpression) : "Should be a getter call"; JsExpression overloadedMethodCallOnPropertyGetter = operationExpression(toCallMethodUpon); @@ -150,7 +150,7 @@ public final class UnaryOperationTranslator extends OperationTranslator { @NotNull private JsExpression translateBaseExpression() { JetExpression baseExpression = getBaseExpression(); - return Translation.translateAsExpression(baseExpression, translationContext()); + return Translation.translateAsExpression(baseExpression, context()); } private JetExpression getBaseExpression() { @@ -168,7 +168,7 @@ public final class UnaryOperationTranslator extends OperationTranslator { } public JsBinaryOperation unaryAsBinary(@NotNull JetToken token, @NotNull JsExpression expression) { - JsNumberLiteral oneLiteral = translationContext().program().getNumberLiteral(1); + JsNumberLiteral oneLiteral = context().program().getNumberLiteral(1); if (token.equals(JetTokens.PLUSPLUS)) { return new JsBinaryOperation(JsBinaryOperator.ADD, expression, oneLiteral); } diff --git a/translator/src/org/jetbrains/k2js/translate/WhenTranslator.java b/translator/src/org/jetbrains/k2js/translate/WhenTranslator.java index ea60ed9c5d8..f29ca1aa297 100644 --- a/translator/src/org/jetbrains/k2js/translate/WhenTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/WhenTranslator.java @@ -55,7 +55,7 @@ public class WhenTranslator extends AbstractTranslator { @NotNull private JsStatement surroundWithDummyIf(@NotNull JsStatement entryStatement) { JsExpression stepNumberEqualsCurrentEntryNumber = new JsBinaryOperation(JsBinaryOperator.EQ, - dummyCounterName.makeRef(), translationContext().program().getNumberLiteral(currentEntryNumber)); + dummyCounterName.makeRef(), context().program().getNumberLiteral(currentEntryNumber)); currentEntryNumber++; return new JsIf(stepNumberEqualsCurrentEntryNumber, entryStatement, null); } @@ -71,7 +71,7 @@ public class WhenTranslator extends AbstractTranslator { @NotNull private JsVars generateInitStatement() { - return AstUtil.newVar(dummyCounterName, translationContext().program().getNumberLiteral(0)); + return AstUtil.newVar(dummyCounterName, context().program().getNumberLiteral(0)); } @NotNull @@ -99,7 +99,7 @@ public class WhenTranslator extends AbstractTranslator { private JsStatement translateExpressionToExecute(@NotNull JetWhenEntry entry) { JetExpression expressionToExecute = entry.getExpression(); assert expressionToExecute != null : "WhenEntry should have whenExpression to execute."; - return Translation.translateAsStatement(expressionToExecute, translationContext()); + return Translation.translateAsStatement(expressionToExecute, context()); } @NotNull @@ -146,9 +146,9 @@ public class WhenTranslator extends AbstractTranslator { @NotNull private JsExpression translateCallCondition(@NotNull JetWhenConditionCall condition) { JsExpression suffixExpression = - Translation.translateAsExpression(getSuffixExpression(condition), translationContext()); + Translation.translateAsExpression(getSuffixExpression(condition), context()); AstUtil.setQualifier(suffixExpression, expressionToMatch); - return AstUtil.equalsTrue(suffixExpression, translationContext().program()); + return AstUtil.equalsTrue(suffixExpression, context().program()); } @NotNull @@ -166,7 +166,7 @@ public class WhenTranslator extends AbstractTranslator { @NotNull private JsExpression translatePatternCondition(@NotNull JetWhenConditionIsPattern condition) { - JsExpression patternMatchExpression = Translation.patternTranslator(translationContext()). + JsExpression patternMatchExpression = Translation.patternTranslator(context()). translatePattern(getPattern(condition), expressionToMatch); if (condition.isNegated()) { return AstUtil.negated(patternMatchExpression); @@ -185,6 +185,6 @@ public class WhenTranslator extends AbstractTranslator { private JsExpression translateExpressionToMatch(@NotNull JetWhenExpression expression) { JetExpression subject = expression.getSubjectExpression(); assert subject != null : "Subject should not be null."; - return Translation.translateAsExpression(subject, translationContext()); + return Translation.translateAsExpression(subject, context()); } } diff --git a/translator/src/org/jetbrains/k2js/translate/ClassDeclarationTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java similarity index 85% rename from translator/src/org/jetbrains/k2js/translate/ClassDeclarationTranslator.java rename to translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java index d45b6df363d..8a7b3d0bbaf 100644 --- a/translator/src/org/jetbrains/k2js/translate/ClassDeclarationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java @@ -1,4 +1,4 @@ -package org.jetbrains.k2js.translate; +package org.jetbrains.k2js.translate.declaration; import com.google.dart.compiler.backend.js.ast.*; import com.google.dart.compiler.util.AstUtil; @@ -7,6 +7,10 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.k2js.translate.AbstractTranslator; +import org.jetbrains.k2js.translate.Namer; +import org.jetbrains.k2js.translate.Translation; +import org.jetbrains.k2js.translate.TranslationContext; import org.jetbrains.k2js.utils.ClassSorter; import java.util.ArrayList; @@ -35,11 +39,11 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { super(context); this.namespace = namespace; this.localToGlobalClassName = new HashMap(); - this.dummyFunctionScope = new JsScope(translationContext().enclosingScope(), "class declaration function"); + this.dummyFunctionScope = new JsScope(context().enclosingScope(), "class declaration function"); } public void generateDeclarations() { - declarationsObject = translationContext().enclosingScope().declareName(Namer.nameForClassesVariable()); + declarationsObject = context().enclosingScope().declareName(Namer.nameForClassesVariable()); assert declarationsObject != null; declarationsStatement = AstUtil.newAssignmentStatement(declarationsObject.makeRef(), generateDummyFunctionInvocation()); @@ -97,16 +101,16 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { classes.add((JetClass) declaration); } } - return ClassSorter.sortUsingInheritanceOrder(classes, translationContext().bindingContext()); + return ClassSorter.sortUsingInheritanceOrder(classes, context().bindingContext()); } @NotNull private JsStatement generateDeclaration(@NotNull JetClass declaration) { - JsName globalClassName = translationContext().getNameForElement(declaration); + JsName globalClassName = context().getNameForElement(declaration); JsName localClassName = dummyFunctionScope.declareName(globalClassName.getIdent()); localToGlobalClassName.put(localClassName, globalClassName); JsInvocation classDeclarationExpression = - Translation.translateClassDeclaration(declaration, translationContext()); + Translation.translateClassDeclaration(declaration, context()); return AstUtil.newVar(localClassName, classDeclarationExpression); } } diff --git a/translator/src/org/jetbrains/k2js/translate/ClassTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java similarity index 88% rename from translator/src/org/jetbrains/k2js/translate/ClassTranslator.java rename to translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java index 8451d47a55d..1e7f8e38de0 100644 --- a/translator/src/org/jetbrains/k2js/translate/ClassTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java @@ -1,4 +1,4 @@ -package org.jetbrains.k2js.translate; +package org.jetbrains.k2js.translate.declaration; import com.google.dart.compiler.backend.js.ast.JsInvocation; import com.google.dart.compiler.backend.js.ast.JsNameRef; @@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.k2js.translate.*; import java.util.ArrayList; import java.util.List; @@ -69,7 +70,7 @@ public final class ClassTranslator extends AbstractTranslator { private List getSuperclassNameReferences() { List superclassReferences = new ArrayList(); List superclassDescriptors = - BindingUtils.getSuperclassDescriptors(translationContext().bindingContext(), classDeclaration); + BindingUtils.getSuperclassDescriptors(context().bindingContext(), classDeclaration); addAncestorClass(superclassReferences, superclassDescriptors); addTraits(superclassReferences, superclassDescriptors); return superclassReferences; @@ -96,8 +97,8 @@ public final class ClassTranslator extends AbstractTranslator { @NotNull private JsNameRef getClassReference(@NotNull ClassDescriptor superClassDescriptor) { //TODO should get a full class name here - return translationContext().getNamespaceQualifiedReference - (translationContext().getNameForDescriptor(superClassDescriptor)); + return context().getNamespaceQualifiedReference + (context().getNameForDescriptor(superClassDescriptor)); } @Nullable @@ -111,10 +112,15 @@ public final class ClassTranslator extends AbstractTranslator { private JsObjectLiteral translateClassDeclarations() { List propertyList = new ArrayList(); if (!classDeclaration.isTrait()) { - propertyList.add(Translation.generateClassInitializerMethod(classDeclaration, translationContext())); + propertyList.add(Translation.generateClassInitializerMethod(classDeclaration, context())); } - propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, - translationContext())); + // propertyList.addAll(translatePropertiesAsConstructorParameters()); + propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, context())); return new JsObjectLiteral(propertyList); } +// +// @NotNull +// private List translatePropertiesAsConstructorParameters() { +// List +// } } diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java b/translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java new file mode 100644 index 00000000000..7c0647f6f79 --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/declaration/DeclarationBodyVisitor.java @@ -0,0 +1,74 @@ +package org.jetbrains.k2js.translate.declaration; + +import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.k2js.translate.BindingUtils; +import org.jetbrains.k2js.translate.Translation; +import org.jetbrains.k2js.translate.TranslationContext; +import org.jetbrains.k2js.translate.TranslatorVisitor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author Talanov Pavel + */ +public final class DeclarationBodyVisitor extends TranslatorVisitor> { + + + @NotNull + public List traverseClass(@NotNull JetClass expression, + @NotNull TranslationContext context) { + List properties = new ArrayList(); + for (JetDeclaration declaration : expression.getDeclarations()) { + properties.addAll(declaration.accept(this, context)); + } + return properties; + } + + @NotNull + public List traverseNamespace(@NotNull JetNamespace expression, + @NotNull TranslationContext context) { + List properties = new ArrayList(); + for (JetDeclaration declaration : expression.getDeclarations()) { + properties.addAll(declaration.accept(this, context)); + } + return properties; + } + + @Override + @NotNull + public List visitClass(@NotNull JetClass expression, @NotNull TranslationContext context) { + //TODO: + return Collections.emptyList(); + } + + @Override + @NotNull + public List visitNamedFunction(@NotNull JetNamedFunction expression, + @NotNull TranslationContext context) { + return Arrays.asList(Translation.functionTranslator(context).translateAsMethod(expression)); + } + + @Override + @NotNull + public List visitProperty(@NotNull JetProperty expression, + @NotNull TranslationContext context) { + PropertyDescriptor propertyDescriptor = + BindingUtils.getPropertyDescriptor(context.bindingContext(), expression); + return PropertyTranslator.translateAccessors(propertyDescriptor, context); + } + + + @Override + @NotNull + public List visitAnonymousInitializer(@NotNull JetClassInitializer expression, + @NotNull TranslationContext context) { + // parsed it in initializer visitor => no additional actions are needed + return Collections.emptyList(); + } +} diff --git a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java similarity index 88% rename from translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java rename to translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java index ff2ab48fe13..76c7c5461bf 100644 --- a/translator/src/org/jetbrains/k2js/translate/NamespaceTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/declaration/NamespaceTranslator.java @@ -1,9 +1,13 @@ -package org.jetbrains.k2js.translate; +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.jet.lang.psi.JetNamespace; +import org.jetbrains.k2js.translate.AbstractTranslator; +import org.jetbrains.k2js.translate.Namer; +import org.jetbrains.k2js.translate.Translation; +import org.jetbrains.k2js.translate.TranslationContext; import java.util.ArrayList; import java.util.List; @@ -62,7 +66,7 @@ public final class NamespaceTranslator extends AbstractTranslator { addMemberDeclarations(namespaceDeclaration); addClassesDeclarations(namespaceDeclaration); return AstUtil.newAssignmentStatement - (translationContext().getNameForElement(namespace).makeRef(), namespaceDeclaration); + (context().getNameForElement(namespace).makeRef(), namespaceDeclaration); } private void addClassesDeclarations(@NotNull JsInvocation namespaceDeclaration) { @@ -77,8 +81,8 @@ public final class NamespaceTranslator extends AbstractTranslator { @NotNull private JsObjectLiteral translateNamespaceMemberDeclarations() { List propertyList = new ArrayList(); - propertyList.add(Translation.generateNamespaceInitializerMethod(namespace, translationContext())); - propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(namespace, translationContext())); + propertyList.add(Translation.generateNamespaceInitializerMethod(namespace, context())); + propertyList.addAll(new DeclarationBodyVisitor().traverseNamespace(namespace, context())); return new JsObjectLiteral(propertyList); } } diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java new file mode 100644 index 00000000000..479cd0ef569 --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/declaration/PropertyTranslator.java @@ -0,0 +1,161 @@ +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; +import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetProperty; +import org.jetbrains.jet.lang.psi.JetPropertyAccessor; +import org.jetbrains.k2js.translate.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Talanov Pavel + */ +public final class PropertyTranslator extends AbstractTranslator { + + @NotNull + private final PropertyDescriptor property; + @NotNull + private final List accessors = new ArrayList(); + @Nullable + private final JetProperty declaration; + + static public List translateAccessors(@NotNull PropertyDescriptor descriptor, + @NotNull TranslationContext context) { + PropertyTranslator propertyTranslator = new PropertyTranslator(descriptor, context); + return propertyTranslator.translate(); + } + + private PropertyTranslator(@NotNull PropertyDescriptor property, @NotNull TranslationContext context) { + super(context); + this.property = property; + this.declaration = BindingUtils.getPropertyForDescriptor(context().bindingContext(), property); + } + + @NotNull + private List translate() { + addGetter(); + if (property.isVar()) { + addSetter(); + } + return accessors; + } + + private void addGetter() { + if (hasCustomGetter()) { + accessors.add(translateCustomAccessor(getCustomGetterDeclaration())); + } else { + accessors.add(generateDefaultGetter()); + } + } + + private void addSetter() { + if (hasCustomSetter()) { + accessors.add(translateCustomAccessor(getCustomSetterDeclaration())); + } else { + accessors.add(generateDefaultSetter()); + } + } + + private boolean hasCustomGetter() { + return ((declaration != null) && (declaration.getGetter() != null)); + } + + private boolean hasCustomSetter() { + return ((declaration != null) && (declaration.getSetter() != null)); + } + + @NotNull + private JetPropertyAccessor getCustomGetterDeclaration() { + assert declaration != null; + JetPropertyAccessor getterDeclaration = declaration.getGetter(); + assert getterDeclaration != null; + return getterDeclaration; + } + + @NotNull + private JetPropertyAccessor getCustomSetterDeclaration() { + assert declaration != null; + JetPropertyAccessor setter = declaration.getSetter(); + assert setter != null; + return setter; + } + + @NotNull + private JsPropertyInitializer generateDefaultGetter() { + PropertyGetterDescriptor getterDescriptor = property.getGetter(); + assert getterDescriptor != null : "Getter descriptor should not be null"; + return AstUtil.newNamedMethod(context().getNameForDescriptor(getterDescriptor), + generateDefaultGetterFunction(getterDescriptor)); + } + + @NotNull + private JsFunction generateDefaultGetterFunction(@NotNull PropertyGetterDescriptor descriptor) { + JsReturn returnExpression = new JsReturn(backingFieldReference()); + JsFunction getterFunction = + JsFunction.getAnonymousFunctionWithScope(context().getScopeForDescriptor(descriptor)); + getterFunction.setBody(AstUtil.convertToBlock(returnExpression)); + return getterFunction; + } + + private JsNameRef backingFieldReference() { + return TranslationUtils.backingFieldReference(context(), property); + } + + @NotNull + private JsPropertyInitializer generateDefaultSetter() { + PropertySetterDescriptor setterDescriptor = property.getSetter(); + assert setterDescriptor != null : "Setter descriptor should not be null"; + return AstUtil.newNamedMethod(context().getNameForDescriptor(setterDescriptor), + generateDefaultSetterFunction(setterDescriptor)); + } + + @NotNull + private JsFunction generateDefaultSetterFunction(@NotNull PropertySetterDescriptor propertySetterDescriptor) { + JsFunction result = JsFunction.getAnonymousFunctionWithScope( + context().getScopeForDescriptor(propertySetterDescriptor)); + JsParameter defaultParameter = + new JsParameter(propertyAccessContext(propertySetterDescriptor).enclosingScope().declareTemporary()); + JsBinaryOperation assignment = assignmentToBackingFieldFromDefaultParameter(defaultParameter); + result.setParameters(Arrays.asList(defaultParameter)); + result.setBody(AstUtil.convertToBlock(assignment)); + return result; + } + + @NotNull + private TranslationContext propertyAccessContext(@NotNull PropertySetterDescriptor propertySetterDescriptor) { + return context().newPropertyAccess(propertySetterDescriptor); + } + + @NotNull + private JsBinaryOperation assignmentToBackingFieldFromDefaultParameter(@NotNull JsParameter defaultParameter) { + return AstUtil.newAssignment(backingFieldReference(), defaultParameter.getName().makeRef()); + } + + @NotNull + private JsPropertyInitializer translateCustomAccessor(@NotNull JetPropertyAccessor expression) { + JsFunction methodBody = translateCustomAccessorBody(expression); + // we know that custom getters and setters always have their descriptors + return AstUtil.newNamedMethod(context().getNameForElement(expression), methodBody); + } + + @NotNull + private JsFunction translateCustomAccessorBody(@NotNull JetPropertyAccessor expression) { + JsFunction methodBody = JsFunction.getAnonymousFunctionWithScope(context().getScopeForElement(expression)); + JetExpression bodyExpression = expression.getBodyExpression(); + assert bodyExpression != null : "Custom accessor should have a body."; + JsBlock methodBodyBlock = AstUtil.convertToBlock( + Translation.translateExpression(bodyExpression, context().newPropertyAccess(expression))); + methodBody.setBody(methodBodyBlock); + return methodBody; + } + +} diff --git a/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java b/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java index 57c3cc31ec6..b521f40bd83 100644 --- a/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/initializer/AbstractInitializerTranslator.java @@ -35,13 +35,13 @@ public abstract class AbstractInitializerTranslator extends AbstractTranslator { @NotNull public JsPropertyInitializer generateInitializeMethod() { JsPropertyInitializer initializer = new JsPropertyInitializer(); - initializer.setLabelExpr(translationContext().program().getStringLiteral(Namer.INITIALIZE_METHOD_NAME)); + initializer.setLabelExpr(context().program().getStringLiteral(Namer.INITIALIZE_METHOD_NAME)); initializer.setValueExpr(generateInitializerFunction()); return initializer; } @NotNull protected List translatePropertyAndAnonymousInitializers(@NotNull JetDeclaration declaration) { - return visitor.traverse(declaration, translationContext()); + return visitor.traverse(declaration, context()); } } diff --git a/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java b/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java index c9ead80fb0e..5aaafbcefad 100644 --- a/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/initializer/ClassInitializerTranslator.java @@ -55,7 +55,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla @NotNull private List generateCallToSuperMethod() { List result = new ArrayList(); - if (BindingUtils.hasAncestorClass(translationContext().bindingContext(), classDeclaration)) { + if (BindingUtils.hasAncestorClass(context().bindingContext(), classDeclaration)) { JsName superMethodName = initializerMethodScope.declareName(Namer.SUPER_METHOD_NAME); List arguments = translateArguments(); result.add(AstUtil.convertToStatement @@ -67,7 +67,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla @NotNull private List translateArguments() { JetDelegatorToSuperCall superCall = getSuperCall(); - return TranslationUtils.translateArgumentList(superCall.getValueArguments(), translationContext()); + return TranslationUtils.translateArgumentList(superCall.getValueArguments(), context()); } @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java b/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java index 4c839c775eb..42899657956 100644 --- a/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/initializer/InitializerVisitor.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.k2js.translate.Translation; import org.jetbrains.k2js.translate.TranslationContext; +import org.jetbrains.k2js.translate.TranslationUtils; import org.jetbrains.k2js.translate.TranslatorVisitor; import java.util.ArrayList; @@ -43,7 +44,8 @@ public final class InitializerVisitor extends TranslatorVisitor