JsFunction seedFunc = new JsFunction(sourceInfo, topScope,
seedFuncName, true);
seedFuncName.setStaticRef(seedFunc);
JsBlock body = new JsBlock(sourceInfo);
seedFunc.setBody(body);
JsExprStmt seedFuncStmt = seedFunc.makeStmt();
globalStmts.add(seedFuncStmt);
typeForStatMap.put(seedFuncStmt, x);
// Setup prototype chain.
// _ = Foo__V.prototype = FooSeed.prototype = new FooSuper();
JsNameRef seedProtoRef = prototype.makeRef(sourceInfo);
seedProtoRef.setQualifier(seedFuncName.makeRef(sourceInfo));
JsExpression protoObj;
if (x.getSuperClass() != null) {
JsNameRef superPrototypeRef = names.get(x.getSuperClass()).makeRef(
sourceInfo);
JsNew newExpr = new JsNew(sourceInfo, superPrototypeRef);
protoObj = newExpr;
} else {
protoObj = new JsObjectLiteral(sourceInfo);
}
JsExpression protoAsg = createAssignment(seedProtoRef, protoObj);
// Chain assign the same prototype to every live constructor.
for (JMethod method : x.getMethods()) {
if (liveCtors.contains(method)) {
JsNameRef protoRef = prototype.makeRef(sourceInfo);
protoRef.setQualifier(names.get(method).makeRef(sourceInfo));
protoAsg = createAssignment(protoRef, protoAsg);
}
}
// Finally, assign to the temp var for setup code.
JsExpression tmpAsg = createAssignment(globalTemp.makeRef(sourceInfo),
protoAsg);
JsExprStmt tmpAsgStmt = tmpAsg.makeStmt();
globalStmts.add(tmpAsgStmt);
typeForStatMap.put(tmpAsgStmt, x);
} else {
/*
* MAGIC: java.lang.String is implemented as a JavaScript String
* primitive with a modified prototype.
*/
JsNameRef rhs = prototype.makeRef(sourceInfo);
rhs.setQualifier(JsRootScope.INSTANCE.findExistingUnobfuscatableName(
"String").makeRef(sourceInfo));
JsExpression tmpAsg = createAssignment(globalTemp.makeRef(sourceInfo),
rhs);
JsExprStmt tmpAsgStmt = tmpAsg.makeStmt();
globalStmts.add(tmpAsgStmt);
typeForStatMap.put(tmpAsgStmt, x);
}
}