public static Node emptyFunction() { return IR.function(IR.name(""), IR.paramList(), IR.block()); }
/** * Creates a function `function name(paramList) { body }` * * @param name STRING node - empty string if no name * @param paramList PARAM_LIST node * @param body BLOCK node * @param type type to apply to the function itself */ Node createFunction(String name, Node paramList, Node body, JSType type) { Node nameNode = createName(name, type); Node result = IR.function(nameNode, paramList, body); if (isAddingTypes()) { checkArgument(type.isFunctionType(), type); result.setJSType(type); } return result; }
public Node buildBranchRecordingFunction(String uri, int id, int lineNo, int conditionNo) { Node params = IR.paramList(IR.name("result")); Node name = IR.name(format("visit%d_%d_%d", id, lineNo, conditionNo)); Node lineAndConditionCall = buildLineAndConditionCall(uri, lineNo, conditionNo); Node body = IR.block(lineAndConditionCall); body.addChildToBack(IR.returnNode(IR.name("result"))); return IR.function(name, params, body); } }
public Node buildBranchRecordingFunction(String uri, int id, int lineNo, int conditionNo) { Node params = IR.paramList(IR.name("result")); Node name = IR.name(format("visit%d_%d_%d", id, lineNo, conditionNo)); Node lineAndConditionCall = buildLineAndConditionCall(uri, lineNo, conditionNo); Node body = IR.block(lineAndConditionCall); body.addChildToBack(IR.returnNode(IR.name("result"))); return IR.function(name, params, body); } }
/** * Adds the generated setter for a readonly property. * @see https://www.polymer-project.org/0.8/docs/devguide/properties.html#read-only */ private Node makeReadOnlySetter(String propName, String qualifiedPath) { String setterName = "_set" + propName.substring(0, 1).toUpperCase() + propName.substring(1); Node fnNode = IR.function(IR.name(""), IR.paramList(IR.name(propName)), IR.block()); Node exprResNode = IR.exprResult( IR.assign(NodeUtil.newQName(compiler, qualifiedPath + setterName), fnNode)); JSDocInfoBuilder info = new JSDocInfoBuilder(true); // This is overriding a generated function which was added to the interface in // {@code addInterfaceExterns}. info.recordOverride(); exprResNode.getFirstChild().setJSDocInfo(info.build()); return exprResNode; }
/** * Adds the generated setter for a readonly property. * * @see https://www.polymer-project.org/0.8/docs/devguide/properties.html#read-only */ private Node makeReadOnlySetter(String propName, String qualifiedPath) { String setterName = "_set" + propName.substring(0, 1).toUpperCase() + propName.substring(1); Node fnNode = IR.function(IR.name(""), IR.paramList(IR.name(propName)), IR.block()); compiler.reportChangeToChangeScope(fnNode); Node exprResNode = IR.exprResult(IR.assign(NodeUtil.newQName(compiler, qualifiedPath + setterName), fnNode)); JSDocInfoBuilder info = new JSDocInfoBuilder(true); // This is overriding a generated function which was added to the interface in // {@code createExportsAndExterns}. info.recordOverride(); exprResNode.getFirstChild().setJSDocInfo(info.build()); return exprResNode; }
Node processComputedPropertyGetter(ComputedPropertyGetterTree tree) { maybeWarnForFeature(tree, Feature.COMPUTED_PROPERTIES); Node key = transform(tree.property); Node body = transform(tree.body); Node function = IR.function(IR.name(""), IR.paramList(), body); function.useSourceInfoIfMissingFromForTree(body); Node n = newNode(Token.COMPUTED_PROP, key, function); n.putBooleanProp(Node.COMPUTED_PROP_GETTER, true); n.putBooleanProp(Node.STATIC_MEMBER, tree.isStatic); return n; }
Node processComputedPropertyGetter(ComputedPropertyGetterTree tree) { maybeWarnEs6Feature(tree, Feature.COMPUTED_PROPERTIES); Node key = transform(tree.property); Node body = transform(tree.body); Node function = IR.function(IR.name(""), IR.paramList(), body); function.useSourceInfoIfMissingFromForTree(body); Node n = newNode(Token.COMPUTED_PROP, key, function); n.putBooleanProp(Node.COMPUTED_PROP_GETTER, true); n.putBooleanProp(Node.STATIC_MEMBER, tree.isStatic); return n; }
/** * Adds a computed property method, with the name of the marker, to the class. * * <pre>{@code * class C { * ['instance_of__C']() {} * } * }</pre> */ private Node addMarkerToClass(String markerName, @Nullable String unused, Node classMembers) { Node function = IR.function(IR.name(""), IR.paramList(), IR.block()); Node member = IR.computedProp(IR.string(markerName), function); member.putBooleanProp(Node.COMPUTED_PROP_METHOD, true); classMembers.addChildToBack(member); compiler.reportChangeToEnclosingScope(member); compiler.reportChangeToChangeScope(function); NodeUtil.addFeatureToScript(traversal.getCurrentScript(), Feature.COMPUTED_PROPERTIES); return classMembers; }
Node processComputedPropertySetter(ComputedPropertySetterTree tree) { maybeWarnEs6Feature(tree, Feature.COMPUTED_PROPERTIES); Node key = transform(tree.property); Node body = transform(tree.body); Node paramList = IR.paramList(safeProcessName(tree.parameter)); Node function = IR.function(IR.name(""), paramList, body); function.useSourceInfoIfMissingFromForTree(body); Node n = newNode(Token.COMPUTED_PROP, key, function); n.putBooleanProp(Node.COMPUTED_PROP_SETTER, true); n.putBooleanProp(Node.STATIC_MEMBER, tree.isStatic); return n; }
Node processComputedPropertySetter(ComputedPropertySetterTree tree) { maybeWarnForFeature(tree, Feature.COMPUTED_PROPERTIES); Node key = transform(tree.property); Node paramList = processFormalParameterList(tree.parameter); setSourceInfo(paramList, tree.parameter); Node body = transform(tree.body); Node function = IR.function(IR.name(""), paramList, body); function.useSourceInfoIfMissingFromForTree(body); Node n = newNode(Token.COMPUTED_PROP, key, function); n.putBooleanProp(Node.COMPUTED_PROP_SETTER, true); n.putBooleanProp(Node.STATIC_MEMBER, tree.isStatic); return n; }
/** Adds an ES5 getter to the given object literal to use an an export. */ private void addExport(Node definePropertiesLit, String exportedName, LocalQName localQName) { Node exportedValue = NodeUtil.newQName(compiler, localQName.qName); Node getterFunction = IR.function(IR.name(""), IR.paramList(), IR.block(IR.returnNode(exportedValue))); getterFunction.useSourceInfoFromForTree(localQName.nodeForSourceInfo); Node objLit = IR.objectlit( IR.stringKey("enumerable", IR.trueNode()), IR.stringKey("get", getterFunction)); definePropertiesLit.addChildToBack(IR.stringKey(exportedName, objLit)); compiler.reportChangeToChangeScope(getterFunction); }
/** * When a class is used in an expressions where adding an alias as the previous statement might * change execution order of a side-effect causing statement, wrap the class in an IIFE so that * decomposition can happen safely. */ private void decomposeInIIFE(NodeTraversal t, Node classNode) { // converts // `class X extends something {}` // to // `(function() { return class X extends something {}; })()` Node functionBody = IR.block(); Node function = IR.function(IR.name(""), IR.paramList(), functionBody); Node call = NodeUtil.newCallNode(function); classNode.replaceWith(call); functionBody.addChildToBack(IR.returnNode(classNode)); call.useSourceInfoIfMissingFromForTree(classNode); // NOTE: extractExtends() will end up reporting the change for the new function, so we only // need to report the change to the enclosing scope t.reportCodeChange(call); // Now do the extends expression extraction within the IIFE extractExtends(t, classNode); } }
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); }
Node fnNode = IR.function(IR.name(""), IR.paramList(), IR.block()); Node varNode = IR.var(NodeUtil.newQName(compiler, interfaceName), fnNode);
/** * Given a function to export, create the empty function that * will be put in the externs file. This extern function should have * the same type as the original function and the same parameter * name but no function body. * * We create a warning here if the the function to export is missing * parameter or return types. */ private Node createExternFunction(Node exportedFunction) { Node paramList = NodeUtil.getFunctionParameters(exportedFunction).cloneTree(); // Use the original parameter names so that the externs look pretty. for (Node param = paramList.getFirstChild(); param != null && param.isName(); param = param.getNext()) { String originalName = param.getOriginalName(); if (originalName != null) { param.setString(originalName); } } Node externFunction = IR.function(IR.name(""), paramList, IR.block()); if (exportedFunction.getJSType() != null) { externFunction.setJSType(exportedFunction.getJSType()); // When this function is printed, it will have a regular jsdoc, so we // don't want inline jsdocs as well deleteInlineJsdocs(externFunction); } return externFunction; }
/** * Given a function to export, create the empty function that * will be put in the externs file. This extern function should have * the same type as the original function and the same parameter * name but no function body. * * We create a warning here if the the function to export is missing * parameter or return types. */ private Node createExternFunction(Node exportedFunction) { Node paramList = NodeUtil.getFunctionParameters(exportedFunction) .cloneTree(); // Use the original parameter names so that the externs look pretty. Node param = paramList.getFirstChild(); while (param != null && param.isName()) { String originalName = param.getOriginalName(); if (originalName != null) { param.setString(originalName); } param = param.getNext(); } Node externFunction = IR.function(IR.name(""), paramList, IR.block()); if (exportedFunction.getJSType() != null) { externFunction.setJSType(exportedFunction.getJSType()); // When this function is printed, it will have a regular jsdoc, so we // don't want inline jsdocs as well deleteInlineJsdocs(externFunction); } return externFunction; }
private void addGetterExport( Node script, Node forSourceInfo, Node objLit, String exportedName, String localName) { // Type checker doesn't infer getters so mark the return as unknown. // { /** @return {?} */ get foo() { return foo; } } Node getter = Node.newString(Token.GETTER_DEF, exportedName); getter.putBooleanProp(Node.MODULE_EXPORT, true); objLit.addChildToBack(getter); Node name = NodeUtil.newQName(compiler, localName); Node function = IR.function(IR.name(""), IR.paramList(), IR.block(IR.returnNode(name))); getter.addChildToFront(function); JSDocInfoBuilder builder = new JSDocInfoBuilder(true); builder.recordReturnType( new JSTypeExpression(new Node(Token.QMARK), script.getSourceFileName())); getter.setJSDocInfo(builder.build()); getter.useSourceInfoIfMissingFromForTree(forSourceInfo); compiler.reportChangeToEnclosingScope(getter.getFirstChild().getLastChild()); compiler.reportChangeToEnclosingScope(getter); }
Node fnc = IR.function(IR.name("").srcref(callTarget), IR.paramList().srcref(callTarget), expandedBlock);
/** Wraps the entire current module definition in a $jscomp.registerAndLoadModule function. */ private void registerAndLoadModule(NodeTraversal t) { Node block = IR.block(); block.addChildrenToFront(script.removeChildren()); block.addChildToFront(IR.exprResult(IR.string(pragma))); Node moduleFunction = IR.function( IR.name(""), IR.paramList(IR.name(REQUIRE), IR.name(EXPORTS), IR.name(MODULE)), block); Node shallowDeps = new Node(Token.ARRAYLIT); for (ModuleRequest request : importRequests) { shallowDeps.addChildToBack(IR.string(request.specifier())); } Node exprResult = IR.exprResult( IR.call( IR.getprop(IR.name("$jscomp"), IR.string("registerAndLoadModule")), moduleFunction, // Resolving this path enables removing module roots from this path. IR.string( normalizePath( compiler.getModuleLoader().resolve(t.getInput().getName()).toString())), shallowDeps)); script.addChildToBack(exprResult.useSourceInfoIfMissingFromForTree(script)); compiler.reportChangeToChangeScope(script); compiler.reportChangeToChangeScope(moduleFunction); t.reportCodeChange(); }