From 2354adfa22f4977383be165faf502b60e5f43429 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 10 Feb 2017 18:38:19 +0300 Subject: [PATCH] JS: support class prototypes in new pipeline --- .../js/translate/context/StaticContext.java | 41 ++----------------- .../kotlin/js/translate/general/Merger.kt | 32 +++++++++++++++ 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index 68ca9159616..7b103129427 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -729,7 +729,9 @@ public final class StaticContext { } public void addClass(@NotNull ClassDescriptor classDescriptor) { - fragment.getClasses().put(getInnerNameForDescriptor(classDescriptor), classModelGenerator.generateClassModel(classDescriptor)); + if (!AnnotationsUtils.isNativeObject(classDescriptor) && !AnnotationsUtils.isLibraryObject(classDescriptor)) { + fragment.getClasses().put(getInnerNameForDescriptor(classDescriptor), classModelGenerator.generateClassModel(classDescriptor)); + } } public void export(@NotNull MemberDescriptor descriptor, boolean force) { @@ -754,41 +756,4 @@ public final class StaticContext { rootFunction.getBody().getStatements().addAll(exporter.getStatements()); rootFunction.getBody().getStatements().addAll(topLevelStatements); }*/ - - /*private void addClassPrototypes() { - Set visited = new HashSet<>(); - for (ClassDescriptor cls : classes) { - addClassPrototypes(cls, visited); - } - }*/ - - /*private void addClassPrototypes(@NotNull ClassDescriptor cls, @NotNull Set visited) { - if (!visited.add(cls)) return; - if (DescriptorUtilsKt.getModule(cls) != currentModule) return; - if (isNativeObject(cls) || isLibraryObject(cls)) return; - - ClassDescriptor superclass = DescriptorUtilsKt.getSuperClassNotAny(cls); - if (superclass != null) { - addClassPrototypes(superclass, visited); - - List statements = rootFunction.getBody().getStatements(); - - JsNameRef superclassRef; - if (isNativeObject(superclass) || isLibraryObject(superclass)) { - superclassRef = getQualifiedReference(superclass); - } - else { - superclassRef = getInnerNameForDescriptor(superclass).makeRef(); - } - - JsExpression superPrototype = JsAstUtils.prototypeOf(superclassRef); - JsExpression superPrototypeInstance = new JsInvocation(new JsNameRef("create", "Object"), superPrototype); - JsExpression classRef = new JsNameRef(getInnerNameForDescriptor(cls)); - JsExpression prototype = JsAstUtils.prototypeOf(classRef); - statements.add(JsAstUtils.assignment(prototype, superPrototypeInstance).makeStmt()); - - JsExpression constructorRef = new JsNameRef("constructor", prototype.deepCopy()); - statements.add(JsAstUtils.assignment(constructorRef, classRef.deepCopy()).makeStmt()); - } - }*/ } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt index f01090b9610..f7b75a6304c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt @@ -30,6 +30,7 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam private val initializerBlock = JsGlobalBlock() private val exportBlock = JsGlobalBlock() private val declaredImports = mutableSetOf() + private val classes = mutableMapOf() // Add declaration and initialization statements from program fragment to resulting single program fun addFragment(fragment: JsProgramFragment) { @@ -94,9 +95,40 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam fun merge() { rootFunction.body.statements.apply { this += importBlock.statements + addClassPrototypes(this) this += declarationBlock.statements this += initializerBlock.statements } rootFunction.body.resolveTemporaryNames() } + + private fun addClassPrototypes(statements: MutableList) { + val visited = mutableSetOf() + for (cls in classes.keys) { + addClassPrototypes(cls, visited, statements) + } + } + + private fun addClassPrototypes( + name: JsName, + visited: MutableSet, + statements: MutableList + ) { + if (!visited.add(name)) return + val cls = classes[name] ?: return + val superName = cls.superName ?: return + + addClassPrototypes(superName, visited, statements) + + val superclassRef = superName.makeRef() + val superPrototype = JsAstUtils.prototypeOf(superclassRef) + val superPrototypeInstance = JsInvocation(JsNameRef("create", "Object"), superPrototype) + + val classRef = name.makeRef() + val prototype = JsAstUtils.prototypeOf(classRef) + statements += JsAstUtils.assignment(prototype, superPrototypeInstance).makeStmt() + + val constructorRef = JsNameRef("constructor", prototype.deepCopy()) + statements += JsAstUtils.assignment(constructorRef, classRef.deepCopy()).makeStmt() + } } \ No newline at end of file