mirror of
https://github.com/zulip/zulip.git
synced 2026-06-21 21:32:29 +08:00
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
|
||
|---|---|---|
| .. | ||
| ci | ||
| circleci | ||
| documentation_crawler | ||
| droplets | ||
| i18n | ||
| lib | ||
| linter_lib | ||
| setup | ||
| test-install | ||
| tests | ||
| zulip-export | ||
| __init__.py | ||
| build-docs | ||
| build-release-tarball | ||
| cache-zulip-git-version | ||
| check-capitalization | ||
| check-frontend-i18n | ||
| check-issue-labels | ||
| check-openapi | ||
| check-provision | ||
| check-templates | ||
| clean-branches | ||
| clean-repo | ||
| commit-message-lint | ||
| commit-msg | ||
| conf.ini-template | ||
| coveragerc | ||
| create-test-api-docs | ||
| deploy-branch | ||
| diagnose | ||
| django-template-graph | ||
| do-destroy-rebuild-database | ||
| do-destroy-rebuild-test-database | ||
| documentation.vnufilter | ||
| fetch-pull-request | ||
| fetch-rebase-pull-request | ||
| find-unused-css | ||
| get-handlebar-vars | ||
| html-grep | ||
| js-dep-visualizer.py | ||
| lint | ||
| pre-commit | ||
| pretty-print-html | ||
| provision | ||
| push-to-pull-request | ||
| README.md | ||
| release-tarball-exclude.txt | ||
| renumber-migrations | ||
| replacer | ||
| reset-to-pull-request | ||
| review | ||
| run-dev.py | ||
| run-mypy | ||
| run-tsc | ||
| run-yarn-deduplicate | ||
| setup-git-repo | ||
| show-profile-results | ||
| stop-run-dev | ||
| test-all | ||
| test-api | ||
| test-backend | ||
| test-documentation | ||
| test-emoji-name-scripts | ||
| test-help-documentation | ||
| test-js-with-casper | ||
| test-js-with-node | ||
| test-locked-requirements | ||
| test-migrations | ||
| test-queue-worker-reload | ||
| test-run-dev | ||
| test-tools | ||
| update-authors-json | ||
| update-locked-requirements | ||
| update-prod-static | ||
| update-zuliprc-api-field | ||
| webpack | ||
| webpack-helpers.ts | ||
| webpack.assets.json | ||
| webpack.config.ts | ||
| zanitizer | ||
| zanitizer_config.pm.sample | ||
This directory contains scripts that are used in building, managing,
testing, and other forms of work in a Zulip development environment.
Note that tools that are also useful in production belong in
scripts/ or should be Django management commands.
For more details, see https://zulip.readthedocs.io/en/latest/overview/directory-structure.html.