module.exports = function (src) { src = typeof src === 'string' ? rocambole.parse(src) : src; return rocambole.moonwalk(src, function (node) { stripDebugger(node); stripConsole(node); }); };
return through.obj(function transform (file, enc, cb) { if (file.isNull()) { return cb(null, file); } if (file.isStream()) { return cb(new PluginError('gulp-debug-finder', 'Streaming not supported.')); } try { const contents = file.contents.toString(); rocambole.moonwalk(contents, (node) => { const expression = node.callee || {}; if (node.type !== 'CallExpression' || expression.type !== 'MemberExpression') { return; } const maybeIdent = expression.object || {}; if (maybeIdent.type === 'Identifier' && maybeIdent.name === 'console' && expression.property) { out = 'There are JavaScript debug statements present.'; } }); } catch (e) { // eslint-disable-next-line no-invalid-this this.emit('error', new PluginError('gulp-debug-finder', e, { fileName: file.path, })); } return cb(); }, function flush (cb) {
function transform(ast, opts) { if (opts !== BYPASS_OPTIONS) { _options.set(opts); } _shouldRemoveTrailingWs = Boolean(_options.get('whiteSpace.removeTrailing')); plugins.transformBefore(ast); _tk.eachInBetween(ast.startToken, ast.endToken, preprocessToken); rocambole.moonwalk(ast, transformNode); _tk.eachInBetween(ast.startToken, ast.endToken, postprocessToken); _br.limitBeforeEndOfFile(ast); // indent should come after all other transformations since it depends on // line breaks caused by "parent" nodes, otherwise it will cause conflicts. // it should also happen after the postprocessToken since it adds line breaks // before/after comments and that changes the indent logic indent.transform(ast); // plugin transformation comes after the indentation since we assume user // knows what he is doing (will increase flexibility and allow plugin to // override the indentation logic) // we have an alias "transform" to match v0.3 API, but favor `transformAfter` // moving forward. (we might deprecate "transform" in the future) plugins.transform(ast); plugins.transformAfter(ast); return ast; }
function format(str, opts){ _options.set(opts); // we remove indent and trailing whitespace before since it's simpler, code // is responsible for re-indenting str = _indent.removeAll(str); str = _ws.removeTrailing(str); str = _br.removeEmptyLines(str); var ast = walker.parse(str); _ws.sanitizeWhiteSpaces( ast.startToken ); walker.moonwalk(ast, transformNode); str = ast.toString(); return str; }
exports.format = function(str, opts){ // everything is sync so we use a local var for brevity _curOpts = merge(DEFAULT_OPTS, opts); _br = _curOpts.lineBreak.value; // we remove indent and trailing whitespace before since it's simpler, code // is responsible for re-indenting str = removeIndent(str); str = removeTrailingWhiteSpace(str); str = removeEmptyLines(str); var ast = walker.parse(str); sanitizeWhiteSpaces( ast.startToken ); walker.moonwalk(ast, transformNode); str = ast.toString(); return str; };
function flush(done) { const ast = rocambole.parse(code); code = rocambole.moonwalk(ast, function strip(node) { if (( // var debug = ...; 'VariableDeclaration' === node.type && 'debug' === node.declarations[0].id.name ) || ( // debug( ... ); 'ExpressionStatement' === node.type && 'CallExpression' === node.expression.type && 'debug' === node.expression.callee.name )) { return remove(node); } }); this.push(code.toString()); done(); }
function transform(ast, opts) { _options.set(opts); _shouldRemoveTrailingWs = Boolean(_options.get('whiteSpace.removeTrailing')); _tk.eachInBetween(ast.startToken, ast.endToken, preprocessToken); rocambole.moonwalk(ast, transformNode); _tk.eachInBetween(ast.startToken, ast.endToken, postprocessToken); // indent should come after all other transformations since it depends on // line breaks caused by "parent" nodes, otherwise it will cause conflicts. // it should also happen after the postprocessToken since it adds line breaks // before/after comments and that changes the indent logic indent.transform(ast); if (process.env.LOG_TOKENS) { _ast.logTokens(ast); } return ast; }
exports.transform = function (ast) { rocambole.moonwalk(ast, exports._transformNode); };
.pipe(vinylMap(function (code, filename) { var stripped = rocambole.moonwalk(code.toString(), stripAsserts); console.log('asserts removed: ' + removedAsserts); return stripped.toString(); }))
function transform(ast) { rocambole.moonwalk(ast, commafirst) return ast }
function strip(string) { return rocambole.moonwalk(string, node => { m(node); }).toString(); }
exports.transform = function (ast) { // Mark up the AST with scope information ast = ecmaVariableScope(ast); // Skip over the custom node properties rocambole.BYPASS_RECURSION._insideWith = true; rocambole.BYPASS_RECURSION._nearestScope = true; rocambole.BYPASS_RECURSION._scopeType = true; rocambole.BYPASS_RECURSION._usedInAWith = true; rocambole.BYPASS_RECURSION.scopeInfo = true; rocambole.BYPASS_RECURSION.scope = true; // Walk over the identifiers rocambole.moonwalk(ast, function updateIdentifiers (node) { // If the node is an identifier var name, newName; if (node.type === 'Identifier') { // If it's a variable if (node.scopeInfo) { // Grab the node and its name name = node.name; newName = variableMap[name]; // If there is no rename, ignore the node if (newName === undefined || newName === name) { return; } // DEV: Logic taken from `uglifyjs2` (linked from `beautify-with-words`) // https://github.com/mishoo/UglifyJS2/blob/v2.4.11/lib/scope.js#L59-L63 // If the identifier has not been declared if (node.scopeInfo.type === ecmaVariableScope.SCOPE_INFO_TYPES.UNDECLARED) { // If we are not cool with renaming undeclared variables, warn and ignore this node if (renameOptions.renameUndeclared !== true) { logger.warn('Saw matching undeclared variable "' + name + '" but did not rename due ' + 'to potential issues. To force a rename on undeclared variables, set the ' + 'option `rename.renameUndeclared` to `true`'); return; } // Otherwise, if the identifier is top level and we aren't touching top level items // DEV: All undeclareds are top level so they should be skipping this step } else if (node.scopeInfo.topLevel === ecmaVariableScope.SCOPE_INFO_TOP_LEVEL.YES) { // If we are not cool with renaming top levels, warn and ignore this node if (renameOptions.renameTopLevel !== true) { logger.warn('Saw matching top level variable "' + name + '" but did not rename due ' + 'to potential issues. To force a rename on top level variables, set the ' + 'option `rename.renameTopLevel` to `true`'); return; } } // If the identifier has ever been used in a with, do nothing var usedInAWith = node.scopeInfo.usedInAWith !== ecmaVariableScope.SCOPE_INFO_USED_IN_A_WITH.NO; if (usedInAWith) { // If we are not cool with ignoring `with` related variables, warn and ignore this node if (renameOptions.ignoreWith !== true) { logger.warn('Saw matching variable "' + name + '" that was used in a `with` but did not rename due ' + 'to potential issues. To force a rename on variables used in a `with`, set the ' + 'option `rename.ignoreWith` to `true`'); return; } } // Rename our identifier (update in both node and token tree) node.name = node.startToken.value = newName; // Otherwise, if it is in a label, break, or continue // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API#Statements // https://github.com/twolfson/ecma-variable-scope/blob/2.1.0/lib/ecma-variable-scope.js#L101-L103 } else if (isLabelIdentifier(node)) { // Grab the new name and update to it newName = labelMap[node.name]; if (newName !== undefined) { node.name = node.startToken.value = newName; } } } }); // Clean up custom iteration skips delete rocambole.BYPASS_RECURSION._insideWith; delete rocambole.BYPASS_RECURSION._nearestScope; delete rocambole.BYPASS_RECURSION._scopeType; delete rocambole.BYPASS_RECURSION._usedInAWith; delete rocambole.BYPASS_RECURSION.scopeInfo; delete rocambole.BYPASS_RECURSION.scope; // Walk over all nodes and clean up our properties // DEV: Without this, we would have infinite recursion on other traversals // DEV: We use `estraverse` over `rocambole` to prevent possible misses due to missing references estraverse.traverse(ast, { enter: function cleanupProperties (node) { delete node._insideWith; delete node._nearestScope; delete node._scopeType; delete node._usedInAWith; delete node.scopeInfo; delete node.scope; } }); // Return the modified AST return ast; };
function transform(ast) { rocambole.moonwalk(ast, transformNode); exports.sanitize(ast); return ast; }
module.exports = source => rocambole.moonwalk(source, node => { stripDebugger(node); stripConsole(node); stripAlert(node); });