Node createMemberFunctionDef(String name, Node function) { // A function used for a member function definition must have an empty name, // because the name string goes on the MEMBER_FUNCTION_DEF node. checkArgument(function.getFirstChild().getString().isEmpty(), function); Node result = IR.memberFunctionDef(name, function); if (isAddingTypes()) { // member function definition must share the type of the function that implements it result.setJSType(function.getJSType()); } return result; }
private void functionAssignmentShortening( Node n, Node functionNode, Node parent) { n.removeChild(functionNode); Node memDefNode = IR.memberFunctionDef(n.getString(), functionNode); parent.replaceChild(n, memDefNode); compiler.reportCodeChange(); } }
/** * Attempts to move a method declaration into a class definition. This generates a new * MEMBER_FUNCTION_DEF Node while removing the old function node from the AST. */ void moveMethodsIntoClasses(ClassMemberDeclaration declaration) { Node classMembers = declaration.classNode.getLastChild(); String fieldName = declaration.memberName; // Detach nodes in order to move them around in the AST. declaration.exprRoot.detach(); declaration.rhs.detach(); Node memberFunc = IR.memberFunctionDef(fieldName, declaration.rhs); memberFunc.setStaticMember(declaration.isStatic); memberFunc.setJSDocInfo(declaration.jsDoc); if (declaration.classNode.getToken() == Token.INTERFACE) { Node body = declaration.rhs.getLastChild(); Preconditions.checkState(body.isNormalBlock()); if (body.hasChildren()) { compiler.report( JSError.make( declaration.rhs, GentsErrorManager.GENTS_CLASS_PASS_ERROR, String.format("Interface method %s should be empty.", declaration.memberName))); } declaration.rhs.replaceChild(body, new Node(Token.EMPTY)); } // Append the new method to the class classMembers.addChildToBack(memberFunc); nodeComments.moveComment(declaration.exprRoot, memberFunc); compiler.reportChangeToEnclosingScope(memberFunc); }
private void addSyntheticConstructor(Node classNode) { Node superClass = classNode.getSecondChild(); Node classMembers = classNode.getLastChild(); Node memberDef; if (superClass.isEmpty()) { memberDef = IR.memberFunctionDef("constructor", IR.function(IR.name(""), IR.paramList(), IR.block())); } else { if (!superClass.isQualifiedName()) { // This will be reported as an error in Es6ToEs3Converter. return; } Node body = IR.block(); if (!classNode.isFromExterns()) { Node exprResult = IR.exprResult(IR.call( IR.getprop(superClass.cloneTree(), IR.string("apply")), IR.thisNode(), IR.name("arguments"))); body.addChildrenToFront(exprResult); } Node constructor = IR.function( IR.name(""), IR.paramList(IR.name("var_args")), body); memberDef = IR.memberFunctionDef("constructor", constructor); } memberDef.useSourceInfoIfMissingFromForTree(classNode); classMembers.addChildToFront(memberDef); }
/** * Converts functions and variables declared in object literals into member method and field * definitions */ void convertObjectLiteral(Node classMembers, Node objectLiteralMember, boolean isStatic) { Preconditions.checkState( objectLiteralMember.isStringKey() || objectLiteralMember.isMemberFunctionDef()); Node value = objectLiteralMember.getFirstChild(); value.detach(); if (value.isFunction()) { Node n = IR.memberFunctionDef(objectLiteralMember.getString(), value); n.setJSDocInfo(objectLiteralMember.getJSDocInfo()); n.setStaticMember(isStatic); // Methods added to back classMembers.addChildToBack(n); nodeComments.moveComment(objectLiteralMember, n); } else { Node n = Node.newString(Token.MEMBER_VARIABLE_DEF, objectLiteralMember.getString()); n.addChildToBack(value); n.setJSDocInfo(objectLiteralMember.getJSDocInfo()); n.setStaticMember(isStatic); // Fields added to front addFieldToClassMembers(classMembers, n); nodeComments.moveComment(objectLiteralMember, n); } }
IR.memberFunctionDef("constructor", IR.function(IR.name(""), params, body)); constructor.useSourceInfoFrom(n);