Node createGetElem(Node receiver, Node key) { Node result = IR.getelem(receiver, key); if (isAddingTypes()) { // In general we cannot assume we know the type we get from a GETELEM. // TODO(bradfordcsmith): When receiver is an Array<T> or an Object<K, V>, use the template // type here. result.setJSType(unknownType); } return result; }
Node buildLineDeclaration(String uri, int lineNo) { Node coverVar = IR.name("_$jscoverage"); Node path = IR.string(uri); Node getURI = IR.getelem(coverVar, path); Node prop = IR.string("branchData"); Node propGet = IR.getprop(getURI, prop); Node number = IR.string("" + lineNo); return IR.getelem(propGet, number); }
Node buildLineNumberExpression(int lineNumber, String fileName, String identifier) { Node coverVar = IR.name("_$jscoverage"); Node path = IR.string(fileName); Node getURI = IR.getelem(coverVar, path); Node prop = IR.string(identifier); Node propGet = IR.getprop(getURI, prop); Node number = IR.number(lineNumber); return IR.getelem(propGet, number); }
Node buildLineDeclaration(String uri, int lineNo) { Node coverVar = IR.name("_$jscoverage"); Node path = IR.string(uri); Node getURI = IR.getelem(coverVar, path); Node prop = IR.string("branchData"); Node propGet = IR.getprop(getURI, prop); Node number = IR.string("" + lineNo); return IR.getelem(propGet, number); }
Node buildLineNumberExpression(int lineNumber, String fileName, String identifier) { Node coverVar = IR.name("_$jscoverage"); Node path = IR.string(fileName); Node getURI = IR.getelem(coverVar, path); Node prop = IR.string(identifier); Node propGet = IR.getprop(getURI, prop); Node number = IR.number(lineNumber); return IR.getelem(propGet, number); }
/** * Create an assignment to the branch coverage data for the given index into the array. * * @return the newly constructed assignment node. */ private Node newBranchInstrumentationNode(NodeTraversal traversal, Node node, int idx) { String arrayName = createArrayName(traversal); // Create instrumentation Node Node getElemNode = IR.getelem(IR.name(arrayName), IR.number(idx)); // Make line number 0-based Node exprNode = IR.exprResult(IR.assign(getElemNode, IR.trueNode())); // Note line as instrumented String fileName = traversal.getSourceName(); if (!instrumentationData.containsKey(fileName)) { instrumentationData.put(fileName, new FileInstrumentationData(fileName, arrayName)); } return exprNode.useSourceInfoIfMissingFromForTree(node); }
public Node buildLineAndConditionCall(String uri, int lineNo, int conditionNo) { Node indexLineNumber = buildLineDeclaration(uri, lineNo); Node conditionNumberLiteral = IR.number(conditionNo); Node indexConditionNumber = IR.getelem(indexLineNumber, conditionNumberLiteral); Node initCall = IR.string("ranCondition"); Node propertyName = IR.getprop(indexConditionNumber, initCall); Node result = IR.name("result"); Node fnCall = IR.call(propertyName, result); return IR.exprResult(fnCall); }
private Node newBranchesInLineNode(String name, FileInstrumentationData data) { List<Node> assignments = new ArrayList<>(); // var JSCompiler_lcov_branchesInLine = []; assignments.add(IR.var(IR.name(name), IR.arraylit())); int lineWithBranch = 0; for (int lineIdx = 1; lineIdx <= data.maxBranchPresentLine(); ++lineIdx) { Integer numBranches = data.getNumBranches(lineIdx); if (numBranches != null && numBranches > 0) { // JSCompiler_lcov_branchesInLine[<branch-index>] = 2; Node assignment = IR.exprResult( IR.assign( IR.getelem(IR.name(name), IR.number(lineWithBranch++)), IR.number(numBranches))); assignments.add(assignment.useSourceInfoIfMissingFromForTree(assignment)); } } return IR.block(assignments); } }
public Node buildLineAndConditionCall(String uri, int lineNo, int conditionNo) { Node indexLineNumber = buildLineDeclaration(uri, lineNo); Node conditionNumberLiteral = IR.number(conditionNo); Node indexConditionNumber = IR.getelem(indexLineNumber, conditionNumberLiteral); Node initCall = IR.string("ranCondition"); Node propertyName = IR.getprop(indexConditionNumber, initCall); Node result = IR.name("result"); Node fnCall = IR.call(propertyName, result); return IR.exprResult(fnCall); }
/** * Constructs a Node that represents an access to the given class member, qualified by either the * static or the instance access context, depending on whether the member is static. * * <p><b>WARNING:</b> {@code member} may be modified/destroyed by this method, do not use it * afterwards. */ private static Node getQualifiedMemberAccess(AbstractCompiler compiler, Node member, Node staticAccess, Node instanceAccess) { Node context = member.isStaticMember() ? staticAccess : instanceAccess; context = context.cloneTree(); if (member.isComputedProp()) { return IR.getelem(context, member.removeFirstChild()); } else { return NodeUtil.newPropertyAccess(compiler, context, member.getString()); } }
/** * Creates and return a new instrumentation node. The instrumentation Node is * of the form: "arrayName[lineNumber] = true;" * Note 1: Node returns a 1-based line number. * Note 2: Line numbers in instrumentation are made 0-based. This is done to * map to their bit representation in BitField. Thus, there's a one-to-one * correspondence of the line number seen on instrumented files and their bit * encodings. * * @return an instrumentation node corresponding to the line number */ private Node newInstrumentationNode(NodeTraversal traversal, Node node) { int lineNumber = node.getLineno(); String arrayName = createArrayName(traversal); // Create instrumentation Node Node getElemNode = IR.getelem( IR.name(arrayName), IR.number(lineNumber - 1)); // Make line number 0-based Node exprNode = IR.exprResult(IR.assign(getElemNode, IR.trueNode())); // Note line as instrumented String fileName = getFileName(traversal); if (!instrumentationData.containsKey(fileName)) { instrumentationData.put(fileName, new FileInstrumentationData(fileName, arrayName)); } instrumentationData.get(fileName).setLineAsInstrumented(lineNumber); return exprNode.useSourceInfoIfMissingFromForTree(node); }
/** * Constructs a Node that represents an access to the given class member, qualified by either the * static or the instance access context, depending on whether the member is static. * * <p><b>WARNING:</b> {@code member} may be modified/destroyed by this method, do not use it * afterwards. */ private static Node getQualifiedMemberAccess(AbstractCompiler compiler, Node member, Node staticAccess, Node instanceAccess) { Node context = member.isStaticMember() ? staticAccess : instanceAccess; context = context.cloneTree(); if (member.isComputedProp()) { return IR.getelem(context, member.removeFirstChild()); } else { return NodeUtil.newPropertyAccess(compiler, context, member.getString()); } }
/** * Creates and return a new instrumentation node. The instrumentation Node is * of the form: "arrayName[lineNumber] = true;" * Note 1: Node returns a 1-based line number. * Note 2: Line numbers in instrumentation are made 0-based. This is done to * map to their bit representation in BitField. Thus, there's a one-to-one * correspondence of the line number seen on instrumented files and their bit * encodings. * * @return an instrumentation node corresponding to the line number */ private Node newInstrumentationNode(NodeTraversal traversal, Node node) { int lineNumber = node.getLineno(); String arrayName = createArrayName(traversal); // Create instrumentation Node Node getElemNode = IR.getelem( IR.name(arrayName), IR.number(lineNumber - 1)); // Make line number 0-based Node exprNode = IR.exprResult(IR.assign(getElemNode, IR.trueNode())); // Note line as instrumented String fileName = getFileName(traversal); if (!instrumentationData.containsKey(fileName)) { instrumentationData.put(fileName, new FileInstrumentationData(fileName, arrayName)); } instrumentationData.get(fileName).setLineAsInstrumented(lineNumber); return exprNode.useSourceInfoIfMissingFromForTree(node); }
public Node buildLineAndConditionInitialisation(String uri, int lineNo, int conditionNo, int position, int length) { Node indexLineNumber = buildLineDeclaration(uri, lineNo); Node conditionNumberLiteral = IR.number(conditionNo); Node indexConditionNumber = IR.getelem(indexLineNumber, conditionNumberLiteral); Node positionLiteral = IR.number(position); Node lengthLiteral = IR.number(length); Node initCall = IR.string("init"); Node propertyName = IR.getprop(indexConditionNumber, initCall); Node fnCall = IR.call(propertyName, positionLiteral, lengthLiteral); return IR.exprResult(fnCall); }
public Node buildLineAndConditionInitialisation(String uri, int lineNo, int conditionNo, int position, int length) { Node indexLineNumber = buildLineDeclaration(uri, lineNo); Node conditionNumberLiteral = IR.number(conditionNo); Node indexConditionNumber = IR.getelem(indexLineNumber, conditionNumberLiteral); Node positionLiteral = IR.number(position); Node lengthLiteral = IR.number(length); Node initCall = IR.string("init"); Node propertyName = IR.getprop(indexConditionNumber, initCall); Node fnCall = IR.call(propertyName, positionLiteral, lengthLiteral); return IR.exprResult(fnCall); }
@Override public void visit(NodeTraversal t, Node n, Node parent) { if (n.isGetProp()) { String propName = n.getLastChild().getString(); if (exposedProperties.contains(propName)) { Node obj = n.removeFirstChild(); Node prop = n.removeFirstChild(); n.getParent().replaceChild(n, IR.getelem(obj, prop)); compiler.reportCodeChange(); } } else if (n.isStringKey()) { String propName = n.getString(); if (exposedProperties.contains(propName)) { n.setQuotedString(); compiler.reportCodeChange(); } } } }
@Override public void visit(NodeTraversal t, Node n, Node parent) { if (n.isGetProp()) { String propName = n.getLastChild().getString(); if (exposedProperties.contains(propName)) { Node obj = n.removeFirstChild(); Node prop = n.removeFirstChild(); compiler.reportChangeToEnclosingScope(n); n.replaceWith(IR.getelem(obj, prop)); } } else if (n.isStringKey()) { String propName = n.getString(); if (exposedProperties.contains(propName)) { if (!n.isQuotedString()) { compiler.reportChangeToEnclosingScope(n); n.setQuotedString(); } } } } }
/** * @return a Node containing file specific setup logic. */ private Node newHeaderNode(NodeTraversal traversal, Node srcref) { String fileName = getFileName(traversal); String arrayName = createArrayName(traversal); FileInstrumentationData data = instrumentationData.get(fileName); checkNotNull(data); String objName = CoverageInstrumentationPass.JS_INSTRUMENTATION_OBJECT_NAME; // var JSCompiler_lcov_data_xx = []; // __jscov['executedLines'].push(JSCompiler_lcov_data_xx); // __jscov['instrumentedLines'].push(hex-data); // __jscov['fileNames'].push(filename); return IR.block( newArrayDeclarationNode(traversal), IR.exprResult( IR.call( IR.getprop(IR.getelem(IR.name(objName), IR.string("executedLines")), "push"), IR.name(arrayName))), IR.exprResult( IR.call( IR.getprop( IR.getelem(IR.name(objName), IR.string("instrumentedLines")), "push"), IR.string(data.getInstrumentedLinesAsHexString()))), IR.exprResult( IR.call( IR.getprop(IR.getelem(IR.name(objName), IR.string("fileNames")), "push"), IR.string(fileName)))) .useSourceInfoIfMissingFromForTree(srcref); }
/** * Assigns a {@code true} prop, with the name of the marker. to the prototype of the class. * * <pre>{@code * /** @constructor *\/ * function C() { } * * C.prototype['instance_of__C'] = true; * }</pre> */ private Node addMarkerToFunction( String markerName, @Nullable String className, Node nodeToInsertAfter) { if (className == null) { // This can happen with anonymous classes declared with the type `Function`. return nodeToInsertAfter; } Node classNode = NodeUtil.newQName(compiler, className); Node assign = IR.exprResult( IR.assign( IR.getelem(IR.getprop(classNode, IR.string("prototype")), IR.string(markerName)), IR.trueNode())); nodeToInsertAfter.getParent().addChildAfter(assign, nodeToInsertAfter); compiler.reportChangeToEnclosingScope(assign); return assign; }
/** * Constructs a Node that represents an access to the given class member, qualified by either the * static or the instance access context, depending on whether the member is static. * * <p><b>WARNING:</b> {@code member} may be modified/destroyed by this method, do not use it * afterwards. */ private static Node getQualifiedMemberAccess(Node member, Node staticAccess, Node instanceAccess) { Node context = member.isStaticMember() ? staticAccess : instanceAccess; context = context.cloneTree(); if (member.isComputedProp()) { return IR.getelem(context, member.removeFirstChild()); } else { Node methodName = member.getFirstChild().getFirstChild(); return IR.getprop(context, IR.string(member.getString()).useSourceInfoFrom(methodName)); } }