Introduce BackingFieldAccessTranslator.
Refactor AccessTranslationUtils, ReferenceTranslator. Add test for namespace properties.
This commit is contained in:
@@ -36,5 +36,9 @@ public class MultiNamespaceTest extends MultipleFilesTranslationTest {
|
||||
checkFooBoxIsTrue("classesInheritedFromOtherNamespace");
|
||||
}
|
||||
|
||||
public void testNamespaceVariableVisibleFromOtherNamespace() throws Exception {
|
||||
checkFooBoxIsTrue("namespaceVariableVisibleFromOtherNamespace");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ public final class PropertyTranslator extends AbstractTranslator {
|
||||
JsFunction result = context().getFunctionObject(propertySetterDescriptor);
|
||||
JsParameter defaultParameter =
|
||||
new JsParameter(propertyAccessContext(propertySetterDescriptor).jsScope().declareTemporary());
|
||||
JsStatement assignment = assignmentToBackingField(context(), property, defaultParameter.getName().makeRef());
|
||||
JsStatement assignment = assignmentToBackingField(context(), property, defaultParameter.getName().makeRef()).makeStmt();
|
||||
setParameters(result, defaultParameter);
|
||||
result.setBody(convertToBlock(assignment));
|
||||
return result;
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
|
||||
getPropertyDescriptorForConstructorParameter(bindingContext(), jetParameter);
|
||||
if (propertyDescriptor != null) {
|
||||
JsStatement assignmentToBackingFieldExpression = assignmentToBackingField
|
||||
(context(), propertyDescriptor, jsParameter.getName().makeRef());
|
||||
(context(), propertyDescriptor, jsParameter.getName().makeRef()).makeStmt();
|
||||
initializerStatements.add(assignmentToBackingFieldExpression);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.initializer;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExprStmt;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||
@@ -33,7 +34,6 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.jetbrains.k2js.translate.general.Translation.translateAsStatement;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDeclarationsForNamespace;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForObjectDeclaration;
|
||||
@@ -62,7 +62,7 @@ public final class InitializerVisitor extends TranslatorVisitor<List<JsStatement
|
||||
private static JsStatement translateInitializer(@NotNull JetProperty property, @NotNull TranslationContext context,
|
||||
@NotNull JetExpression initializer) {
|
||||
JsExpression initExpression = Translation.translateAsExpression(initializer, context);
|
||||
return assignmentToBackingField(context, property, initExpression);
|
||||
return assignmentToBackingField(context, property, initExpression).makeStmt();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,7 +87,9 @@ public final class InitializerVisitor extends TranslatorVisitor<List<JsStatement
|
||||
= getPropertyDescriptorForObjectDeclaration(context.bindingContext(), objectName);
|
||||
JetObjectDeclaration objectDeclaration = getObjectDeclarationForName(objectName);
|
||||
JsInvocation objectValue = ClassTranslator.generateClassCreationExpression(objectDeclaration, context);
|
||||
return singletonList(assignmentToBackingField(context, propertyDescriptorForObjectDeclaration, objectValue));
|
||||
JsExprStmt assignment = assignmentToBackingField(context, propertyDescriptorForObjectDeclaration, objectValue)
|
||||
.makeStmt();
|
||||
return Collections.<JsStatement>singletonList(assignment);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+6
-11
@@ -28,24 +28,19 @@ public final class AccessTranslationUtils {
|
||||
private AccessTranslationUtils() {
|
||||
}
|
||||
|
||||
//TODO: this piece of code represents dangerously convoluted logic, think of the ways it can be improved
|
||||
@NotNull
|
||||
public static AccessTranslator getAccessTranslator(@NotNull JetExpression referenceExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
assert ((referenceExpression instanceof JetReferenceExpression) ||
|
||||
(referenceExpression instanceof JetQualifiedExpression));
|
||||
if (PropertyAccessTranslator.canBePropertyAccess(referenceExpression, context)) {
|
||||
if (referenceExpression instanceof JetQualifiedExpression) {
|
||||
return QualifiedExpressionTranslator.getAccessTranslator((JetQualifiedExpression) referenceExpression, context);
|
||||
}
|
||||
assert referenceExpression instanceof JetSimpleNameExpression;
|
||||
return PropertyAccessTranslator.newInstance((JetSimpleNameExpression) referenceExpression,
|
||||
null, CallType.NORMAL, context);
|
||||
if (referenceExpression instanceof JetQualifiedExpression) {
|
||||
return QualifiedExpressionTranslator.getAccessTranslator((JetQualifiedExpression) referenceExpression, context);
|
||||
}
|
||||
if (referenceExpression instanceof JetArrayAccessExpression) {
|
||||
return ArrayAccessTranslator.newInstance((JetArrayAccessExpression) referenceExpression, context);
|
||||
if (referenceExpression instanceof JetSimpleNameExpression) {
|
||||
return ReferenceTranslator.getAccessTranslator((JetSimpleNameExpression) referenceExpression, context);
|
||||
}
|
||||
return ReferenceAccessTranslator.newInstance((JetSimpleNameExpression) referenceExpression, context);
|
||||
assert referenceExpression instanceof JetArrayAccessExpression;
|
||||
return ArrayAccessTranslator.newInstance((JetArrayAccessExpression) referenceExpression, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.reference;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
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.utils.PsiUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class BackingFieldAccessTranslator extends AbstractTranslator implements CachedAccessTranslator {
|
||||
|
||||
@NotNull
|
||||
private final PropertyDescriptor descriptor;
|
||||
|
||||
/*package*/
|
||||
static BackingFieldAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
assert PsiUtils.isBackingFieldReference(expression);
|
||||
DeclarationDescriptor referencedProperty = getDescriptorForReferenceExpression(context.bindingContext(), expression);
|
||||
assert referencedProperty instanceof PropertyDescriptor;
|
||||
return new BackingFieldAccessTranslator((PropertyDescriptor) referencedProperty, context);
|
||||
}
|
||||
|
||||
private BackingFieldAccessTranslator(@NotNull PropertyDescriptor descriptor, @NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression translateAsGet() {
|
||||
return backingFieldReference(context(), descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression translateAsSet(@NotNull JsExpression setTo) {
|
||||
return assignmentToBackingField(context(), descriptor, setTo);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public CachedAccessTranslator getCached() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TemporaryVariable> declaredTemporaries() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
+2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.reference;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -26,5 +27,6 @@ import java.util.List;
|
||||
* Represents a translator which guaranties that all expression will be computed only once.
|
||||
*/
|
||||
public interface CachedAccessTranslator extends AccessTranslator {
|
||||
@NotNull
|
||||
List<TemporaryVariable> declaredTemporaries();
|
||||
}
|
||||
|
||||
+1
@@ -57,6 +57,7 @@ public final class CachedArrayAccessTranslator extends ArrayAccessTranslator imp
|
||||
return translateAsSet(arrayExpression.reference(), toExpressionList(indexExpressions), setTo);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TemporaryVariable> declaredTemporaries() {
|
||||
List<TemporaryVariable> result = Lists.newArrayList();
|
||||
|
||||
+1
@@ -68,6 +68,7 @@ public final class CachedPropertyAccessTranslator implements CachedAccessTransla
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TemporaryVariable> declaredTemporaries() {
|
||||
return cachedReceiver != null ? singletonList(cachedReceiver) : Collections.<TemporaryVariable>emptyList();
|
||||
|
||||
+11
-9
@@ -20,6 +20,7 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
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.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
@@ -28,6 +29,9 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.reference.ReferenceTranslator.translateAsLocalNameReference;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
@@ -36,30 +40,27 @@ public final class ReferenceAccessTranslator extends AbstractTranslator implemen
|
||||
@NotNull
|
||||
/*package*/ static ReferenceAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return new ReferenceAccessTranslator(expression, context);
|
||||
DeclarationDescriptor referenceDescriptor = getDescriptorForReferenceExpression(context.bindingContext(), expression);
|
||||
return new ReferenceAccessTranslator(referenceDescriptor, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final JetSimpleNameExpression expression;
|
||||
private final JsExpression reference;
|
||||
|
||||
private ReferenceAccessTranslator(@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
private ReferenceAccessTranslator(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.expression = expression;
|
||||
this.reference = translateAsLocalNameReference(descriptor, context());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsExpression translateAsGet() {
|
||||
//TODO: consider evaluating only once
|
||||
return ReferenceTranslator.translateSimpleName(expression, context());
|
||||
return reference;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
|
||||
//TODO: consider evaluating only once
|
||||
JsExpression reference = ReferenceTranslator.translateSimpleName(expression, context());
|
||||
assert reference instanceof JsNameRef;
|
||||
return AstUtil.newAssignment((JsNameRef) reference, toSetTo);
|
||||
}
|
||||
@@ -70,6 +71,7 @@ public final class ReferenceAccessTranslator extends AbstractTranslator implemen
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TemporaryVariable> declaredTemporaries() {
|
||||
return Collections.emptyList();
|
||||
|
||||
+13
-7
@@ -23,8 +23,8 @@ 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;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.isBackingFieldReference;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -37,12 +37,7 @@ public final class ReferenceTranslator {
|
||||
@NotNull
|
||||
public static JsExpression translateSimpleName(@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
if (PropertyAccessTranslator.canBePropertyGetterCall(expression, context)) {
|
||||
return PropertyAccessTranslator.translateAsPropertyGetterCall(expression, null, CallType.NORMAL, context);
|
||||
}
|
||||
DeclarationDescriptor referencedDescriptor =
|
||||
getDescriptorForReferenceExpression(context.bindingContext(), expression);
|
||||
return translateAsLocalNameReference(referencedDescriptor, context);
|
||||
return getAccessTranslator(expression, context).translateAsGet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -62,4 +57,15 @@ public final class ReferenceTranslator {
|
||||
JsName referencedName = context.getNameForDescriptor(referencedDescriptor);
|
||||
return referencedName.makeRef();
|
||||
}
|
||||
|
||||
public static AccessTranslator getAccessTranslator(JetSimpleNameExpression referenceExpression, TranslationContext context) {
|
||||
if (isBackingFieldReference(referenceExpression)) {
|
||||
return BackingFieldAccessTranslator.newInstance(referenceExpression, context);
|
||||
}
|
||||
if (PropertyAccessTranslator.canBePropertyAccess(referenceExpression, context)) {
|
||||
return PropertyAccessTranslator.newInstance(referenceExpression,
|
||||
null, CallType.NORMAL, context);
|
||||
}
|
||||
return ReferenceAccessTranslator.newInstance(referenceExpression, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ public final class BindingUtils {
|
||||
|
||||
|
||||
//TODO: refactor duplication
|
||||
//TODO: check where we use there, suspicious
|
||||
//TODO: check where we use these, suspicious
|
||||
public static boolean isOwnedByNamespace(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof ConstructorDescriptor) {
|
||||
DeclarationDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||
|
||||
@@ -30,7 +30,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||
import static com.google.dart.compiler.util.AstUtil.newAssignment;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getExpectedReceiverDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
|
||||
@@ -77,21 +79,15 @@ public final class TranslationUtils {
|
||||
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
|
||||
@NotNull PropertyDescriptor descriptor) {
|
||||
JsName backingFieldName = context.getNameForDescriptor(descriptor);
|
||||
if (isOwnedByClass(descriptor)) {
|
||||
return qualified(backingFieldName, new JsThisRef());
|
||||
}
|
||||
assert isOwnedByNamespace(descriptor)
|
||||
: "Only classes and namespaces may own backing fields.";
|
||||
JsNameRef qualifier = context.getQualifierForDescriptor(descriptor);
|
||||
return qualified(backingFieldName, qualifier);
|
||||
return qualified(backingFieldName, new JsThisRef());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsStatement assignmentToBackingField(@NotNull TranslationContext context,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull JsExpression assignTo) {
|
||||
public static JsExpression assignmentToBackingField(@NotNull TranslationContext context,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull JsExpression assignTo) {
|
||||
JsNameRef backingFieldReference = backingFieldReference(context, descriptor);
|
||||
return newAssignmentStatement(backingFieldReference, assignTo);
|
||||
return newAssignment(backingFieldReference, assignTo);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -223,9 +219,8 @@ public final class TranslationUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsStatement assignmentToBackingField(@NotNull TranslationContext context, @NotNull JetProperty property,
|
||||
@NotNull JsExpression initExpression) {
|
||||
|
||||
public static JsExpression assignmentToBackingField(@NotNull TranslationContext context, @NotNull JetProperty property,
|
||||
@NotNull JsExpression initExpression) {
|
||||
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(context.bindingContext(), property);
|
||||
return assignmentToBackingField(context, propertyDescriptor, initExpression);
|
||||
}
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package foo
|
||||
|
||||
val a = 2
|
||||
|
||||
fun box() = (a + bar.a) == 5
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package bar
|
||||
|
||||
val a = 3
|
||||
Reference in New Issue
Block a user