CheckClassAssignments checkAssigns = new CheckClassAssignments(name);
NodeTraversal.traverse(compiler, enclosingFunction, checkAssigns);
}
private void visitSuper(Node node, Node parent) {
Node enclosing = parent;
Node potentialCallee = node;
if (!parent.isCall()) {
enclosing = parent.getParent();
potentialCallee = parent;
}
if (!enclosing.isCall() || enclosing.getFirstChild() != potentialCallee) {
cannotConvertYet(node, "Only calls to super or to a method of super are supported.");
return;
}
Node clazz = NodeUtil.getEnclosingClass(node);
if (clazz == null) {
compiler.report(JSError.make(node, NO_SUPERTYPE));
return;
}
if (NodeUtil.getClassNameNode(clazz) == null) {
// Unnamed classes of the form:
// f(class extends D { ... });
// give the problem that there is no name to be used in the call to goog.base for the
// translation of super calls.
// This will throw an error when the class is processed.
return;
}
Node enclosingMemberDef = NodeUtil.getEnclosingClassMember(node);
if (enclosingMemberDef.isStaticMember()) {
Node superName = clazz.getFirstChild().getNext();
if (!superName.isQualifiedName()) {
// This has already been reported, just don't need to continue processing the class.
return;
}
Node callTarget;
potentialCallee.detachFromParent();
if (potentialCallee == node) {
// of the form super()
potentialCallee =
IR.getprop(superName.cloneTree(), IR.string(enclosingMemberDef.getString()));
enclosing.putBooleanProp(Node.FREE_CALL, false);
} else {
// of the form super.method()
potentialCallee.replaceChild(node, superName.cloneTree());
}
callTarget = IR.getprop(potentialCallee, IR.string("call"));
enclosing.addChildToFront(callTarget);
enclosing.addChildAfter(IR.thisNode(), callTarget);
enclosing.useSourceInfoIfMissingFromForTree(enclosing);
compiler.reportCodeChange();
return;
}
String methodName;
Node callName = enclosing.removeFirstChild();
if (callName.isSuper()) {
methodName = enclosingMemberDef.getString();
} else {
methodName = callName.getLastChild().getString();
}
Node baseCall = baseCall(clazz, methodName, enclosing.removeChildren())
.useSourceInfoIfMissingFromForTree(enclosing);
enclosing.getParent().replaceChild(enclosing, baseCall);
compiler.reportCodeChange();
}