KT-11030 Simplify code and refactor generation of object expressions

This commit is contained in:
Alexey Andreev
2016-03-24 18:45:04 +03:00
parent c1c57a06bb
commit e305898f84
4 changed files with 24 additions and 58 deletions
@@ -39,9 +39,7 @@ import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWi
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getPrimaryConstructorParameters
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.simpleReturnFunction
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.toInvocationWith
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -197,33 +195,6 @@ class ClassTranslator private constructor(
}
}
private fun translateObjectInsideClass(outerClassContext: TranslationContext): JsExpression {
var outerDeclaration = descriptor.containingDeclaration.containingDeclaration
if (outerDeclaration != null && outerDeclaration !is ClassDescriptor) {
outerDeclaration = DescriptorUtils.getContainingClass(outerDeclaration)
}
val scope = if (outerDeclaration != null)
outerClassContext.getScopeForDescriptor(outerDeclaration)
else
outerClassContext.rootScope
val classContext = outerClassContext.innerWithUsageTracker(scope, descriptor)
var declarationArgs = getClassCreateInvocationArguments(classContext)
val jsClass = JsInvocation(context().namer().classCreationMethodReference(), declarationArgs)
val name = outerClassContext.getNameForDescriptor(descriptor)
val constructor = outerClassContext.define(name, jsClass)
val closure = outerClassContext.getLocalClassClosure(descriptor)
var closureArgs = emptyList<JsExpression>()
if (closure != null) {
closureArgs = closure.map { context().getParameterNameRefForInvocation(it) }.toList()
}
return JsNew(constructor, closureArgs)
}
private fun generatedBridgeMethods(properties: MutableList<JsPropertyInitializer>) {
if (isTrait()) return
@@ -270,7 +241,7 @@ class ClassTranslator private constructor(
}
companion object {
fun translate(classDeclaration: KtClass, context: TranslationContext): List<JsPropertyInitializer> {
fun translate(classDeclaration: KtClassOrObject, context: TranslationContext): List<JsPropertyInitializer> {
val result = arrayListOf<JsPropertyInitializer>()
val classDescriptor = getClassDescriptor(context.bindingContext(), classDeclaration)
@@ -286,14 +257,10 @@ class ClassTranslator private constructor(
return result
}
@JvmStatic fun generateClassCreation(classDeclaration: KtClassOrObject, context: TranslationContext): JsInvocation {
private fun generateClassCreation(classDeclaration: KtClassOrObject, context: TranslationContext): JsInvocation {
return ClassTranslator(classDeclaration, context).translate()
}
@JvmStatic fun generateObjectLiteral(objectDeclaration: KtObjectDeclaration, context: TranslationContext): JsExpression {
return ClassTranslator(objectDeclaration, context).translateObjectInsideClass(context)
}
private fun generateSecondaryConstructor(constructor: KtSecondaryConstructor, context: TranslationContext): JsPropertyInitializer {
// Prepare
val constructorDescriptor = BindingUtils.getDescriptorForElement(context.bindingContext(), constructor) as ConstructorDescriptor
@@ -73,22 +73,18 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
ClassDescriptor descriptor = getClassDescriptor(data.bindingContext(), enumEntry);
List<KotlinType> supertypes = getSupertypesWithoutFakes(descriptor);
if (enumEntry.getBody() != null || supertypes.size() > 1) {
jsEnumEntryCreation = ClassTranslator.generateClassCreation(enumEntry, data);
enumEntryList.addAll(ClassTranslator.Companion.translate(enumEntry, data));
} else {
assert supertypes.size() == 1 : "Simple Enum entry must have one supertype";
jsEnumEntryCreation = new ClassInitializerTranslator(enumEntry, data).generateEnumEntryInstanceCreation(supertypes.get(0));
enumEntryList.add(new JsPropertyInitializer(data.getNameForDescriptor(descriptor).makeRef(), jsEnumEntryCreation));
}
enumEntryList.add(new JsPropertyInitializer(data.getNameForDescriptor(descriptor).makeRef(), jsEnumEntryCreation));
return null;
}
@Override
public Void visitObjectDeclaration(@NotNull KtObjectDeclaration declaration, TranslationContext context) {
JsExpression object = ClassTranslator.generateClassCreation(declaration, context);
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), declaration);
JsName objName = context.getNameForDescriptor(descriptor);
staticResult.add(new JsPropertyInitializer(objName.makeRef(), object));
staticResult.addAll(ClassTranslator.Companion.translate(declaration, context));
return null;
}
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.js.translate.general.Translation
import org.jetbrains.kotlin.js.translate.initializer.InitializerUtils.generateInitializerForDelegate
import org.jetbrains.kotlin.js.translate.initializer.InitializerUtils.generateInitializerForProperty
import org.jetbrains.kotlin.js.translate.initializer.InitializerVisitor
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getPropertyDescriptor
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.psi.KtClass
@@ -59,10 +58,7 @@ class FileDeclarationVisitor(
context!!
// TODO: avoid duplication with superclass
val obj = ClassTranslator.generateClassCreation(declaration, context)
val descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), declaration)
val objName = context.getNameForDescriptor(descriptor)
result.add(JsPropertyInitializer(objName.makeRef(), obj))
result.addAll(ClassTranslator.translate(declaration, context))
return null
}
@@ -52,6 +52,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor;
@@ -519,17 +520,23 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@Override
@NotNull
public JsNode visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, @NotNull TranslationContext context) {
return ClassTranslator.generateObjectLiteral(expression.getObjectDeclaration(), context);
}
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), expression.getObjectDeclaration());
JsScope scope = context.getScopeForDescriptor(descriptor);
TranslationContext classContext = context.innerWithUsageTracker(scope, descriptor);
@Override
@NotNull
public JsNode visitObjectDeclaration(@NotNull KtObjectDeclaration expression,
@NotNull TranslationContext context) {
DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), expression);
JsName name = context.getNameForDescriptor(descriptor);
JsExpression value = ClassTranslator.generateClassCreation(expression, context);
return newVar(name, value).source(expression);
List<JsPropertyInitializer> properties = ClassTranslator.Companion.translate(expression.getObjectDeclaration(), classContext);
context.getDefinitionPlace().getProperties().addAll(properties);
JsExpression constructor = context.getQualifiedReference(descriptor);
List<DeclarationDescriptor> closure = context.getLocalClassClosure(descriptor);
List<JsExpression> closureArgs = new ArrayList<JsExpression>();
if (closure != null) {
for (DeclarationDescriptor capturedValue : closure) {
closureArgs.add(context.getParameterNameRefForInvocation(capturedValue));
}
}
return new JsNew(constructor, closureArgs);
}
@Override
@@ -569,7 +576,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@Override
public JsNode visitClass(@NotNull KtClass klass, TranslationContext context) {
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), klass);
JsObjectScope scope = new JsObjectScope(context.scope(), descriptor.toString(), "");
JsScope scope = context.getScopeForDescriptor(descriptor);
TranslationContext classContext = context.innerWithUsageTracker(scope, descriptor);
context.getDefinitionPlace().getProperties().addAll(ClassTranslator.Companion.translate(klass, classContext));