Java Code Examples for com.google.javascript.rhino.Node#detach()
The following examples show how to use
com.google.javascript.rhino.Node#detach() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TypeConversionPass.java From clutz with MIT License | 6 votes |
private void stripFunctionDefaultParamsAndBody(Node member) { Node functionNode = member.getFirstChild(); Node functionName = functionNode.getFirstChild(); Node functionParams = functionNode.getSecondChild(); // Remove defaults from parameters Node functionParamsNoDefaults = new Node(Token.PARAM_LIST); for (Node param : functionParams.children()) { Node paramNoDefault = param.isDefaultValue() ? param.getFirstChild() : param; functionParamsNoDefaults.addChildToBack(paramNoDefault.detach()); } // Strip body from function definitions. Node newFunction = new Node( Token.FUNCTION, functionName.detach(), functionParamsNoDefaults, new Node(Token.EMPTY)); newFunction.useSourceInfoFrom(functionNode); nodeComments.replaceWithComment(functionNode, newFunction); }
Example 2
Source File: ModuleConversionPass.java From clutz with MIT License | 6 votes |
/** * Takes an assignment statement (export or goog.provide one), removes it and instead finds the * matching declaration and adds an 'export' keyword. * * <p>Before: class C {} exports.C = C; * * <p>After: export class C {}; */ private void moveExportStmtToADeclKeyword(Node assignmentNode, Node declarationNode) { // Rewrite the AST to export the symbol directly using information from the export // assignment. Node next = declarationNode.getNext(); Node parent = declarationNode.getParent(); declarationNode.detach(); Node export = new Node(Token.EXPORT, declarationNode); export.useSourceInfoFrom(assignmentNode); nodeComments.moveComment(declarationNode, export); astComments.moveComment(declarationNode, export); parent.addChildBefore(export, next); compiler.reportChangeToEnclosingScope(parent); }
Example 3
Source File: TypeScriptGenerator.java From clutz with MIT License | 5 votes |
/** Removes the root nodes for all the library files from the source node. */ private static void stripNonCompiledNodes(Node n, Set<String> filesToCompile) { for (Node child : n.children()) { if (!filesToCompile.contains(child.getSourceFileName())) { child.detach(); } } }
Example 4
Source File: TypeConversionPass.java From clutz with MIT License | 5 votes |
/** Converts goog.defineClass calls into class definitions. */ private void convertDefineClassToClass(Node n) { Preconditions.checkState(n.isCall()); Node superClass = n.getSecondChild(); if (superClass.isNull()) { superClass = IR.empty(); } else { superClass.detach(); } Node classMembers = new Node(Token.CLASS_MEMBERS); classMembers.useSourceInfoFrom(n); for (Node child : n.getLastChild().children()) { if (child.isStringKey() || child.isMemberFunctionDef()) { // Handle static methods if ("statics".equals(child.getString())) { for (Node child2 : child.getFirstChild().children()) { convertObjectLiteral(classMembers, child2, true); } } else { // prototype methods convertObjectLiteral(classMembers, child, false); } } else { // Add all other members, such as EMPTY comment nodes, as is. child.detach(); classMembers.addChildToBack(child); } } Node classNode = new Node(Token.CLASS, IR.empty(), superClass, classMembers); classNode.useSourceInfoFrom(n); nodeComments.replaceWithComment(n, classNode); }
Example 5
Source File: ModuleConversionPass.java From clutz with MIT License | 5 votes |
/** * Converts a destructuring Closure goog.require call into a TypeScript import statement. * * <p>The resulting node is dependent on the exports by the module being imported: * * <pre> * import {A as localName, B} from "./valueExports"; * </pre> */ private void convertDestructuringRequireToImportStatements(Node n, ModuleImport moduleImport) { // The imported file is already in TS if (moduleImport.isAlreadyConverted()) { convertRequireForAlreadyConverted(moduleImport); return; } // The imported file is kept in JS if (moduleImport.module.shouldUseOldSyntax()) { convertRequireToImportsIfImportedIsKeptInJs(moduleImport); return; } // For the rest of the function, the imported and importing files are migrating together // import {localName} from "./file" Node importSpecs = createNamedImports(moduleImport); Node importNode = new Node( Token.IMPORT, IR.empty(), importSpecs, Node.newString(moduleImport.referencedFile)); addImportNode(n, importNode); for (int i = 0; i < moduleImport.fullLocalNames.size(); i++) { registerLocalSymbol( n.getSourceFileName(), moduleImport.fullLocalNames.get(i), moduleImport.requiredNamespace, moduleImport.localNames.get(i)); } compiler.reportChangeToEnclosingScope(n); n.detach(); }
Example 6
Source File: StyleFixPass.java From clutz with MIT License | 5 votes |
/** * Attempts to lift class or functions declarations of the form 'var/let/const x = class/function * {...}' into 'class/function x {...}' */ private void liftClassOrFunctionDefinition(Node n) { Node rhs = n.getFirstFirstChild(); Node oldName = rhs.getFirstChild(); Node newName = n.getFirstChild(); // Replace name node with declared name rhs.detach(); newName.detach(); nodeComments.replaceWithComment(oldName, newName); nodeComments.replaceWithComment(n, rhs); }
Example 7
Source File: RemoveGoogScopePass.java From clutz with MIT License | 5 votes |
private void rewriteGoogScope(Node n) { // Extract the goog.scope contents, and add them to module being constructed. Node blockOfScopeContents = n.getLastChild().getLastChild().getLastChild(); blockOfScopeContents.detach(); // Rewrite the AST, moving each node in the contents of the scope after the node. // Create a marker so that we know where to insert the goog.scope contents. Node insertAfterThisNode = n; @Nullable Node nodeToMove = blockOfScopeContents.getFirstChild(); while (nodeToMove != null) { RewriteStatus rewriteStatus = maybeRewriteAlias(nodeToMove); // (1) nodeToMove is detached, alias to provided namespace is recorded, the next node is // returned. The next node should be 'maybeRewriteAlias()' checked before it can be moved out // of goog.scope if (rewriteStatus != stillAttached) { nodeToMove = rewriteStatus.nextNode; continue; } // (2) Alias is re-assigned with the provided namespace. In this case, node is not detached // and stillAttached sentinel is returned. nodeToMove needs to be moved out of goog.scope // Store the next node in a temp variable since detaching the node breaks the chain. Node nextNodeToMove = nodeToMove.getNext(); nodeToMove.detach(); n.getParent().addChildAfter(nodeToMove, insertAfterThisNode); insertAfterThisNode = nodeToMove; nodeToMove = nextNodeToMove; } compiler.reportChangeToEnclosingScope(n); n.detach(); }
Example 8
Source File: RemoveGoogScopePass.java From clutz with MIT License | 5 votes |
private RewriteStatus maybeRecordAndRemoveAlias(Node assign) { Node lhs = assign; Node rhs = assign.getLastChild(); if (rhs == null) { // var foo; return stillAttached; } if (isInProvidedNamespace(rhs)) { aliasToProvidedNamespace.put(lhs.getString(), rhs.getQualifiedName()); Node next = assign.getParent().getNext(); assign.detach(); return new RewriteStatus(next); } return stillAttached; }
Example 9
Source File: TypeConversionPass.java From clutz with MIT License | 4 votes |
/** * Attempts to remove an inheritance statement. ex. goog.inherits(base, super) * * <p>This returns without any modification if the node is not an inheritance statement. This * fails by reporting an error when the node is an invalid inheritance statement. */ private void maybeRemoveInherits(Node exprNode) { Preconditions.checkState(exprNode.isExprResult()); if (exprNode.getFirstChild().isCall()) { Node callNode = exprNode.getFirstChild(); // Remove goog.inherits calls if (!callNode.getFirstChild().matchesQualifiedName("goog.inherits")) { return; } String className = callNode.getSecondChild().getQualifiedName(); String superClassName = callNode.getLastChild().getQualifiedName(); // Check that class exists if (!types.containsKey(className)) { compiler.report( JSError.make( exprNode, GentsErrorManager.GENTS_CLASS_PASS_ERROR, String.format("Class %s could not be found.", className))); return; } // Check that superclass is consistent Node classNode = types.get(className); String storedSuperClassName = classNode.getSecondChild().getQualifiedName(); if (classNode.getSecondChild().isEmpty() || !storedSuperClassName.equals(superClassName)) { compiler.report( JSError.make( exprNode, GentsErrorManager.GENTS_CLASS_PASS_ERROR, String.format("Invalid superclass for %s", className))); return; } compiler.reportChangeToEnclosingScope(exprNode); exprNode.detach(); } else if (exprNode.getFirstChild().isAssign()) { Node assignNode = exprNode.getFirstChild(); // Report error if trying to assign to prototype directly Node lhs = assignNode.getFirstChild(); if (lhs.isGetProp() && "prototype".equals(lhs.getLastChild().getString())) { compiler.report( JSError.make( exprNode, GentsErrorManager.GENTS_CLASS_PASS_ERROR, String.format( "Cannot directly assign to prototype for %s", lhs.getFirstChild().getQualifiedName()))); } } }
Example 10
Source File: TypeConversionPass.java From clutz with MIT License | 4 votes |
/** * Attempts to convert a ES5 superclass call into a ES6 super() call. * * <p>Examples: * * <pre> * B.call(this, args) -> super(args); * B.prototype.foo.call(this, args) ->super.foo(args); * A.base(this, 'constructor', args) -> super(args); * A.base(this, 'foo', args) -> super.foo(args); * </pre> * * <p>This returns without any modification if the node is not an superclass call statement. */ private void maybeReplaceSuperCall(Node callNode) { Preconditions.checkState(callNode.isCall()); String callName = callNode.getFirstChild().getQualifiedName(); // First validate that we are inside a constructor call that extends another class Node classNode = NodeUtil.getEnclosingClass(callNode); if (callName == null || classNode == null) { return; } String className = NodeUtil.getName(classNode); // Translate super constructor or super method calls as follows: // A.base(this, 'constructor', args) -> super(args); // A.base(this, 'foo', args) -> super.foo(args); if (callName.equals(className + ".base") && callNode.getSecondChild().isThis()) { // Super calls for root classes are not converted if (classNode.getSecondChild().isEmpty()) { compiler.report( JSError.make( callNode, GentsErrorManager.GENTS_CLASS_PASS_ERROR, String.format("Cannot call superclass in root class %s", className))); return; } String methodName = callNode.getChildAtIndex(2).getString(); if ("constructor".equals(methodName)) { nodeComments.replaceWithComment(callNode.getFirstChild(), IR.superNode()); } else { nodeComments.replaceWithComment( callNode.getFirstChild(), NodeUtil.newQName(compiler, "super." + methodName)); } // Remove twice to get rid of "this" and the method name callNode.removeChild(callNode.getSecondChild()); callNode.removeChild(callNode.getSecondChild()); compiler.reportChangeToEnclosingScope(callNode); return; } String superClassName = classNode.getSecondChild().getQualifiedName(); // B.call(this, args) -> super(args); if (callName.equals(superClassName + ".call") && callNode.getSecondChild().isThis()) { nodeComments.replaceWithComment(callNode.getFirstChild(), IR.superNode()); callNode.removeChild(callNode.getSecondChild()); compiler.reportChangeToEnclosingScope(callNode); return; } // B.prototype.foo.call(this, args) -> super.foo(args); if (callName.startsWith(superClassName + ".prototype.") && callName.endsWith(".call")) { if (callNode.getSecondChild().isThis()) { // Determine name of method being called Node nameNode = callNode.getFirstFirstChild(); Node n = nameNode; while (!n.getLastChild().getString().equals("prototype")) { n = n.getFirstChild(); } nameNode.detach(); nodeComments.replaceWithComment(n, IR.superNode()); nodeComments.replaceWithComment(callNode.getFirstChild(), nameNode); callNode.removeChild(callNode.getSecondChild()); compiler.reportChangeToEnclosingScope(callNode); return; } } }