private static SuggestedFix getFixForUnsortedRequiresOrProvides( String closureFunction, JSError error, AbstractCompiler compiler) { SuggestedFix.Builder fix = new SuggestedFix.Builder(); fix.setOriginalMatchedNode(error.node); Node script = NodeUtil.getEnclosingScript(error.node); RequireProvideSorter cb = new RequireProvideSorter(closureFunction); NodeTraversal.traverseEs6(compiler, script, cb); Node first = cb.calls.get(0); Node last = Iterables.getLast(cb.calls); cb.sortCallsAlphabetically(); StringBuilder sb = new StringBuilder(); for (Node n : cb.calls) { String statement = fix.generateCode(compiler, n); JSDocInfo jsDoc = NodeUtil.getBestJSDocInfo(n); if (jsDoc != null) { statement = jsDoc.getOriginalCommentString() + "\n" + statement; } sb.append(statement); } // Trim to remove the newline after the last goog.require/provide. String newContent = sb.toString().trim(); return fix.replaceRange(first, last, newContent).build(); }
/** * Replaces the provided node with new node in the source file. */ public Builder replace(Node original, Node newNode, AbstractCompiler compiler) { Node parent = original.getParent(); // EXPR_RESULT nodes will contain the trailing semicolons, but the child node // will not. Replace the EXPR_RESULT node to ensure that the semicolons are // correct in the final output. if (original.getParent().isExprResult()) { original = original.getParent(); } // TODO(mknichel): Move this logic to CodePrinter. String newCode = generateCode(compiler, newNode); // The generated code may contain a trailing newline but that is never wanted. if (newCode.endsWith("\n")) { newCode = newCode.substring(0, newCode.length() - 1); } // Most replacements don't need the semicolon in the new generated code - however, some // statements that are blocks or expressions will need the semicolon. boolean needsSemicolon = parent.isExprResult() || parent.isBlock() || parent.isScript(); if (newCode.endsWith(";") && !needsSemicolon) { newCode = newCode.substring(0, newCode.length() - 1); } replacements.put( original.getSourceFileName(), new CodeReplacement(original.getSourceOffset(), original.getLength(), newCode)); return this; }
startPosition, 0, generateCode(m.getMetadata().getCompiler(), googRequireNode))); return this; } else { } else { replacements.put(script.getSourceFileName(), new CodeReplacement( 0, 0, generateCode(m.getMetadata().getCompiler(), googRequireNode))); return this;
/** * Adds a cast of the given type to the provided node. */ public Builder addCast(Node n, AbstractCompiler compiler, String type) { // TODO(mknichel): Figure out the best way to output the typecast. replacements.put( n.getSourceFileName(), new CodeReplacement( n.getSourceOffset(), n.getLength(), "/** @type {" + type + "} */ (" + generateCode(compiler, n) + ")")); return this; }
private Builder insertBefore( Node nodeToInsertBefore, Node n, AbstractCompiler compiler, String sortKey) { return insertBefore(nodeToInsertBefore, generateCode(compiler, n), sortKey); }