eslint-rule-forge 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,8 +5,7 @@ import {
5
5
  } from '@typescript-eslint/utils';
6
6
  import type { ReadonlyRecord } from 'ts-type-forge';
7
7
  import * as ts from 'typescript';
8
- import { hasForeignBinding } from '../bindings.mjs';
9
- import { bindValueImports } from '../imports.mjs';
8
+ import { bindValueImportsAt } from '../imports.mjs';
10
9
  import { getArgumentText } from '../parentheses.mjs';
11
10
  import {
12
11
  isIdentifierNamed,
@@ -142,7 +141,7 @@ const createSafeParseRule = <MessageId extends string>(
142
141
  schema: [],
143
142
  messages: {
144
143
  ...messages,
145
- replaceWithSafeParse: `Replace with \`Result.unwrapOkOr(${namespace}.${method}({{argName}}), Number.NaN)\`.`,
144
+ replaceWithSafeParse: `Replace with \`{{resultName}}.unwrapOkOr({{namespaceName}}.${method}({{argName}}), Number.NaN)\`.`,
146
145
  },
147
146
  defaultOptions: [],
148
147
  },
@@ -185,30 +184,39 @@ const createSafeParseRule = <MessageId extends string>(
185
184
  mut_reports.push({ node, argExpression: firstArg });
186
185
  },
187
186
  'Program:exit': () => {
188
- const binding = bindValueImports(
187
+ if (mut_reports.length === 0) {
188
+ return;
189
+ }
190
+
191
+ const bindingAt = bindValueImportsAt(
189
192
  sourceCode,
190
193
  moduleName,
191
194
  requiredImports,
192
195
  );
193
196
 
194
- const localNameOf = (name: string): string | undefined =>
195
- binding?.localNames[requiredImports.indexOf(name)];
196
-
197
- const namespaceName = localNameOf(namespace);
198
-
199
- const resultName = localNameOf('Result');
200
-
201
197
  // A suggestion, never an autofix: the replacement parses some
202
198
  // strings differently (`parseInt('1e3')` is 1, the rewrite 1000;
203
199
  // `parseFloat('12px')` is 12, the rewrite NaN; `Number('')` is 0, the
204
200
  // rewrite NaN), so applying it is a person's decision. Each one
205
201
  // brings its names into scope itself, so that it is complete alone.
206
202
  for (const { node, argExpression } of mut_reports) {
203
+ const binding = bindingAt(node);
204
+
205
+ const localNameOf = (name: string): string | undefined =>
206
+ binding?.localNames[requiredImports.indexOf(name)];
207
+
208
+ const namespaceName = localNameOf(namespace);
209
+
210
+ const resultName = localNameOf('Result');
211
+
207
212
  const argText = getArgumentText(sourceCode, argExpression);
208
213
 
209
214
  const data = {
210
215
  original: sourceCode.getText(node),
211
216
  argName: argText,
217
+ // The names the suggestion writes; with none, the exports' own.
218
+ namespaceName: namespaceName ?? namespace,
219
+ resultName: resultName ?? 'Result',
212
220
  } as const;
213
221
 
214
222
  context.report({
@@ -218,10 +226,7 @@ const createSafeParseRule = <MessageId extends string>(
218
226
  suggest:
219
227
  binding === undefined ||
220
228
  namespaceName === undefined ||
221
- resultName === undefined ||
222
- [namespaceName, resultName].some((name) =>
223
- hasForeignBinding(sourceCode, node, name, moduleName),
224
- )
229
+ resultName === undefined
225
230
  ? []
226
231
  : [
227
232
  {
@@ -244,12 +249,12 @@ const createSafeParseRule = <MessageId extends string>(
244
249
  } as const;
245
250
  };
246
251
 
247
- const messageText = ({
248
- moduleName,
249
- namespace,
250
- method,
251
- }: SafeParseRuleConfig): string =>
252
- `Replace \`{{original}}\` with \`Result.unwrapOkOr(${namespace}.${method}({{argName}}), Number.NaN)\` from ${moduleName}. It parses some strings differently from the call it replaces, so check the input before applying it.` as const;
252
+ /**
253
+ * The report's message. `{{namespaceName}}` and `{{resultName}}` are the names
254
+ * the suggestion writes.
255
+ */
256
+ const messageText = ({ moduleName, method }: SafeParseRuleConfig): string =>
257
+ `Replace \`{{original}}\` with \`{{resultName}}.unwrapOkOr({{namespaceName}}.${method}({{argName}}), Number.NaN)\` from ${moduleName}. It parses some strings differently from the call it replaces, so check the input before applying it.` as const;
253
258
 
254
259
  /** Whether `callee` is the global function `name`, as in `parseInt(...)`. */
255
260
  const isGlobalCall = (callee: TSESTree.Expression, name: string): boolean =>