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.Namer;
|
||||
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.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
||||
@@ -241,7 +242,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
for (JetParameter parameter : getPrimaryConstructorParameters(classDeclaration)) {
|
||||
PropertyDescriptor descriptor = getPropertyDescriptorForConstructorParameter(bindingContext(), parameter);
|
||||
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.types.JetType;
|
||||
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.TranslatorVisitor;
|
||||
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
||||
@@ -114,7 +115,7 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
||||
@Override
|
||||
public Void visitProperty(@NotNull JetProperty expression, TranslationContext context) {
|
||||
PropertyDescriptor propertyDescriptor = BindingUtils.getPropertyDescriptor(context.bindingContext(), expression);
|
||||
PropertyTranslator.translateAccessors(propertyDescriptor, expression, result, context);
|
||||
PropertyTranslatorPackage.translateAccessors(propertyDescriptor, expression, result, context);
|
||||
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