Skip to content

Commit

Permalink
Use built-in no-restricted-syntax to ban null instead of plugin, ban …
Browse files Browse the repository at this point in the history
…null type too (#58095)
  • Loading branch information
jakebailey authored Apr 18, 2024
1 parent 72f413c commit 17e420d
Show file tree
Hide file tree
Showing 45 changed files with 128 additions and 139 deletions.
18 changes: 13 additions & 5 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
],
"plugins": [
"@typescript-eslint",
"no-null",
"eslint-plugin-local"
],
"ignorePatterns": [
Expand Down Expand Up @@ -60,6 +59,18 @@
"prefer-object-spread": "error",
"unicode-bom": ["error", "never"],

"no-restricted-syntax": [
"error",
{
"selector": "Literal[raw=null]",
"message": "Avoid using null; use undefined instead."
},
{
"selector": "TSNullKeyword",
"message": "Avoid using null; use undefined instead."
}
],

// Enabled in eslint:recommended, but not applicable here
"no-extra-boolean-cast": "off",
"no-case-declarations": "off",
Expand Down Expand Up @@ -132,10 +143,7 @@
"local/no-in-operator": "error",
"local/debug-assert": "error",
"local/no-keywords": "error",
"local/jsdoc-format": "error",

// eslint-plugin-no-null
"no-null/no-null": "error"
"local/jsdoc-format": "error"
},
"overrides": [
// By default, the ESLint CLI only looks at .js files. But, it will also look at
Expand Down
20 changes: 0 additions & 20 deletions package-lock.json

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

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
"eslint": "^8.57.0",
"eslint-formatter-autolinkable-stylish": "^1.3.0",
"eslint-plugin-local": "^4.2.1",
"eslint-plugin-no-null": "^1.0.2",
"fast-xml-parser": "^4.3.6",
"glob": "^10.3.10",
"hereby": "^1.8.9",
Expand Down
4 changes: 2 additions & 2 deletions scripts/configurePrerelease.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function main() {
writeFileSync(tsFilePath, modifiedTsFileContents);
}

/* eslint-disable no-null/no-null */
/* eslint-disable no-restricted-syntax */
/**
* @param {string} tsFilePath
* @param {string} tsFileContents
Expand Down Expand Up @@ -101,7 +101,7 @@ function parsePackageJsonVersion(versionString) {
assert(match !== null, "package.json 'version' should match " + versionRgx.toString());
return { majorMinor: match[1], patch: match[2] };
}
/* eslint-enable no-null/no-null */
/* eslint-enable no-restricted-syntax */

/**
* e.g. 0-dev.20170707
Expand Down
2 changes: 1 addition & 1 deletion scripts/eslint/rules/argument-trivia.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = createRule({
}

if (node.type === AST_NODE_TYPES.Literal) {
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
return node.value === null || node.value === true || node.value === false;
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/eslint/rules/only-arrow-functions.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ module.exports = createRule({
return;
}

if ((allowNamedFunctions && node.id !== null) || isMethodType(node)) { // eslint-disable-line no-null/no-null
if ((allowNamedFunctions && node.id !== null) || isMethodType(node)) { // eslint-disable-line no-restricted-syntax
return;
}

Expand Down
6 changes: 3 additions & 3 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2394,7 +2394,7 @@ export function convertToJson(
return false;

case SyntaxKind.NullKeyword:
return null; // eslint-disable-line no-null/no-null
return null; // eslint-disable-line no-restricted-syntax

case SyntaxKind.StringLiteral:
if (!isDoubleQuotedString(valueExpression)) {
Expand Down Expand Up @@ -2869,8 +2869,8 @@ export function setConfigFileInOptions(options: CompilerOptions, configFile: TsC
}
}

function isNullOrUndefined(x: any): x is null | undefined {
return x === undefined || x === null; // eslint-disable-line no-null/no-null
function isNullOrUndefined(x: any): x is null | undefined { // eslint-disable-line no-restricted-syntax
return x === undefined || x === null; // eslint-disable-line no-restricted-syntax
}

function directoryOfCombinedPath(fileName: string, basePath: string) {
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -872,9 +872,9 @@ export function arrayIsEqualTo<T>(array1: readonly T[] | undefined, array2: read
*
* @internal
*/
export function compact<T>(array: (T | undefined | null | false | 0 | "")[]): T[];
export function compact<T>(array: (T | undefined | null | false | 0 | "")[]): T[]; // eslint-disable-line no-restricted-syntax
/** @internal */
export function compact<T>(array: readonly (T | undefined | null | false | 0 | "")[]): readonly T[];
export function compact<T>(array: readonly (T | undefined | null | false | 0 | "")[]): readonly T[]; // eslint-disable-line no-restricted-syntax
// ESLint thinks these can be combined with the above - they cannot; they'd produce higher-priority inferences and prevent the falsey types from being stripped
/** @internal */
export function compact<T>(array: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures
Expand Down Expand Up @@ -1511,8 +1511,8 @@ export function group<T, K>(values: readonly T[], getGroupId: (value: T) => K, r
/** @internal */
export function groupBy<T, U extends T>(values: readonly T[] | undefined, keySelector: (value: T) => value is U): { true?: U[]; false?: Exclude<T, U>[]; };
/** @internal */
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; };
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; } {
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; }; // eslint-disable-line no-restricted-syntax
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; } { // eslint-disable-line no-restricted-syntax
const result: Record<string, T[]> = {};
if (values) {
for (const value of values) {
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,13 @@ export namespace Debug {
}

export function assertIsDefined<T>(value: T, message?: string, stackCrawlMark?: AnyFunction): asserts value is NonNullable<T> {
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
if (value === undefined || value === null) {
fail(message, stackCrawlMark || assertIsDefined);
}
}

export function checkDefined<T>(value: T | null | undefined, message?: string, stackCrawlMark?: AnyFunction): T {
export function checkDefined<T>(value: T | null | undefined, message?: string, stackCrawlMark?: AnyFunction): T { // eslint-disable-line no-restricted-syntax
assertIsDefined(value, message, stackCrawlMark || checkDefined);
return value;
}
Expand Down Expand Up @@ -935,7 +935,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
FlowFlags.Condition |
FlowFlags.ArrayMutation;

const links: Record<number, FlowGraphNode> = Object.create(/*o*/ null); // eslint-disable-line no-null/no-null
const links: Record<number, FlowGraphNode> = Object.create(/*o*/ null); // eslint-disable-line no-restricted-syntax
const nodes: FlowGraphNode[] = [];
const edges: FlowGraphEdge[] = [];
const root = buildGraphNode(flowNode, new Set());
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/executeCommandLine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ function executeCommandLineWorker(
configParseResult.errors.forEach(reportDiagnostic);
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
}
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
sys.write(JSON.stringify(convertToTSConfig(configParseResult, configFileName, sys), null, 4) + sys.newLine);
return sys.exit(ExitStatus.Success);
}
Expand Down Expand Up @@ -693,7 +693,7 @@ function executeCommandLineWorker(
}
else {
if (commandLineOptions.showConfig) {
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
sys.write(JSON.stringify(convertToTSConfig(commandLine, combinePaths(currentDirectory, "tsconfig.json"), sys), null, 4) + sys.newLine);
return sys.exit(ExitStatus.Success);
}
Expand Down
18 changes: 9 additions & 9 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,9 @@ function readPackageJsonField<K extends keyof PackageJson>(jsonContent: PackageJ
return;
}
const value = jsonContent[fieldName];
if (typeof value !== typeOfTag || value === null) { // eslint-disable-line no-null/no-null
if (typeof value !== typeOfTag || value === null) { // eslint-disable-line no-restricted-syntax
if (state.traceEnabled) {
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value);
}
return;
Expand Down Expand Up @@ -822,7 +822,7 @@ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: M
const packageJsonPath = combinePaths(root, normalized, "package.json");
// `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
// See `createNotNeededPackageJSON` in the types-publisher` repo.
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null;
if (!isNotNeededPackage) {
const baseFileName = getBaseFileName(normalized);
Expand Down Expand Up @@ -934,7 +934,7 @@ export interface PackageJsonInfoCache {
export type PerModuleNameCache = PerNonRelativeNameCache<ResolvedModuleWithFailedLookupLocations>;

function compilerOptionValueToString(value: unknown): string {
if (value === null || typeof value !== "object") { // eslint-disable-line no-null/no-null
if (value === null || typeof value !== "object") { // eslint-disable-line no-restricted-syntax
return "" + value;
}
if (isArray(value)) {
Expand Down Expand Up @@ -2276,7 +2276,7 @@ function loadEntrypointsFromExportMap(
loadEntrypointsFromTargetExports(target);
}
}
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
else if (typeof exports === "object" && exports !== null && allKeysStartWithDot(exports as MapLike<unknown>)) {
for (const key in exports) {
loadEntrypointsFromTargetExports((exports as MapLike<unknown>)[key]);
Expand Down Expand Up @@ -2331,7 +2331,7 @@ function loadEntrypointsFromExportMap(
}
}
}
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
else if (typeof target === "object" && target !== null) {
return forEach(getOwnKeys(target as MapLike<unknown>), key => {
if (key === "default" || contains(state.conditions, key) || isApplicableVersionedTypesKey(state.conditions, key)) {
Expand Down Expand Up @@ -2797,7 +2797,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
if (inputLink) return inputLink;
return toSearchResult(withPackageId(scope, loadFileNameFromPackageJsonField(extensions, finalPath, /*onlyRecordFailures*/ false, state), state));
}
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-restricted-syntax
if (!Array.isArray(target)) {
traceIfEnabled(state, Diagnostics.Entering_conditional_exports);
for (const condition of getOwnKeys(target as MapLike<unknown>)) {
Expand Down Expand Up @@ -2836,7 +2836,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
}
}
}
else if (target === null) { // eslint-disable-line no-null/no-null
else if (target === null) { // eslint-disable-line no-restricted-syntax
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_scope_0_explicitly_maps_specifier_1_to_null, scope.packageDirectory, moduleName);
}
Expand Down Expand Up @@ -3092,7 +3092,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
);
if (
!pathAndExtension && packageInfo
// eslint-disable-next-line no-null/no-null
// eslint-disable-next-line no-restricted-syntax
&& (packageInfo.contents.packageJsonContent.exports === undefined || packageInfo.contents.packageJsonContent.exports === null)
&& state.features & NodeResolutionFeatures.EsmMode
) {
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/moduleSpecifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ function tryGetModuleNameFromExportsOrImports(options: CompilerOptions, host: Mo
else if (Array.isArray(exports)) {
return forEach(exports, e => tryGetModuleNameFromExportsOrImports(options, host, targetFilePath, packageDirectory, packageName, e, conditions, mode, isImports));
}
else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-null/no-null
else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-restricted-syntax
// conditional mapping
for (const key of getOwnKeys(exports as MapLike<unknown>)) {
if (key === "default" || conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(conditions, key)) {
Expand All @@ -980,7 +980,7 @@ function tryGetModuleNameFromExportsOrImports(options: CompilerOptions, host: Mo
}

function tryGetModuleNameFromExports(options: CompilerOptions, host: ModuleSpecifierResolutionHost, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[]): { moduleFileToTry: string; } | undefined {
if (typeof exports === "object" && exports !== null && !Array.isArray(exports) && allKeysStartWithDot(exports as MapLike<unknown>)) { // eslint-disable-line no-null/no-null
if (typeof exports === "object" && exports !== null && !Array.isArray(exports) && allKeysStartWithDot(exports as MapLike<unknown>)) { // eslint-disable-line no-restricted-syntax
// sub-mappings
// 3 cases:
// * directory mappings (legacyish, key ends with / (technically allows index/extension resolution under cjs mode))
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10672,7 +10672,7 @@ function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, te

if (range.kind === SyntaxKind.MultiLineCommentTrivia) {
const multiLinePragmaRegEx = /@(\S+)(\s+.*)?$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
let multiLineMatch: RegExpExecArray | null;
let multiLineMatch: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch);
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3457,7 +3457,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg

function collectDynamicImportOrRequireOrJsDocImportCalls(file: SourceFile) {
const r = /import|require/g;
while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null
while (r.exec(file.text) !== null) { // eslint-disable-line no-restricted-syntax
const node = getNodeAtPosition(file, r.lastIndex);
if (isJavaScriptFile && isRequireCall(node, /*requireStringLiteralLikeArgument*/ true)) {
setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here
Expand Down
10 changes: 5 additions & 5 deletions src/compiler/sourcemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo
var rawSources: string[] = [];
var sources: string[] = [];
var sourceToSourceIndexMap = new Map<string, number>();
var sourcesContent: (string | null)[] | undefined;
var sourcesContent: (string | null)[] | undefined; // eslint-disable-line no-restricted-syntax

var names: string[] = [];
var nameToNameIndexMap: Map<string, number> | undefined;
Expand Down Expand Up @@ -98,7 +98,7 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo
return sourceIndex;
}

/* eslint-disable no-null/no-null */
/* eslint-disable no-restricted-syntax */
function setSourceContent(sourceIndex: number, content: string | null) {
enter();
if (content !== null) {
Expand All @@ -110,7 +110,7 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo
}
exit();
}
/* eslint-enable no-null/no-null */
/* eslint-enable no-restricted-syntax */

function addName(name: string) {
enter();
Expand Down Expand Up @@ -400,7 +400,7 @@ export function tryGetSourceMappingURL(lineInfo: LineInfo) {
}
}

/* eslint-disable no-null/no-null */
/* eslint-disable no-restricted-syntax */
function isStringOrNull(x: any) {
return typeof x === "string" || x === null;
}
Expand All @@ -417,7 +417,7 @@ export function isRawSourceMap(x: any): x is RawSourceMap {
&& (x.sourcesContent === undefined || x.sourcesContent === null || isArray(x.sourcesContent) && every(x.sourcesContent, isStringOrNull))
&& (x.names === undefined || x.names === null || isArray(x.names) && every(x.names, isString));
}
/* eslint-enable no-null/no-null */
/* eslint-enable no-restricted-syntax */

/** @internal */
export function tryParseRawSourceMap(text: string) {
Expand Down
Loading

0 comments on commit 17e420d

Please sign in to comment.