@react-native/compatibility-check 0.0.0 → 0.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.
@@ -0,0 +1,1253 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true,
5
+ });
6
+ exports.compareEnumDeclarationMemberArrays = compareEnumDeclarationMemberArrays;
7
+ exports.compareEnumDeclarationWithMembers = compareEnumDeclarationWithMembers;
8
+ exports.compareEnumDeclarations = compareEnumDeclarations;
9
+ exports.compareFunctionTypes = compareFunctionTypes;
10
+ exports.compareGenericObjectTypes = compareGenericObjectTypes;
11
+ exports.compareNumberLiteralTypes = compareNumberLiteralTypes;
12
+ exports.compareObjectTypes = compareObjectTypes;
13
+ exports.comparePromiseTypes = comparePromiseTypes;
14
+ exports.compareStringLiteralTypes = compareStringLiteralTypes;
15
+ exports.compareStringLiteralUnionTypes = compareStringLiteralUnionTypes;
16
+ exports.compareTypeAnnotation = compareTypeAnnotation;
17
+ exports.compareTypes = compareTypes;
18
+ exports.compareUnionTypes = compareUnionTypes;
19
+ var _ComparisonResult = require("./ComparisonResult");
20
+ var _SortTypeAnnotations = require("./SortTypeAnnotations.js");
21
+ var _invariant = _interopRequireDefault(require("invariant"));
22
+ function _interopRequireDefault(e) {
23
+ return e && e.__esModule ? e : { default: e };
24
+ }
25
+ const EQUALITY_MSG = "previousType and afterType differ despite check";
26
+ let _newerTypesReg, _olderTypesReg, _newerEnumMap, _olderEnumMap;
27
+ function compareTypes(
28
+ newerType,
29
+ olderType,
30
+ newerTypesReg,
31
+ olderTypesReg,
32
+ newerEnumMap,
33
+ olderEnumMap
34
+ ) {
35
+ if (!olderType) {
36
+ return {
37
+ status: "skipped",
38
+ };
39
+ }
40
+ _newerTypesReg = newerTypesReg;
41
+ _olderTypesReg = olderTypesReg;
42
+ _newerEnumMap = newerEnumMap;
43
+ _olderEnumMap = olderEnumMap;
44
+ const res = compareTypeAnnotation(newerType, olderType);
45
+ _newerTypesReg = undefined;
46
+ _olderTypesReg = undefined;
47
+ _newerEnumMap = undefined;
48
+ _olderEnumMap = undefined;
49
+ return res;
50
+ }
51
+ function removeNullableTypeAnnotations(annotation) {
52
+ if (annotation.type === "NullableTypeAnnotation") {
53
+ return removeNullableTypeAnnotations(annotation.typeAnnotation);
54
+ }
55
+ return annotation;
56
+ }
57
+ function lookupType(name, aliases) {
58
+ return aliases?.[name];
59
+ }
60
+ function lookupEnum(name, enums) {
61
+ return enums?.[name];
62
+ }
63
+ function compareTypeAnnotation(
64
+ originalNewerAnnotation,
65
+ originalOlderAnnotation
66
+ ) {
67
+ const newerAnnotation = originalNewerAnnotation;
68
+ const olderAnnotation = originalOlderAnnotation;
69
+ if (newerAnnotation.type === "TypeAliasTypeAnnotation") {
70
+ const newerAnnotationDefinition = lookupType(
71
+ newerAnnotation.name,
72
+ _newerTypesReg
73
+ );
74
+ if (newerAnnotationDefinition != null) {
75
+ return compareTypeAnnotation(newerAnnotationDefinition, olderAnnotation);
76
+ }
77
+ }
78
+ if (olderAnnotation.type === "TypeAliasTypeAnnotation") {
79
+ const olderAnnotationDefinition = lookupType(
80
+ olderAnnotation.name,
81
+ _olderTypesReg
82
+ );
83
+ if (olderAnnotationDefinition != null) {
84
+ return compareTypeAnnotation(newerAnnotation, olderAnnotationDefinition);
85
+ }
86
+ }
87
+ (0, _invariant.default)(
88
+ newerAnnotation.type !== "TypeAliasTypeAnnotation" &&
89
+ olderAnnotation.type !== "TypeAliasTypeAnnotation",
90
+ EQUALITY_MSG
91
+ );
92
+ if (newerAnnotation.type !== olderAnnotation.type) {
93
+ if (
94
+ newerAnnotation.type === "NullableTypeAnnotation" ||
95
+ olderAnnotation.type === "NullableTypeAnnotation"
96
+ ) {
97
+ return compareNullableChange(newerAnnotation, olderAnnotation);
98
+ }
99
+ return (0, _ComparisonResult.makeError)(
100
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
101
+ "Type annotations are not the same.",
102
+ newerAnnotation,
103
+ olderAnnotation
104
+ )
105
+ );
106
+ }
107
+ switch (newerAnnotation.type) {
108
+ case "AnyTypeAnnotation":
109
+ case "MixedTypeAnnotation":
110
+ case "DoubleTypeAnnotation":
111
+ case "FloatTypeAnnotation":
112
+ case "Int32TypeAnnotation":
113
+ case "BooleanTypeAnnotation":
114
+ case "NumberTypeAnnotation":
115
+ case "StringTypeAnnotation":
116
+ case "VoidTypeAnnotation":
117
+ return {
118
+ status: "matching",
119
+ };
120
+ case "ArrayTypeAnnotation":
121
+ (0, _invariant.default)(
122
+ olderAnnotation.type === "ArrayTypeAnnotation",
123
+ EQUALITY_MSG
124
+ );
125
+ return compareTypeAnnotation(
126
+ newerAnnotation.elementType,
127
+ olderAnnotation.elementType
128
+ );
129
+ case "EnumDeclaration":
130
+ (0, _invariant.default)(
131
+ olderAnnotation.type === "EnumDeclaration",
132
+ EQUALITY_MSG
133
+ );
134
+ return compareEnumDeclarations(newerAnnotation, olderAnnotation);
135
+ case "EnumDeclarationWithMembers":
136
+ (0, _invariant.default)(
137
+ olderAnnotation.type === "EnumDeclarationWithMembers",
138
+ EQUALITY_MSG
139
+ );
140
+ return compareEnumDeclarationWithMembers(
141
+ newerAnnotation,
142
+ olderAnnotation
143
+ );
144
+ case "FunctionTypeAnnotation":
145
+ (0, _invariant.default)(
146
+ olderAnnotation.type === "FunctionTypeAnnotation",
147
+ EQUALITY_MSG
148
+ );
149
+ return compareFunctionTypes(newerAnnotation, olderAnnotation);
150
+ case "PromiseTypeAnnotation":
151
+ (0, _invariant.default)(
152
+ olderAnnotation.type === "PromiseTypeAnnotation",
153
+ EQUALITY_MSG
154
+ );
155
+ return comparePromiseTypes(newerAnnotation, olderAnnotation);
156
+ case "GenericObjectTypeAnnotation":
157
+ (0, _invariant.default)(
158
+ olderAnnotation.type === "GenericObjectTypeAnnotation",
159
+ EQUALITY_MSG
160
+ );
161
+ return compareGenericObjectTypes(newerAnnotation, olderAnnotation);
162
+ case "NullableTypeAnnotation":
163
+ (0, _invariant.default)(
164
+ olderAnnotation.type === "NullableTypeAnnotation",
165
+ EQUALITY_MSG
166
+ );
167
+ return compareTypeAnnotation(
168
+ newerAnnotation.typeAnnotation,
169
+ olderAnnotation.typeAnnotation
170
+ );
171
+ case "ObjectTypeAnnotation":
172
+ (0, _invariant.default)(
173
+ olderAnnotation.type === "ObjectTypeAnnotation",
174
+ EQUALITY_MSG
175
+ );
176
+ return compareObjectTypes(
177
+ newerAnnotation.properties,
178
+ olderAnnotation.properties
179
+ );
180
+ case "NumberLiteralTypeAnnotation":
181
+ (0, _invariant.default)(
182
+ olderAnnotation.type === "NumberLiteralTypeAnnotation",
183
+ EQUALITY_MSG
184
+ );
185
+ return compareNumberLiteralTypes(newerAnnotation, olderAnnotation);
186
+ case "StringLiteralUnionTypeAnnotation":
187
+ (0, _invariant.default)(
188
+ olderAnnotation.type === "StringLiteralUnionTypeAnnotation",
189
+ EQUALITY_MSG
190
+ );
191
+ return compareStringLiteralUnionTypes(newerAnnotation, olderAnnotation);
192
+ case "StringLiteralTypeAnnotation":
193
+ (0, _invariant.default)(
194
+ olderAnnotation.type === "StringLiteralTypeAnnotation",
195
+ EQUALITY_MSG
196
+ );
197
+ return compareStringLiteralTypes(newerAnnotation, olderAnnotation);
198
+ case "UnionTypeAnnotation":
199
+ (0, _invariant.default)(
200
+ olderAnnotation.type === "UnionTypeAnnotation",
201
+ EQUALITY_MSG
202
+ );
203
+ return compareUnionTypes(newerAnnotation, olderAnnotation);
204
+ case "EventEmitterTypeAnnotation":
205
+ (0, _invariant.default)(
206
+ olderAnnotation.type === "EventEmitterTypeAnnotation",
207
+ EQUALITY_MSG
208
+ );
209
+ return compareEventEmitterTypes(newerAnnotation, olderAnnotation);
210
+ case "ReservedTypeAnnotation":
211
+ (0, _invariant.default)(
212
+ olderAnnotation.type === "ReservedTypeAnnotation",
213
+ EQUALITY_MSG
214
+ );
215
+ return compareReservedTypeAnnotation(newerAnnotation, olderAnnotation);
216
+ default:
217
+ throw new Error(`Unsupported type annotation: ${newerAnnotation.type}`);
218
+ }
219
+ }
220
+ function compareObjectTypeProperty(first, second) {
221
+ if (first.name < second.name) {
222
+ return -1;
223
+ } else if (first.name > second.name) {
224
+ return 1;
225
+ }
226
+ return 0;
227
+ }
228
+ function compareEnumMember(first, second) {
229
+ if (first.name < second.name) {
230
+ return -1;
231
+ } else if (first.name > second.name) {
232
+ return 1;
233
+ }
234
+ return 0;
235
+ }
236
+ function updatePropertyError(name, newType, oldType, result) {
237
+ return (oldError) => {
238
+ const comparisonError = (0,
239
+ _ComparisonResult.typeAnnotationComparisonError)(
240
+ "has conflicting type changes",
241
+ newType,
242
+ oldType,
243
+ oldError
244
+ );
245
+ const newFault = {
246
+ property: name,
247
+ fault: comparisonError,
248
+ };
249
+ if (result.errorProperties) {
250
+ result.errorProperties.push(newFault);
251
+ } else {
252
+ result.errorProperties = [newFault];
253
+ }
254
+ };
255
+ }
256
+ function updateEnumMemberError(name, newType, oldType, result) {
257
+ return (oldError) => {
258
+ const comparisonError = (0,
259
+ _ComparisonResult.typeAnnotationComparisonError)(
260
+ "has conflicting changes",
261
+ newType,
262
+ oldType,
263
+ oldError
264
+ );
265
+ const newFault = {
266
+ member: name,
267
+ fault: comparisonError,
268
+ };
269
+ if (result.errorMembers) {
270
+ result.errorMembers.push(newFault);
271
+ } else {
272
+ result.errorMembers = [newFault];
273
+ }
274
+ };
275
+ }
276
+ function updateNestedProperties(name, propertyChange, result) {
277
+ if (result.nestedPropertyChanges) {
278
+ result.nestedPropertyChanges.push([name, propertyChange]);
279
+ } else {
280
+ result.nestedPropertyChanges = [[name, propertyChange]];
281
+ }
282
+ }
283
+ function updateMadeOptional(name, result, furtherChange) {
284
+ if (result.madeOptional) {
285
+ result.madeOptional.push({
286
+ property: name,
287
+ furtherChange,
288
+ });
289
+ } else {
290
+ result.madeOptional = [
291
+ {
292
+ property: name,
293
+ furtherChange,
294
+ },
295
+ ];
296
+ }
297
+ }
298
+ function updateMadeStrict(name, result, furtherChange) {
299
+ if (result.madeStrict) {
300
+ result.madeStrict.push({
301
+ property: name,
302
+ furtherChange,
303
+ });
304
+ } else {
305
+ result.madeStrict = [
306
+ {
307
+ property: name,
308
+ furtherChange,
309
+ },
310
+ ];
311
+ }
312
+ }
313
+ function checkOptionalityChanges(
314
+ name,
315
+ newOptionality,
316
+ oldOptionality,
317
+ result,
318
+ furtherChange
319
+ ) {
320
+ if (newOptionality === oldOptionality) {
321
+ if (furtherChange) {
322
+ updateNestedProperties(name, furtherChange, result);
323
+ }
324
+ return result;
325
+ }
326
+ if (newOptionality) {
327
+ updateMadeOptional(name, result, furtherChange);
328
+ } else {
329
+ updateMadeStrict(name, result, furtherChange);
330
+ }
331
+ return result;
332
+ }
333
+ function comparePropertyArrays(newerOriginal, olderOriginal) {
334
+ const newer = newerOriginal.slice(0);
335
+ const older = olderOriginal.slice(0);
336
+ if (newer.length === 0 && older.length === 0) {
337
+ return {};
338
+ }
339
+ if (newer.length === 0) {
340
+ return {
341
+ missingProperties: older,
342
+ };
343
+ }
344
+ if (older.length === 0) {
345
+ return {
346
+ addedProperties: newer,
347
+ };
348
+ }
349
+ const newerHead = newer.pop();
350
+ const olderHead = older.pop();
351
+ (0, _invariant.default)(
352
+ newerHead != null && olderHead != null,
353
+ "Array is empty"
354
+ );
355
+ const newerName = newerHead.name;
356
+ const olderName = olderHead.name;
357
+ if (newerName === olderName) {
358
+ const comparedTypes = compareTypeAnnotation(
359
+ newerHead.typeAnnotation,
360
+ olderHead.typeAnnotation
361
+ );
362
+ const result = comparePropertyArrays(newer, older);
363
+ switch (comparedTypes.status) {
364
+ case "matching":
365
+ return checkOptionalityChanges(
366
+ newerName,
367
+ newerHead.optional,
368
+ olderHead.optional,
369
+ result
370
+ );
371
+ case "skipped":
372
+ throw new Error(
373
+ "Internal error: returned 'skipped' for non-optional older type"
374
+ );
375
+ case "nullableChange":
376
+ return checkOptionalityChanges(
377
+ newerName,
378
+ !comparedTypes.nullableLog.optionsReduced,
379
+ comparedTypes.nullableLog.optionsReduced,
380
+ result
381
+ );
382
+ case "members":
383
+ case "properties":
384
+ case "functionChange":
385
+ case "positionalTypeChange":
386
+ return checkOptionalityChanges(
387
+ newerName,
388
+ newerHead.optional,
389
+ olderHead.optional,
390
+ result,
391
+ comparedTypes
392
+ );
393
+ case "error":
394
+ updatePropertyError(
395
+ newerName,
396
+ newerHead.typeAnnotation,
397
+ olderHead.typeAnnotation,
398
+ result
399
+ )(comparedTypes.errorLog);
400
+ return result;
401
+ default:
402
+ throw new Error("Unsupported status " + comparedTypes.status);
403
+ }
404
+ }
405
+ if (newerName > olderName) {
406
+ older.push(olderHead);
407
+ const result = comparePropertyArrays(newer, older);
408
+ if (result.hasOwnProperty("addedProperties") && result.addedProperties) {
409
+ result.addedProperties = result.addedProperties.concat([newerHead]);
410
+ } else {
411
+ result.addedProperties = [newerHead];
412
+ }
413
+ return result;
414
+ }
415
+ newer.push(newerHead);
416
+ const result = comparePropertyArrays(newer, older);
417
+ if (result.hasOwnProperty("missingProperties") && result.missingProperties) {
418
+ result.missingProperties = result.missingProperties.concat([olderHead]);
419
+ } else {
420
+ result.missingProperties = [olderHead];
421
+ }
422
+ return result;
423
+ }
424
+ function compareObjectTypes(newerPropertyTypes, olderPropertyTypes) {
425
+ if (newerPropertyTypes.length === 0 && olderPropertyTypes.length === 0) {
426
+ return {
427
+ status: "matching",
428
+ };
429
+ }
430
+ const sortedNewerTypes = [];
431
+ newerPropertyTypes.forEach((prop) => sortedNewerTypes.push(prop));
432
+ if (sortedNewerTypes.length !== 0) {
433
+ sortedNewerTypes.sort(compareObjectTypeProperty);
434
+ }
435
+ const sortedOlderTypes = [];
436
+ olderPropertyTypes.forEach((prop) => sortedOlderTypes.push(prop));
437
+ if (sortedOlderTypes.length !== 0) {
438
+ sortedOlderTypes.sort(compareObjectTypeProperty);
439
+ }
440
+ if (sortedNewerTypes.length === 0) {
441
+ return {
442
+ status: "properties",
443
+ propertyLog: {
444
+ missingProperties: sortedOlderTypes,
445
+ },
446
+ };
447
+ }
448
+ if (sortedOlderTypes.length === 0) {
449
+ return {
450
+ status: "properties",
451
+ propertyLog: {
452
+ addedProperties: sortedNewerTypes,
453
+ },
454
+ };
455
+ }
456
+ const result = comparePropertyArrays(sortedNewerTypes, sortedOlderTypes);
457
+ if ((0, _ComparisonResult.isPropertyLogEmpty)(result)) {
458
+ return {
459
+ status: "matching",
460
+ };
461
+ }
462
+ if (result.errorProperties) {
463
+ return (0, _ComparisonResult.makeError)(
464
+ (0, _ComparisonResult.propertyComparisonError)(
465
+ result.errorProperties.length > 1
466
+ ? "Object contained properties with type mismatches"
467
+ : "Object contained a property with a type mismatch",
468
+ result.errorProperties
469
+ )
470
+ );
471
+ }
472
+ if (
473
+ (result.addedProperties &&
474
+ result.addedProperties.length > 0 &&
475
+ result.addedProperties.length === newerPropertyTypes.length) ||
476
+ (result.missingProperties &&
477
+ result.missingProperties.length > 0 &&
478
+ result.missingProperties.length === olderPropertyTypes.length)
479
+ ) {
480
+ return (0, _ComparisonResult.makeError)(
481
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
482
+ "Object types do not match.",
483
+ objectTypeAnnotation(newerPropertyTypes),
484
+ objectTypeAnnotation(olderPropertyTypes)
485
+ )
486
+ );
487
+ }
488
+ return {
489
+ status: "properties",
490
+ propertyLog: result,
491
+ };
492
+ }
493
+ function objectTypeAnnotation(properties) {
494
+ return {
495
+ type: "ObjectTypeAnnotation",
496
+ properties,
497
+ baseTypes: [],
498
+ };
499
+ }
500
+ function compareEnumDeclarations(newerDeclaration, olderDeclaration) {
501
+ if (newerDeclaration.memberType !== olderDeclaration.memberType) {
502
+ return (0, _ComparisonResult.makeError)(
503
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
504
+ "EnumDeclaration member types are not the same",
505
+ newerDeclaration,
506
+ olderDeclaration
507
+ )
508
+ );
509
+ }
510
+ const newerAnnotationDefinition = lookupEnum(
511
+ newerDeclaration.name,
512
+ _newerEnumMap
513
+ );
514
+ const olderAnnotationDefinition = lookupEnum(
515
+ olderDeclaration.name,
516
+ _olderEnumMap
517
+ );
518
+ (0, _invariant.default)(
519
+ newerAnnotationDefinition != null && olderAnnotationDefinition != null,
520
+ "Could not find enum definition"
521
+ );
522
+ return compareTypeAnnotation(
523
+ newerAnnotationDefinition,
524
+ olderAnnotationDefinition
525
+ );
526
+ }
527
+ function compareEnumDeclarationMemberArrays(newer, older) {
528
+ if (newer.length === 0 && older.length === 0) {
529
+ return {};
530
+ } else if (newer.length === 0) {
531
+ return {
532
+ missingMembers: older,
533
+ };
534
+ } else if (older.length === 0) {
535
+ return {
536
+ addedMembers: newer,
537
+ };
538
+ }
539
+ const newerHead = newer.pop();
540
+ const olderHead = older.pop();
541
+ (0, _invariant.default)(
542
+ newerHead != null && olderHead != null,
543
+ "Array is empty"
544
+ );
545
+ const newerName = newerHead.name;
546
+ const olderName = olderHead.name;
547
+ if (newerName === olderName) {
548
+ const comparedTypes = compareTypeAnnotation(
549
+ newerHead.value,
550
+ olderHead.value
551
+ );
552
+ const result = compareEnumDeclarationMemberArrays(newer, older);
553
+ switch (comparedTypes.status) {
554
+ case "matching":
555
+ return result;
556
+ case "error":
557
+ updateEnumMemberError(
558
+ newerName,
559
+ newerHead.value,
560
+ olderHead.value,
561
+ result
562
+ )(comparedTypes.errorLog);
563
+ return result;
564
+ case "skipped":
565
+ throw new Error(
566
+ "Internal error: returned 'skipped' for non-optional older type"
567
+ );
568
+ case "nullableChange":
569
+ case "properties":
570
+ case "functionChange":
571
+ case "positionalTypeChange":
572
+ case "members":
573
+ break;
574
+ default:
575
+ throw new Error("Unsupported status " + comparedTypes.status);
576
+ }
577
+ } else if (newerName > olderName) {
578
+ older.push(olderHead);
579
+ const result = compareEnumDeclarationMemberArrays(newer, older);
580
+ if (result.hasOwnProperty("addedMembers") && result.addedMembers) {
581
+ result.addedMembers.push(newerHead);
582
+ } else {
583
+ result.addedMembers = [newerHead];
584
+ }
585
+ return result;
586
+ } else if (newerName < olderName) {
587
+ newer.push(newerHead);
588
+ const result = compareEnumDeclarationMemberArrays(newer, older);
589
+ if (result.hasOwnProperty("missingMembers") && result.missingMembers) {
590
+ result.missingMembers.push(olderHead);
591
+ } else {
592
+ result.missingMembers = [olderHead];
593
+ }
594
+ return result;
595
+ }
596
+ throw new Error("Internal error: should not reach here");
597
+ }
598
+ function compareEnumDeclarationWithMembers(newerDeclaration, olderDeclaration) {
599
+ const sortedNewerTypes = Array.from(newerDeclaration.members).sort(
600
+ compareEnumMember
601
+ );
602
+ const sortedOlderTypes = Array.from(olderDeclaration.members).sort(
603
+ compareEnumMember
604
+ );
605
+ const result = compareEnumDeclarationMemberArrays(
606
+ sortedNewerTypes,
607
+ sortedOlderTypes
608
+ );
609
+ if ((0, _ComparisonResult.isMemberLogEmpty)(result)) {
610
+ return {
611
+ status: "matching",
612
+ };
613
+ } else if (result.errorMembers) {
614
+ return (0, _ComparisonResult.makeError)(
615
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
616
+ "Enum types do not match",
617
+ newerDeclaration,
618
+ olderDeclaration,
619
+ (0, _ComparisonResult.memberComparisonError)(
620
+ result.errorMembers.length > 1
621
+ ? "Enum contained members with type mismatches"
622
+ : "Enum contained a member with a type mismatch",
623
+ result.errorMembers
624
+ )
625
+ )
626
+ );
627
+ } else if (
628
+ (result.addedMembers &&
629
+ result.addedMembers.length > 0 &&
630
+ result.addedMembers.length === newerDeclaration.members.length) ||
631
+ (result.missingMembers &&
632
+ result.missingMembers.length > 0 &&
633
+ result.missingMembers.length === olderDeclaration.members.length)
634
+ ) {
635
+ return (0, _ComparisonResult.makeError)(
636
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
637
+ "Enum types do not match.",
638
+ newerDeclaration,
639
+ olderDeclaration
640
+ )
641
+ );
642
+ }
643
+ return {
644
+ status: "members",
645
+ memberLog: result,
646
+ };
647
+ }
648
+ function compareNullableChange(newerAnnotation, olderAnnotation) {
649
+ const newVoidRemoved =
650
+ newerAnnotation.type === "NullableTypeAnnotation"
651
+ ? removeNullableTypeAnnotations(newerAnnotation)
652
+ : newerAnnotation;
653
+ const oldVoidRemoved =
654
+ olderAnnotation.type === "NullableTypeAnnotation"
655
+ ? removeNullableTypeAnnotations(olderAnnotation)
656
+ : olderAnnotation;
657
+ const optionalNew = newVoidRemoved.type !== newerAnnotation.type;
658
+ const optionalOld = oldVoidRemoved.type !== olderAnnotation.type;
659
+ (0, _invariant.default)(
660
+ optionalNew !== optionalOld,
661
+ "compareNullableChange called with both being nullable"
662
+ );
663
+ const optionsReduced = !optionalNew && optionalOld;
664
+ if (
665
+ newVoidRemoved.type === "VoidTypeAnnotation" ||
666
+ oldVoidRemoved.type === "VoidTypeAnnotation"
667
+ ) {
668
+ return {
669
+ status: "nullableChange",
670
+ nullableLog: {
671
+ typeRefined: true,
672
+ optionsReduced,
673
+ interiorLog: null,
674
+ newType: newerAnnotation,
675
+ oldType: olderAnnotation,
676
+ },
677
+ };
678
+ }
679
+ const interiorLog = compareTypeAnnotation(newVoidRemoved, oldVoidRemoved);
680
+ switch (interiorLog.status) {
681
+ case "error":
682
+ return (0, _ComparisonResult.makeError)(
683
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
684
+ "Type annotations are not the same.",
685
+ newerAnnotation,
686
+ olderAnnotation
687
+ )
688
+ );
689
+ case "matching":
690
+ return {
691
+ status: "nullableChange",
692
+ nullableLog: {
693
+ typeRefined: false,
694
+ optionsReduced,
695
+ interiorLog,
696
+ newType: newerAnnotation,
697
+ oldType: olderAnnotation,
698
+ },
699
+ };
700
+ default:
701
+ return {
702
+ status: "nullableChange",
703
+ nullableLog: {
704
+ typeRefined: false,
705
+ optionsReduced,
706
+ interiorLog,
707
+ newType: newerAnnotation,
708
+ oldType: olderAnnotation,
709
+ },
710
+ };
711
+ }
712
+ }
713
+ function compareUnionTypes(newerType, olderType) {
714
+ if (newerType.memberType !== olderType.memberType) {
715
+ return (0, _ComparisonResult.makeError)(
716
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
717
+ "Union member type does not match",
718
+ newerType,
719
+ olderType
720
+ )
721
+ );
722
+ }
723
+ return {
724
+ status: "matching",
725
+ };
726
+ }
727
+ function comparePromiseTypes(newerType, olderType) {
728
+ if (newerType.elementType == null || olderType.elementType == null) {
729
+ return (0, _ComparisonResult.makeError)(
730
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
731
+ "Promise has differing arguments",
732
+ newerType,
733
+ olderType
734
+ )
735
+ );
736
+ }
737
+ (0, _invariant.default)(
738
+ newerType.elementType != null && olderType.elementType != null,
739
+ EQUALITY_MSG
740
+ );
741
+ return compareTypeAnnotation(newerType.elementType, olderType.elementType);
742
+ }
743
+ function compareGenericObjectTypes(newerType, olderType) {
744
+ if (
745
+ newerType.dictionaryValueType == null &&
746
+ olderType.dictionaryValueType == null
747
+ ) {
748
+ return {
749
+ status: "matching",
750
+ };
751
+ }
752
+ if (
753
+ newerType.dictionaryValueType != null &&
754
+ olderType.dictionaryValueType != null
755
+ ) {
756
+ return compareTypeAnnotation(
757
+ newerType.dictionaryValueType,
758
+ olderType.dictionaryValueType
759
+ );
760
+ }
761
+ return (0, _ComparisonResult.makeError)(
762
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
763
+ "Generic Object types do not have matching dictionary types",
764
+ newerType,
765
+ olderType
766
+ )
767
+ );
768
+ }
769
+ function compareNumberLiteralTypes(newerType, olderType) {
770
+ return newerType.value === olderType.value
771
+ ? {
772
+ status: "matching",
773
+ }
774
+ : (0, _ComparisonResult.makeError)(
775
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
776
+ "Numeric literals are not equal",
777
+ newerType,
778
+ olderType
779
+ )
780
+ );
781
+ }
782
+ function compareStringLiteralTypes(newerType, olderType) {
783
+ return newerType.value === olderType.value
784
+ ? {
785
+ status: "matching",
786
+ }
787
+ : (0, _ComparisonResult.makeError)(
788
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
789
+ "String literals are not equal",
790
+ newerType,
791
+ olderType
792
+ )
793
+ );
794
+ }
795
+ function compareStringLiteralUnionTypes(newerType, olderType) {
796
+ const results = compareArrayOfTypes(
797
+ true,
798
+ false,
799
+ newerType.types,
800
+ olderType.types
801
+ );
802
+ switch (results.status) {
803
+ case "length-mismatch":
804
+ throw new Error("length-mismatch returned with length changes allowed");
805
+ case "type-mismatch":
806
+ return (0, _ComparisonResult.makeError)(
807
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
808
+ `Subtype of union at position ${results.newIndex} did not match`,
809
+ newerType,
810
+ olderType,
811
+ results.error
812
+ )
813
+ );
814
+ case "subtypable-changes":
815
+ if (results.nestedChanges.length > 0) {
816
+ throw new Error(
817
+ "Unexpected inline objects/functions in string literal union"
818
+ );
819
+ }
820
+ if (results.addedElements.length > 0) {
821
+ return {
822
+ status: "positionalTypeChange",
823
+ changeLog: {
824
+ typeKind: "stringUnion",
825
+ nestedChanges: [],
826
+ addedElements: results.addedElements,
827
+ },
828
+ };
829
+ }
830
+ if (results.removedElements.length > 0) {
831
+ return {
832
+ status: "positionalTypeChange",
833
+ changeLog: {
834
+ typeKind: "stringUnion",
835
+ nestedChanges: [],
836
+ removedElements: results.removedElements,
837
+ },
838
+ };
839
+ }
840
+ console.log(JSON.stringify(results));
841
+ throw new Error("string union returned unexpected set of changes");
842
+ case "matching":
843
+ return {
844
+ status: "matching",
845
+ };
846
+ default:
847
+ throw new Error("Unknown status");
848
+ }
849
+ }
850
+ function compareFunctionTypes(newerType, olderType) {
851
+ const returnTypeResult = compareTypeAnnotation(
852
+ newerType.returnTypeAnnotation,
853
+ olderType.returnTypeAnnotation
854
+ );
855
+ if (returnTypeResult.status === "error") {
856
+ return (0, _ComparisonResult.makeError)(
857
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
858
+ "Function return types do not match",
859
+ newerType,
860
+ olderType,
861
+ returnTypeResult.errorLog
862
+ )
863
+ );
864
+ }
865
+ const functionChanges = {};
866
+ if (
867
+ returnTypeResult.status === "properties" ||
868
+ returnTypeResult.status === "members" ||
869
+ returnTypeResult.status === "functionChange" ||
870
+ returnTypeResult.status === "positionalTypeChange" ||
871
+ returnTypeResult.status === "nullableChange"
872
+ ) {
873
+ functionChanges.returnType = returnTypeResult;
874
+ }
875
+ const argumentResults = compareArrayOfTypes(
876
+ true,
877
+ true,
878
+ newerType.params.map((_) => _.typeAnnotation),
879
+ olderType.params.map((_) => _.typeAnnotation)
880
+ );
881
+ switch (argumentResults.status) {
882
+ case "length-mismatch":
883
+ return (0, _ComparisonResult.makeError)(
884
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
885
+ "Function types have differing length of arguments",
886
+ newerType,
887
+ olderType
888
+ )
889
+ );
890
+ case "type-mismatch":
891
+ return (0, _ComparisonResult.makeError)(
892
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
893
+ `Parameter at index ${argumentResults.newIndex} did not match`,
894
+ newerType,
895
+ olderType,
896
+ argumentResults.error
897
+ )
898
+ );
899
+ case "subtypable-changes":
900
+ functionChanges.parameterTypes = {
901
+ typeKind: "parameter",
902
+ nestedChanges: argumentResults.nestedChanges,
903
+ };
904
+ break;
905
+ case "matching":
906
+ default:
907
+ break;
908
+ }
909
+ if ((0, _ComparisonResult.isFunctionLogEmpty)(functionChanges)) {
910
+ return {
911
+ status: "matching",
912
+ };
913
+ }
914
+ return {
915
+ status: "functionChange",
916
+ functionChangeLog: functionChanges,
917
+ };
918
+ }
919
+ function compareArrayOfTypes(fixedOrder, fixedLength, newerTypes, olderTypes) {
920
+ const sameLength = newerTypes.length === olderTypes.length;
921
+ if (fixedLength && !sameLength) {
922
+ return {
923
+ status: "length-mismatch",
924
+ };
925
+ }
926
+ const nestedChanges = [];
927
+ const minLength = Math.min(newerTypes.length, olderTypes.length);
928
+ if (fixedOrder) {
929
+ for (let i = 0; i < minLength; i++) {
930
+ const result = compareTypeAnnotation(newerTypes[i], olderTypes[i]);
931
+ if (result.status === "error") {
932
+ return {
933
+ status: "type-mismatch",
934
+ error: result.errorLog,
935
+ newIndex: i,
936
+ oldIndex: i,
937
+ };
938
+ }
939
+ if (
940
+ result.status === "properties" ||
941
+ result.status === "members" ||
942
+ result.status === "functionChange" ||
943
+ result.status === "positionalTypeChange" ||
944
+ result.status === "nullableChange"
945
+ ) {
946
+ nestedChanges.push([i, i, result]);
947
+ }
948
+ }
949
+ if (nestedChanges.length === 0 && sameLength) {
950
+ return {
951
+ status: "matching",
952
+ };
953
+ }
954
+ const addedElements = [];
955
+ const removedElements = [];
956
+ if (newerTypes.length < olderTypes.length) {
957
+ const elements = olderTypes.slice(minLength, olderTypes.length);
958
+ for (let i = 0; i < elements.length; i++) {
959
+ removedElements.push([i + minLength + 1, elements[i]]);
960
+ }
961
+ }
962
+ if (newerTypes.length > olderTypes.length) {
963
+ const elements = newerTypes.slice(minLength, newerTypes.length);
964
+ for (let i = 0; i < elements.length; i++) {
965
+ addedElements.push([i + minLength + 1, elements[i]]);
966
+ }
967
+ }
968
+ return {
969
+ status: "subtypable-changes",
970
+ nestedChanges,
971
+ addedElements,
972
+ removedElements,
973
+ };
974
+ }
975
+ return compareArrayTypesOutOfOrder(
976
+ (0, _SortTypeAnnotations.sortTypeAnnotations)(newerTypes),
977
+ 0,
978
+ (0, _SortTypeAnnotations.sortTypeAnnotations)(olderTypes),
979
+ 0,
980
+ [],
981
+ [],
982
+ []
983
+ );
984
+ }
985
+ function compareArrayTypesOutOfOrder(
986
+ newerTypes,
987
+ newerIndex,
988
+ olderTypes,
989
+ olderIndex,
990
+ potentiallyAddedElements,
991
+ potentiallyRemovedElements,
992
+ nestedChanges
993
+ ) {
994
+ const newLength = newerTypes.length;
995
+ const oldLength = olderTypes.length;
996
+ if (newerIndex === newLength || olderIndex === oldLength) {
997
+ const [errors, added, removed] = resolvePotentials(
998
+ potentiallyAddedElements,
999
+ potentiallyRemovedElements
1000
+ );
1001
+ if (errors.length !== 0) {
1002
+ return {
1003
+ status: "type-mismatch",
1004
+ error: errors[0][0],
1005
+ oldIndex: errors[0][1],
1006
+ newIndex: errors[0][2],
1007
+ };
1008
+ }
1009
+ if (
1010
+ added.length === 0 &&
1011
+ removed.length === 0 &&
1012
+ nestedChanges.length === 0 &&
1013
+ newerIndex === newLength &&
1014
+ olderIndex === oldLength
1015
+ ) {
1016
+ return {
1017
+ status: "matching",
1018
+ };
1019
+ }
1020
+ if (newerIndex === newLength && olderIndex === oldLength) {
1021
+ return {
1022
+ status: "subtypable-changes",
1023
+ nestedChanges,
1024
+ addedElements: added,
1025
+ removedElements: removed,
1026
+ };
1027
+ }
1028
+ if (newerIndex === newLength) {
1029
+ return {
1030
+ status: "subtypable-changes",
1031
+ nestedChanges,
1032
+ addedElements: added,
1033
+ removedElements: removed.concat(
1034
+ olderTypes.slice(olderIndex, oldLength)
1035
+ ),
1036
+ };
1037
+ }
1038
+ return {
1039
+ status: "subtypable-changes",
1040
+ nestedChanges,
1041
+ addedElements: added.concat(newerTypes.slice(newerIndex, newLength)),
1042
+ removedElements: removed,
1043
+ };
1044
+ }
1045
+ const newTypePosn = newerTypes[newerIndex][0];
1046
+ const newType = newerTypes[newerIndex][1];
1047
+ const oldTypePosn = olderTypes[olderIndex][0];
1048
+ const oldType = olderTypes[olderIndex][1];
1049
+ const currentResult = compareTypeAnnotation(newType, oldType);
1050
+ const sortComparison = (0,
1051
+ _SortTypeAnnotations.compareTypeAnnotationForSorting)(
1052
+ newerTypes[newerIndex],
1053
+ olderTypes[olderIndex]
1054
+ );
1055
+ switch (currentResult.status) {
1056
+ case "matching":
1057
+ return compareArrayTypesOutOfOrder(
1058
+ newerTypes,
1059
+ newerIndex + 1,
1060
+ olderTypes,
1061
+ olderIndex + 1,
1062
+ potentiallyAddedElements,
1063
+ potentiallyRemovedElements,
1064
+ nestedChanges
1065
+ );
1066
+ case "properties":
1067
+ case "functionChange":
1068
+ case "positionalTypeChange":
1069
+ case "nullableChange":
1070
+ return compareArrayTypesOutOfOrder(
1071
+ newerTypes,
1072
+ newerIndex + 1,
1073
+ olderTypes,
1074
+ olderIndex + 1,
1075
+ potentiallyAddedElements,
1076
+ potentiallyRemovedElements,
1077
+ nestedChanges.concat[[oldTypePosn, newTypePosn, currentResult]]
1078
+ );
1079
+ case "error":
1080
+ if (sortComparison === 0) {
1081
+ return {
1082
+ status: "type-mismatch",
1083
+ error: currentResult.errorLog,
1084
+ newIndex: newTypePosn,
1085
+ oldIndex: oldTypePosn,
1086
+ };
1087
+ }
1088
+ if (sortComparison < 0) {
1089
+ return compareArrayTypesOutOfOrder(
1090
+ newerTypes,
1091
+ newerIndex + 1,
1092
+ olderTypes,
1093
+ olderIndex,
1094
+ potentiallyAddedElements.concat([
1095
+ {
1096
+ olderPosition: oldTypePosn,
1097
+ newerPosition: newTypePosn,
1098
+ error: currentResult.errorLog,
1099
+ annotation: newType,
1100
+ },
1101
+ ]),
1102
+ potentiallyRemovedElements,
1103
+ nestedChanges
1104
+ );
1105
+ }
1106
+ return compareArrayTypesOutOfOrder(
1107
+ newerTypes,
1108
+ newerIndex,
1109
+ olderTypes,
1110
+ olderIndex + 1,
1111
+ potentiallyAddedElements,
1112
+ potentiallyRemovedElements.concat([
1113
+ {
1114
+ olderPosition: oldTypePosn,
1115
+ newerPosition: newTypePosn,
1116
+ error: currentResult.errorLog,
1117
+ annotation: oldType,
1118
+ },
1119
+ ]),
1120
+ nestedChanges
1121
+ );
1122
+ case "skipped":
1123
+ throw new Error(
1124
+ "Unexpected skipped status for array of type annotations"
1125
+ );
1126
+ default:
1127
+ throw new Error("Unsupported status " + currentResult.status);
1128
+ }
1129
+ }
1130
+ function resolvePotentials(potentiallyAdded, potentiallyRemoved) {
1131
+ const addedLength = potentiallyAdded.length;
1132
+ const removedLength = potentiallyRemoved.length;
1133
+ if (addedLength === 0 && removedLength === 0) {
1134
+ return [[], [], []];
1135
+ }
1136
+ if (addedLength === 0) {
1137
+ return [
1138
+ [],
1139
+ [],
1140
+ potentiallyRemoved.map((removed) => [
1141
+ removed.olderPosition,
1142
+ removed.annotation,
1143
+ ]),
1144
+ ];
1145
+ }
1146
+ if (removedLength === 0) {
1147
+ return [
1148
+ [],
1149
+ potentiallyAdded.map((added) => [added.newerPosition, added.annotation]),
1150
+ [],
1151
+ ];
1152
+ }
1153
+ const addedHead = potentiallyAdded[0];
1154
+ const removedHead = potentiallyRemoved[0];
1155
+ if (addedHead.olderPosition === removedHead.olderPosition) {
1156
+ return [
1157
+ [[addedHead.error, addedHead.olderPosition, addedHead.newerPosition]],
1158
+ [],
1159
+ [],
1160
+ ];
1161
+ }
1162
+ if (removedHead.newerPosition === addedHead.newerPosition) {
1163
+ return [
1164
+ [
1165
+ [
1166
+ removedHead.error,
1167
+ removedHead.olderPosition,
1168
+ removedHead.newerPosition,
1169
+ ],
1170
+ ],
1171
+ [],
1172
+ [],
1173
+ ];
1174
+ }
1175
+ const sortedOrder = (0, _SortTypeAnnotations.compareTypeAnnotationForSorting)(
1176
+ [addedHead.newerPosition, addedHead.annotation],
1177
+ [removedHead.olderPosition, removedHead.annotation]
1178
+ );
1179
+ if (sortedOrder === 0) {
1180
+ const [errors, added, removed] = resolvePotentials(
1181
+ potentiallyAdded.slice(1, addedLength),
1182
+ potentiallyRemoved.slice(1, removedLength)
1183
+ );
1184
+ return [
1185
+ errors,
1186
+ added.concat([[addedHead.newerPosition, addedHead.annotation]]),
1187
+ removed.concat([[removedHead.olderPosition, removedHead.annotation]]),
1188
+ ];
1189
+ }
1190
+ if (sortedOrder < 0) {
1191
+ const [errors, added, removed] = resolvePotentials(
1192
+ potentiallyAdded.slice(1, addedLength),
1193
+ potentiallyRemoved
1194
+ );
1195
+ return [
1196
+ errors,
1197
+ added.concat([[addedHead.newerPosition, addedHead.annotation]]),
1198
+ removed,
1199
+ ];
1200
+ }
1201
+ const [errors, added, removed] = resolvePotentials(
1202
+ potentiallyAdded,
1203
+ potentiallyRemoved.slice(1, removedLength)
1204
+ );
1205
+ return [
1206
+ errors,
1207
+ added,
1208
+ removed.concat([[removedHead.olderPosition, removedHead.annotation]]),
1209
+ ];
1210
+ }
1211
+ function compareEventEmitterTypes(newerAnnotation, olderAnnotation) {
1212
+ const comparison = compareTypeAnnotation(
1213
+ newerAnnotation.typeAnnotation,
1214
+ olderAnnotation.typeAnnotation
1215
+ );
1216
+ if (comparison.status === "error") {
1217
+ return (0, _ComparisonResult.makeError)(
1218
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
1219
+ "EventEmitter eventTypes are not equivalent",
1220
+ newerAnnotation,
1221
+ olderAnnotation,
1222
+ comparison.errorLog
1223
+ )
1224
+ );
1225
+ }
1226
+ return comparison;
1227
+ }
1228
+ function compareReservedTypeAnnotation(newerAnnotation, olderAnnotation) {
1229
+ if (newerAnnotation.name !== olderAnnotation.name) {
1230
+ return (0, _ComparisonResult.makeError)(
1231
+ (0, _ComparisonResult.typeAnnotationComparisonError)(
1232
+ "Types are not equivalent",
1233
+ newerAnnotation,
1234
+ olderAnnotation
1235
+ )
1236
+ );
1237
+ }
1238
+ switch (newerAnnotation.name) {
1239
+ case "RootTag":
1240
+ case "ColorPrimitive":
1241
+ case "ImageSourcePrimitive":
1242
+ case "PointPrimitive":
1243
+ case "EdgeInsetsPrimitive":
1244
+ case "ImageRequestPrimitive":
1245
+ case "DimensionPrimitive":
1246
+ return {
1247
+ status: "matching",
1248
+ };
1249
+ default:
1250
+ newerAnnotation.name;
1251
+ throw new Error("Unknown reserved type " + newerAnnotation.name);
1252
+ }
1253
+ }