Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .eslintplugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const fs = require("fs");
const path = require("path");

const rulesDir = path.join(__dirname, "scripts", "eslint", "rules");
const ext = ".js";
const ruleFiles = fs.readdirSync(rulesDir).filter((p) => p.endsWith(ext));

module.exports = {
rules: Object.fromEntries(ruleFiles.map((p) => {
return [p.slice(0, -ext.length), require(path.join(rulesDir, p))];
})),
}
24 changes: 12 additions & 12 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"es6": true
},
"plugins": [
"@typescript-eslint", "jsdoc", "no-null", "import"
"@typescript-eslint", "jsdoc", "no-null", "import", "eslint-plugin-local"
],
"overrides": [
// By default, the ESLint CLI only looks at .js files. But, it will also look at
Expand Down Expand Up @@ -81,20 +81,20 @@
"@typescript-eslint/unified-signatures": "error",

// scripts/eslint/rules
"object-literal-surrounding-space": "error",
"no-type-assertion-whitespace": "error",
"type-operator-spacing": "error",
"only-arrow-functions": ["error", {
"local/object-literal-surrounding-space": "error",
"local/no-type-assertion-whitespace": "error",
"local/type-operator-spacing": "error",
"local/only-arrow-functions": ["error", {
"allowNamedFunctions": true ,
"allowDeclarations": true
}],
"no-double-space": "error",
"boolean-trivia": "error",
"no-in-operator": "error",
"simple-indent": "error",
"debug-assert": "error",
"no-keywords": "error",
"one-namespace-per-file": "error",
"local/no-double-space": "error",
"local/boolean-trivia": "error",
"local/no-in-operator": "error",
"local/simple-indent": "error",
"local/debug-assert": "error",
"local/no-keywords": "error",
"local/one-namespace-per-file": "error",

// eslint-plugin-import
"import/no-extraneous-dependencies": ["error", { "optionalDependencies": false }],
Expand Down
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ Dockerfile
.eslintrc.json
.yarnrc
tmp
.eslintplugin.js
.eslintcache

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should have included this on my eslint-at-root PR; I really dislike npmignore for this reason. Maybe I'll sit down and change our package to use "files" instead.

6 changes: 0 additions & 6 deletions .vscode/settings.template.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
// Rename this file 'settings.json' or merge its
// contents into your existing settings.
{
"eslint.validate": [

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this gone, the template consists solely of suggestions for typescript.tsdk values.

"typescript"
],
"eslint.options": {
"rulePaths": ["./scripts/eslint/built/rules/"],
},
// To use the last-known-good (LKG) compiler version:
// "typescript.tsdk": "lib"

Expand Down
8 changes: 2 additions & 6 deletions Gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@ const eslint = (folder) => async () => {
"--cache",
"--cache-location", `${folder}/.eslintcache`,
"--format", formatter,
"--rulesdir", "scripts/eslint/built/rules",
];

if (cmdLineOptions.fix) {
Expand All @@ -369,10 +368,7 @@ const eslint = (folder) => async () => {
return exec(process.execPath, args);
};

const lintRoot = eslint(".");
lintRoot.displayName = "lint";

const lint = series([buildEslintRules, lintRoot]);
const lint = eslint(".");
lint.displayName = "lint";
task("lint", lint);
task("lint").description = "Runs eslint on the compiler and scripts sources.";
Expand Down Expand Up @@ -431,7 +427,7 @@ task("watch-local").flags = {
const preTest = parallel(buildTsc, buildTests, buildServices, buildLssl);
preTest.displayName = "preTest";

const postTest = (done) => cmdLineOptions.lint ? lint(done) : done();
const postTest = (done) => cmdLineOptions.lint ? lint() : done();

const runTests = () => runConsoleTests("built/local/run.js", "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false);
task("runtests", series(preBuild, preTest, runTests, postTest));
Expand Down
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"eslint-formatter-autolinkable-stylish": "^1.2.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^39.3.6",
"eslint-plugin-local": "^1.0.0",
"eslint-plugin-no-null": "^1.0.2",
"fancy-log": "latest",
"fs-extra": "^9.1.0",
Expand Down Expand Up @@ -90,7 +91,6 @@
"es5-ext": "0.10.53"
},
"scripts": {
"prepare": "gulp build-eslint-rules",
"pretest": "gulp tests",
"test": "gulp runtests-parallel --light=false",
"test:eslint-rules": "gulp run-eslint-rules-tests",
Expand Down
2 changes: 1 addition & 1 deletion scripts/build/prepend.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function prepend(data) {
sourcesContent: input.sourcesContent
};
}
// eslint-disable-next-line boolean-trivia, no-null/no-null
// eslint-disable-next-line local/boolean-trivia, no-null/no-null
return cb(null, output);
}
catch (e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
import { createRule } from "./utils";
const { AST_NODE_TYPES, TSESTree } = require("@typescript-eslint/utils");
const { createRule } = require("./utils");

export = createRule({
module.exports = createRule({

@jakebailey jakebailey Aug 22, 2022

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are all now CJS (well, they were before after compilation, but now we're hand-writing that); a future version of ESLint is poised to completely revamp the way that configuration works and will likely enable ESM rules.

name: "boolean-trivia",
meta: {
docs: {
Expand All @@ -21,8 +21,10 @@ export = createRule({
const sourceCode = context.getSourceCode();
const sourceCodeText = sourceCode.getText();

const isSetOrAssert = (name: string): boolean => name.startsWith("set") || name.startsWith("assert");
const isTrivia = (node: TSESTree.Node): boolean => {
/** @type {(name: string) => boolean} */
const isSetOrAssert = (name) => name.startsWith("set") || name.startsWith("assert");
/** @type {(node: TSESTree.Node) => boolean} */
const isTrivia = (node) => {
if (node.type === AST_NODE_TYPES.Identifier) {
return node.name === "undefined";
}
Expand All @@ -35,7 +37,8 @@ export = createRule({
return false;
};

const shouldIgnoreCalledExpression = (node: TSESTree.CallExpression): boolean => {
/** @type {(node: TSESTree.CallExpression) => boolean} */
const shouldIgnoreCalledExpression = (node) => {
if (node.callee && node.callee.type === AST_NODE_TYPES.MemberExpression) {
const methodName = node.callee.property.type === AST_NODE_TYPES.Identifier
? node.callee.property.name
Expand Down Expand Up @@ -68,7 +71,8 @@ export = createRule({
return false;
};

const checkArg = (node: TSESTree.Node): void => {
/** @type {(node: TSESTree.Node) => void} */
const checkArg = (node) => {
if (!isTrivia(node)) {
return;
}
Expand All @@ -88,7 +92,8 @@ export = createRule({
}
};

const checkBooleanTrivia = (node: TSESTree.CallExpression) => {
/** @type {(node: TSESTree.CallExpression) => void} */
const checkBooleanTrivia = (node) => {
if (shouldIgnoreCalledExpression(node)) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
import { createRule } from "./utils";
const { AST_NODE_TYPES, TSESTree } = require("@typescript-eslint/utils");
const { createRule } = require("./utils");

export = createRule({
module.exports = createRule({
name: "debug-assert",
meta: {
docs: {
Expand All @@ -18,19 +18,23 @@ export = createRule({
defaultOptions: [],

create(context) {
const isArrowFunction = (node: TSESTree.Node) => node.type === AST_NODE_TYPES.ArrowFunctionExpression;
const isStringLiteral = (node: TSESTree.Node): boolean => (
/** @type {(node: TSESTree.Node) => boolean} */
const isArrowFunction = (node) => node.type === AST_NODE_TYPES.ArrowFunctionExpression;
/** @type {(node: TSESTree.Node) => boolean} */
const isStringLiteral = (node) => (
(node.type === AST_NODE_TYPES.Literal && typeof node.value === "string") || node.type === AST_NODE_TYPES.TemplateLiteral
);

const isDebugAssert = (node: TSESTree.MemberExpression): boolean => (
/** @type {(node: TSESTree.MemberExpression) => boolean} */
const isDebugAssert = (node) => (
node.object.type === AST_NODE_TYPES.Identifier
&& node.object.name === "Debug"
&& node.property.type === AST_NODE_TYPES.Identifier
&& node.property.name === "assert"
);

const checkDebugAssert = (node: TSESTree.CallExpression) => {
/** @type {(node: TSESTree.CallExpression) => void} */
const checkDebugAssert = (node) => {
const args = node.arguments;
const argsLen = args.length;
if (!(node.callee.type === AST_NODE_TYPES.MemberExpression && isDebugAssert(node.callee)) || argsLen < 2) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TSESTree, AST_NODE_TYPES } from "@typescript-eslint/utils";
import { createRule } from "./utils";
const { TSESTree, AST_NODE_TYPES } = require("@typescript-eslint/utils");
const { createRule } = require("./utils");

export = createRule({
module.exports = createRule({
name: "no-double-space",
meta: {
docs: {
Expand All @@ -20,19 +20,22 @@ export = createRule({
const sourceCode = context.getSourceCode();
const lines = sourceCode.getLines();

const isStringLiteral = (node: TSESTree.Node | null): boolean => {
/** @type {(node: TSESTree.Node | null) => boolean} */
const isStringLiteral = (node) => {
return !!(node && (
(node.type === AST_NODE_TYPES.TemplateElement) ||
(node.type === AST_NODE_TYPES.TemplateLiteral && node.quasis) ||
(node.type === AST_NODE_TYPES.Literal && typeof node.value === "string")
));
};

const isRegexLiteral = (node: TSESTree.Node | null): boolean => {
/** @type {(node: TSESTree.Node | null) => boolean} */
const isRegexLiteral = (node) => {
return !!(node && node.type === AST_NODE_TYPES.Literal && Object.prototype.hasOwnProperty.call(node, "regex"));
};

const checkDoubleSpace = (node: TSESTree.Node) => {
/** @type {(node: TSESTree.Node) => void} */
const checkDoubleSpace = (node) => {
lines.forEach((line, index) => {
const firstNonSpace = /\S/.exec(line);
if (!firstNonSpace || line.includes("@param")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TSESTree } from "@typescript-eslint/utils";
import { createRule } from "./utils";
const { TSESTree } = require("@typescript-eslint/utils");
const { createRule } = require("./utils");

export = createRule({
module.exports = createRule({
name: "no-in-operator",
meta: {
docs: {
Expand All @@ -18,7 +18,8 @@ export = createRule({

create(context) {
const IN_OPERATOR = "in";
const checkInOperator = (node: TSESTree.BinaryExpression) => {
/** @type {(node: TSESTree.BinaryExpression) => void} */
const checkInOperator = (node) => {
if (node.operator === IN_OPERATOR) {
context.report({ messageId: "noInOperatorError", node });
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TSESTree, AST_NODE_TYPES } from "@typescript-eslint/utils";
import { createRule } from "./utils";
const { TSESTree, AST_NODE_TYPES } = require("@typescript-eslint/utils");
const { createRule } = require("./utils");

export = createRule({
module.exports = createRule({
name: "no-keywords",
meta: {
docs: {
Expand Down Expand Up @@ -35,13 +35,16 @@ export = createRule({
"any",
];

const isKeyword = (name: string) => keywords.includes(name);
/** @type {(name: string) => boolean} */
const isKeyword = (name) => keywords.includes(name);

const report = (node: TSESTree.Identifier) => {
/** @type {(node: TSESTree.Identifier) => void} */
const report = (node) => {
context.report({ messageId: "noKeywordsError", data: { name: node.name }, node });
};

const checkProperties = (node: TSESTree.ObjectPattern): void => {
/** @type {(node: TSESTree.ObjectPattern) => void} */
const checkProperties = (node) => {
node.properties.forEach(property => {
if (
property &&
Expand All @@ -54,7 +57,8 @@ export = createRule({
});
};

const checkElements = (node: TSESTree.ArrayPattern): void => {
/** @type {(node: TSESTree.ArrayPattern) => void} */
const checkElements = (node) => {
node.elements.forEach(element => {
if (
element &&
Expand All @@ -66,14 +70,8 @@ export = createRule({
});
};

const checkParams = (
node:
| TSESTree.ArrowFunctionExpression
| TSESTree.FunctionDeclaration
| TSESTree.FunctionExpression
| TSESTree.TSMethodSignature
| TSESTree.TSFunctionType
): void => {
/** @type {(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSMethodSignature | TSESTree.TSFunctionType) => void} */
const checkParams = (node) => {
if (!node || !node.params || !node.params.length) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { TSESTree } from "@typescript-eslint/utils";
import { createRule } from "./utils";
const { TSESTree } = require("@typescript-eslint/utils");
const { createRule } = require("./utils");

export = createRule({
module.exports = createRule({
name: "no-type-assertion-whitespace",
meta: {
docs: {
Expand All @@ -18,7 +18,8 @@ export = createRule({

create(context) {
const sourceCode = context.getSourceCode();
const checkTypeAssertionWhitespace = (node: TSESTree.TSTypeAssertion) => {
/** @type {(node: TSESTree.TSTypeAssertion) => void} */
const checkTypeAssertionWhitespace = (node) => {
const leftToken = sourceCode.getLastToken(node.typeAnnotation);
const rightToken = sourceCode.getFirstToken(node.expression);

Expand Down
Loading