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) {
|
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) {
|
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(exporter.getStatements());
|
||||||
rootFunction.getBody().getStatements().addAll(topLevelStatements);
|
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 initializerBlock = JsGlobalBlock()
|
||||||
private val exportBlock = JsGlobalBlock()
|
private val exportBlock = JsGlobalBlock()
|
||||||
private val declaredImports = mutableSetOf<String>()
|
private val declaredImports = mutableSetOf<String>()
|
||||||
|
private val classes = mutableMapOf<JsName, JsClassModel>()
|
||||||
|
|
||||||
// Add declaration and initialization statements from program fragment to resulting single program
|
// Add declaration and initialization statements from program fragment to resulting single program
|
||||||
fun addFragment(fragment: JsProgramFragment) {
|
fun addFragment(fragment: JsProgramFragment) {
|
||||||
@@ -94,9 +95,40 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
|
|||||||
fun merge() {
|
fun merge() {
|
||||||
rootFunction.body.statements.apply {
|
rootFunction.body.statements.apply {
|
||||||
this += importBlock.statements
|
this += importBlock.statements
|
||||||
|
addClassPrototypes(this)
|
||||||
this += declarationBlock.statements
|
this += declarationBlock.statements
|
||||||
this += initializerBlock.statements
|
this += initializerBlock.statements
|
||||||
}
|
}
|
||||||
rootFunction.body.resolveTemporaryNames()
|
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