JS backend: convert PropertyTranslator to Kotlin
This commit is contained in:
@@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
|||||||
import org.jetbrains.k2js.translate.context.DefinitionPlace;
|
import org.jetbrains.k2js.translate.context.DefinitionPlace;
|
||||||
import org.jetbrains.k2js.translate.context.Namer;
|
import org.jetbrains.k2js.translate.context.Namer;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.declaration.propertyTranslator.PropertyTranslatorPackage;
|
||||||
import org.jetbrains.k2js.translate.expression.ExpressionPackage;
|
import org.jetbrains.k2js.translate.expression.ExpressionPackage;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
||||||
@@ -241,7 +242,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
for (JetParameter parameter : getPrimaryConstructorParameters(classDeclaration)) {
|
for (JetParameter parameter : getPrimaryConstructorParameters(classDeclaration)) {
|
||||||
PropertyDescriptor descriptor = getPropertyDescriptorForConstructorParameter(bindingContext(), parameter);
|
PropertyDescriptor descriptor = getPropertyDescriptorForConstructorParameter(bindingContext(), parameter);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
PropertyTranslator.translateAccessors(descriptor, result, classDeclarationContext);
|
PropertyTranslatorPackage.translateAccessors(descriptor, result, classDeclarationContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.declaration.propertyTranslator.PropertyTranslatorPackage;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
||||||
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
||||||
@@ -114,7 +115,7 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
|||||||
@Override
|
@Override
|
||||||
public Void visitProperty(@NotNull JetProperty expression, TranslationContext context) {
|
public Void visitProperty(@NotNull JetProperty expression, TranslationContext context) {
|
||||||
PropertyDescriptor propertyDescriptor = BindingUtils.getPropertyDescriptor(context.bindingContext(), expression);
|
PropertyDescriptor propertyDescriptor = BindingUtils.getPropertyDescriptor(context.bindingContext(), expression);
|
||||||
PropertyTranslator.translateAccessors(propertyDescriptor, expression, result, context);
|
PropertyTranslatorPackage.translateAccessors(propertyDescriptor, expression, result, context);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-193
@@ -1,193 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2013 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.declaration;
|
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
|
||||||
import com.intellij.util.SmartList;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
|
||||||
import org.jetbrains.k2js.translate.callTranslator.CallTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
|
||||||
import org.jetbrains.k2js.translate.expression.FunctionTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
|
||||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.context.Namer.getDelegateNameRef;
|
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates single property /w accessors.
|
|
||||||
*/
|
|
||||||
public final class PropertyTranslator extends AbstractTranslator {
|
|
||||||
@NotNull
|
|
||||||
private final PropertyDescriptor descriptor;
|
|
||||||
@Nullable
|
|
||||||
private final JetProperty declaration;
|
|
||||||
|
|
||||||
public static void translateAccessors(@NotNull PropertyDescriptor descriptor, @NotNull List<JsPropertyInitializer> result, @NotNull TranslationContext context) {
|
|
||||||
translateAccessors(descriptor, null, result, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void translateAccessors(@NotNull PropertyDescriptor descriptor,
|
|
||||||
@Nullable JetProperty declaration,
|
|
||||||
@NotNull List<JsPropertyInitializer> result,
|
|
||||||
@NotNull TranslationContext context) {
|
|
||||||
if (!JsDescriptorUtils.isSimpleFinalProperty(descriptor)) {
|
|
||||||
new PropertyTranslator(descriptor, declaration, context).translate(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private PropertyTranslator(@NotNull PropertyDescriptor descriptor, @Nullable JetProperty declaration, @NotNull TranslationContext context) {
|
|
||||||
super(context);
|
|
||||||
|
|
||||||
this.descriptor = descriptor;
|
|
||||||
this.declaration = declaration;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void translate(@NotNull List<JsPropertyInitializer> result) {
|
|
||||||
List<JsPropertyInitializer> to;
|
|
||||||
if (!JsDescriptorUtils.isExtension(descriptor)) {
|
|
||||||
to = new SmartList<JsPropertyInitializer>();
|
|
||||||
result.add(new JsPropertyInitializer(context().getNameForDescriptor(descriptor).makeRef(), new JsObjectLiteral(to, true)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
to = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
to.add(generateGetter());
|
|
||||||
if (descriptor.isVar()) {
|
|
||||||
to.add(generateSetter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsPropertyInitializer generateGetter() {
|
|
||||||
if (hasCustomGetter()) {
|
|
||||||
return translateCustomAccessor(getCustomGetterDeclaration());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return generateDefaultGetter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsPropertyInitializer generateSetter() {
|
|
||||||
if (hasCustomSetter()) {
|
|
||||||
return translateCustomAccessor(getCustomSetterDeclaration());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return generateDefaultSetter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasCustomGetter() {
|
|
||||||
return declaration != null && declaration.getGetter() != null && getCustomGetterDeclaration().hasBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasCustomSetter() {
|
|
||||||
return declaration != null && declaration.getSetter() != null && getCustomSetterDeclaration().hasBody();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 = descriptor.getGetter();
|
|
||||||
assert getterDescriptor != null : "Getter descriptor should not be null";
|
|
||||||
return generateDefaultAccessor(getterDescriptor, generateDefaultGetterFunction(getterDescriptor));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getPropertyName() {
|
|
||||||
return descriptor.getName().asString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsFunction generateDefaultGetterFunction(@NotNull PropertyGetterDescriptor getterDescriptor) {
|
|
||||||
JsExpression value;
|
|
||||||
ResolvedCall<FunctionDescriptor> delegatedCall = bindingContext().get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor);
|
|
||||||
if (delegatedCall != null) {
|
|
||||||
value = CallTranslator.INSTANCE$.translate(context(), delegatedCall, getDelegateNameRef(getPropertyName()));
|
|
||||||
} else {
|
|
||||||
value = backingFieldReference(context(), this.descriptor);
|
|
||||||
}
|
|
||||||
return simpleReturnFunction(context().getScopeForDescriptor(getterDescriptor.getContainingDeclaration()), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsPropertyInitializer generateDefaultSetter() {
|
|
||||||
PropertySetterDescriptor setterDescriptor = descriptor.getSetter();
|
|
||||||
assert setterDescriptor != null : "Setter descriptor should not be null";
|
|
||||||
return generateDefaultAccessor(setterDescriptor, generateDefaultSetterFunction(setterDescriptor));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsFunction generateDefaultSetterFunction(@NotNull PropertySetterDescriptor setterDescriptor) {
|
|
||||||
JsFunction fun = new JsFunction(context().getScopeForDescriptor(setterDescriptor.getContainingDeclaration()));
|
|
||||||
|
|
||||||
assert setterDescriptor.getValueParameters().size() == 1 : "Setter must have 1 parameter";
|
|
||||||
ValueParameterDescriptor valueParameterDescriptor = setterDescriptor.getValueParameters().get(0);
|
|
||||||
JsParameter defaultParameter = new JsParameter(fun.getScope().declareTemporary());
|
|
||||||
JsNameRef defaultParameterRef = defaultParameter.getName().makeRef();
|
|
||||||
|
|
||||||
fun.getParameters().add(defaultParameter);
|
|
||||||
TranslationContext contextWithAliased = context().innerContextWithAliased(valueParameterDescriptor, defaultParameterRef);
|
|
||||||
|
|
||||||
JsExpression setExpression;
|
|
||||||
ResolvedCall<FunctionDescriptor> delegatedCall = bindingContext().get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL,
|
|
||||||
setterDescriptor);
|
|
||||||
if (delegatedCall != null) {
|
|
||||||
setExpression = CallTranslator.INSTANCE$.translate(contextWithAliased, delegatedCall, getDelegateNameRef(getPropertyName()));
|
|
||||||
} else {
|
|
||||||
setExpression = assignmentToBackingField(contextWithAliased, descriptor, defaultParameterRef);
|
|
||||||
}
|
|
||||||
fun.setBody(new JsBlock(setExpression.makeStmt()));
|
|
||||||
return fun;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsPropertyInitializer generateDefaultAccessor(@NotNull PropertyAccessorDescriptor accessorDescriptor,
|
|
||||||
@NotNull JsFunction function) {
|
|
||||||
return TranslationUtils.translateFunctionAsEcma5PropertyDescriptor(function, accessorDescriptor, context());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsPropertyInitializer translateCustomAccessor(@NotNull JetPropertyAccessor expression) {
|
|
||||||
FunctionTranslator translator = Translation.functionTranslator(expression, context());
|
|
||||||
return translator.translateAsEcma5PropertyDescriptor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 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.declaration.propertyTranslator
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.*
|
||||||
|
import com.intellij.util.SmartList
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*
|
||||||
|
import org.jetbrains.jet.lang.psi.JetProperty
|
||||||
|
import org.jetbrains.jet.lang.psi.JetPropertyAccessor
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||||
|
import org.jetbrains.k2js.translate.callTranslator.CallTranslator
|
||||||
|
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.JsDescriptorUtils
|
||||||
|
|
||||||
|
import org.jetbrains.k2js.translate.context.Namer.getDelegateNameRef
|
||||||
|
import org.jetbrains.k2js.translate.utils.TranslationUtils.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates single property /w accessors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public fun translateAccessors(
|
||||||
|
descriptor: PropertyDescriptor,
|
||||||
|
declaration: JetProperty?,
|
||||||
|
result: MutableList<JsPropertyInitializer>,
|
||||||
|
context: TranslationContext
|
||||||
|
) {
|
||||||
|
if (!JsDescriptorUtils.isSimpleFinalProperty(descriptor)) {
|
||||||
|
PropertyTranslator(descriptor, declaration, context).translate(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun translateAccessors(
|
||||||
|
descriptor: PropertyDescriptor,
|
||||||
|
result: MutableList<JsPropertyInitializer>,
|
||||||
|
context: TranslationContext
|
||||||
|
) {
|
||||||
|
translateAccessors(descriptor, null, result, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PropertyTranslator(
|
||||||
|
val descriptor: PropertyDescriptor,
|
||||||
|
val declaration: JetProperty?,
|
||||||
|
context: TranslationContext
|
||||||
|
) : AbstractTranslator(context) {
|
||||||
|
|
||||||
|
private val propertyName: String = descriptor.getName().asString()
|
||||||
|
|
||||||
|
fun translate(result: MutableList<JsPropertyInitializer>) {
|
||||||
|
val to: MutableList<JsPropertyInitializer>
|
||||||
|
if (!JsDescriptorUtils.isExtension(descriptor)) {
|
||||||
|
to = SmartList<JsPropertyInitializer>()
|
||||||
|
result.add(JsPropertyInitializer(context().getNameForDescriptor(descriptor).makeRef(), JsObjectLiteral(to, true)))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
to = result
|
||||||
|
}
|
||||||
|
|
||||||
|
to.add(generateGetter())
|
||||||
|
if (descriptor.isVar()) {
|
||||||
|
to.add(generateSetter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateGetter(): JsPropertyInitializer =
|
||||||
|
if (hasCustomGetter()) translateCustomAccessor(getCustomGetterDeclaration()) else generateDefaultGetter()
|
||||||
|
|
||||||
|
private fun generateSetter(): JsPropertyInitializer =
|
||||||
|
if (hasCustomSetter()) translateCustomAccessor(getCustomSetterDeclaration()) else generateDefaultSetter()
|
||||||
|
|
||||||
|
private fun hasCustomGetter() = declaration != null && declaration.getGetter() != null && getCustomGetterDeclaration().hasBody()
|
||||||
|
|
||||||
|
private fun hasCustomSetter() = declaration != null && declaration.getSetter() != null && getCustomSetterDeclaration().hasBody()
|
||||||
|
|
||||||
|
private fun getCustomGetterDeclaration(): JetPropertyAccessor =
|
||||||
|
declaration?.getGetter() ?:
|
||||||
|
throw IllegalStateException("declaration and getter should not be null descriptor=${descriptor} declaration=${declaration}")
|
||||||
|
|
||||||
|
private fun getCustomSetterDeclaration(): JetPropertyAccessor =
|
||||||
|
declaration?.getSetter() ?:
|
||||||
|
throw IllegalStateException("declaration and setter should not be null descriptor=${descriptor} declaration=${declaration}")
|
||||||
|
|
||||||
|
private fun generateDefaultGetter(): JsPropertyInitializer {
|
||||||
|
val getterDescriptor = descriptor.getGetter() ?: throw IllegalStateException("Getter descriptor should not be null")
|
||||||
|
return generateDefaultAccessor(getterDescriptor, generateDefaultGetterFunction(getterDescriptor))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateDefaultGetterFunction(getterDescriptor: PropertyGetterDescriptor): JsFunction {
|
||||||
|
val delegatedCall = bindingContext().get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
||||||
|
|
||||||
|
val value = if (delegatedCall != null)
|
||||||
|
CallTranslator.translate(context(), delegatedCall, getDelegateNameRef(propertyName))
|
||||||
|
else
|
||||||
|
backingFieldReference(context(), this.descriptor)
|
||||||
|
|
||||||
|
return simpleReturnFunction(context().getScopeForDescriptor(getterDescriptor.getContainingDeclaration()), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateDefaultSetter(): JsPropertyInitializer {
|
||||||
|
val setterDescriptor = descriptor.getSetter() ?: throw IllegalStateException("Setter descriptor should not be null")
|
||||||
|
return generateDefaultAccessor(setterDescriptor, generateDefaultSetterFunction(setterDescriptor))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateDefaultSetterFunction(setterDescriptor: PropertySetterDescriptor): JsFunction {
|
||||||
|
val jsFunction = JsFunction(context().getScopeForDescriptor(setterDescriptor.getContainingDeclaration()))
|
||||||
|
|
||||||
|
assert(setterDescriptor.getValueParameters().size() == 1, "Setter must have 1 parameter")
|
||||||
|
val valueParameterDescriptor = setterDescriptor.getValueParameters().get(0)
|
||||||
|
val defaultParameter = JsParameter(jsFunction.getScope().declareTemporary())
|
||||||
|
val defaultParameterRef = defaultParameter.getName().makeRef()
|
||||||
|
val contextWithAliased = context().innerContextWithAliased(valueParameterDescriptor, defaultParameterRef)
|
||||||
|
|
||||||
|
val delegatedCall = bindingContext().get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
|
||||||
|
|
||||||
|
val setExpression = if (delegatedCall != null)
|
||||||
|
CallTranslator.translate(contextWithAliased, delegatedCall, getDelegateNameRef(propertyName))
|
||||||
|
else
|
||||||
|
assignmentToBackingField(contextWithAliased, descriptor, defaultParameterRef)
|
||||||
|
|
||||||
|
jsFunction.getParameters().add(defaultParameter)
|
||||||
|
jsFunction.setBody(JsBlock(setExpression.makeStmt()))
|
||||||
|
return jsFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateDefaultAccessor(accessorDescriptor: PropertyAccessorDescriptor, function: JsFunction): JsPropertyInitializer =
|
||||||
|
translateFunctionAsEcma5PropertyDescriptor(function, accessorDescriptor, context())
|
||||||
|
|
||||||
|
private fun translateCustomAccessor(expression: JetPropertyAccessor): JsPropertyInitializer =
|
||||||
|
Translation.functionTranslator(expression, context()).translateAsEcma5PropertyDescriptor()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user