ts-codemod-lib 4.0.0 → 4.1.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.
- package/README.md +2 -1
- package/dist/functions/ast-transformers/append-as-const.d.mts +9 -10
- package/dist/functions/ast-transformers/append-as-const.d.mts.map +1 -1
- package/dist/functions/ast-transformers/append-as-const.mjs +123 -114
- package/dist/functions/ast-transformers/append-as-const.mjs.map +1 -1
- package/dist/functions/ast-transformers/convert-to-readonly.d.mts +28 -7
- package/dist/functions/ast-transformers/convert-to-readonly.d.mts.map +1 -1
- package/dist/functions/ast-transformers/convert-to-readonly.mjs +452 -253
- package/dist/functions/ast-transformers/convert-to-readonly.mjs.map +1 -1
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.d.mts +8 -8
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs +103 -104
- package/dist/functions/ast-transformers/enable-no-unchecked-indexed-access.mjs.map +1 -1
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.d.mts +2 -2
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs +51 -51
- package/dist/functions/ast-transformers/replace-record-with-unknown-record.mjs.map +1 -1
- package/dist/functions/ast-transformers/transform-source-code.d.mts.map +1 -1
- package/dist/functions/ast-transformers/transform-source-code.mjs +69 -69
- package/dist/functions/ast-transformers/transform-source-code.mjs.map +1 -1
- package/dist/functions/constants/mutable-prefixes.d.mts +8 -8
- package/dist/functions/functions/has-disable-next-line-comment.mjs +23 -23
- package/dist/functions/functions/has-disable-next-line-comment.mjs.map +1 -1
- package/dist/functions/functions/is-readonly-node.d.mts +2 -2
- package/dist/functions/functions/is-readonly-node.d.mts.map +1 -1
- package/dist/functions/functions/is-readonly-node.mjs +13 -13
- package/dist/functions/functions/is-readonly-node.mjs.map +1 -1
- package/dist/functions/functions/wrap-with-parentheses.d.mts +2 -2
- package/dist/functions/functions/wrap-with-parentheses.d.mts.map +1 -1
- package/dist/functions/functions/wrap-with-parentheses.mjs +87 -32
- package/dist/functions/functions/wrap-with-parentheses.mjs.map +1 -1
- package/dist/functions/utils/replace-node-with-text.d.mts +10 -11
- package/dist/functions/utils/replace-node-with-text.d.mts.map +1 -1
- package/dist/functions/utils/replace-node-with-text.mjs +0 -1
- package/dist/functions/utils/replace-node-with-text.mjs.map +1 -1
- package/package.json +9 -9
- package/src/functions/ast-transformers/append-as-const.mts +242 -231
- package/src/functions/ast-transformers/append-as-const.test.mts +39 -6
- package/src/functions/ast-transformers/convert-to-readonly-record-import.test.mts +458 -0
- package/src/functions/ast-transformers/convert-to-readonly.mts +1003 -694
- package/src/functions/ast-transformers/convert-to-readonly.test.mts +80 -33
- package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.mts +178 -179
- package/src/functions/ast-transformers/enable-no-unchecked-indexed-access.test.mts +29 -29
- package/src/functions/ast-transformers/replace-any-with-unknown.test.mts +6 -6
- package/src/functions/ast-transformers/replace-record-with-unknown-record.mts +75 -75
- package/src/functions/ast-transformers/replace-record-with-unknown-record.test.mts +6 -6
- package/src/functions/ast-transformers/transform-source-code.mts +110 -110
- package/src/functions/ast-transformers/transformer-specific-ignore.test.mts +6 -6
- package/src/functions/constants/mutable-prefixes.mts +8 -8
- package/src/functions/functions/has-disable-next-line-comment.mts +35 -35
- package/src/functions/functions/is-readonly-node.mts +25 -25
- package/src/functions/functions/wrap-with-parentheses.mts +138 -52
- package/src/functions/functions/wrap-with-parentheses.test.mts +115 -0
- package/src/functions/utils/replace-node-with-text.mts +10 -11
|
@@ -5,6 +5,8 @@ import { hasCallOrConstructSignature, hasDisableNextLineComment, isAtomicTypeNod
|
|
|
5
5
|
import { replaceNodeWithDebugPrint, replaceNodeWithText, } from '../utils/index.mjs';
|
|
6
6
|
import { groupUnionIntersectionTypes, invalidDeepReadonlyTypeName, isMergeableReadonlyTypeReferenceNode, nextReadonlyContext, } from './readonly-transformer-helpers/index.mjs';
|
|
7
7
|
const TRANSFORMER_NAME = 'convert-to-readonly';
|
|
8
|
+
const READONLY_RECORD_NAME = 'ReadonlyRecord';
|
|
9
|
+
const READONLY_RECORD_MODULE = 'ts-type-forge';
|
|
8
10
|
export const convertToReadonlyTransformer = (options) => {
|
|
9
11
|
if (options?.DeepReadonly?.typeName !== undefined &&
|
|
10
12
|
invalidDeepReadonlyTypeName.has(options.DeepReadonly.typeName)) {
|
|
@@ -27,6 +29,7 @@ export const convertToReadonlyTransformer = (options) => {
|
|
|
27
29
|
mutableTypePrefixes: ISet.create(options?.mutableTypePrefixes ?? DEFAULT_MUTABLE_TYPE_PREFIXES),
|
|
28
30
|
mutablePropertyPrefixes: ISet.create(options?.mutablePropertyPrefixes ?? DEFAULT_MUTABLE_PREFIXES),
|
|
29
31
|
recordStyle: options?.recordStyle ?? 'ReadonlyRecord',
|
|
32
|
+
importStyle: options?.importStyle ?? 'named',
|
|
30
33
|
debugPrint: options?.debug === true ? console.debug : () => { },
|
|
31
34
|
replaceNode: options?.debug === true
|
|
32
35
|
? replaceNodeWithDebugPrint
|
|
@@ -35,8 +38,23 @@ export const convertToReadonlyTransformer = (options) => {
|
|
|
35
38
|
return {
|
|
36
39
|
name: TRANSFORMER_NAME,
|
|
37
40
|
transform: (sourceAst) => {
|
|
41
|
+
const scope = optionsInternal.recordStyle === 'ReadonlyRecord' &&
|
|
42
|
+
optionsInternal.importStyle === 'named'
|
|
43
|
+
? readonlyRecordScope(sourceAst.compilerNode)
|
|
44
|
+
: 'in-scope';
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
const mayImport = scope === 'free' && tsm.ts.isExternalModule(sourceAst.compilerNode);
|
|
50
|
+
const fileOptions = scope !== 'in-scope' && !mayImport
|
|
51
|
+
? { ...optionsInternal, recordStyle: 'Readonly<Record>' }
|
|
52
|
+
: optionsInternal;
|
|
38
53
|
for (const node of sourceAst.getChildren()) {
|
|
39
|
-
transformNode(node, initialReadonlyContext,
|
|
54
|
+
transformNode(node, initialReadonlyContext, fileOptions);
|
|
55
|
+
}
|
|
56
|
+
if (mayImport && referencesReadonlyRecord(sourceAst.compilerNode)) {
|
|
57
|
+
addReadonlyRecordImport(sourceAst);
|
|
40
58
|
}
|
|
41
59
|
},
|
|
42
60
|
};
|
|
@@ -45,6 +63,18 @@ const initialReadonlyContext = {
|
|
|
45
63
|
type: 'none',
|
|
46
64
|
indexedAccessDepth: 0,
|
|
47
65
|
};
|
|
66
|
+
|
|
67
|
+
const hasMutableTypeName = (name, options) => name !== undefined &&
|
|
68
|
+
options.mutableTypePrefixes.some((p) => name.startsWith(p));
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
const mutablePrefixesOfParameter = (
|
|
74
|
+
|
|
75
|
+
param, options) => param.isParameterProperty()
|
|
76
|
+
? options.mutablePropertyPrefixes
|
|
77
|
+
: options.mutableVariablePrefixes;
|
|
48
78
|
const transformNode = (node, readonlyContext, options) => {
|
|
49
79
|
if (tsm.Node.isTypeNode(node) ||
|
|
50
80
|
node.isKind(tsm.SyntaxKind.InterfaceDeclaration) ||
|
|
@@ -198,6 +228,322 @@ const transformNode = (node, readonlyContext, options) => {
|
|
|
198
228
|
|
|
199
229
|
|
|
200
230
|
|
|
231
|
+
const topLevelBindings = (
|
|
232
|
+
|
|
233
|
+
statement) => {
|
|
234
|
+
if (tsm.ts.isImportDeclaration(statement)) {
|
|
235
|
+
const clause = statement.importClause;
|
|
236
|
+
const bindings = clause?.namedBindings;
|
|
237
|
+
|
|
238
|
+
const namespaceImport = bindings !== undefined && tsm.ts.isNamespaceImport(bindings)
|
|
239
|
+
? [{ name: bindings.name.text, isType: false }]
|
|
240
|
+
: [];
|
|
241
|
+
const named = bindings !== undefined && tsm.ts.isNamedImports(bindings)
|
|
242
|
+
? bindings.elements.map((element) => ({
|
|
243
|
+
name: element.name.text,
|
|
244
|
+
isType: true,
|
|
245
|
+
}))
|
|
246
|
+
: [];
|
|
247
|
+
const defaultImport = clause?.name === undefined
|
|
248
|
+
? []
|
|
249
|
+
: [{ name: clause.name.text, isType: true }];
|
|
250
|
+
return [...defaultImport, ...namespaceImport, ...named];
|
|
251
|
+
}
|
|
252
|
+
if (tsm.ts.isImportEqualsDeclaration(statement)) {
|
|
253
|
+
return [{ name: statement.name.text, isType: true }];
|
|
254
|
+
}
|
|
255
|
+
if (tsm.ts.isTypeAliasDeclaration(statement) ||
|
|
256
|
+
tsm.ts.isInterfaceDeclaration(statement) ||
|
|
257
|
+
tsm.ts.isClassDeclaration(statement) ||
|
|
258
|
+
tsm.ts.isEnumDeclaration(statement)) {
|
|
259
|
+
return statement.name === undefined
|
|
260
|
+
? []
|
|
261
|
+
: [{ name: statement.name.text, isType: true }];
|
|
262
|
+
}
|
|
263
|
+
if ((tsm.ts.isFunctionDeclaration(statement) ||
|
|
264
|
+
tsm.ts.isModuleDeclaration(statement)) &&
|
|
265
|
+
statement.name !== undefined &&
|
|
266
|
+
tsm.ts.isIdentifier(statement.name)) {
|
|
267
|
+
return [{ name: statement.name.text, isType: false }];
|
|
268
|
+
}
|
|
269
|
+
if (tsm.ts.isVariableStatement(statement)) {
|
|
270
|
+
return statement.declarationList.declarations.flatMap((declaration) => tsm.ts.isIdentifier(declaration.name)
|
|
271
|
+
? [{ name: declaration.name.text, isType: false }]
|
|
272
|
+
: []);
|
|
273
|
+
}
|
|
274
|
+
return [];
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
const referencesReadonlyRecord = (node) => (tsm.ts.isTypeReferenceNode(node) &&
|
|
281
|
+
tsm.ts.isIdentifier(node.typeName) &&
|
|
282
|
+
node.typeName.text === READONLY_RECORD_NAME) ||
|
|
283
|
+
(tsm.ts.isExpressionWithTypeArguments(node) &&
|
|
284
|
+
tsm.ts.isIdentifier(node.expression) &&
|
|
285
|
+
node.expression.text === READONLY_RECORD_NAME) ||
|
|
286
|
+
(tsm.ts.forEachChild(node, (child) => referencesReadonlyRecord(child) || undefined) ??
|
|
287
|
+
false);
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
const readonlyRecordScope = (
|
|
303
|
+
|
|
304
|
+
sourceFile) => {
|
|
305
|
+
const topLevelNames = sourceFile.statements.flatMap(topLevelBindings);
|
|
306
|
+
return topLevelNames.some(({ name, isType }) => isType && name === READONLY_RECORD_NAME) || referencesReadonlyRecord(sourceFile)
|
|
307
|
+
? 'in-scope'
|
|
308
|
+
: topLevelNames.some(({ name }) => name === READONLY_RECORD_NAME)
|
|
309
|
+
? 'taken'
|
|
310
|
+
: 'free';
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
const endOfLineComments = (text, end) => tsm.ts.getTrailingCommentRanges(text, end)?.at(-1)?.end ?? end;
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
const newImportPosition = (
|
|
328
|
+
|
|
329
|
+
sourceFile) => {
|
|
330
|
+
const text = sourceFile.getFullText();
|
|
331
|
+
const first = sourceFile.getStatements().at(0);
|
|
332
|
+
if (first === undefined) {
|
|
333
|
+
return text.length;
|
|
334
|
+
}
|
|
335
|
+
const comments = tsm.ts.getLeadingCommentRanges(text, first.getFullStart()) ?? [];
|
|
336
|
+
let mut_position = first.getStart();
|
|
337
|
+
for (const comment of comments.toReversed()) {
|
|
338
|
+
const commentText = text.slice(comment.pos, comment.end);
|
|
339
|
+
if (/\n[^\S\n]*\n/u.test(text.slice(comment.end, mut_position)) ||
|
|
340
|
+
commentText.startsWith('///') ||
|
|
341
|
+
(commentText.startsWith('/*') && !commentText.startsWith('/**')) ||
|
|
342
|
+
/@(?:ts-nocheck|ts-check|jsx)/u.test(commentText)) {
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
mut_position = comment.pos;
|
|
346
|
+
}
|
|
347
|
+
return mut_position;
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
const directivePrologue = (
|
|
351
|
+
|
|
352
|
+
sourceFile) => {
|
|
353
|
+
const statements = sourceFile.compilerNode.statements;
|
|
354
|
+
const end = statements.findIndex((statement) => !(tsm.ts.isExpressionStatement(statement) &&
|
|
355
|
+
tsm.ts.isStringLiteral(statement.expression)));
|
|
356
|
+
return statements.slice(0, end === -1 ? statements.length : end);
|
|
357
|
+
};
|
|
358
|
+
const insertReadonlyRecordImport = (
|
|
359
|
+
|
|
360
|
+
sourceFile, text) => {
|
|
361
|
+
const imports = sourceFile.getImportDeclarations();
|
|
362
|
+
const hosts = imports.filter((decl) => decl.getModuleSpecifierValue() === READONLY_RECORD_MODULE &&
|
|
363
|
+
tsm.Node.isNamedImports(decl.getImportClause()?.getNamedBindings()));
|
|
364
|
+
const host = hosts.find((decl) => decl.isTypeOnly()) ?? hosts.at(0);
|
|
365
|
+
if (host !== undefined) {
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
host.addNamedImport({
|
|
369
|
+
name: READONLY_RECORD_NAME,
|
|
370
|
+
isTypeOnly: !host.isTypeOnly(),
|
|
371
|
+
});
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
const declaration = `import type { ${READONLY_RECORD_NAME} } from '${READONLY_RECORD_MODULE}';`;
|
|
377
|
+
const anchorEnd = imports.at(-1)?.getEnd() ?? directivePrologue(sourceFile).at(-1)?.end;
|
|
378
|
+
if (anchorEnd === undefined) {
|
|
379
|
+
sourceFile.insertText(newImportPosition(sourceFile), `${declaration}\n\n`);
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
sourceFile.insertText(endOfLineComments(text, anchorEnd), `\n${declaration}`);
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
const addReadonlyRecordImport = (
|
|
393
|
+
|
|
394
|
+
sourceFile) => {
|
|
395
|
+
const text = sourceFile.getFullText();
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
const { manipulationSettings } = sourceFile.getProject();
|
|
399
|
+
const newLineKind = manipulationSettings.getNewLineKind();
|
|
400
|
+
manipulationSettings.set({
|
|
401
|
+
newLineKind: text.includes('\r\n')
|
|
402
|
+
? tsm.NewLineKind.CarriageReturnLineFeed
|
|
403
|
+
: tsm.NewLineKind.LineFeed,
|
|
404
|
+
});
|
|
405
|
+
try {
|
|
406
|
+
insertReadonlyRecordImport(sourceFile, text);
|
|
407
|
+
}
|
|
408
|
+
finally {
|
|
409
|
+
manipulationSettings.set({ newLineKind });
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
const readonlyRecordText = (keyText, valueText, options) => options.recordStyle === 'ReadonlyRecord'
|
|
417
|
+
? `ReadonlyRecord<${keyText}, ${valueText}>`
|
|
418
|
+
: `Readonly<Record<${keyText}, ${valueText}>>`;
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
const commentsBetween = (
|
|
425
|
+
|
|
426
|
+
sourceFile, from, to) => {
|
|
427
|
+
if (to <= from) {
|
|
428
|
+
return '';
|
|
429
|
+
}
|
|
430
|
+
const scanner = tsm.ts.createScanner(tsm.ts.ScriptTarget.Latest, false, tsm.ts.LanguageVariant.Standard, sourceFile.getFullText(), undefined, from, to - from);
|
|
431
|
+
const mut_comments = [];
|
|
432
|
+
while (scanner.scan() !== tsm.ts.SyntaxKind.EndOfFileToken) {
|
|
433
|
+
const token = scanner.getToken();
|
|
434
|
+
|
|
435
|
+
const separator = token === tsm.ts.SyntaxKind.SingleLineCommentTrivia
|
|
436
|
+
? '\n'
|
|
437
|
+
: token === tsm.ts.SyntaxKind.MultiLineCommentTrivia
|
|
438
|
+
? ' '
|
|
439
|
+
: undefined;
|
|
440
|
+
if (separator !== undefined) {
|
|
441
|
+
mut_comments.push(`${scanner.getTokenText()}${separator}`);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return mut_comments.join('');
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
const getDeepReadonlyTypeArg = (
|
|
448
|
+
|
|
449
|
+
node, deepReadonlyTypeName) => {
|
|
450
|
+
if (!node.isKind(tsm.SyntaxKind.TypeReference)) {
|
|
451
|
+
return undefined;
|
|
452
|
+
}
|
|
453
|
+
const typeName = node.getTypeName();
|
|
454
|
+
const typeArguments = node.getTypeArguments();
|
|
455
|
+
return typeName.isKind(tsm.SyntaxKind.Identifier) &&
|
|
456
|
+
typeName.getText() === deepReadonlyTypeName &&
|
|
457
|
+
Arr.isFixedLengthArray(1, typeArguments)
|
|
458
|
+
? typeArguments[0]
|
|
459
|
+
: undefined;
|
|
460
|
+
};
|
|
461
|
+
const checkIfPropertyNameShouldBeIgnored = (
|
|
462
|
+
|
|
463
|
+
nameNode, options) => {
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
return (
|
|
467
|
+
|
|
468
|
+
(nameNode.isKind(tsm.SyntaxKind.Identifier) &&
|
|
469
|
+
pipe(nameNode.getText()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p))).value) ||
|
|
470
|
+
|
|
471
|
+
(nameNode.isKind(tsm.SyntaxKind.StringLiteral) &&
|
|
472
|
+
pipe(nameNode.getLiteralValue()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p))).value) ||
|
|
473
|
+
|
|
474
|
+
(nameNode.isKind(tsm.SyntaxKind.PrivateIdentifier) &&
|
|
475
|
+
pipe(nameNode.getText()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p) || nm.startsWith(`#${p}`))).value) ||
|
|
476
|
+
|
|
477
|
+
(nameNode.isKind(tsm.SyntaxKind.ComputedPropertyName) &&
|
|
478
|
+
pipe(nameNode.getExpression()).map((exp) => {
|
|
479
|
+
if (exp.isKind(tsm.SyntaxKind.StringLiteral) ||
|
|
480
|
+
exp.isKind(tsm.SyntaxKind.NoSubstitutionTemplateLiteral)) {
|
|
481
|
+
const nm = exp.getLiteralValue();
|
|
482
|
+
return options.mutablePropertyPrefixes.some((p) => nm.startsWith(p));
|
|
483
|
+
}
|
|
484
|
+
return false;
|
|
485
|
+
}).value));
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
const isLeftUnwrapped = (
|
|
503
|
+
|
|
504
|
+
node, options) => {
|
|
505
|
+
const members = node.getMembers();
|
|
506
|
+
const isMethodOrAccessor = (
|
|
507
|
+
|
|
508
|
+
mb) => mb.isKind(tsm.SyntaxKind.MethodSignature) ||
|
|
509
|
+
mb.isKind(tsm.SyntaxKind.GetAccessor) ||
|
|
510
|
+
mb.isKind(tsm.SyntaxKind.SetAccessor);
|
|
511
|
+
const isIgnoredMember = (
|
|
512
|
+
|
|
513
|
+
mb) => (mb.isKind(tsm.SyntaxKind.PropertySignature) || isMethodOrAccessor(mb)) &&
|
|
514
|
+
checkIfPropertyNameShouldBeIgnored(mb.getNameNode(), options);
|
|
515
|
+
const needsReadonlyWrapper = (
|
|
516
|
+
|
|
517
|
+
mb) => !isIgnoredMember(mb) &&
|
|
518
|
+
(isMethodOrAccessor(mb) ||
|
|
519
|
+
((mb.isKind(tsm.SyntaxKind.PropertySignature) ||
|
|
520
|
+
mb.isKind(tsm.SyntaxKind.IndexSignature)) &&
|
|
521
|
+
!mb.hasModifier(tsm.SyntaxKind.ReadonlyKeyword) &&
|
|
522
|
+
hasDisableNextLineComment(mb)));
|
|
523
|
+
return members.some(isIgnoredMember) && !members.some(needsReadonlyWrapper);
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
const hasDisableNextLineCommentAround = (node) => {
|
|
527
|
+
if (hasDisableNextLineComment(node, TRANSFORMER_NAME)) {
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
const parent = node.getParent();
|
|
531
|
+
return (parent?.isKind(tsm.SyntaxKind.ParenthesizedType) === true &&
|
|
532
|
+
hasDisableNextLineCommentAround(parent));
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
const takesOffReadonly = (
|
|
542
|
+
|
|
543
|
+
node, options) => isLeftUnwrapped(node, options) &&
|
|
544
|
+
!hasCallOrConstructSignature(node) &&
|
|
545
|
+
!hasDisableNextLineCommentAround(node);
|
|
546
|
+
|
|
201
547
|
|
|
202
548
|
|
|
203
549
|
|
|
@@ -520,10 +866,6 @@ node, readonlyContext, options) => {
|
|
|
520
866
|
}
|
|
521
867
|
};
|
|
522
868
|
|
|
523
|
-
const readonlyRecordText = (keyText, valueText, options) => options.recordStyle === 'ReadonlyRecord'
|
|
524
|
-
? `ReadonlyRecord<${keyText}, ${valueText}>`
|
|
525
|
-
: `Readonly<Record<${keyText}, ${valueText}>>`;
|
|
526
|
-
|
|
527
869
|
const transformArrayTypeNode = (
|
|
528
870
|
|
|
529
871
|
node, readonlyContext, options) => {
|
|
@@ -828,104 +1170,6 @@ const transformUnionTypeNode = (
|
|
|
828
1170
|
node, readonlyContext, options) => {
|
|
829
1171
|
transformUnionOrIntersectionTypeNodeImpl(node, readonlyContext, options, '|');
|
|
830
1172
|
};
|
|
831
|
-
const transformUnionOrIntersectionTypeNodeImpl = (
|
|
832
|
-
|
|
833
|
-
node, readonlyContext, options, operator) => {
|
|
834
|
-
const nextReadonlyContextValue = nextReadonlyContext({
|
|
835
|
-
currentReadonlyContext: readonlyContext,
|
|
836
|
-
nextReadonlyContextType: 'none',
|
|
837
|
-
indexedAccessDepthChange: 'keep',
|
|
838
|
-
});
|
|
839
|
-
|
|
840
|
-
for (const n of node.getTypeNodes() ) {
|
|
841
|
-
transformNode(n, nextReadonlyContextValue, options);
|
|
842
|
-
}
|
|
843
|
-
const newTypes = node.getTypeNodes();
|
|
844
|
-
const withLeadingComments = (
|
|
845
|
-
|
|
846
|
-
member, memberText) => `${leadingCommentsOfMember(node, member)}${memberText}`;
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
const wrapsTypeLiterals = nextReadonlyContextValue.type !== 'DeepReadonly' &&
|
|
850
|
-
nextReadonlyContextValue.indexedAccessDepth === 0;
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
const underReadonly = readonlyContext.type === 'Readonly' &&
|
|
854
|
-
readonlyContext.indexedAccessDepth === 0 &&
|
|
855
|
-
isTypeArgumentOfReadonly(node);
|
|
856
|
-
const { primitives, arraysAndTuples, typeLiterals, others } = groupUnionIntersectionTypes(newTypes, {
|
|
857
|
-
operator,
|
|
858
|
-
underReadonly,
|
|
859
|
-
deepReadonlyTypeName: options.DeepReadonly.typeName,
|
|
860
|
-
keptUnwrapped: (t) => wrapsTypeLiterals && takesOffReadonly(t, options),
|
|
861
|
-
});
|
|
862
|
-
options.debugPrint({ primitives, arraysAndTuples, typeLiterals, others });
|
|
863
|
-
|
|
864
|
-
const isEmptyTypeLiteral = (
|
|
865
|
-
|
|
866
|
-
n) => n.isKind(tsm.SyntaxKind.TypeLiteral) && Arr.isEmpty(n.getMembers());
|
|
867
|
-
const nonEmptyTypeLiterals = typeLiterals === undefined
|
|
868
|
-
? undefined
|
|
869
|
-
: options.ignoreEmptyObjectTypes
|
|
870
|
-
? typeLiterals.nodes.filter((n) => !isEmptyTypeLiteral(n))
|
|
871
|
-
: typeLiterals.nodes;
|
|
872
|
-
const emptyTypeLiterals = typeLiterals === undefined || !options.ignoreEmptyObjectTypes
|
|
873
|
-
? undefined
|
|
874
|
-
: typeLiterals.nodes.filter(isEmptyTypeLiteral);
|
|
875
|
-
const typeLiteralsWrappedWithReadonly = nonEmptyTypeLiterals === undefined || Arr.isEmpty(nonEmptyTypeLiterals)
|
|
876
|
-
? []
|
|
877
|
-
: [
|
|
878
|
-
unionToString({
|
|
879
|
-
types: nonEmptyTypeLiterals.map((n) => withLeadingComments(n, isMergeableReadonlyTypeReferenceNode(n, operator)
|
|
880
|
-
?
|
|
881
|
-
|
|
882
|
-
readonlyTypeArgTextSplicedInto(n, operator)
|
|
883
|
-
: n.isKind(tsm.SyntaxKind.TypeLiteral)
|
|
884
|
-
? n.getText()
|
|
885
|
-
:
|
|
886
|
-
wrapWithParentheses(n.getText()))),
|
|
887
|
-
op: operator,
|
|
888
|
-
wrapWithReadonly: wrapsTypeLiterals,
|
|
889
|
-
}),
|
|
890
|
-
];
|
|
891
|
-
|
|
892
|
-
const sorted = [
|
|
893
|
-
mapNullable(primitives, (a) => [
|
|
894
|
-
a.nodes.map((n) => withLeadingComments(n, n.getText())),
|
|
895
|
-
a.firstPosition,
|
|
896
|
-
]),
|
|
897
|
-
mapNullable(arraysAndTuples, (a) => [
|
|
898
|
-
a.nodes.map((n) => withLeadingComments(n, n.getText())),
|
|
899
|
-
a.firstPosition,
|
|
900
|
-
]),
|
|
901
|
-
nonEmptyTypeLiterals !== undefined && Arr.isNonEmpty(nonEmptyTypeLiterals)
|
|
902
|
-
? mapNullable(typeLiterals, (a) => [typeLiteralsWrappedWithReadonly, a.firstPosition])
|
|
903
|
-
: undefined,
|
|
904
|
-
emptyTypeLiterals !== undefined && Arr.isNonEmpty(emptyTypeLiterals)
|
|
905
|
-
? mapNullable(typeLiterals, (a) => [
|
|
906
|
-
emptyTypeLiterals.map((n) => withLeadingComments(n, n.getText())),
|
|
907
|
-
|
|
908
|
-
a.firstPosition +
|
|
909
|
-
(nonEmptyTypeLiterals !== undefined &&
|
|
910
|
-
Arr.isNonEmpty(nonEmptyTypeLiterals)
|
|
911
|
-
? 0.5
|
|
912
|
-
: 0),
|
|
913
|
-
])
|
|
914
|
-
: undefined,
|
|
915
|
-
mapNullable(others, (a) => [
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
operator === '|'
|
|
919
|
-
? mergeDeepReadonlyUnionMembers(a.nodes, options.DeepReadonly.typeName, withLeadingComments)
|
|
920
|
-
: a.nodes.map((n) => withLeadingComments(n, wrapWithParentheses(n.getText()))),
|
|
921
|
-
a.firstPosition,
|
|
922
|
-
]),
|
|
923
|
-
]
|
|
924
|
-
.filter((x) => x !== undefined)
|
|
925
|
-
.toSorted((a, b) => a[1] - b[1])
|
|
926
|
-
.flatMap((a) => a[0]);
|
|
927
|
-
|
|
928
|
-
|
|
929
1173
|
|
|
930
1174
|
|
|
931
1175
|
|
|
@@ -934,14 +1178,28 @@ node, readonlyContext, options, operator) => {
|
|
|
934
1178
|
|
|
935
1179
|
|
|
936
1180
|
|
|
1181
|
+
const textWithoutParentheses = (
|
|
937
1182
|
|
|
1183
|
+
outer,
|
|
938
1184
|
|
|
1185
|
+
inner) => `${commentsBetween(outer.getSourceFile(), outer.getPos(), inner.getStart())}${inner.getText()}`;
|
|
1186
|
+
const unionToStringImpl = ({ types, op, wrapWithReadonly, }) => Arr.isEmpty(types)
|
|
1187
|
+
? 'never'
|
|
1188
|
+
: Arr.isFixedLengthArray(1, types)
|
|
1189
|
+
? wrapWithReadonly === false
|
|
1190
|
+
? wrapWithParentheses(types[0])
|
|
1191
|
+
: `${isString(wrapWithReadonly) ? wrapWithReadonly : 'Readonly'}<${types[0]}>`
|
|
1192
|
+
: wrapWithReadonly === false
|
|
1193
|
+
? wrapWithParentheses(types.join(` ${op} `))
|
|
1194
|
+
: `${isString(wrapWithReadonly) ? wrapWithReadonly : 'Readonly'}<${types.join(` ${op} `)}>`;
|
|
1195
|
+
const unionToString = ({ types: typesRaw, op, wrapWithReadonly, }) => {
|
|
939
1196
|
|
|
940
1197
|
|
|
941
1198
|
|
|
942
1199
|
|
|
943
1200
|
|
|
944
|
-
|
|
1201
|
+
const types = typesRaw.map((s) => s.trim());
|
|
1202
|
+
return unionToStringImpl({ types, op, wrapWithReadonly });
|
|
945
1203
|
};
|
|
946
1204
|
|
|
947
1205
|
|
|
@@ -1061,79 +1319,121 @@ node, operator) => {
|
|
|
1061
1319
|
? textWithoutParentheses(typeArgument, T)
|
|
1062
1320
|
: unwrapReadonlyTypeArgText(node);
|
|
1063
1321
|
};
|
|
1322
|
+
const transformUnionOrIntersectionTypeNodeImpl = (
|
|
1064
1323
|
|
|
1324
|
+
node, readonlyContext, options, operator) => {
|
|
1325
|
+
const nextReadonlyContextValue = nextReadonlyContext({
|
|
1326
|
+
currentReadonlyContext: readonlyContext,
|
|
1327
|
+
nextReadonlyContextType: 'none',
|
|
1328
|
+
indexedAccessDepthChange: 'keep',
|
|
1329
|
+
});
|
|
1065
1330
|
|
|
1331
|
+
for (const n of node.getTypeNodes() ) {
|
|
1332
|
+
transformNode(n, nextReadonlyContextValue, options);
|
|
1333
|
+
}
|
|
1334
|
+
const newTypes = node.getTypeNodes();
|
|
1335
|
+
const withLeadingComments = (
|
|
1066
1336
|
|
|
1337
|
+
member, memberText) => `${leadingCommentsOfMember(node, member)}${memberText}`;
|
|
1067
1338
|
|
|
1068
1339
|
|
|
1340
|
+
const wrapsTypeLiterals = nextReadonlyContextValue.type !== 'DeepReadonly' &&
|
|
1341
|
+
nextReadonlyContextValue.indexedAccessDepth === 0;
|
|
1069
1342
|
|
|
1070
1343
|
|
|
1344
|
+
const underReadonly = readonlyContext.type === 'Readonly' &&
|
|
1345
|
+
readonlyContext.indexedAccessDepth === 0 &&
|
|
1346
|
+
isTypeArgumentOfReadonly(node);
|
|
1347
|
+
const { primitives, arraysAndTuples, typeLiterals, others } = groupUnionIntersectionTypes(newTypes, {
|
|
1348
|
+
operator,
|
|
1349
|
+
underReadonly,
|
|
1350
|
+
deepReadonlyTypeName: options.DeepReadonly.typeName,
|
|
1351
|
+
keptUnwrapped: (t) => wrapsTypeLiterals && takesOffReadonly(t, options),
|
|
1352
|
+
});
|
|
1353
|
+
options.debugPrint({ primitives, arraysAndTuples, typeLiterals, others });
|
|
1071
1354
|
|
|
1072
|
-
const
|
|
1355
|
+
const isEmptyTypeLiteral = (
|
|
1073
1356
|
|
|
1074
|
-
|
|
1357
|
+
n) => n.isKind(tsm.SyntaxKind.TypeLiteral) && Arr.isEmpty(n.getMembers());
|
|
1358
|
+
const nonEmptyTypeLiterals = typeLiterals === undefined
|
|
1359
|
+
? undefined
|
|
1360
|
+
: options.ignoreEmptyObjectTypes
|
|
1361
|
+
? typeLiterals.nodes.filter((n) => !isEmptyTypeLiteral(n))
|
|
1362
|
+
: typeLiterals.nodes;
|
|
1363
|
+
const emptyTypeLiterals = typeLiterals === undefined || !options.ignoreEmptyObjectTypes
|
|
1364
|
+
? undefined
|
|
1365
|
+
: typeLiterals.nodes.filter(isEmptyTypeLiteral);
|
|
1366
|
+
const typeLiteralsWrappedWithReadonly = nonEmptyTypeLiterals === undefined || Arr.isEmpty(nonEmptyTypeLiterals)
|
|
1367
|
+
? []
|
|
1368
|
+
: [
|
|
1369
|
+
unionToString({
|
|
1370
|
+
types: nonEmptyTypeLiterals.map((n) => withLeadingComments(n, isMergeableReadonlyTypeReferenceNode(n, operator)
|
|
1371
|
+
?
|
|
1075
1372
|
|
|
1076
|
-
|
|
1373
|
+
readonlyTypeArgTextSplicedInto(n, operator)
|
|
1374
|
+
: n.isKind(tsm.SyntaxKind.TypeLiteral)
|
|
1375
|
+
? n.getText()
|
|
1376
|
+
:
|
|
1377
|
+
wrapWithParentheses(n.getText()))),
|
|
1378
|
+
op: operator,
|
|
1379
|
+
wrapWithReadonly: wrapsTypeLiterals,
|
|
1380
|
+
}),
|
|
1381
|
+
];
|
|
1382
|
+
|
|
1383
|
+
const sorted = [
|
|
1384
|
+
mapNullable(primitives, (a) => [
|
|
1385
|
+
a.nodes.map((n) => withLeadingComments(n, n.getText())),
|
|
1386
|
+
a.firstPosition,
|
|
1387
|
+
]),
|
|
1388
|
+
mapNullable(arraysAndTuples, (a) => [
|
|
1389
|
+
a.nodes.map((n) => withLeadingComments(n, n.getText())),
|
|
1390
|
+
a.firstPosition,
|
|
1391
|
+
]),
|
|
1392
|
+
nonEmptyTypeLiterals !== undefined && Arr.isNonEmpty(nonEmptyTypeLiterals)
|
|
1393
|
+
? mapNullable(typeLiterals, (a) => [typeLiteralsWrappedWithReadonly, a.firstPosition])
|
|
1394
|
+
: undefined,
|
|
1395
|
+
emptyTypeLiterals !== undefined && Arr.isNonEmpty(emptyTypeLiterals)
|
|
1396
|
+
? mapNullable(typeLiterals, (a) => [
|
|
1397
|
+
emptyTypeLiterals.map((n) => withLeadingComments(n, n.getText())),
|
|
1398
|
+
|
|
1399
|
+
a.firstPosition +
|
|
1400
|
+
(nonEmptyTypeLiterals !== undefined &&
|
|
1401
|
+
Arr.isNonEmpty(nonEmptyTypeLiterals)
|
|
1402
|
+
? 0.5
|
|
1403
|
+
: 0),
|
|
1404
|
+
])
|
|
1405
|
+
: undefined,
|
|
1406
|
+
mapNullable(others, (a) => [
|
|
1077
1407
|
|
|
1078
1408
|
|
|
1409
|
+
operator === '|'
|
|
1410
|
+
? mergeDeepReadonlyUnionMembers(a.nodes, options.DeepReadonly.typeName, withLeadingComments)
|
|
1411
|
+
: a.nodes.map((n) => withLeadingComments(n, wrapWithParentheses(n.getText()))),
|
|
1412
|
+
a.firstPosition,
|
|
1413
|
+
]),
|
|
1414
|
+
]
|
|
1415
|
+
.filter((x) => x !== undefined)
|
|
1416
|
+
.toSorted((a, b) => a[1] - b[1])
|
|
1417
|
+
.flatMap((a) => a[0]);
|
|
1079
1418
|
|
|
1080
1419
|
|
|
1081
1420
|
|
|
1082
|
-
const commentsBetween = (
|
|
1083
1421
|
|
|
1084
|
-
sourceFile, from, to) => {
|
|
1085
|
-
if (to <= from) {
|
|
1086
|
-
return '';
|
|
1087
|
-
}
|
|
1088
|
-
const scanner = tsm.ts.createScanner(tsm.ts.ScriptTarget.Latest, false, tsm.ts.LanguageVariant.Standard, sourceFile.getFullText(), undefined, from, to - from);
|
|
1089
|
-
const mut_comments = [];
|
|
1090
|
-
while (scanner.scan() !== tsm.ts.SyntaxKind.EndOfFileToken) {
|
|
1091
|
-
const token = scanner.getToken();
|
|
1092
1422
|
|
|
1093
|
-
const separator = token === tsm.ts.SyntaxKind.SingleLineCommentTrivia
|
|
1094
|
-
? '\n'
|
|
1095
|
-
: token === tsm.ts.SyntaxKind.MultiLineCommentTrivia
|
|
1096
|
-
? ' '
|
|
1097
|
-
: undefined;
|
|
1098
|
-
if (separator !== undefined) {
|
|
1099
|
-
mut_comments.push(`${scanner.getTokenText()}${separator}`);
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
return mut_comments.join('');
|
|
1103
|
-
};
|
|
1104
1423
|
|
|
1105
|
-
const getDeepReadonlyTypeArg = (
|
|
1106
1424
|
|
|
1107
|
-
node, deepReadonlyTypeName) => {
|
|
1108
|
-
if (!node.isKind(tsm.SyntaxKind.TypeReference)) {
|
|
1109
|
-
return undefined;
|
|
1110
|
-
}
|
|
1111
|
-
const typeName = node.getTypeName();
|
|
1112
|
-
const typeArguments = node.getTypeArguments();
|
|
1113
|
-
return typeName.isKind(tsm.SyntaxKind.Identifier) &&
|
|
1114
|
-
typeName.getText() === deepReadonlyTypeName &&
|
|
1115
|
-
Arr.isFixedLengthArray(1, typeArguments)
|
|
1116
|
-
? typeArguments[0]
|
|
1117
|
-
: undefined;
|
|
1118
|
-
};
|
|
1119
|
-
const unionToString = ({ types: typesRaw, op, wrapWithReadonly, }) => {
|
|
1120
1425
|
|
|
1121
1426
|
|
|
1122
1427
|
|
|
1123
1428
|
|
|
1124
1429
|
|
|
1125
|
-
|
|
1126
|
-
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
options.replaceNode(node, unionToString({ types: sorted, op: operator, wrapWithReadonly: false }));
|
|
1127
1436
|
};
|
|
1128
|
-
const unionToStringImpl = ({ types, op, wrapWithReadonly, }) => Arr.isEmpty(types)
|
|
1129
|
-
? 'never'
|
|
1130
|
-
: Arr.isFixedLengthArray(1, types)
|
|
1131
|
-
? wrapWithReadonly === false
|
|
1132
|
-
? wrapWithParentheses(types[0])
|
|
1133
|
-
: `${isString(wrapWithReadonly) ? wrapWithReadonly : 'Readonly'}<${types[0]}>`
|
|
1134
|
-
: wrapWithReadonly === false
|
|
1135
|
-
? wrapWithParentheses(types.join(` ${op} `))
|
|
1136
|
-
: `${isString(wrapWithReadonly) ? wrapWithReadonly : 'Readonly'}<${types.join(` ${op} `)}>`;
|
|
1137
1437
|
|
|
1138
1438
|
const transformParenthesizedTypeNode = (
|
|
1139
1439
|
|
|
@@ -1147,16 +1447,12 @@ node, readonlyContext, options) => {
|
|
|
1147
1447
|
const T = node.getTypeNode();
|
|
1148
1448
|
if (
|
|
1149
1449
|
|
|
1150
|
-
|
|
1151
1450
|
T.isKind(tsm.SyntaxKind.TypeReference) ||
|
|
1152
1451
|
|
|
1153
|
-
|
|
1154
1452
|
T.isKind(tsm.SyntaxKind.ArrayType) ||
|
|
1155
1453
|
|
|
1156
|
-
|
|
1157
1454
|
T.isKind(tsm.SyntaxKind.TupleType) ||
|
|
1158
1455
|
|
|
1159
|
-
|
|
1160
1456
|
isAtomicTypeNode(T) ||
|
|
1161
1457
|
|
|
1162
1458
|
|
|
@@ -1253,101 +1549,4 @@ node, readonlyModifier, readonlyContext, options) => {
|
|
|
1253
1549
|
}
|
|
1254
1550
|
}
|
|
1255
1551
|
};
|
|
1256
|
-
const checkIfPropertyNameShouldBeIgnored = (
|
|
1257
|
-
|
|
1258
|
-
nameNode, options) => {
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
return (
|
|
1262
|
-
|
|
1263
|
-
(nameNode.isKind(tsm.SyntaxKind.Identifier) &&
|
|
1264
|
-
pipe(nameNode.getText()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p))).value) ||
|
|
1265
|
-
|
|
1266
|
-
(nameNode.isKind(tsm.SyntaxKind.StringLiteral) &&
|
|
1267
|
-
pipe(nameNode.getLiteralValue()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p))).value) ||
|
|
1268
|
-
|
|
1269
|
-
(nameNode.isKind(tsm.SyntaxKind.PrivateIdentifier) &&
|
|
1270
|
-
pipe(nameNode.getText()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p) || nm.startsWith(`#${p}`))).value) ||
|
|
1271
|
-
|
|
1272
|
-
(nameNode.isKind(tsm.SyntaxKind.ComputedPropertyName) &&
|
|
1273
|
-
pipe(nameNode.getExpression()).map((exp) => {
|
|
1274
|
-
if (exp.isKind(tsm.SyntaxKind.StringLiteral) ||
|
|
1275
|
-
exp.isKind(tsm.SyntaxKind.NoSubstitutionTemplateLiteral)) {
|
|
1276
|
-
const nm = exp.getLiteralValue();
|
|
1277
|
-
return options.mutablePropertyPrefixes.some((p) => nm.startsWith(p));
|
|
1278
|
-
}
|
|
1279
|
-
return false;
|
|
1280
|
-
}).value));
|
|
1281
|
-
};
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
const isLeftUnwrapped = (
|
|
1298
|
-
|
|
1299
|
-
node, options) => {
|
|
1300
|
-
const members = node.getMembers();
|
|
1301
|
-
const isMethodOrAccessor = (
|
|
1302
|
-
|
|
1303
|
-
mb) => mb.isKind(tsm.SyntaxKind.MethodSignature) ||
|
|
1304
|
-
mb.isKind(tsm.SyntaxKind.GetAccessor) ||
|
|
1305
|
-
mb.isKind(tsm.SyntaxKind.SetAccessor);
|
|
1306
|
-
const isIgnoredMember = (
|
|
1307
|
-
|
|
1308
|
-
mb) => (mb.isKind(tsm.SyntaxKind.PropertySignature) || isMethodOrAccessor(mb)) &&
|
|
1309
|
-
checkIfPropertyNameShouldBeIgnored(mb.getNameNode(), options);
|
|
1310
|
-
const needsReadonlyWrapper = (
|
|
1311
|
-
|
|
1312
|
-
mb) => !isIgnoredMember(mb) &&
|
|
1313
|
-
(isMethodOrAccessor(mb) ||
|
|
1314
|
-
((mb.isKind(tsm.SyntaxKind.PropertySignature) ||
|
|
1315
|
-
mb.isKind(tsm.SyntaxKind.IndexSignature)) &&
|
|
1316
|
-
!mb.hasModifier(tsm.SyntaxKind.ReadonlyKeyword) &&
|
|
1317
|
-
hasDisableNextLineComment(mb)));
|
|
1318
|
-
return members.some(isIgnoredMember) && !members.some(needsReadonlyWrapper);
|
|
1319
|
-
};
|
|
1320
|
-
|
|
1321
|
-
const hasDisableNextLineCommentAround = (node) => {
|
|
1322
|
-
if (hasDisableNextLineComment(node, TRANSFORMER_NAME)) {
|
|
1323
|
-
return true;
|
|
1324
|
-
}
|
|
1325
|
-
const parent = node.getParent();
|
|
1326
|
-
return (parent?.isKind(tsm.SyntaxKind.ParenthesizedType) === true &&
|
|
1327
|
-
hasDisableNextLineCommentAround(parent));
|
|
1328
|
-
};
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
const takesOffReadonly = (
|
|
1337
|
-
|
|
1338
|
-
node, options) => isLeftUnwrapped(node, options) &&
|
|
1339
|
-
!hasCallOrConstructSignature(node) &&
|
|
1340
|
-
!hasDisableNextLineCommentAround(node);
|
|
1341
|
-
|
|
1342
|
-
const hasMutableTypeName = (name, options) => name !== undefined &&
|
|
1343
|
-
options.mutableTypePrefixes.some((p) => name.startsWith(p));
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
const mutablePrefixesOfParameter = (
|
|
1349
|
-
|
|
1350
|
-
param, options) => param.isParameterProperty()
|
|
1351
|
-
? options.mutablePropertyPrefixes
|
|
1352
|
-
: options.mutableVariablePrefixes;
|
|
1353
1552
|
//# sourceMappingURL=convert-to-readonly.mjs.map
|