String superClassString = superClassName.getQualifiedName();
Verify.verify(NodeUtil.isStatement(insertionPoint));
Node constructor = null;
JSDocInfo ctorJSDocInfo = null;
// Process all members of the class
for (Node member : classMembers.children()) {
if (member.isEmpty()) {
continue;
}
if (member.isMemberDef() && member.getString().equals("constructor")) {
ctorJSDocInfo = member.getJSDocInfo();
constructor = member.getFirstChild().detachFromParent();
if (!anonymous) {
constructor.replaceChild(
constructor.getFirstChild(), className.cloneNode());
}
} else {
Node qualifiedMemberName;
Node method;
if (member.isMemberDef()) {
if (member.isStaticMember()) {
qualifiedMemberName = NodeUtil.newQName(
compiler,
Joiner.on(".").join(
uniqueFullClassName,
member.getString()));
} else {
qualifiedMemberName = NodeUtil.newQName(
compiler,
Joiner.on(".").join(
uniqueFullClassName,
"prototype",
member.getString()));
}
method = member.getFirstChild().detachFromParent();
} else if (member.isComputedProp()) {
if (member.isStaticMember()) {
qualifiedMemberName = IR.getelem(
NodeUtil.newQName(
compiler,
uniqueFullClassName),
member.removeFirstChild());
} else {
qualifiedMemberName = IR.getelem(
NodeUtil.newQName(
compiler,
Joiner.on('.').join(uniqueFullClassName, "prototype")),
member.removeFirstChild());
}
method = member.getLastChild().detachFromParent();
} else {
throw new IllegalStateException("Unexpected class member: " + member);
}
Node assign = IR.assign(qualifiedMemberName, method);
assign.useSourceInfoIfMissingFromForTree(member);
JSDocInfo info = member.getJSDocInfo();
if (member.isStaticMember() && NodeUtil.referencesThis(assign.getLastChild())) {
JSDocInfoBuilder memberDoc;
if (info == null) {
memberDoc = new JSDocInfoBuilder(true);
} else {
memberDoc = JSDocInfoBuilder.copyFrom(info);
}
memberDoc.recordThisType(
new JSTypeExpression(new Node(Token.BANG, new Node(Token.QMARK)),
member.getSourceFileName()));
info = memberDoc.build(assign);
}
if (info != null) {
info.setAssociatedNode(assign);
assign.setJSDocInfo(info);
}
Node newNode = NodeUtil.newExpr(assign);
insertionPoint.getParent().addChildAfter(newNode, insertionPoint);
insertionPoint = newNode;
}
}
// Rewrite constructor
if (constructor == null) {
Node body = IR.block();
if (!superClassName.isEmpty()) {
Node superCall = baseCall(classNode, "constructor", null);
body.addChildToBack(IR.exprResult(superCall));
}
Node name = anonymous
? IR.name("").srcref(className) : className.detachFromParent();
constructor = IR.function(
name,
IR.paramList(),
body).useSourceInfoIfMissingFromForTree(classNode);
}
JSDocInfo classJSDoc = classNode.getJSDocInfo();
JSDocInfoBuilder newInfo = (classJSDoc != null) ?
JSDocInfoBuilder.copyFrom(classJSDoc) :
new JSDocInfoBuilder(true);
newInfo.recordConstructor();