JS: support class prototypes in new pipeline
This commit is contained in:
@@ -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<ClassDescriptor> visited = new HashSet<>();
|
||||
for (ClassDescriptor cls : classes) {
|
||||
addClassPrototypes(cls, visited);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*private void addClassPrototypes(@NotNull ClassDescriptor cls, @NotNull Set<ClassDescriptor> 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<JsStatement> 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());
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -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<String>()
|
||||
private val classes = mutableMapOf<JsName, JsClassModel>()
|
||||
|
||||
// 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<JsStatement>) {
|
||||
val visited = mutableSetOf<JsName>()
|
||||
for (cls in classes.keys) {
|
||||
addClassPrototypes(cls, visited, statements)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addClassPrototypes(
|
||||
name: JsName,
|
||||
visited: MutableSet<JsName>,
|
||||
statements: MutableList<JsStatement>
|
||||
) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user