ts-codemod-lib 4.0.0 → 4.0.1
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/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 +4 -4
- package/dist/functions/ast-transformers/convert-to-readonly.mjs +248 -252
- 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 +6 -6
- 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.mts +467 -471
- package/src/functions/ast-transformers/convert-to-readonly.test.mts +60 -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
|
@@ -45,6 +45,18 @@ const initialReadonlyContext = {
|
|
|
45
45
|
type: 'none',
|
|
46
46
|
indexedAccessDepth: 0,
|
|
47
47
|
};
|
|
48
|
+
|
|
49
|
+
const hasMutableTypeName = (name, options) => name !== undefined &&
|
|
50
|
+
options.mutableTypePrefixes.some((p) => name.startsWith(p));
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
const mutablePrefixesOfParameter = (
|
|
56
|
+
|
|
57
|
+
param, options) => param.isParameterProperty()
|
|
58
|
+
? options.mutablePropertyPrefixes
|
|
59
|
+
: options.mutableVariablePrefixes;
|
|
48
60
|
const transformNode = (node, readonlyContext, options) => {
|
|
49
61
|
if (tsm.Node.isTypeNode(node) ||
|
|
50
62
|
node.isKind(tsm.SyntaxKind.InterfaceDeclaration) ||
|
|
@@ -198,6 +210,137 @@ const transformNode = (node, readonlyContext, options) => {
|
|
|
198
210
|
|
|
199
211
|
|
|
200
212
|
|
|
213
|
+
const readonlyRecordText = (keyText, valueText, options) => options.recordStyle === 'ReadonlyRecord'
|
|
214
|
+
? `ReadonlyRecord<${keyText}, ${valueText}>`
|
|
215
|
+
: `Readonly<Record<${keyText}, ${valueText}>>`;
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
const commentsBetween = (
|
|
222
|
+
|
|
223
|
+
sourceFile, from, to) => {
|
|
224
|
+
if (to <= from) {
|
|
225
|
+
return '';
|
|
226
|
+
}
|
|
227
|
+
const scanner = tsm.ts.createScanner(tsm.ts.ScriptTarget.Latest, false, tsm.ts.LanguageVariant.Standard, sourceFile.getFullText(), undefined, from, to - from);
|
|
228
|
+
const mut_comments = [];
|
|
229
|
+
while (scanner.scan() !== tsm.ts.SyntaxKind.EndOfFileToken) {
|
|
230
|
+
const token = scanner.getToken();
|
|
231
|
+
|
|
232
|
+
const separator = token === tsm.ts.SyntaxKind.SingleLineCommentTrivia
|
|
233
|
+
? '\n'
|
|
234
|
+
: token === tsm.ts.SyntaxKind.MultiLineCommentTrivia
|
|
235
|
+
? ' '
|
|
236
|
+
: undefined;
|
|
237
|
+
if (separator !== undefined) {
|
|
238
|
+
mut_comments.push(`${scanner.getTokenText()}${separator}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return mut_comments.join('');
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const getDeepReadonlyTypeArg = (
|
|
245
|
+
|
|
246
|
+
node, deepReadonlyTypeName) => {
|
|
247
|
+
if (!node.isKind(tsm.SyntaxKind.TypeReference)) {
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
const typeName = node.getTypeName();
|
|
251
|
+
const typeArguments = node.getTypeArguments();
|
|
252
|
+
return typeName.isKind(tsm.SyntaxKind.Identifier) &&
|
|
253
|
+
typeName.getText() === deepReadonlyTypeName &&
|
|
254
|
+
Arr.isFixedLengthArray(1, typeArguments)
|
|
255
|
+
? typeArguments[0]
|
|
256
|
+
: undefined;
|
|
257
|
+
};
|
|
258
|
+
const checkIfPropertyNameShouldBeIgnored = (
|
|
259
|
+
|
|
260
|
+
nameNode, options) => {
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
|
|
265
|
+
(nameNode.isKind(tsm.SyntaxKind.Identifier) &&
|
|
266
|
+
pipe(nameNode.getText()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p))).value) ||
|
|
267
|
+
|
|
268
|
+
(nameNode.isKind(tsm.SyntaxKind.StringLiteral) &&
|
|
269
|
+
pipe(nameNode.getLiteralValue()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p))).value) ||
|
|
270
|
+
|
|
271
|
+
(nameNode.isKind(tsm.SyntaxKind.PrivateIdentifier) &&
|
|
272
|
+
pipe(nameNode.getText()).map((nm) => options.mutablePropertyPrefixes.some((p) => nm.startsWith(p) || nm.startsWith(`#${p}`))).value) ||
|
|
273
|
+
|
|
274
|
+
(nameNode.isKind(tsm.SyntaxKind.ComputedPropertyName) &&
|
|
275
|
+
pipe(nameNode.getExpression()).map((exp) => {
|
|
276
|
+
if (exp.isKind(tsm.SyntaxKind.StringLiteral) ||
|
|
277
|
+
exp.isKind(tsm.SyntaxKind.NoSubstitutionTemplateLiteral)) {
|
|
278
|
+
const nm = exp.getLiteralValue();
|
|
279
|
+
return options.mutablePropertyPrefixes.some((p) => nm.startsWith(p));
|
|
280
|
+
}
|
|
281
|
+
return false;
|
|
282
|
+
}).value));
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
const isLeftUnwrapped = (
|
|
300
|
+
|
|
301
|
+
node, options) => {
|
|
302
|
+
const members = node.getMembers();
|
|
303
|
+
const isMethodOrAccessor = (
|
|
304
|
+
|
|
305
|
+
mb) => mb.isKind(tsm.SyntaxKind.MethodSignature) ||
|
|
306
|
+
mb.isKind(tsm.SyntaxKind.GetAccessor) ||
|
|
307
|
+
mb.isKind(tsm.SyntaxKind.SetAccessor);
|
|
308
|
+
const isIgnoredMember = (
|
|
309
|
+
|
|
310
|
+
mb) => (mb.isKind(tsm.SyntaxKind.PropertySignature) || isMethodOrAccessor(mb)) &&
|
|
311
|
+
checkIfPropertyNameShouldBeIgnored(mb.getNameNode(), options);
|
|
312
|
+
const needsReadonlyWrapper = (
|
|
313
|
+
|
|
314
|
+
mb) => !isIgnoredMember(mb) &&
|
|
315
|
+
(isMethodOrAccessor(mb) ||
|
|
316
|
+
((mb.isKind(tsm.SyntaxKind.PropertySignature) ||
|
|
317
|
+
mb.isKind(tsm.SyntaxKind.IndexSignature)) &&
|
|
318
|
+
!mb.hasModifier(tsm.SyntaxKind.ReadonlyKeyword) &&
|
|
319
|
+
hasDisableNextLineComment(mb)));
|
|
320
|
+
return members.some(isIgnoredMember) && !members.some(needsReadonlyWrapper);
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const hasDisableNextLineCommentAround = (node) => {
|
|
324
|
+
if (hasDisableNextLineComment(node, TRANSFORMER_NAME)) {
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
const parent = node.getParent();
|
|
328
|
+
return (parent?.isKind(tsm.SyntaxKind.ParenthesizedType) === true &&
|
|
329
|
+
hasDisableNextLineCommentAround(parent));
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
const takesOffReadonly = (
|
|
339
|
+
|
|
340
|
+
node, options) => isLeftUnwrapped(node, options) &&
|
|
341
|
+
!hasCallOrConstructSignature(node) &&
|
|
342
|
+
!hasDisableNextLineCommentAround(node);
|
|
343
|
+
|
|
201
344
|
|
|
202
345
|
|
|
203
346
|
|
|
@@ -520,10 +663,6 @@ node, readonlyContext, options) => {
|
|
|
520
663
|
}
|
|
521
664
|
};
|
|
522
665
|
|
|
523
|
-
const readonlyRecordText = (keyText, valueText, options) => options.recordStyle === 'ReadonlyRecord'
|
|
524
|
-
? `ReadonlyRecord<${keyText}, ${valueText}>`
|
|
525
|
-
: `Readonly<Record<${keyText}, ${valueText}>>`;
|
|
526
|
-
|
|
527
666
|
const transformArrayTypeNode = (
|
|
528
667
|
|
|
529
668
|
node, readonlyContext, options) => {
|
|
@@ -828,104 +967,6 @@ const transformUnionTypeNode = (
|
|
|
828
967
|
node, readonlyContext, options) => {
|
|
829
968
|
transformUnionOrIntersectionTypeNodeImpl(node, readonlyContext, options, '|');
|
|
830
969
|
};
|
|
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
970
|
|
|
930
971
|
|
|
931
972
|
|
|
@@ -934,14 +975,28 @@ node, readonlyContext, options, operator) => {
|
|
|
934
975
|
|
|
935
976
|
|
|
936
977
|
|
|
978
|
+
const textWithoutParentheses = (
|
|
937
979
|
|
|
980
|
+
outer,
|
|
938
981
|
|
|
982
|
+
inner) => `${commentsBetween(outer.getSourceFile(), outer.getPos(), inner.getStart())}${inner.getText()}`;
|
|
983
|
+
const unionToStringImpl = ({ types, op, wrapWithReadonly, }) => Arr.isEmpty(types)
|
|
984
|
+
? 'never'
|
|
985
|
+
: Arr.isFixedLengthArray(1, types)
|
|
986
|
+
? wrapWithReadonly === false
|
|
987
|
+
? wrapWithParentheses(types[0])
|
|
988
|
+
: `${isString(wrapWithReadonly) ? wrapWithReadonly : 'Readonly'}<${types[0]}>`
|
|
989
|
+
: wrapWithReadonly === false
|
|
990
|
+
? wrapWithParentheses(types.join(` ${op} `))
|
|
991
|
+
: `${isString(wrapWithReadonly) ? wrapWithReadonly : 'Readonly'}<${types.join(` ${op} `)}>`;
|
|
992
|
+
const unionToString = ({ types: typesRaw, op, wrapWithReadonly, }) => {
|
|
939
993
|
|
|
940
994
|
|
|
941
995
|
|
|
942
996
|
|
|
943
997
|
|
|
944
|
-
|
|
998
|
+
const types = typesRaw.map((s) => s.trim());
|
|
999
|
+
return unionToStringImpl({ types, op, wrapWithReadonly });
|
|
945
1000
|
};
|
|
946
1001
|
|
|
947
1002
|
|
|
@@ -1061,79 +1116,121 @@ node, operator) => {
|
|
|
1061
1116
|
? textWithoutParentheses(typeArgument, T)
|
|
1062
1117
|
: unwrapReadonlyTypeArgText(node);
|
|
1063
1118
|
};
|
|
1119
|
+
const transformUnionOrIntersectionTypeNodeImpl = (
|
|
1064
1120
|
|
|
1121
|
+
node, readonlyContext, options, operator) => {
|
|
1122
|
+
const nextReadonlyContextValue = nextReadonlyContext({
|
|
1123
|
+
currentReadonlyContext: readonlyContext,
|
|
1124
|
+
nextReadonlyContextType: 'none',
|
|
1125
|
+
indexedAccessDepthChange: 'keep',
|
|
1126
|
+
});
|
|
1065
1127
|
|
|
1128
|
+
for (const n of node.getTypeNodes() ) {
|
|
1129
|
+
transformNode(n, nextReadonlyContextValue, options);
|
|
1130
|
+
}
|
|
1131
|
+
const newTypes = node.getTypeNodes();
|
|
1132
|
+
const withLeadingComments = (
|
|
1066
1133
|
|
|
1134
|
+
member, memberText) => `${leadingCommentsOfMember(node, member)}${memberText}`;
|
|
1067
1135
|
|
|
1068
1136
|
|
|
1137
|
+
const wrapsTypeLiterals = nextReadonlyContextValue.type !== 'DeepReadonly' &&
|
|
1138
|
+
nextReadonlyContextValue.indexedAccessDepth === 0;
|
|
1069
1139
|
|
|
1070
1140
|
|
|
1141
|
+
const underReadonly = readonlyContext.type === 'Readonly' &&
|
|
1142
|
+
readonlyContext.indexedAccessDepth === 0 &&
|
|
1143
|
+
isTypeArgumentOfReadonly(node);
|
|
1144
|
+
const { primitives, arraysAndTuples, typeLiterals, others } = groupUnionIntersectionTypes(newTypes, {
|
|
1145
|
+
operator,
|
|
1146
|
+
underReadonly,
|
|
1147
|
+
deepReadonlyTypeName: options.DeepReadonly.typeName,
|
|
1148
|
+
keptUnwrapped: (t) => wrapsTypeLiterals && takesOffReadonly(t, options),
|
|
1149
|
+
});
|
|
1150
|
+
options.debugPrint({ primitives, arraysAndTuples, typeLiterals, others });
|
|
1071
1151
|
|
|
1072
|
-
const
|
|
1152
|
+
const isEmptyTypeLiteral = (
|
|
1073
1153
|
|
|
1074
|
-
|
|
1154
|
+
n) => n.isKind(tsm.SyntaxKind.TypeLiteral) && Arr.isEmpty(n.getMembers());
|
|
1155
|
+
const nonEmptyTypeLiterals = typeLiterals === undefined
|
|
1156
|
+
? undefined
|
|
1157
|
+
: options.ignoreEmptyObjectTypes
|
|
1158
|
+
? typeLiterals.nodes.filter((n) => !isEmptyTypeLiteral(n))
|
|
1159
|
+
: typeLiterals.nodes;
|
|
1160
|
+
const emptyTypeLiterals = typeLiterals === undefined || !options.ignoreEmptyObjectTypes
|
|
1161
|
+
? undefined
|
|
1162
|
+
: typeLiterals.nodes.filter(isEmptyTypeLiteral);
|
|
1163
|
+
const typeLiteralsWrappedWithReadonly = nonEmptyTypeLiterals === undefined || Arr.isEmpty(nonEmptyTypeLiterals)
|
|
1164
|
+
? []
|
|
1165
|
+
: [
|
|
1166
|
+
unionToString({
|
|
1167
|
+
types: nonEmptyTypeLiterals.map((n) => withLeadingComments(n, isMergeableReadonlyTypeReferenceNode(n, operator)
|
|
1168
|
+
?
|
|
1075
1169
|
|
|
1076
|
-
|
|
1170
|
+
readonlyTypeArgTextSplicedInto(n, operator)
|
|
1171
|
+
: n.isKind(tsm.SyntaxKind.TypeLiteral)
|
|
1172
|
+
? n.getText()
|
|
1173
|
+
:
|
|
1174
|
+
wrapWithParentheses(n.getText()))),
|
|
1175
|
+
op: operator,
|
|
1176
|
+
wrapWithReadonly: wrapsTypeLiterals,
|
|
1177
|
+
}),
|
|
1178
|
+
];
|
|
1077
1179
|
|
|
1180
|
+
const sorted = [
|
|
1181
|
+
mapNullable(primitives, (a) => [
|
|
1182
|
+
a.nodes.map((n) => withLeadingComments(n, n.getText())),
|
|
1183
|
+
a.firstPosition,
|
|
1184
|
+
]),
|
|
1185
|
+
mapNullable(arraysAndTuples, (a) => [
|
|
1186
|
+
a.nodes.map((n) => withLeadingComments(n, n.getText())),
|
|
1187
|
+
a.firstPosition,
|
|
1188
|
+
]),
|
|
1189
|
+
nonEmptyTypeLiterals !== undefined && Arr.isNonEmpty(nonEmptyTypeLiterals)
|
|
1190
|
+
? mapNullable(typeLiterals, (a) => [typeLiteralsWrappedWithReadonly, a.firstPosition])
|
|
1191
|
+
: undefined,
|
|
1192
|
+
emptyTypeLiterals !== undefined && Arr.isNonEmpty(emptyTypeLiterals)
|
|
1193
|
+
? mapNullable(typeLiterals, (a) => [
|
|
1194
|
+
emptyTypeLiterals.map((n) => withLeadingComments(n, n.getText())),
|
|
1078
1195
|
|
|
1196
|
+
a.firstPosition +
|
|
1197
|
+
(nonEmptyTypeLiterals !== undefined &&
|
|
1198
|
+
Arr.isNonEmpty(nonEmptyTypeLiterals)
|
|
1199
|
+
? 0.5
|
|
1200
|
+
: 0),
|
|
1201
|
+
])
|
|
1202
|
+
: undefined,
|
|
1203
|
+
mapNullable(others, (a) => [
|
|
1079
1204
|
|
|
1080
1205
|
|
|
1206
|
+
operator === '|'
|
|
1207
|
+
? mergeDeepReadonlyUnionMembers(a.nodes, options.DeepReadonly.typeName, withLeadingComments)
|
|
1208
|
+
: a.nodes.map((n) => withLeadingComments(n, wrapWithParentheses(n.getText()))),
|
|
1209
|
+
a.firstPosition,
|
|
1210
|
+
]),
|
|
1211
|
+
]
|
|
1212
|
+
.filter((x) => x !== undefined)
|
|
1213
|
+
.toSorted((a, b) => a[1] - b[1])
|
|
1214
|
+
.flatMap((a) => a[0]);
|
|
1081
1215
|
|
|
1082
|
-
const commentsBetween = (
|
|
1083
1216
|
|
|
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
1217
|
|
|
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
1218
|
|
|
1105
|
-
const getDeepReadonlyTypeArg = (
|
|
1106
1219
|
|
|
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
1220
|
|
|
1121
1221
|
|
|
1122
1222
|
|
|
1123
1223
|
|
|
1124
1224
|
|
|
1125
|
-
|
|
1126
|
-
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
options.replaceNode(node, unionToString({ types: sorted, op: operator, wrapWithReadonly: false }));
|
|
1127
1233
|
};
|
|
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
1234
|
|
|
1138
1235
|
const transformParenthesizedTypeNode = (
|
|
1139
1236
|
|
|
@@ -1147,16 +1244,12 @@ node, readonlyContext, options) => {
|
|
|
1147
1244
|
const T = node.getTypeNode();
|
|
1148
1245
|
if (
|
|
1149
1246
|
|
|
1150
|
-
|
|
1151
1247
|
T.isKind(tsm.SyntaxKind.TypeReference) ||
|
|
1152
1248
|
|
|
1153
|
-
|
|
1154
1249
|
T.isKind(tsm.SyntaxKind.ArrayType) ||
|
|
1155
1250
|
|
|
1156
|
-
|
|
1157
1251
|
T.isKind(tsm.SyntaxKind.TupleType) ||
|
|
1158
1252
|
|
|
1159
|
-
|
|
1160
1253
|
isAtomicTypeNode(T) ||
|
|
1161
1254
|
|
|
1162
1255
|
|
|
@@ -1253,101 +1346,4 @@ node, readonlyModifier, readonlyContext, options) => {
|
|
|
1253
1346
|
}
|
|
1254
1347
|
}
|
|
1255
1348
|
};
|
|
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
1349
|
//# sourceMappingURL=convert-to-readonly.mjs.map
|