forked from microsoft/TypeScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move eslint rules from eslint-plugin-microsoft-typescript to scripts/…
…eslint
- Loading branch information
1 parent
a79f598
commit 0059763
Showing
41 changed files
with
1,254 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ src | |
tests | ||
Jakefile.js | ||
.eslintrc | ||
.eslintignore | ||
.editorconfig | ||
.failed-tests | ||
.git | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { SyntaxKind } from "typescript"; | ||
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/experimental-utils"; | ||
import { getEsTreeNodeToTSNodeMap, createRule } from "./utils"; | ||
|
||
export = createRule({ | ||
name: "boolean-trivia", | ||
meta: { | ||
docs: { | ||
description: ``, | ||
category: "Best Practices", | ||
recommended: "error", | ||
}, | ||
messages: { | ||
booleanTriviaArgumentError: `Tag argument with parameter name`, | ||
booleanTriviaArgumentSpaceError: `There should be 1 space between an argument and its comment`, | ||
}, | ||
schema: [], | ||
type: "problem", | ||
}, | ||
defaultOptions: [], | ||
|
||
create(context) { | ||
const esTreeNodeToTSNodeMap = getEsTreeNodeToTSNodeMap(context.parserServices); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCodeText = sourceCode.getText(); | ||
|
||
const isSetOrAssert = (name: string): boolean => name.startsWith("set") || name.startsWith("assert"); | ||
const isTrivia = (node: TSESTree.Expression): boolean => { | ||
const tsNode = esTreeNodeToTSNodeMap.get(node); | ||
|
||
if (tsNode.kind === SyntaxKind.Identifier) { | ||
return tsNode.originalKeywordKind === SyntaxKind.UndefinedKeyword; | ||
} | ||
|
||
return [SyntaxKind.TrueKeyword, SyntaxKind.FalseKeyword, SyntaxKind.NullKeyword].indexOf(tsNode.kind) >= 0; | ||
}; | ||
|
||
const shouldIgnoreCalledExpression = (node: TSESTree.CallExpression): boolean => { | ||
if (node.callee && node.callee.type === AST_NODE_TYPES.MemberExpression) { | ||
const methodName = node.callee.property.type === AST_NODE_TYPES.Identifier | ||
? node.callee.property.name | ||
: ""; | ||
|
||
if (isSetOrAssert(methodName)) { | ||
return true; | ||
} | ||
|
||
return ["apply", "call", "equal", "fail", "isTrue", "output", "stringify", "push"].indexOf(methodName) >= 0; | ||
} | ||
|
||
if (node.callee && node.callee.type === AST_NODE_TYPES.Identifier) { | ||
const functionName = node.callee.name; | ||
|
||
if (isSetOrAssert(functionName)) { | ||
return true; | ||
} | ||
|
||
return [ | ||
"createImportSpecifier", | ||
"createAnonymousType", | ||
"createSignature", | ||
"createProperty", | ||
"resolveName", | ||
"contains", | ||
].indexOf(functionName) >= 0; | ||
} | ||
|
||
return false; | ||
}; | ||
|
||
const checkArg = (node: TSESTree.Expression): void => { | ||
if (!isTrivia(node)) { | ||
return; | ||
} | ||
|
||
const comments = sourceCode.getCommentsBefore(node); | ||
if (!comments || comments.length !== 1 || comments[0].type !== "Block") { | ||
context.report({ messageId: "booleanTriviaArgumentError", node }); | ||
return; | ||
} | ||
|
||
const argRangeStart = node.range[0]; | ||
const commentRangeEnd = comments[0].range[1]; | ||
const hasNewLine = sourceCodeText.slice(commentRangeEnd, argRangeStart).indexOf("\n") >= 0; | ||
|
||
if (argRangeStart !== commentRangeEnd + 1 && !hasNewLine) { | ||
context.report({ messageId: "booleanTriviaArgumentSpaceError", node }); | ||
} | ||
}; | ||
|
||
const checkBooleanTrivia = (node: TSESTree.CallExpression) => { | ||
if (shouldIgnoreCalledExpression(node)) { | ||
return; | ||
} | ||
|
||
for (const arg of node.arguments) { | ||
checkArg(arg); | ||
} | ||
}; | ||
|
||
return { | ||
CallExpression: checkBooleanTrivia, | ||
}; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/experimental-utils"; | ||
import { createRule } from "./utils"; | ||
|
||
export = createRule({ | ||
name: "debug-assert", | ||
meta: { | ||
docs: { | ||
description: ``, | ||
category: "Possible Errors", | ||
recommended: "error", | ||
}, | ||
messages: { | ||
secondArgumentDebugAssertError: `Second argument to 'Debug.assert' should be a string literal`, | ||
thirdArgumentDebugAssertError: `Third argument to 'Debug.assert' should be a string literal or arrow function`, | ||
}, | ||
schema: [], | ||
type: "problem", | ||
}, | ||
defaultOptions: [], | ||
|
||
create(context) { | ||
const isArrowFunction = (node: TSESTree.Node) => node.type === AST_NODE_TYPES.ArrowFunctionExpression; | ||
const isStringLiteral = (node: TSESTree.Node): boolean => ( | ||
(node.type === AST_NODE_TYPES.Literal && typeof node.value === "string") || node.type === AST_NODE_TYPES.TemplateLiteral | ||
); | ||
|
||
const isDebugAssert = (node: TSESTree.MemberExpression): boolean => ( | ||
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) => { | ||
const args = node.arguments; | ||
const argsLen = args.length; | ||
if (!(node.callee.type === AST_NODE_TYPES.MemberExpression && isDebugAssert(node.callee)) || argsLen < 2) { | ||
return; | ||
} | ||
|
||
const message1Node = args[1]; | ||
if (message1Node && !isStringLiteral(message1Node)) { | ||
context.report({ messageId: "secondArgumentDebugAssertError", node: message1Node }); | ||
} | ||
|
||
if (argsLen < 3) { | ||
return; | ||
} | ||
|
||
const message2Node = args[2]; | ||
if (message2Node && (!isStringLiteral(message2Node) && !isArrowFunction(message2Node))) { | ||
context.report({ messageId: "thirdArgumentDebugAssertError", node: message2Node }); | ||
} | ||
}; | ||
|
||
return { | ||
CallExpression: checkDebugAssert, | ||
}; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { TSESTree } from "@typescript-eslint/experimental-utils"; | ||
import { SyntaxKind } from "typescript"; | ||
import { getEsTreeNodeToTSNodeMap, createRule } from "./utils"; | ||
|
||
export = createRule({ | ||
name: "no-double-space", | ||
meta: { | ||
docs: { | ||
description: ``, | ||
category: "Stylistic Issues", | ||
recommended: "error", | ||
}, | ||
messages: { | ||
noDoubleSpaceError: `Use only one space`, | ||
}, | ||
schema: [], | ||
type: "problem", | ||
}, | ||
defaultOptions: [], | ||
|
||
create(context) { | ||
const esTreeNodeToTSNodeMap = getEsTreeNodeToTSNodeMap(context.parserServices); | ||
const sourceCode = context.getSourceCode(); | ||
const lines = sourceCode.getLines(); | ||
|
||
const isLiteral = (node: TSESTree.Node | null) => { | ||
if (!node) { | ||
return false; | ||
} | ||
|
||
const tsNode = esTreeNodeToTSNodeMap.get(node); | ||
if (!tsNode) { | ||
return false; | ||
} | ||
|
||
return [ | ||
SyntaxKind.NoSubstitutionTemplateLiteral, | ||
SyntaxKind.RegularExpressionLiteral, | ||
SyntaxKind.TemplateMiddle, | ||
SyntaxKind.StringLiteral, | ||
SyntaxKind.TemplateHead, | ||
SyntaxKind.TemplateTail, | ||
].indexOf(tsNode.kind) >= 0; | ||
}; | ||
|
||
const checkDoubleSpace = (node: TSESTree.Node) => { | ||
lines.forEach((line, index) => { | ||
const firstNonSpace = /\S/.exec(line); | ||
if (!firstNonSpace || line.includes("@param")) { | ||
return; | ||
} | ||
|
||
// Allow common uses of double spaces | ||
// * To align `=` or `!=` signs | ||
// * To align comments at the end of lines | ||
// * To indent inside a comment | ||
// * To use two spaces after a period | ||
// * To include aligned `->` in a comment | ||
const rgx = /[^/*. ][ ]{2}[^-!/= ]/g; | ||
rgx.lastIndex = firstNonSpace.index; | ||
const doubleSpace = rgx.exec(line); | ||
|
||
if (!doubleSpace) { | ||
return; | ||
} | ||
|
||
const locIndex = sourceCode.getIndexFromLoc({ column: doubleSpace.index, line: index + 1 }); | ||
const sourceNode = sourceCode.getNodeByRangeIndex(locIndex); | ||
if (isLiteral(sourceNode)) { | ||
return; | ||
} | ||
|
||
context.report({ messageId: "noDoubleSpaceError", node, loc: { line: index + 1, column: doubleSpace.index + 1 } }); | ||
}); | ||
}; | ||
|
||
return { | ||
Program: checkDoubleSpace, | ||
}; | ||
}, | ||
}); |
Oops, something went wrong.