@effect/language-service 0.64.1 → 0.66.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/README.md +30 -39
- package/cli.js +3713 -986
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +1326 -308
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +1370 -333
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +1324 -306
- package/transform.js.map +1 -1
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
// node_modules/.pnpm/effect@3.19.
|
|
3
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Function.js
|
|
4
4
|
var isFunction = (input) => typeof input === "function";
|
|
5
5
|
var dual = function(arity, body) {
|
|
6
6
|
if (typeof arity === "function") {
|
|
@@ -98,7 +98,7 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
// node_modules/.pnpm/effect@3.19.
|
|
101
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Equivalence.js
|
|
102
102
|
var make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
|
|
103
103
|
var array = (item) => make((self, that) => {
|
|
104
104
|
if (self.length !== that.length) {
|
|
@@ -113,7 +113,7 @@ var array = (item) => make((self, that) => {
|
|
|
113
113
|
return true;
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
-
// node_modules/.pnpm/effect@3.19.
|
|
116
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/GlobalValue.js
|
|
117
117
|
var globalStoreId = `effect/GlobalValue`;
|
|
118
118
|
var globalStore;
|
|
119
119
|
var globalValue = (id, compute) => {
|
|
@@ -127,7 +127,7 @@ var globalValue = (id, compute) => {
|
|
|
127
127
|
return globalStore.get(id);
|
|
128
128
|
};
|
|
129
129
|
|
|
130
|
-
// node_modules/.pnpm/effect@3.19.
|
|
130
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Predicate.js
|
|
131
131
|
var isString = (input) => typeof input === "string";
|
|
132
132
|
var isNumber = (input) => typeof input === "number";
|
|
133
133
|
var isBoolean = (input) => typeof input === "boolean";
|
|
@@ -138,10 +138,10 @@ var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) &&
|
|
|
138
138
|
var isTagged = /* @__PURE__ */ dual(2, (self, tag) => hasProperty(self, "_tag") && self["_tag"] === tag);
|
|
139
139
|
var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
|
|
140
140
|
|
|
141
|
-
// node_modules/.pnpm/effect@3.19.
|
|
141
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/errors.js
|
|
142
142
|
var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
|
|
143
143
|
|
|
144
|
-
// node_modules/.pnpm/effect@3.19.
|
|
144
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Utils.js
|
|
145
145
|
var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
|
|
146
146
|
var GenKindImpl = class {
|
|
147
147
|
value;
|
|
@@ -263,7 +263,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
|
|
|
263
263
|
var genConstructor = function* () {
|
|
264
264
|
}.constructor;
|
|
265
265
|
|
|
266
|
-
// node_modules/.pnpm/effect@3.19.
|
|
266
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Hash.js
|
|
267
267
|
var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
|
|
268
268
|
var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
|
|
269
269
|
var hash = (self) => {
|
|
@@ -372,7 +372,7 @@ var cached = function() {
|
|
|
372
372
|
return hash2;
|
|
373
373
|
};
|
|
374
374
|
|
|
375
|
-
// node_modules/.pnpm/effect@3.19.
|
|
375
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Equal.js
|
|
376
376
|
var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
|
|
377
377
|
function equals() {
|
|
378
378
|
if (arguments.length === 1) {
|
|
@@ -428,7 +428,7 @@ function compareBoth(self, that) {
|
|
|
428
428
|
var isEqual = (u) => hasProperty(u, symbol2);
|
|
429
429
|
var equivalence = () => equals;
|
|
430
430
|
|
|
431
|
-
// node_modules/.pnpm/effect@3.19.
|
|
431
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Inspectable.js
|
|
432
432
|
var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
433
433
|
var toJSON = (x) => {
|
|
434
434
|
try {
|
|
@@ -486,7 +486,7 @@ var redact = (u) => {
|
|
|
486
486
|
return u;
|
|
487
487
|
};
|
|
488
488
|
|
|
489
|
-
// node_modules/.pnpm/effect@3.19.
|
|
489
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Pipeable.js
|
|
490
490
|
var pipeArguments = (self, args2) => {
|
|
491
491
|
switch (args2.length) {
|
|
492
492
|
case 0:
|
|
@@ -519,16 +519,16 @@ var pipeArguments = (self, args2) => {
|
|
|
519
519
|
}
|
|
520
520
|
};
|
|
521
521
|
|
|
522
|
-
// node_modules/.pnpm/effect@3.19.
|
|
522
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/opCodes/effect.js
|
|
523
523
|
var OP_COMMIT = "Commit";
|
|
524
524
|
var OP_FAILURE = "Failure";
|
|
525
525
|
var OP_WITH_RUNTIME = "WithRuntime";
|
|
526
526
|
|
|
527
|
-
// node_modules/.pnpm/effect@3.19.
|
|
528
|
-
var moduleVersion = "3.19.
|
|
527
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/version.js
|
|
528
|
+
var moduleVersion = "3.19.14";
|
|
529
529
|
var getCurrentVersion = () => moduleVersion;
|
|
530
530
|
|
|
531
|
-
// node_modules/.pnpm/effect@3.19.
|
|
531
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/effectable.js
|
|
532
532
|
var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
|
|
533
533
|
var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
|
|
534
534
|
var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
|
|
@@ -615,7 +615,7 @@ var StructuralCommitPrototype = {
|
|
|
615
615
|
...StructuralPrototype
|
|
616
616
|
};
|
|
617
617
|
|
|
618
|
-
// node_modules/.pnpm/effect@3.19.
|
|
618
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/option.js
|
|
619
619
|
var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
|
|
620
620
|
var CommonProto = {
|
|
621
621
|
...EffectPrototype,
|
|
@@ -673,7 +673,7 @@ var some = (value) => {
|
|
|
673
673
|
return a;
|
|
674
674
|
};
|
|
675
675
|
|
|
676
|
-
// node_modules/.pnpm/effect@3.19.
|
|
676
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/either.js
|
|
677
677
|
var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
|
|
678
678
|
var CommonProto2 = {
|
|
679
679
|
...EffectPrototype,
|
|
@@ -735,7 +735,7 @@ var right = (right3) => {
|
|
|
735
735
|
return a;
|
|
736
736
|
};
|
|
737
737
|
|
|
738
|
-
// node_modules/.pnpm/effect@3.19.
|
|
738
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Either.js
|
|
739
739
|
var right2 = right;
|
|
740
740
|
var left2 = left;
|
|
741
741
|
var isLeft2 = isLeft;
|
|
@@ -743,10 +743,10 @@ var isRight2 = isRight;
|
|
|
743
743
|
var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
|
|
744
744
|
var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
|
|
745
745
|
|
|
746
|
-
// node_modules/.pnpm/effect@3.19.
|
|
746
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/array.js
|
|
747
747
|
var isNonEmptyArray = (self) => self.length > 0;
|
|
748
748
|
|
|
749
|
-
// node_modules/.pnpm/effect@3.19.
|
|
749
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Order.js
|
|
750
750
|
var make2 = (compare) => (self, that) => self === that ? 0 : compare(self, that);
|
|
751
751
|
var string2 = /* @__PURE__ */ make2((self, that) => self < that ? -1 : 1);
|
|
752
752
|
var number2 = /* @__PURE__ */ make2((self, that) => self < that ? -1 : 1);
|
|
@@ -760,7 +760,7 @@ var combine2 = /* @__PURE__ */ dual(2, (self, that) => make2((a1, a2) => {
|
|
|
760
760
|
}));
|
|
761
761
|
var mapInput = /* @__PURE__ */ dual(2, (self, f) => make2((b1, b2) => self(f(b1), f(b2))));
|
|
762
762
|
|
|
763
|
-
// node_modules/.pnpm/effect@3.19.
|
|
763
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Option.js
|
|
764
764
|
var none2 = () => none;
|
|
765
765
|
var some2 = some;
|
|
766
766
|
var isNone2 = isNone;
|
|
@@ -771,7 +771,7 @@ var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nu
|
|
|
771
771
|
var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
|
|
772
772
|
var map2 = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : some2(f(self.value)));
|
|
773
773
|
|
|
774
|
-
// node_modules/.pnpm/effect@3.19.
|
|
774
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Record.js
|
|
775
775
|
var map3 = /* @__PURE__ */ dual(2, (self, f) => {
|
|
776
776
|
const out = {
|
|
777
777
|
...self
|
|
@@ -783,7 +783,7 @@ var map3 = /* @__PURE__ */ dual(2, (self, f) => {
|
|
|
783
783
|
});
|
|
784
784
|
var keys = (self) => Object.keys(self);
|
|
785
785
|
|
|
786
|
-
// node_modules/.pnpm/effect@3.19.
|
|
786
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Array.js
|
|
787
787
|
var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
|
|
788
788
|
var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
|
|
789
789
|
var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
|
|
@@ -887,7 +887,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
|
|
|
887
887
|
var dedupe = (self) => dedupeWith(self, equivalence());
|
|
888
888
|
var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
|
|
889
889
|
|
|
890
|
-
// node_modules/.pnpm/effect@3.19.
|
|
890
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Chunk.js
|
|
891
891
|
var TypeId3 = /* @__PURE__ */ Symbol.for("effect/Chunk");
|
|
892
892
|
function copy(src, srcPos, dest, destPos, len) {
|
|
893
893
|
for (let i = srcPos; i < Math.min(src.length, srcPos + len); i++) {
|
|
@@ -1183,14 +1183,14 @@ var isNonEmpty = (self) => self.length > 0;
|
|
|
1183
1183
|
var unsafeHead = (self) => unsafeGet2(self, 0);
|
|
1184
1184
|
var headNonEmpty2 = unsafeHead;
|
|
1185
1185
|
|
|
1186
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1186
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/config.js
|
|
1187
1187
|
var SIZE = 5;
|
|
1188
1188
|
var BUCKET_SIZE = /* @__PURE__ */ Math.pow(2, SIZE);
|
|
1189
1189
|
var MASK = BUCKET_SIZE - 1;
|
|
1190
1190
|
var MAX_INDEX_NODE = BUCKET_SIZE / 2;
|
|
1191
1191
|
var MIN_ARRAY_NODE = BUCKET_SIZE / 4;
|
|
1192
1192
|
|
|
1193
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1193
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/bitwise.js
|
|
1194
1194
|
function popcount(x) {
|
|
1195
1195
|
x -= x >> 1 & 1431655765;
|
|
1196
1196
|
x = (x & 858993459) + (x >> 2 & 858993459);
|
|
@@ -1209,13 +1209,13 @@ function fromBitmap(bitmap, bit) {
|
|
|
1209
1209
|
return popcount(bitmap & bit - 1);
|
|
1210
1210
|
}
|
|
1211
1211
|
|
|
1212
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1212
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/stack.js
|
|
1213
1213
|
var make4 = (value, previous) => ({
|
|
1214
1214
|
value,
|
|
1215
1215
|
previous
|
|
1216
1216
|
});
|
|
1217
1217
|
|
|
1218
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1218
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/array.js
|
|
1219
1219
|
function arrayUpdate(mutate3, at, v, arr) {
|
|
1220
1220
|
let out = arr;
|
|
1221
1221
|
if (!mutate3) {
|
|
@@ -1260,7 +1260,7 @@ function arraySpliceIn(mutate3, at, v, arr) {
|
|
|
1260
1260
|
return out;
|
|
1261
1261
|
}
|
|
1262
1262
|
|
|
1263
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1263
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/node.js
|
|
1264
1264
|
var EmptyNode = class _EmptyNode {
|
|
1265
1265
|
_tag = "EmptyNode";
|
|
1266
1266
|
modify(edit, _shift, f, hash2, key, size4) {
|
|
@@ -1495,7 +1495,7 @@ function mergeLeaves(edit, shift, h1, n1, h2, n2) {
|
|
|
1495
1495
|
}
|
|
1496
1496
|
}
|
|
1497
1497
|
|
|
1498
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1498
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap.js
|
|
1499
1499
|
var HashMapSymbolKey = "effect/HashMap";
|
|
1500
1500
|
var HashMapTypeId = /* @__PURE__ */ Symbol.for(HashMapSymbolKey);
|
|
1501
1501
|
var HashMapProto = {
|
|
@@ -1707,7 +1707,7 @@ var reduce2 = /* @__PURE__ */ dual(3, (self, zero2, f) => {
|
|
|
1707
1707
|
return zero2;
|
|
1708
1708
|
});
|
|
1709
1709
|
|
|
1710
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1710
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashSet.js
|
|
1711
1711
|
var HashSetSymbolKey = "effect/HashSet";
|
|
1712
1712
|
var HashSetTypeId = /* @__PURE__ */ Symbol.for(HashSetSymbolKey);
|
|
1713
1713
|
var HashSetProto = {
|
|
@@ -1769,13 +1769,13 @@ var union2 = /* @__PURE__ */ dual(2, (self, that) => mutate(empty4(), (set2) =>
|
|
|
1769
1769
|
}));
|
|
1770
1770
|
var forEach2 = /* @__PURE__ */ dual(2, (self, f) => forEach(self._keyMap, (_, k) => f(k)));
|
|
1771
1771
|
|
|
1772
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1772
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/HashSet.js
|
|
1773
1773
|
var empty5 = empty4;
|
|
1774
1774
|
var size3 = size2;
|
|
1775
1775
|
var add2 = add;
|
|
1776
1776
|
var union3 = union2;
|
|
1777
1777
|
|
|
1778
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1778
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/data.js
|
|
1779
1779
|
var ArrayProto = /* @__PURE__ */ Object.assign(/* @__PURE__ */ Object.create(Array.prototype), {
|
|
1780
1780
|
[symbol]() {
|
|
1781
1781
|
return cached(this, array2(this));
|
|
@@ -1798,7 +1798,7 @@ var Structural = /* @__PURE__ */ (function() {
|
|
|
1798
1798
|
return Structural2;
|
|
1799
1799
|
})();
|
|
1800
1800
|
|
|
1801
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1801
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/opCodes/cause.js
|
|
1802
1802
|
var OP_DIE = "Die";
|
|
1803
1803
|
var OP_EMPTY = "Empty";
|
|
1804
1804
|
var OP_FAIL = "Fail";
|
|
@@ -1806,7 +1806,7 @@ var OP_INTERRUPT = "Interrupt";
|
|
|
1806
1806
|
var OP_PARALLEL = "Parallel";
|
|
1807
1807
|
var OP_SEQUENTIAL = "Sequential";
|
|
1808
1808
|
|
|
1809
|
-
// node_modules/.pnpm/effect@3.19.
|
|
1809
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/cause.js
|
|
1810
1810
|
var CauseSymbolKey = "effect/Cause";
|
|
1811
1811
|
var CauseTypeId = /* @__PURE__ */ Symbol.for(CauseSymbolKey);
|
|
1812
1812
|
var variance = {
|
|
@@ -2238,7 +2238,7 @@ var prettyErrors = (cause) => reduceWithContext(cause, void 0, {
|
|
|
2238
2238
|
sequentialCase: (_, l, r) => [...l, ...r]
|
|
2239
2239
|
});
|
|
2240
2240
|
|
|
2241
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2241
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/singleShotGen.js
|
|
2242
2242
|
var SingleShotGen2 = class _SingleShotGen {
|
|
2243
2243
|
self;
|
|
2244
2244
|
called = false;
|
|
@@ -2268,7 +2268,7 @@ var SingleShotGen2 = class _SingleShotGen {
|
|
|
2268
2268
|
}
|
|
2269
2269
|
};
|
|
2270
2270
|
|
|
2271
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2271
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/core.js
|
|
2272
2272
|
var EffectTypeId2 = /* @__PURE__ */ Symbol.for("effect/Effect");
|
|
2273
2273
|
var EffectPrimitive = class {
|
|
2274
2274
|
_op;
|
|
@@ -2552,7 +2552,7 @@ var currentSpanFromFiber = (fiber) => {
|
|
|
2552
2552
|
return span !== void 0 && span._tag === "Span" ? some2(span) : none2();
|
|
2553
2553
|
};
|
|
2554
2554
|
|
|
2555
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2555
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Data.js
|
|
2556
2556
|
var Class2 = Structural;
|
|
2557
2557
|
var Error2 = /* @__PURE__ */ (function() {
|
|
2558
2558
|
const plainArgsSymbol = /* @__PURE__ */ Symbol.for("effect/Data/Error/plainArgs");
|
|
@@ -2590,10 +2590,10 @@ var TaggedError = (tag) => {
|
|
|
2590
2590
|
return O.BaseEffectError;
|
|
2591
2591
|
};
|
|
2592
2592
|
|
|
2593
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2593
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/encoding/common.js
|
|
2594
2594
|
var encoder = /* @__PURE__ */ new TextEncoder();
|
|
2595
2595
|
|
|
2596
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2596
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/encoding/base64.js
|
|
2597
2597
|
var encode = (bytes) => {
|
|
2598
2598
|
const length = bytes.length;
|
|
2599
2599
|
let result = "";
|
|
@@ -2619,13 +2619,13 @@ var encode = (bytes) => {
|
|
|
2619
2619
|
};
|
|
2620
2620
|
var base64abc = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"];
|
|
2621
2621
|
|
|
2622
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2622
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/encoding/base64Url.js
|
|
2623
2623
|
var encode2 = (data) => encode(data).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
2624
2624
|
|
|
2625
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2625
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Encoding.js
|
|
2626
2626
|
var encodeBase64Url = (input) => typeof input === "string" ? encode2(encoder.encode(input)) : encode2(input);
|
|
2627
2627
|
|
|
2628
|
-
// node_modules/.pnpm/effect@3.19.
|
|
2628
|
+
// node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Graph.js
|
|
2629
2629
|
var TypeId4 = "~effect/Graph";
|
|
2630
2630
|
var Edge = class extends Class2 {
|
|
2631
2631
|
};
|
|
@@ -3454,7 +3454,7 @@ var defaults = {
|
|
|
3454
3454
|
diagnosticSeverity: {},
|
|
3455
3455
|
diagnosticsName: true,
|
|
3456
3456
|
missingDiagnosticNextLine: "warning",
|
|
3457
|
-
|
|
3457
|
+
includeSuggestionsInTsc: true,
|
|
3458
3458
|
quickinfo: true,
|
|
3459
3459
|
quickinfoEffectParameters: "whentruncated",
|
|
3460
3460
|
quickinfoMaximumLength: -1,
|
|
@@ -3478,7 +3478,7 @@ var defaults = {
|
|
|
3478
3478
|
skipLeadingPath: ["src/"]
|
|
3479
3479
|
}],
|
|
3480
3480
|
extendedKeyDetection: false,
|
|
3481
|
-
pipeableMinArgCount:
|
|
3481
|
+
pipeableMinArgCount: 2,
|
|
3482
3482
|
layerGraphFollowDepth: 0,
|
|
3483
3483
|
mermaidProvider: "mermaid.live"
|
|
3484
3484
|
};
|
|
@@ -3501,7 +3501,7 @@ function parse(config) {
|
|
|
3501
3501
|
diagnosticSeverity: isObject(config) && hasProperty(config, "diagnosticSeverity") && isRecord(config.diagnosticSeverity) ? parseDiagnosticSeverity(config.diagnosticSeverity) : defaults.diagnosticSeverity,
|
|
3502
3502
|
diagnosticsName: isObject(config) && hasProperty(config, "diagnosticsName") && isBoolean(config.diagnosticsName) ? config.diagnosticsName : defaults.diagnosticsName,
|
|
3503
3503
|
missingDiagnosticNextLine: isObject(config) && hasProperty(config, "missingDiagnosticNextLine") && isString(config.missingDiagnosticNextLine) && isValidSeverityLevel(config.missingDiagnosticNextLine) ? config.missingDiagnosticNextLine : defaults.missingDiagnosticNextLine,
|
|
3504
|
-
|
|
3504
|
+
includeSuggestionsInTsc: isObject(config) && hasProperty(config, "includeSuggestionsInTsc") && isBoolean(config.includeSuggestionsInTsc) ? config.includeSuggestionsInTsc : defaults.includeSuggestionsInTsc,
|
|
3505
3505
|
quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : defaults.quickinfo,
|
|
3506
3506
|
quickinfoEffectParameters: isObject(config) && hasProperty(config, "quickinfoEffectParameters") && isString(config.quickinfoEffectParameters) && ["always", "never", "whentruncated"].includes(config.quickinfoEffectParameters.toLowerCase()) ? config.quickinfoEffectParameters.toLowerCase() : defaults.quickinfoEffectParameters,
|
|
3507
3507
|
quickinfoMaximumLength: isObject(config) && hasProperty(config, "quickinfoMaximumLength") && isNumber(config.quickinfoMaximumLength) ? config.quickinfoMaximumLength : defaults.quickinfoMaximumLength,
|
|
@@ -4083,6 +4083,16 @@ function makeTypeScriptUtils(ts) {
|
|
|
4083
4083
|
function isDeclarationKind(kind) {
|
|
4084
4084
|
return kind === ts.SyntaxKind.ArrowFunction || kind === ts.SyntaxKind.BindingElement || kind === ts.SyntaxKind.ClassDeclaration || kind === ts.SyntaxKind.ClassExpression || kind === ts.SyntaxKind.ClassStaticBlockDeclaration || kind === ts.SyntaxKind.Constructor || kind === ts.SyntaxKind.EnumDeclaration || kind === ts.SyntaxKind.EnumMember || kind === ts.SyntaxKind.ExportSpecifier || kind === ts.SyntaxKind.FunctionDeclaration || kind === ts.SyntaxKind.FunctionExpression || kind === ts.SyntaxKind.GetAccessor || kind === ts.SyntaxKind.ImportClause || kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportSpecifier || kind === ts.SyntaxKind.InterfaceDeclaration || kind === ts.SyntaxKind.JsxAttribute || kind === ts.SyntaxKind.MethodDeclaration || kind === ts.SyntaxKind.MethodSignature || kind === ts.SyntaxKind.ModuleDeclaration || kind === ts.SyntaxKind.NamespaceExportDeclaration || kind === ts.SyntaxKind.NamespaceImport || kind === ts.SyntaxKind.NamespaceExport || kind === ts.SyntaxKind.Parameter || kind === ts.SyntaxKind.PropertyAssignment || kind === ts.SyntaxKind.PropertyDeclaration || kind === ts.SyntaxKind.PropertySignature || kind === ts.SyntaxKind.SetAccessor || kind === ts.SyntaxKind.ShorthandPropertyAssignment || kind === ts.SyntaxKind.TypeAliasDeclaration || kind === ts.SyntaxKind.TypeParameter || kind === ts.SyntaxKind.VariableDeclaration || kind === ts.SyntaxKind.JSDocTypedefTag || kind === ts.SyntaxKind.JSDocCallbackTag || kind === ts.SyntaxKind.JSDocPropertyTag || kind === ts.SyntaxKind.NamedTupleMember;
|
|
4085
4085
|
}
|
|
4086
|
+
function isVoidExpression(node) {
|
|
4087
|
+
const unwrapped = ts.isExpression(node) ? skipOuterExpressions(node) : node;
|
|
4088
|
+
if (ts.isVoidExpression(unwrapped) && ts.isNumericLiteral(unwrapped.expression) && unwrapped.expression.text === "0") {
|
|
4089
|
+
return true;
|
|
4090
|
+
}
|
|
4091
|
+
if (ts.isIdentifier(unwrapped) && ts.idText(unwrapped) === "undefined") {
|
|
4092
|
+
return true;
|
|
4093
|
+
}
|
|
4094
|
+
return false;
|
|
4095
|
+
}
|
|
4086
4096
|
return {
|
|
4087
4097
|
findNodeAtPositionIncludingTrivia,
|
|
4088
4098
|
parsePackageContentNameAndVersionFromScope,
|
|
@@ -4106,7 +4116,8 @@ function makeTypeScriptUtils(ts) {
|
|
|
4106
4116
|
getSourceFileOfNode,
|
|
4107
4117
|
isOuterExpression,
|
|
4108
4118
|
skipOuterExpressions,
|
|
4109
|
-
isDeclarationKind
|
|
4119
|
+
isDeclarationKind,
|
|
4120
|
+
isVoidExpression
|
|
4110
4121
|
};
|
|
4111
4122
|
}
|
|
4112
4123
|
|
|
@@ -5364,13 +5375,15 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
5364
5375
|
);
|
|
5365
5376
|
}
|
|
5366
5377
|
const propertyAccess = node.expression;
|
|
5378
|
+
const pipeArguments2 = node.arguments.slice(1);
|
|
5367
5379
|
return pipe(
|
|
5368
5380
|
isNodeReferenceToEffectModuleApi("fnUntraced")(propertyAccess),
|
|
5369
5381
|
map8(() => ({
|
|
5370
5382
|
node,
|
|
5371
5383
|
effectModule: propertyAccess.expression,
|
|
5372
5384
|
generatorFunction,
|
|
5373
|
-
body: generatorFunction.body
|
|
5385
|
+
body: generatorFunction.body,
|
|
5386
|
+
pipeArguments: pipeArguments2
|
|
5374
5387
|
}))
|
|
5375
5388
|
);
|
|
5376
5389
|
},
|
|
@@ -5409,19 +5422,112 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
5409
5422
|
);
|
|
5410
5423
|
}
|
|
5411
5424
|
const propertyAccess = expressionToTest;
|
|
5425
|
+
const pipeArguments2 = node.arguments.slice(1);
|
|
5412
5426
|
return pipe(
|
|
5413
5427
|
isNodeReferenceToEffectModuleApi("fn")(propertyAccess),
|
|
5414
5428
|
map8(() => ({
|
|
5415
5429
|
node,
|
|
5416
5430
|
generatorFunction,
|
|
5417
5431
|
effectModule: propertyAccess.expression,
|
|
5418
|
-
body: generatorFunction.body
|
|
5432
|
+
body: generatorFunction.body,
|
|
5433
|
+
pipeArguments: pipeArguments2
|
|
5419
5434
|
}))
|
|
5420
5435
|
);
|
|
5421
5436
|
},
|
|
5422
5437
|
"TypeParser.effectFnGen",
|
|
5423
5438
|
(node) => node
|
|
5424
5439
|
);
|
|
5440
|
+
const findEnclosingScopes = fn("TypeParser.findEnclosingScopes")(function* (startNode) {
|
|
5441
|
+
let currentParent = startNode.parent;
|
|
5442
|
+
let scopeNode = void 0;
|
|
5443
|
+
let effectGenResult = void 0;
|
|
5444
|
+
while (currentParent) {
|
|
5445
|
+
const nodeToCheck = currentParent;
|
|
5446
|
+
if (!scopeNode) {
|
|
5447
|
+
if (ts.isFunctionExpression(nodeToCheck) || ts.isFunctionDeclaration(nodeToCheck) || ts.isMethodDeclaration(nodeToCheck) || ts.isArrowFunction(nodeToCheck) || ts.isGetAccessorDeclaration(nodeToCheck) || ts.isSetAccessorDeclaration(nodeToCheck)) {
|
|
5448
|
+
scopeNode = nodeToCheck;
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
5451
|
+
if (!effectGenResult) {
|
|
5452
|
+
const isEffectGen = yield* pipe(
|
|
5453
|
+
effectGen(nodeToCheck),
|
|
5454
|
+
map8((result) => ({
|
|
5455
|
+
node: result.node,
|
|
5456
|
+
effectModule: result.effectModule,
|
|
5457
|
+
generatorFunction: result.generatorFunction,
|
|
5458
|
+
body: result.body
|
|
5459
|
+
})),
|
|
5460
|
+
orElse2(
|
|
5461
|
+
() => pipe(
|
|
5462
|
+
effectFnUntracedGen(nodeToCheck),
|
|
5463
|
+
map8((result) => ({
|
|
5464
|
+
node: result.node,
|
|
5465
|
+
effectModule: result.effectModule,
|
|
5466
|
+
generatorFunction: result.generatorFunction,
|
|
5467
|
+
body: result.body,
|
|
5468
|
+
pipeArguments: result.pipeArguments
|
|
5469
|
+
}))
|
|
5470
|
+
)
|
|
5471
|
+
),
|
|
5472
|
+
orElse2(
|
|
5473
|
+
() => pipe(
|
|
5474
|
+
effectFnGen(nodeToCheck),
|
|
5475
|
+
map8((result) => ({
|
|
5476
|
+
node: result.node,
|
|
5477
|
+
effectModule: result.effectModule,
|
|
5478
|
+
generatorFunction: result.generatorFunction,
|
|
5479
|
+
body: result.body,
|
|
5480
|
+
pipeArguments: result.pipeArguments
|
|
5481
|
+
}))
|
|
5482
|
+
)
|
|
5483
|
+
),
|
|
5484
|
+
option
|
|
5485
|
+
);
|
|
5486
|
+
if (isSome2(isEffectGen)) {
|
|
5487
|
+
effectGenResult = isEffectGen.value;
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5490
|
+
if (scopeNode && effectGenResult) {
|
|
5491
|
+
break;
|
|
5492
|
+
}
|
|
5493
|
+
currentParent = nodeToCheck.parent;
|
|
5494
|
+
}
|
|
5495
|
+
return { scopeNode, effectGen: effectGenResult };
|
|
5496
|
+
});
|
|
5497
|
+
const effectFn = cachedBy(
|
|
5498
|
+
function(node) {
|
|
5499
|
+
if (!ts.isCallExpression(node)) {
|
|
5500
|
+
return typeParserIssue("Node is not a call expression", void 0, node);
|
|
5501
|
+
}
|
|
5502
|
+
if (node.arguments.length === 0) {
|
|
5503
|
+
return typeParserIssue("Node has no arguments", void 0, node);
|
|
5504
|
+
}
|
|
5505
|
+
const regularFunction = node.arguments[0];
|
|
5506
|
+
if (!ts.isFunctionExpression(regularFunction) && !ts.isArrowFunction(regularFunction)) {
|
|
5507
|
+
return typeParserIssue("Node is not a function expression or arrow function", void 0, node);
|
|
5508
|
+
}
|
|
5509
|
+
if (ts.isFunctionExpression(regularFunction) && regularFunction.asteriskToken !== void 0) {
|
|
5510
|
+
return typeParserIssue("Node is a generator function, not a regular function", void 0, node);
|
|
5511
|
+
}
|
|
5512
|
+
const expressionToTest = ts.isCallExpression(node.expression) ? node.expression.expression : node.expression;
|
|
5513
|
+
if (!ts.isPropertyAccessExpression(expressionToTest)) {
|
|
5514
|
+
return typeParserIssue("Node is not a property access expression", void 0, node);
|
|
5515
|
+
}
|
|
5516
|
+
const propertyAccess = expressionToTest;
|
|
5517
|
+
const pipeArguments2 = node.arguments.slice(1);
|
|
5518
|
+
return pipe(
|
|
5519
|
+
isNodeReferenceToEffectModuleApi("fn")(propertyAccess),
|
|
5520
|
+
map8(() => ({
|
|
5521
|
+
node,
|
|
5522
|
+
effectModule: propertyAccess.expression,
|
|
5523
|
+
regularFunction,
|
|
5524
|
+
pipeArguments: pipeArguments2
|
|
5525
|
+
}))
|
|
5526
|
+
);
|
|
5527
|
+
},
|
|
5528
|
+
"TypeParser.effectFn",
|
|
5529
|
+
(node) => node
|
|
5530
|
+
);
|
|
5425
5531
|
const unnecessaryEffectGen2 = cachedBy(
|
|
5426
5532
|
fn("TypeParser.unnecessaryEffectGen")(function* (node) {
|
|
5427
5533
|
const { body } = yield* effectGen(node);
|
|
@@ -5533,6 +5639,28 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
5533
5639
|
`TypeParser.isNodeReferenceToEffectSchemaModuleApi(${memberName})`,
|
|
5534
5640
|
(node) => node
|
|
5535
5641
|
);
|
|
5642
|
+
const isEffectParseResultSourceFile = cachedBy(
|
|
5643
|
+
fn("TypeParser.isEffectParseResultSourceFile")(function* (sourceFile) {
|
|
5644
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
5645
|
+
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
5646
|
+
const parseIssueSymbol = typeChecker.tryGetMemberInModuleExports("ParseIssue", moduleSymbol);
|
|
5647
|
+
if (!parseIssueSymbol) return yield* typeParserIssue("ParseIssue type not found", void 0, sourceFile);
|
|
5648
|
+
const decodeSyncSymbol = typeChecker.tryGetMemberInModuleExports("decodeSync", moduleSymbol);
|
|
5649
|
+
if (!decodeSyncSymbol) return yield* typeParserIssue("decodeSync not found", void 0, sourceFile);
|
|
5650
|
+
const encodeSyncSymbol = typeChecker.tryGetMemberInModuleExports("encodeSync", moduleSymbol);
|
|
5651
|
+
if (!encodeSyncSymbol) return yield* typeParserIssue("encodeSync not found", void 0, sourceFile);
|
|
5652
|
+
return sourceFile;
|
|
5653
|
+
}),
|
|
5654
|
+
"TypeParser.isEffectParseResultSourceFile",
|
|
5655
|
+
(sourceFile) => sourceFile
|
|
5656
|
+
);
|
|
5657
|
+
const isNodeReferenceToEffectParseResultModuleApi = (memberName) => cachedBy(
|
|
5658
|
+
fn("TypeParser.isNodeReferenceToEffectParseResultModuleApi")(function* (node) {
|
|
5659
|
+
return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectParseResultSourceFile, memberName);
|
|
5660
|
+
}),
|
|
5661
|
+
`TypeParser.isNodeReferenceToEffectParseResultModuleApi(${memberName})`,
|
|
5662
|
+
(node) => node
|
|
5663
|
+
);
|
|
5536
5664
|
const contextTagVarianceStruct = (type, atLocation) => map8(
|
|
5537
5665
|
all(
|
|
5538
5666
|
varianceStructInvariantType(type, atLocation, "_Identifier"),
|
|
@@ -5602,6 +5730,23 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
5602
5730
|
"TypeParser.pipeCall",
|
|
5603
5731
|
(node) => node
|
|
5604
5732
|
);
|
|
5733
|
+
const singleArgCall = cachedBy(
|
|
5734
|
+
function(node) {
|
|
5735
|
+
if (!ts.isCallExpression(node)) {
|
|
5736
|
+
return typeParserIssue("Node is not a call expression", void 0, node);
|
|
5737
|
+
}
|
|
5738
|
+
if (node.arguments.length !== 1) {
|
|
5739
|
+
return typeParserIssue("Node must have exactly one argument", void 0, node);
|
|
5740
|
+
}
|
|
5741
|
+
return succeed({
|
|
5742
|
+
node,
|
|
5743
|
+
callee: node.expression,
|
|
5744
|
+
subject: node.arguments[0]
|
|
5745
|
+
});
|
|
5746
|
+
},
|
|
5747
|
+
"TypeParser.singleArgCall",
|
|
5748
|
+
(node) => node
|
|
5749
|
+
);
|
|
5605
5750
|
const scopeType = cachedBy(
|
|
5606
5751
|
fn("TypeParser.scopeType")(function* (type, atLocation) {
|
|
5607
5752
|
yield* pipeableType(type, atLocation);
|
|
@@ -6140,9 +6285,333 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
6140
6285
|
`TypeParser.isNodeReferenceToEffectLayerModuleApi(${memberName})`,
|
|
6141
6286
|
(node) => node
|
|
6142
6287
|
);
|
|
6288
|
+
const lazyExpression = cachedBy(
|
|
6289
|
+
function(node) {
|
|
6290
|
+
if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
|
|
6291
|
+
return typeParserIssue("Node is not an arrow function or function expression", void 0, node);
|
|
6292
|
+
}
|
|
6293
|
+
if (node.parameters.length !== 0) {
|
|
6294
|
+
return typeParserIssue("Function must have zero parameters", void 0, node);
|
|
6295
|
+
}
|
|
6296
|
+
if (node.typeParameters && node.typeParameters.length > 0) {
|
|
6297
|
+
return typeParserIssue("Function must have no type parameters", void 0, node);
|
|
6298
|
+
}
|
|
6299
|
+
const body = node.body;
|
|
6300
|
+
const returnType = node.type;
|
|
6301
|
+
if (ts.isArrowFunction(node) && !ts.isBlock(body)) {
|
|
6302
|
+
return succeed({
|
|
6303
|
+
node,
|
|
6304
|
+
body,
|
|
6305
|
+
expression: body,
|
|
6306
|
+
returnType
|
|
6307
|
+
});
|
|
6308
|
+
}
|
|
6309
|
+
if (ts.isBlock(body)) {
|
|
6310
|
+
if (body.statements.length !== 1) {
|
|
6311
|
+
return typeParserIssue("Block must have exactly one statement", void 0, node);
|
|
6312
|
+
}
|
|
6313
|
+
const stmt = body.statements[0];
|
|
6314
|
+
if (!ts.isReturnStatement(stmt)) {
|
|
6315
|
+
return typeParserIssue("Statement must be a return statement", void 0, node);
|
|
6316
|
+
}
|
|
6317
|
+
if (!stmt.expression) {
|
|
6318
|
+
return typeParserIssue("Return statement must have an expression", void 0, node);
|
|
6319
|
+
}
|
|
6320
|
+
return succeed({
|
|
6321
|
+
node,
|
|
6322
|
+
body,
|
|
6323
|
+
expression: stmt.expression,
|
|
6324
|
+
returnType
|
|
6325
|
+
});
|
|
6326
|
+
}
|
|
6327
|
+
return typeParserIssue("Invalid function body", void 0, node);
|
|
6328
|
+
},
|
|
6329
|
+
"TypeParser.lazyExpression",
|
|
6330
|
+
(node) => node
|
|
6331
|
+
);
|
|
6332
|
+
const emptyFunction = cachedBy(
|
|
6333
|
+
function(node) {
|
|
6334
|
+
if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
|
|
6335
|
+
return typeParserIssue("Node is not an arrow function or function expression", void 0, node);
|
|
6336
|
+
}
|
|
6337
|
+
const body = node.body;
|
|
6338
|
+
const returnType = node.type;
|
|
6339
|
+
if (!ts.isBlock(body)) {
|
|
6340
|
+
return typeParserIssue("Body must be a block", void 0, node);
|
|
6341
|
+
}
|
|
6342
|
+
if (body.statements.length !== 0) {
|
|
6343
|
+
return typeParserIssue("Block must have zero statements", void 0, node);
|
|
6344
|
+
}
|
|
6345
|
+
return succeed({
|
|
6346
|
+
node,
|
|
6347
|
+
body,
|
|
6348
|
+
returnType
|
|
6349
|
+
});
|
|
6350
|
+
},
|
|
6351
|
+
"TypeParser.emptyFunction",
|
|
6352
|
+
(node) => node
|
|
6353
|
+
);
|
|
6354
|
+
const pipingFlows = (includeEffectFn) => cachedBy(
|
|
6355
|
+
fn("TypeParser.pipingFlows")(function* (sourceFile) {
|
|
6356
|
+
const result = [];
|
|
6357
|
+
const workQueue = [[sourceFile, void 0]];
|
|
6358
|
+
while (workQueue.length > 0) {
|
|
6359
|
+
const [node, parentFlow] = workQueue.pop();
|
|
6360
|
+
if (ts.isCallExpression(node)) {
|
|
6361
|
+
const parsed = yield* pipe(
|
|
6362
|
+
pipeCall(node),
|
|
6363
|
+
map8((p) => ({ _tag: "pipe", ...p })),
|
|
6364
|
+
orElse2(
|
|
6365
|
+
() => pipe(
|
|
6366
|
+
singleArgCall(node),
|
|
6367
|
+
map8((s) => ({ _tag: "call", ...s }))
|
|
6368
|
+
)
|
|
6369
|
+
),
|
|
6370
|
+
option
|
|
6371
|
+
);
|
|
6372
|
+
if (isSome2(parsed)) {
|
|
6373
|
+
const result2 = parsed.value;
|
|
6374
|
+
let transformations;
|
|
6375
|
+
let flowNode;
|
|
6376
|
+
let childrenToTraverse = [];
|
|
6377
|
+
if (result2._tag === "pipe") {
|
|
6378
|
+
const signature = typeChecker.getResolvedSignature(result2.node);
|
|
6379
|
+
const typeArguments = signature ? typeChecker.getTypeArgumentsForResolvedSignature(signature) : void 0;
|
|
6380
|
+
transformations = [];
|
|
6381
|
+
for (let i = 0; i < result2.args.length; i++) {
|
|
6382
|
+
const arg = result2.args[i];
|
|
6383
|
+
const outType = typeArguments?.[i + 1];
|
|
6384
|
+
if (ts.isCallExpression(arg)) {
|
|
6385
|
+
transformations.push({
|
|
6386
|
+
callee: arg.expression,
|
|
6387
|
+
// e.g., Effect.map
|
|
6388
|
+
args: Array.from(arg.arguments),
|
|
6389
|
+
// e.g., [(x) => x + 1]
|
|
6390
|
+
outType,
|
|
6391
|
+
kind: result2.kind
|
|
6392
|
+
});
|
|
6393
|
+
} else {
|
|
6394
|
+
transformations.push({
|
|
6395
|
+
callee: arg,
|
|
6396
|
+
// e.g., Effect.asVoid
|
|
6397
|
+
args: void 0,
|
|
6398
|
+
outType,
|
|
6399
|
+
kind: result2.kind
|
|
6400
|
+
});
|
|
6401
|
+
}
|
|
6402
|
+
}
|
|
6403
|
+
flowNode = result2.node;
|
|
6404
|
+
childrenToTraverse = result2.args;
|
|
6405
|
+
} else {
|
|
6406
|
+
const callSignature = typeChecker.getResolvedSignature(node);
|
|
6407
|
+
const outType = callSignature ? typeChecker.getReturnTypeOfSignature(callSignature) : void 0;
|
|
6408
|
+
transformations = [{
|
|
6409
|
+
callee: result2.callee,
|
|
6410
|
+
args: void 0,
|
|
6411
|
+
outType,
|
|
6412
|
+
kind: "call"
|
|
6413
|
+
}];
|
|
6414
|
+
flowNode = node;
|
|
6415
|
+
}
|
|
6416
|
+
if (parentFlow) {
|
|
6417
|
+
parentFlow.transformations.unshift(...transformations);
|
|
6418
|
+
parentFlow.subject = {
|
|
6419
|
+
node: result2.subject,
|
|
6420
|
+
outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
|
|
6421
|
+
};
|
|
6422
|
+
workQueue.push([result2.subject, parentFlow]);
|
|
6423
|
+
} else {
|
|
6424
|
+
const newFlow = {
|
|
6425
|
+
node: flowNode,
|
|
6426
|
+
subject: {
|
|
6427
|
+
node: result2.subject,
|
|
6428
|
+
outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
|
|
6429
|
+
},
|
|
6430
|
+
transformations
|
|
6431
|
+
};
|
|
6432
|
+
workQueue.push([result2.subject, newFlow]);
|
|
6433
|
+
}
|
|
6434
|
+
for (const child of childrenToTraverse) {
|
|
6435
|
+
ts.forEachChild(child, (c) => {
|
|
6436
|
+
workQueue.push([c, void 0]);
|
|
6437
|
+
});
|
|
6438
|
+
}
|
|
6439
|
+
continue;
|
|
6440
|
+
}
|
|
6441
|
+
if (includeEffectFn) {
|
|
6442
|
+
const effectFnGenParsed = yield* pipe(effectFnGen(node), option);
|
|
6443
|
+
const effectFnUntracedGenParsed = isNone2(effectFnGenParsed) ? yield* pipe(effectFnUntracedGen(node), option) : none2();
|
|
6444
|
+
const effectFnNonGenParsed = isNone2(effectFnGenParsed) && isNone2(effectFnUntracedGenParsed) ? yield* pipe(effectFn(node), option) : none2();
|
|
6445
|
+
const isEffectFnGen = isSome2(effectFnGenParsed);
|
|
6446
|
+
const isEffectFnUntracedGen = isSome2(effectFnUntracedGenParsed);
|
|
6447
|
+
const isEffectFnNonGen = isSome2(effectFnNonGenParsed);
|
|
6448
|
+
const transformationKind = isEffectFnUntracedGen ? "effectFnUntraced" : "effectFn";
|
|
6449
|
+
if (isEffectFnGen || isEffectFnUntracedGen) {
|
|
6450
|
+
const effectFnParsed = isEffectFnGen ? effectFnGenParsed : effectFnUntracedGenParsed;
|
|
6451
|
+
if (isSome2(effectFnParsed) && effectFnParsed.value.pipeArguments.length > 0) {
|
|
6452
|
+
const fnResult = effectFnParsed.value;
|
|
6453
|
+
const pipeArgs = fnResult.pipeArguments;
|
|
6454
|
+
const transformations = [];
|
|
6455
|
+
let subjectType;
|
|
6456
|
+
for (let i = 0; i < pipeArgs.length; i++) {
|
|
6457
|
+
const arg = pipeArgs[i];
|
|
6458
|
+
const contextualType = typeChecker.getContextualType(arg);
|
|
6459
|
+
const callSigs = contextualType ? typeChecker.getSignaturesOfType(contextualType, ts.SignatureKind.Call) : [];
|
|
6460
|
+
const outType = callSigs.length > 0 ? typeChecker.getReturnTypeOfSignature(callSigs[0]) : void 0;
|
|
6461
|
+
if (i === 0 && callSigs.length > 0) {
|
|
6462
|
+
const params = callSigs[0].parameters;
|
|
6463
|
+
if (params.length > 0) {
|
|
6464
|
+
subjectType = typeChecker.getTypeOfSymbol(params[0]);
|
|
6465
|
+
}
|
|
6466
|
+
}
|
|
6467
|
+
if (ts.isCallExpression(arg)) {
|
|
6468
|
+
transformations.push({
|
|
6469
|
+
callee: arg.expression,
|
|
6470
|
+
args: Array.from(arg.arguments),
|
|
6471
|
+
outType,
|
|
6472
|
+
kind: transformationKind
|
|
6473
|
+
});
|
|
6474
|
+
} else {
|
|
6475
|
+
transformations.push({
|
|
6476
|
+
callee: arg,
|
|
6477
|
+
args: void 0,
|
|
6478
|
+
outType,
|
|
6479
|
+
kind: transformationKind
|
|
6480
|
+
});
|
|
6481
|
+
}
|
|
6482
|
+
}
|
|
6483
|
+
const newFlow = {
|
|
6484
|
+
node,
|
|
6485
|
+
subject: {
|
|
6486
|
+
node,
|
|
6487
|
+
outType: subjectType
|
|
6488
|
+
},
|
|
6489
|
+
transformations
|
|
6490
|
+
};
|
|
6491
|
+
result.push(newFlow);
|
|
6492
|
+
workQueue.push([fnResult.body, void 0]);
|
|
6493
|
+
for (const arg of pipeArgs) {
|
|
6494
|
+
ts.forEachChild(arg, (c) => {
|
|
6495
|
+
workQueue.push([c, void 0]);
|
|
6496
|
+
});
|
|
6497
|
+
}
|
|
6498
|
+
continue;
|
|
6499
|
+
}
|
|
6500
|
+
}
|
|
6501
|
+
if (isEffectFnNonGen && isSome2(effectFnNonGenParsed) && effectFnNonGenParsed.value.pipeArguments.length > 0) {
|
|
6502
|
+
const fnResult = effectFnNonGenParsed.value;
|
|
6503
|
+
const pipeArgs = fnResult.pipeArguments;
|
|
6504
|
+
const transformations = [];
|
|
6505
|
+
let subjectType;
|
|
6506
|
+
for (let i = 0; i < pipeArgs.length; i++) {
|
|
6507
|
+
const arg = pipeArgs[i];
|
|
6508
|
+
const contextualType = typeChecker.getContextualType(arg);
|
|
6509
|
+
const callSigs = contextualType ? typeChecker.getSignaturesOfType(contextualType, ts.SignatureKind.Call) : [];
|
|
6510
|
+
const outType = callSigs.length > 0 ? typeChecker.getReturnTypeOfSignature(callSigs[0]) : void 0;
|
|
6511
|
+
if (i === 0 && callSigs.length > 0) {
|
|
6512
|
+
const params = callSigs[0].parameters;
|
|
6513
|
+
if (params.length > 0) {
|
|
6514
|
+
subjectType = typeChecker.getTypeOfSymbol(params[0]);
|
|
6515
|
+
}
|
|
6516
|
+
}
|
|
6517
|
+
if (ts.isCallExpression(arg)) {
|
|
6518
|
+
transformations.push({
|
|
6519
|
+
callee: arg.expression,
|
|
6520
|
+
args: Array.from(arg.arguments),
|
|
6521
|
+
outType,
|
|
6522
|
+
kind: "effectFn"
|
|
6523
|
+
});
|
|
6524
|
+
} else {
|
|
6525
|
+
transformations.push({
|
|
6526
|
+
callee: arg,
|
|
6527
|
+
args: void 0,
|
|
6528
|
+
outType,
|
|
6529
|
+
kind: "effectFn"
|
|
6530
|
+
});
|
|
6531
|
+
}
|
|
6532
|
+
}
|
|
6533
|
+
const newFlow = {
|
|
6534
|
+
node,
|
|
6535
|
+
subject: {
|
|
6536
|
+
node,
|
|
6537
|
+
outType: subjectType
|
|
6538
|
+
},
|
|
6539
|
+
transformations
|
|
6540
|
+
};
|
|
6541
|
+
result.push(newFlow);
|
|
6542
|
+
const regularFn = fnResult.regularFunction;
|
|
6543
|
+
if (ts.isArrowFunction(regularFn)) {
|
|
6544
|
+
if (ts.isBlock(regularFn.body)) {
|
|
6545
|
+
workQueue.push([regularFn.body, void 0]);
|
|
6546
|
+
} else {
|
|
6547
|
+
workQueue.push([regularFn.body, void 0]);
|
|
6548
|
+
}
|
|
6549
|
+
} else if (regularFn.body) {
|
|
6550
|
+
workQueue.push([regularFn.body, void 0]);
|
|
6551
|
+
}
|
|
6552
|
+
for (const arg of pipeArgs) {
|
|
6553
|
+
ts.forEachChild(arg, (c) => {
|
|
6554
|
+
workQueue.push([c, void 0]);
|
|
6555
|
+
});
|
|
6556
|
+
}
|
|
6557
|
+
continue;
|
|
6558
|
+
}
|
|
6559
|
+
}
|
|
6560
|
+
}
|
|
6561
|
+
if (parentFlow && parentFlow.transformations.length > 0) {
|
|
6562
|
+
result.push(parentFlow);
|
|
6563
|
+
}
|
|
6564
|
+
ts.forEachChild(node, (child) => {
|
|
6565
|
+
workQueue.push([child, void 0]);
|
|
6566
|
+
});
|
|
6567
|
+
}
|
|
6568
|
+
result.sort((a, b) => a.node.pos - b.node.pos);
|
|
6569
|
+
return result;
|
|
6570
|
+
}),
|
|
6571
|
+
`TypeParser.pipingFlows(${includeEffectFn})`,
|
|
6572
|
+
(sourceFile) => sourceFile
|
|
6573
|
+
);
|
|
6574
|
+
const reconstructPipingFlow = (flow2) => {
|
|
6575
|
+
if (flow2.transformations.length > 0 && flow2.transformations.every((t) => t.kind === "effectFn" || t.kind === "effectFnUntraced")) {
|
|
6576
|
+
return flow2.subject.node;
|
|
6577
|
+
}
|
|
6578
|
+
let result = flow2.subject.node;
|
|
6579
|
+
for (const t of flow2.transformations) {
|
|
6580
|
+
if (t.kind === "call") {
|
|
6581
|
+
result = ts.factory.createCallExpression(
|
|
6582
|
+
t.callee,
|
|
6583
|
+
void 0,
|
|
6584
|
+
[result]
|
|
6585
|
+
);
|
|
6586
|
+
} else if (t.kind === "effectFn" || t.kind === "effectFnUntraced") {
|
|
6587
|
+
continue;
|
|
6588
|
+
} else {
|
|
6589
|
+
if (t.args) {
|
|
6590
|
+
const transformCall = ts.factory.createCallExpression(
|
|
6591
|
+
t.callee,
|
|
6592
|
+
void 0,
|
|
6593
|
+
t.args
|
|
6594
|
+
);
|
|
6595
|
+
result = ts.factory.createCallExpression(
|
|
6596
|
+
transformCall,
|
|
6597
|
+
void 0,
|
|
6598
|
+
[result]
|
|
6599
|
+
);
|
|
6600
|
+
} else {
|
|
6601
|
+
result = ts.factory.createCallExpression(
|
|
6602
|
+
t.callee,
|
|
6603
|
+
void 0,
|
|
6604
|
+
[result]
|
|
6605
|
+
);
|
|
6606
|
+
}
|
|
6607
|
+
}
|
|
6608
|
+
}
|
|
6609
|
+
return result;
|
|
6610
|
+
};
|
|
6143
6611
|
return {
|
|
6144
6612
|
isNodeReferenceToEffectModuleApi,
|
|
6145
6613
|
isNodeReferenceToEffectSchemaModuleApi,
|
|
6614
|
+
isNodeReferenceToEffectParseResultModuleApi,
|
|
6146
6615
|
isNodeReferenceToEffectDataModuleApi,
|
|
6147
6616
|
isNodeReferenceToEffectContextModuleApi,
|
|
6148
6617
|
isNodeReferenceToEffectSqlModelModuleApi,
|
|
@@ -6156,12 +6625,15 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
6156
6625
|
effectGen,
|
|
6157
6626
|
effectFnUntracedGen,
|
|
6158
6627
|
effectFnGen,
|
|
6628
|
+
findEnclosingScopes,
|
|
6629
|
+
effectFn,
|
|
6159
6630
|
extendsCauseYieldableError,
|
|
6160
6631
|
unnecessaryEffectGen: unnecessaryEffectGen2,
|
|
6161
6632
|
effectSchemaType,
|
|
6162
6633
|
contextTag,
|
|
6163
6634
|
pipeableType,
|
|
6164
6635
|
pipeCall,
|
|
6636
|
+
singleArgCall,
|
|
6165
6637
|
scopeType,
|
|
6166
6638
|
promiseLike,
|
|
6167
6639
|
extendsEffectTag,
|
|
@@ -6173,7 +6645,11 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
6173
6645
|
extendsDataTaggedError,
|
|
6174
6646
|
extendsDataTaggedClass,
|
|
6175
6647
|
extendsSchemaTaggedRequest,
|
|
6176
|
-
extendsEffectSqlModelClass
|
|
6648
|
+
extendsEffectSqlModelClass,
|
|
6649
|
+
lazyExpression,
|
|
6650
|
+
emptyFunction,
|
|
6651
|
+
pipingFlows,
|
|
6652
|
+
reconstructPipingFlow
|
|
6177
6653
|
};
|
|
6178
6654
|
}
|
|
6179
6655
|
|
|
@@ -7521,48 +7997,45 @@ var catchAllToMapError = createDiagnostic({
|
|
|
7521
7997
|
return none2();
|
|
7522
7998
|
});
|
|
7523
7999
|
};
|
|
7524
|
-
const
|
|
7525
|
-
const
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
while (nodeToVisit.length > 0) {
|
|
7531
|
-
const node = nodeToVisit.shift();
|
|
7532
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
7533
|
-
if (ts.isCallExpression(node)) {
|
|
8000
|
+
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
8001
|
+
for (const flow2 of flows) {
|
|
8002
|
+
for (const transformation of flow2.transformations) {
|
|
8003
|
+
if (!transformation.args || transformation.args.length === 0) {
|
|
8004
|
+
continue;
|
|
8005
|
+
}
|
|
7534
8006
|
const isCatchAllCall = yield* pipe(
|
|
7535
|
-
typeParser.isNodeReferenceToEffectModuleApi("catchAll")(
|
|
8007
|
+
typeParser.isNodeReferenceToEffectModuleApi("catchAll")(transformation.callee),
|
|
7536
8008
|
option
|
|
7537
8009
|
);
|
|
7538
|
-
if (
|
|
7539
|
-
|
|
7540
|
-
if (!callback) continue;
|
|
7541
|
-
const functionBody = getFunctionBody(callback);
|
|
7542
|
-
if (!functionBody) continue;
|
|
7543
|
-
const failCallInfo = yield* getEffectFailCallInfo(functionBody);
|
|
7544
|
-
if (isNone2(failCallInfo)) continue;
|
|
7545
|
-
const { failArg, failCall } = failCallInfo.value;
|
|
7546
|
-
report({
|
|
7547
|
-
location: node.expression,
|
|
7548
|
-
messageText: `You can use Effect.mapError instead of Effect.catchAll + Effect.fail to transform the error type.`,
|
|
7549
|
-
fixes: [{
|
|
7550
|
-
fixName: "catchAllToMapError_fix",
|
|
7551
|
-
description: "Replace with Effect.mapError",
|
|
7552
|
-
apply: gen(function* () {
|
|
7553
|
-
const changeTracker = yield* service(ChangeTracker);
|
|
7554
|
-
if (ts.isPropertyAccessExpression(node.expression)) {
|
|
7555
|
-
changeTracker.replaceNode(
|
|
7556
|
-
sourceFile,
|
|
7557
|
-
node.expression.name,
|
|
7558
|
-
ts.factory.createIdentifier("mapError")
|
|
7559
|
-
);
|
|
7560
|
-
}
|
|
7561
|
-
changeTracker.replaceNode(sourceFile, failCall, failArg);
|
|
7562
|
-
})
|
|
7563
|
-
}]
|
|
7564
|
-
});
|
|
8010
|
+
if (isNone2(isCatchAllCall)) {
|
|
8011
|
+
continue;
|
|
7565
8012
|
}
|
|
8013
|
+
const callback = transformation.args[0];
|
|
8014
|
+
if (!callback) continue;
|
|
8015
|
+
const functionBody = getFunctionBody(callback);
|
|
8016
|
+
if (!functionBody) continue;
|
|
8017
|
+
const failCallInfo = yield* getEffectFailCallInfo(functionBody);
|
|
8018
|
+
if (isNone2(failCallInfo)) continue;
|
|
8019
|
+
const { failArg, failCall } = failCallInfo.value;
|
|
8020
|
+
report({
|
|
8021
|
+
location: transformation.callee,
|
|
8022
|
+
messageText: `You can use Effect.mapError instead of Effect.catchAll + Effect.fail to transform the error type.`,
|
|
8023
|
+
fixes: [{
|
|
8024
|
+
fixName: "catchAllToMapError_fix",
|
|
8025
|
+
description: "Replace with Effect.mapError",
|
|
8026
|
+
apply: gen(function* () {
|
|
8027
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
8028
|
+
if (ts.isPropertyAccessExpression(transformation.callee)) {
|
|
8029
|
+
changeTracker.replaceNode(
|
|
8030
|
+
sourceFile,
|
|
8031
|
+
transformation.callee.name,
|
|
8032
|
+
ts.factory.createIdentifier("mapError")
|
|
8033
|
+
);
|
|
8034
|
+
}
|
|
8035
|
+
changeTracker.replaceNode(sourceFile, failCall, failArg);
|
|
8036
|
+
})
|
|
8037
|
+
}]
|
|
8038
|
+
});
|
|
7566
8039
|
}
|
|
7567
8040
|
}
|
|
7568
8041
|
})
|
|
@@ -7577,66 +8050,39 @@ var catchUnfailableEffect = createDiagnostic({
|
|
|
7577
8050
|
apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
|
|
7578
8051
|
const ts = yield* service(TypeScriptApi);
|
|
7579
8052
|
const typeParser = yield* service(TypeParser);
|
|
7580
|
-
const
|
|
7581
|
-
const
|
|
7582
|
-
const
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
while (nodeToVisit.length > 0) {
|
|
7589
|
-
const node = nodeToVisit.shift();
|
|
7590
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
7591
|
-
if (ts.isCallExpression(node)) {
|
|
7592
|
-
const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
|
|
8053
|
+
const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
|
|
8054
|
+
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
8055
|
+
for (const flow2 of flows) {
|
|
8056
|
+
for (let i = 0; i < flow2.transformations.length; i++) {
|
|
8057
|
+
const transformation = flow2.transformations[i];
|
|
8058
|
+
if (!transformation.args || transformation.args.length === 0) {
|
|
8059
|
+
continue;
|
|
8060
|
+
}
|
|
7593
8061
|
const isCatchCall = yield* pipe(
|
|
7594
8062
|
firstSuccessOf(
|
|
7595
|
-
catchFunctions.map((catchFn) => typeParser.isNodeReferenceToEffectModuleApi(catchFn)(
|
|
8063
|
+
catchFunctions.map((catchFn) => typeParser.isNodeReferenceToEffectModuleApi(catchFn)(transformation.callee))
|
|
7596
8064
|
),
|
|
7597
8065
|
option
|
|
7598
8066
|
);
|
|
7599
|
-
if (
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
effectTypeToCheck = typeArguments[argIndex];
|
|
7619
|
-
}
|
|
7620
|
-
}
|
|
7621
|
-
}
|
|
7622
|
-
if (effectTypeToCheck) {
|
|
7623
|
-
const effectType = yield* pipe(
|
|
7624
|
-
typeParser.effectType(effectTypeToCheck, node),
|
|
7625
|
-
option
|
|
7626
|
-
);
|
|
7627
|
-
if (isSome2(effectType)) {
|
|
7628
|
-
const { E } = effectType.value;
|
|
7629
|
-
if (E.flags & ts.TypeFlags.Never) {
|
|
7630
|
-
report({
|
|
7631
|
-
location: node.expression,
|
|
7632
|
-
messageText: `Looks like the previous effect never fails, so probably this error handling will never be triggered.`,
|
|
7633
|
-
fixes: []
|
|
7634
|
-
});
|
|
7635
|
-
}
|
|
7636
|
-
}
|
|
7637
|
-
}
|
|
7638
|
-
}
|
|
7639
|
-
}
|
|
8067
|
+
if (isNone2(isCatchCall)) {
|
|
8068
|
+
continue;
|
|
8069
|
+
}
|
|
8070
|
+
const inputType = i === 0 ? flow2.subject.outType : flow2.transformations[i - 1].outType;
|
|
8071
|
+
if (!inputType) {
|
|
8072
|
+
continue;
|
|
8073
|
+
}
|
|
8074
|
+
const effectType = yield* pipe(
|
|
8075
|
+
typeParser.effectType(inputType, transformation.callee),
|
|
8076
|
+
option
|
|
8077
|
+
);
|
|
8078
|
+
if (isSome2(effectType)) {
|
|
8079
|
+
const { E } = effectType.value;
|
|
8080
|
+
if (E.flags & ts.TypeFlags.Never) {
|
|
8081
|
+
report({
|
|
8082
|
+
location: transformation.callee,
|
|
8083
|
+
messageText: `Looks like the previous effect never fails, so probably this error handling will never be triggered.`,
|
|
8084
|
+
fixes: []
|
|
8085
|
+
});
|
|
7640
8086
|
}
|
|
7641
8087
|
}
|
|
7642
8088
|
}
|
|
@@ -7879,6 +8325,269 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
|
|
|
7879
8325
|
})
|
|
7880
8326
|
});
|
|
7881
8327
|
|
|
8328
|
+
// src/diagnostics/effectFnOpportunity.ts
|
|
8329
|
+
var effectFnOpportunity = createDiagnostic({
|
|
8330
|
+
name: "effectFnOpportunity",
|
|
8331
|
+
code: 41,
|
|
8332
|
+
description: "Suggests using Effect.fn for functions that returns an Effect",
|
|
8333
|
+
severity: "suggestion",
|
|
8334
|
+
apply: fn("effectFnOpportunity.apply")(function* (sourceFile, report) {
|
|
8335
|
+
const ts = yield* service(TypeScriptApi);
|
|
8336
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
8337
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
8338
|
+
const typeParser = yield* service(TypeParser);
|
|
8339
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
8340
|
+
const sourceEffectModuleName = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
8341
|
+
sourceFile,
|
|
8342
|
+
"effect",
|
|
8343
|
+
"Effect"
|
|
8344
|
+
) || "Effect";
|
|
8345
|
+
const findSingleReturnStatement = (block) => {
|
|
8346
|
+
if (block.statements.length !== 1) return void 0;
|
|
8347
|
+
const statement = block.statements[0];
|
|
8348
|
+
if (!ts.isReturnStatement(statement)) return void 0;
|
|
8349
|
+
return statement;
|
|
8350
|
+
};
|
|
8351
|
+
const getBodyExpression = (fnNode) => {
|
|
8352
|
+
if (ts.isArrowFunction(fnNode)) {
|
|
8353
|
+
if (ts.isBlock(fnNode.body)) {
|
|
8354
|
+
return findSingleReturnStatement(fnNode.body)?.expression;
|
|
8355
|
+
}
|
|
8356
|
+
return fnNode.body;
|
|
8357
|
+
} else if ((ts.isFunctionExpression(fnNode) || ts.isFunctionDeclaration(fnNode)) && fnNode.body) {
|
|
8358
|
+
return findSingleReturnStatement(fnNode.body)?.expression;
|
|
8359
|
+
}
|
|
8360
|
+
return void 0;
|
|
8361
|
+
};
|
|
8362
|
+
const getNameIdentifier = (node) => {
|
|
8363
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
8364
|
+
return node.name;
|
|
8365
|
+
}
|
|
8366
|
+
if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
|
|
8367
|
+
return node.parent.name;
|
|
8368
|
+
}
|
|
8369
|
+
if (node.parent && ts.isPropertyAssignment(node.parent)) {
|
|
8370
|
+
const name = node.parent.name;
|
|
8371
|
+
if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
|
|
8372
|
+
return name;
|
|
8373
|
+
}
|
|
8374
|
+
}
|
|
8375
|
+
if (node.parent && ts.isPropertyDeclaration(node.parent)) {
|
|
8376
|
+
const name = node.parent.name;
|
|
8377
|
+
if (ts.isIdentifier(name)) {
|
|
8378
|
+
return name;
|
|
8379
|
+
}
|
|
8380
|
+
}
|
|
8381
|
+
return void 0;
|
|
8382
|
+
};
|
|
8383
|
+
const areParametersReferencedIn = (fnNode, nodes2) => {
|
|
8384
|
+
if (fnNode.parameters.length === 0 || nodes2.length === 0) return false;
|
|
8385
|
+
const firstParam = fnNode.parameters[0];
|
|
8386
|
+
const lastParam = fnNode.parameters[fnNode.parameters.length - 1];
|
|
8387
|
+
const paramsStart = firstParam.pos;
|
|
8388
|
+
const paramsEnd = lastParam.end;
|
|
8389
|
+
const isSymbolDeclaredInParams = (symbol3) => {
|
|
8390
|
+
const declarations = symbol3.declarations;
|
|
8391
|
+
if (!declarations) return false;
|
|
8392
|
+
return declarations.some((decl) => decl.pos >= paramsStart && decl.end <= paramsEnd);
|
|
8393
|
+
};
|
|
8394
|
+
const nodesToVisit = [...nodes2];
|
|
8395
|
+
while (nodesToVisit.length > 0) {
|
|
8396
|
+
const node = nodesToVisit.shift();
|
|
8397
|
+
if (ts.isIdentifier(node)) {
|
|
8398
|
+
const symbol3 = typeChecker.getSymbolAtLocation(node);
|
|
8399
|
+
if (symbol3 && isSymbolDeclaredInParams(symbol3)) {
|
|
8400
|
+
return true;
|
|
8401
|
+
}
|
|
8402
|
+
}
|
|
8403
|
+
if (ts.isShorthandPropertyAssignment(node)) {
|
|
8404
|
+
const valueSymbol = typeChecker.getShorthandAssignmentValueSymbol(node);
|
|
8405
|
+
if (valueSymbol && isSymbolDeclaredInParams(valueSymbol)) {
|
|
8406
|
+
return true;
|
|
8407
|
+
}
|
|
8408
|
+
}
|
|
8409
|
+
ts.forEachChild(node, (child) => {
|
|
8410
|
+
nodesToVisit.push(child);
|
|
8411
|
+
return void 0;
|
|
8412
|
+
});
|
|
8413
|
+
}
|
|
8414
|
+
return false;
|
|
8415
|
+
};
|
|
8416
|
+
const tryParseGenOpportunity = (fnNode) => gen(function* () {
|
|
8417
|
+
const bodyExpression = getBodyExpression(fnNode);
|
|
8418
|
+
if (!bodyExpression) return yield* TypeParserIssue.issue;
|
|
8419
|
+
const { pipeArguments: pipeArguments2, subject } = yield* pipe(
|
|
8420
|
+
typeParser.pipeCall(bodyExpression),
|
|
8421
|
+
map8(({ args: args2, subject: subject2 }) => ({ subject: subject2, pipeArguments: args2 })),
|
|
8422
|
+
orElse2(() => succeed({ subject: bodyExpression, pipeArguments: [] }))
|
|
8423
|
+
);
|
|
8424
|
+
const { effectModule, generatorFunction } = yield* typeParser.effectGen(subject);
|
|
8425
|
+
const effectModuleName = ts.isIdentifier(effectModule) ? ts.idText(effectModule) : sourceEffectModuleName;
|
|
8426
|
+
return { effectModuleName, generatorFunction, pipeArguments: pipeArguments2 };
|
|
8427
|
+
});
|
|
8428
|
+
const isInsideEffectFn = (fnNode) => {
|
|
8429
|
+
const parent = fnNode.parent;
|
|
8430
|
+
if (!parent || !ts.isCallExpression(parent)) {
|
|
8431
|
+
return succeed(false);
|
|
8432
|
+
}
|
|
8433
|
+
if (parent.arguments[0] !== fnNode) {
|
|
8434
|
+
return succeed(false);
|
|
8435
|
+
}
|
|
8436
|
+
return pipe(
|
|
8437
|
+
typeParser.effectFn(parent),
|
|
8438
|
+
orElse2(() => typeParser.effectFnGen(parent)),
|
|
8439
|
+
orElse2(() => typeParser.effectFnUntracedGen(parent)),
|
|
8440
|
+
map8(() => true),
|
|
8441
|
+
orElse2(() => succeed(false))
|
|
8442
|
+
);
|
|
8443
|
+
};
|
|
8444
|
+
const parseEffectFnOpportunityTarget = (node) => gen(function* () {
|
|
8445
|
+
if (!ts.isFunctionExpression(node) && !ts.isArrowFunction(node) && !ts.isFunctionDeclaration(node)) {
|
|
8446
|
+
return yield* TypeParserIssue.issue;
|
|
8447
|
+
}
|
|
8448
|
+
if ((ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.asteriskToken) {
|
|
8449
|
+
return yield* TypeParserIssue.issue;
|
|
8450
|
+
}
|
|
8451
|
+
if (ts.isFunctionExpression(node) && node.name) {
|
|
8452
|
+
return yield* TypeParserIssue.issue;
|
|
8453
|
+
}
|
|
8454
|
+
if (yield* isInsideEffectFn(node)) {
|
|
8455
|
+
return yield* TypeParserIssue.issue;
|
|
8456
|
+
}
|
|
8457
|
+
const functionType = typeChecker.getTypeAtLocation(node);
|
|
8458
|
+
if (!functionType) return yield* TypeParserIssue.issue;
|
|
8459
|
+
const callSignatures = typeChecker.getSignaturesOfType(functionType, ts.SignatureKind.Call);
|
|
8460
|
+
if (callSignatures.length !== 1) return yield* TypeParserIssue.issue;
|
|
8461
|
+
const signature = callSignatures[0];
|
|
8462
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signature);
|
|
8463
|
+
const unionMembers = typeCheckerUtils.unrollUnionMembers(returnType);
|
|
8464
|
+
yield* all(...unionMembers.map((member) => typeParser.strictEffectType(member, node)));
|
|
8465
|
+
const nameIdentifier = getNameIdentifier(node);
|
|
8466
|
+
const traceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
|
|
8467
|
+
if (!traceName) return yield* TypeParserIssue.issue;
|
|
8468
|
+
const opportunity = yield* pipe(
|
|
8469
|
+
tryParseGenOpportunity(node),
|
|
8470
|
+
orElse2(
|
|
8471
|
+
() => succeed({ effectModuleName: sourceEffectModuleName, pipeArguments: [], generatorFunction: void 0 })
|
|
8472
|
+
)
|
|
8473
|
+
);
|
|
8474
|
+
return {
|
|
8475
|
+
node,
|
|
8476
|
+
nameIdentifier,
|
|
8477
|
+
effectModuleName: opportunity.effectModuleName,
|
|
8478
|
+
traceName,
|
|
8479
|
+
pipeArguments: opportunity.pipeArguments,
|
|
8480
|
+
generatorFunction: opportunity.generatorFunction,
|
|
8481
|
+
hasParamsInPipeArgs: areParametersReferencedIn(node, opportunity.pipeArguments)
|
|
8482
|
+
};
|
|
8483
|
+
});
|
|
8484
|
+
const getFunctionBodyBlock = (node) => {
|
|
8485
|
+
if (ts.isArrowFunction(node)) {
|
|
8486
|
+
if (ts.isBlock(node.body)) {
|
|
8487
|
+
return node.body;
|
|
8488
|
+
}
|
|
8489
|
+
return ts.factory.createBlock([ts.factory.createReturnStatement(node.body)], true);
|
|
8490
|
+
}
|
|
8491
|
+
return node.body;
|
|
8492
|
+
};
|
|
8493
|
+
const isGeneratorFunction = (node) => {
|
|
8494
|
+
if (ts.isArrowFunction(node)) return false;
|
|
8495
|
+
return node.asteriskToken !== void 0;
|
|
8496
|
+
};
|
|
8497
|
+
const createEffectFnNode = (originalNode, innerFunction, effectModuleName, traceName, pipeArguments2) => {
|
|
8498
|
+
const isGenerator = isGeneratorFunction(innerFunction);
|
|
8499
|
+
const newFunction = ts.factory.createFunctionExpression(
|
|
8500
|
+
void 0,
|
|
8501
|
+
isGenerator ? ts.factory.createToken(ts.SyntaxKind.AsteriskToken) : void 0,
|
|
8502
|
+
void 0,
|
|
8503
|
+
originalNode.typeParameters,
|
|
8504
|
+
originalNode.parameters,
|
|
8505
|
+
void 0,
|
|
8506
|
+
getFunctionBodyBlock(innerFunction)
|
|
8507
|
+
);
|
|
8508
|
+
let fnExpression = ts.factory.createPropertyAccessExpression(
|
|
8509
|
+
ts.factory.createIdentifier(effectModuleName),
|
|
8510
|
+
"fn"
|
|
8511
|
+
);
|
|
8512
|
+
if (traceName) {
|
|
8513
|
+
fnExpression = ts.factory.createCallExpression(
|
|
8514
|
+
fnExpression,
|
|
8515
|
+
void 0,
|
|
8516
|
+
[ts.factory.createStringLiteral(traceName)]
|
|
8517
|
+
);
|
|
8518
|
+
}
|
|
8519
|
+
const effectFnCall = ts.factory.createCallExpression(fnExpression, void 0, [newFunction, ...pipeArguments2]);
|
|
8520
|
+
if (ts.isFunctionDeclaration(originalNode)) {
|
|
8521
|
+
return tsUtils.tryPreserveDeclarationSemantics(originalNode, effectFnCall, false);
|
|
8522
|
+
}
|
|
8523
|
+
return effectFnCall;
|
|
8524
|
+
};
|
|
8525
|
+
const createEffectFnUntracedNode = (originalNode, innerFunction, effectModuleName, pipeArguments2) => {
|
|
8526
|
+
const isGenerator = isGeneratorFunction(innerFunction);
|
|
8527
|
+
const newFunction = ts.factory.createFunctionExpression(
|
|
8528
|
+
void 0,
|
|
8529
|
+
isGenerator ? ts.factory.createToken(ts.SyntaxKind.AsteriskToken) : void 0,
|
|
8530
|
+
void 0,
|
|
8531
|
+
originalNode.typeParameters,
|
|
8532
|
+
originalNode.parameters,
|
|
8533
|
+
void 0,
|
|
8534
|
+
getFunctionBodyBlock(innerFunction)
|
|
8535
|
+
);
|
|
8536
|
+
const effectFnCall = ts.factory.createCallExpression(
|
|
8537
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(effectModuleName), "fnUntraced"),
|
|
8538
|
+
void 0,
|
|
8539
|
+
[newFunction, ...pipeArguments2]
|
|
8540
|
+
);
|
|
8541
|
+
if (ts.isFunctionDeclaration(originalNode)) {
|
|
8542
|
+
return tsUtils.tryPreserveDeclarationSemantics(originalNode, effectFnCall, false);
|
|
8543
|
+
}
|
|
8544
|
+
return effectFnCall;
|
|
8545
|
+
};
|
|
8546
|
+
const nodeToVisit = [];
|
|
8547
|
+
const appendNodeToVisit = (node) => {
|
|
8548
|
+
nodeToVisit.push(node);
|
|
8549
|
+
return void 0;
|
|
8550
|
+
};
|
|
8551
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
8552
|
+
while (nodeToVisit.length > 0) {
|
|
8553
|
+
const node = nodeToVisit.shift();
|
|
8554
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
8555
|
+
const target = yield* pipe(parseEffectFnOpportunityTarget(node), option);
|
|
8556
|
+
if (isNone2(target)) continue;
|
|
8557
|
+
if (target.value.hasParamsInPipeArgs) continue;
|
|
8558
|
+
const { effectModuleName, nameIdentifier, node: targetNode, pipeArguments: pipeArguments2, traceName } = target.value;
|
|
8559
|
+
const innerFunction = target.value.generatorFunction ?? targetNode;
|
|
8560
|
+
const fixes = [];
|
|
8561
|
+
fixes.push({
|
|
8562
|
+
fixName: "effectFnOpportunity_toEffectFn",
|
|
8563
|
+
description: traceName ? `Convert to Effect.fn("${traceName}")` : "Convert to Effect.fn",
|
|
8564
|
+
apply: gen(function* () {
|
|
8565
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
8566
|
+
const newNode = createEffectFnNode(targetNode, innerFunction, effectModuleName, traceName, pipeArguments2);
|
|
8567
|
+
changeTracker.replaceNode(sourceFile, targetNode, newNode);
|
|
8568
|
+
})
|
|
8569
|
+
});
|
|
8570
|
+
if (target.value.generatorFunction) {
|
|
8571
|
+
fixes.push({
|
|
8572
|
+
fixName: "effectFnOpportunity_toEffectFnUntraced",
|
|
8573
|
+
description: "Convert to Effect.fnUntraced",
|
|
8574
|
+
apply: gen(function* () {
|
|
8575
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
8576
|
+
const newNode = createEffectFnUntracedNode(targetNode, innerFunction, effectModuleName, pipeArguments2);
|
|
8577
|
+
changeTracker.replaceNode(sourceFile, targetNode, newNode);
|
|
8578
|
+
})
|
|
8579
|
+
});
|
|
8580
|
+
}
|
|
8581
|
+
const pipeArgsSuffix = pipeArguments2.length > 0 ? ` Effect.fn also accepts the piped transformations as additional arguments.` : ``;
|
|
8582
|
+
report({
|
|
8583
|
+
location: nameIdentifier ?? targetNode,
|
|
8584
|
+
messageText: target.value.generatorFunction ? `This function could benefit from Effect.fn's automatic tracing and concise syntax, or Effect.fnUntraced to get just a more concise syntax.${pipeArgsSuffix}` : `This function could benefit from Effect.fn's automatic tracing and concise syntax.${pipeArgsSuffix}`,
|
|
8585
|
+
fixes
|
|
8586
|
+
});
|
|
8587
|
+
}
|
|
8588
|
+
})
|
|
8589
|
+
});
|
|
8590
|
+
|
|
7882
8591
|
// src/diagnostics/effectGenUsesAdapter.ts
|
|
7883
8592
|
var effectGenUsesAdapter = createDiagnostic({
|
|
7884
8593
|
name: "effectGenUsesAdapter",
|
|
@@ -7966,6 +8675,70 @@ var effectInVoidSuccess = createDiagnostic({
|
|
|
7966
8675
|
})
|
|
7967
8676
|
});
|
|
7968
8677
|
|
|
8678
|
+
// src/diagnostics/effectMapVoid.ts
|
|
8679
|
+
var effectMapVoid = createDiagnostic({
|
|
8680
|
+
name: "effectMapVoid",
|
|
8681
|
+
code: 40,
|
|
8682
|
+
description: "Suggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {})",
|
|
8683
|
+
severity: "suggestion",
|
|
8684
|
+
apply: fn("effectMapVoid.apply")(function* (sourceFile, report) {
|
|
8685
|
+
const ts = yield* service(TypeScriptApi);
|
|
8686
|
+
const typeParser = yield* service(TypeParser);
|
|
8687
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
8688
|
+
const nodeToVisit = [];
|
|
8689
|
+
const appendNodeToVisit = (node) => {
|
|
8690
|
+
nodeToVisit.push(node);
|
|
8691
|
+
return void 0;
|
|
8692
|
+
};
|
|
8693
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
8694
|
+
while (nodeToVisit.length > 0) {
|
|
8695
|
+
const node = nodeToVisit.shift();
|
|
8696
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
8697
|
+
if (ts.isCallExpression(node)) {
|
|
8698
|
+
const isMapCall = yield* pipe(
|
|
8699
|
+
typeParser.isNodeReferenceToEffectModuleApi("map")(node.expression),
|
|
8700
|
+
option
|
|
8701
|
+
);
|
|
8702
|
+
if (isSome2(isMapCall)) {
|
|
8703
|
+
const callback = node.arguments[0];
|
|
8704
|
+
if (!callback) continue;
|
|
8705
|
+
const match3 = yield* pipe(
|
|
8706
|
+
typeParser.emptyFunction(callback),
|
|
8707
|
+
orElse2(
|
|
8708
|
+
() => pipe(
|
|
8709
|
+
typeParser.lazyExpression(callback),
|
|
8710
|
+
flatMap4(
|
|
8711
|
+
(lazy) => tsUtils.isVoidExpression(lazy.expression) ? succeed(lazy) : typeParserIssue("Expression is not void")
|
|
8712
|
+
)
|
|
8713
|
+
)
|
|
8714
|
+
),
|
|
8715
|
+
option
|
|
8716
|
+
);
|
|
8717
|
+
if (isNone2(match3)) continue;
|
|
8718
|
+
report({
|
|
8719
|
+
location: node.expression,
|
|
8720
|
+
messageText: "Effect.asVoid can be used instead to discard the success value",
|
|
8721
|
+
fixes: [{
|
|
8722
|
+
fixName: "effectMapVoid_fix",
|
|
8723
|
+
description: "Replace with Effect.asVoid",
|
|
8724
|
+
apply: gen(function* () {
|
|
8725
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
8726
|
+
if (ts.isPropertyAccessExpression(node.expression)) {
|
|
8727
|
+
const newNode = ts.factory.createPropertyAccessExpression(
|
|
8728
|
+
node.expression.expression,
|
|
8729
|
+
ts.factory.createIdentifier("asVoid")
|
|
8730
|
+
);
|
|
8731
|
+
changeTracker.replaceNode(sourceFile, node, newNode);
|
|
8732
|
+
}
|
|
8733
|
+
})
|
|
8734
|
+
}]
|
|
8735
|
+
});
|
|
8736
|
+
}
|
|
8737
|
+
}
|
|
8738
|
+
}
|
|
8739
|
+
})
|
|
8740
|
+
});
|
|
8741
|
+
|
|
7969
8742
|
// src/diagnostics/floatingEffect.ts
|
|
7970
8743
|
var floatingEffect = createDiagnostic({
|
|
7971
8744
|
name: "floatingEffect",
|
|
@@ -8574,75 +9347,153 @@ var missedPipeableOpportunity = createDiagnostic({
|
|
|
8574
9347
|
apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
|
|
8575
9348
|
const ts = yield* service(TypeScriptApi);
|
|
8576
9349
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
8577
|
-
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
8578
9350
|
const typeParser = yield* service(TypeParser);
|
|
8579
9351
|
const options = yield* service(LanguageServicePluginOptions);
|
|
8580
|
-
const
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
9352
|
+
const isSafelyPipeableCallee = (callee) => {
|
|
9353
|
+
if (ts.isCallExpression(callee)) {
|
|
9354
|
+
return true;
|
|
9355
|
+
}
|
|
9356
|
+
if (ts.isArrowFunction(callee)) {
|
|
9357
|
+
return true;
|
|
9358
|
+
}
|
|
9359
|
+
if (ts.isFunctionExpression(callee)) {
|
|
9360
|
+
return true;
|
|
9361
|
+
}
|
|
9362
|
+
if (ts.isParenthesizedExpression(callee)) {
|
|
9363
|
+
return isSafelyPipeableCallee(callee.expression);
|
|
9364
|
+
}
|
|
9365
|
+
if (ts.isIdentifier(callee)) {
|
|
9366
|
+
const symbol3 = typeChecker.getSymbolAtLocation(callee);
|
|
9367
|
+
if (!symbol3) return false;
|
|
9368
|
+
if (symbol3.flags & (ts.SymbolFlags.Module | ts.SymbolFlags.Namespace | ts.SymbolFlags.ValueModule)) {
|
|
9369
|
+
return true;
|
|
9370
|
+
}
|
|
9371
|
+
const declarations = symbol3.declarations;
|
|
9372
|
+
if (declarations && declarations.length > 0) {
|
|
9373
|
+
const decl = declarations[0];
|
|
9374
|
+
if (ts.isFunctionDeclaration(decl) || ts.isVariableDeclaration(decl) || ts.isImportSpecifier(decl) || ts.isImportClause(decl) || ts.isNamespaceImport(decl)) {
|
|
9375
|
+
return true;
|
|
9376
|
+
}
|
|
9377
|
+
}
|
|
9378
|
+
return false;
|
|
9379
|
+
}
|
|
9380
|
+
if (ts.isPropertyAccessExpression(callee)) {
|
|
9381
|
+
const subject = callee.expression;
|
|
9382
|
+
const symbol3 = typeChecker.getSymbolAtLocation(subject);
|
|
9383
|
+
if (!symbol3) return false;
|
|
9384
|
+
if (symbol3.flags & (ts.SymbolFlags.Module | ts.SymbolFlags.Namespace | ts.SymbolFlags.ValueModule)) {
|
|
9385
|
+
return true;
|
|
9386
|
+
}
|
|
9387
|
+
const declarations = symbol3.declarations;
|
|
9388
|
+
if (declarations && declarations.length > 0) {
|
|
9389
|
+
const decl = declarations[0];
|
|
9390
|
+
if (ts.isNamespaceImport(decl) || ts.isSourceFile(decl) || ts.isModuleDeclaration(decl)) {
|
|
9391
|
+
return true;
|
|
9392
|
+
}
|
|
9393
|
+
}
|
|
9394
|
+
return false;
|
|
9395
|
+
}
|
|
9396
|
+
return false;
|
|
8584
9397
|
};
|
|
8585
|
-
const
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
9398
|
+
const flows = yield* typeParser.pipingFlows(false)(sourceFile);
|
|
9399
|
+
for (const flow2 of flows) {
|
|
9400
|
+
if (flow2.transformations.length < options.pipeableMinArgCount) {
|
|
9401
|
+
continue;
|
|
9402
|
+
}
|
|
9403
|
+
const finalType = flow2.transformations[flow2.transformations.length - 1].outType;
|
|
9404
|
+
if (!finalType) {
|
|
9405
|
+
continue;
|
|
9406
|
+
}
|
|
9407
|
+
const callSigs = typeChecker.getSignaturesOfType(finalType, ts.SignatureKind.Call);
|
|
9408
|
+
if (callSigs.length > 0) {
|
|
9409
|
+
continue;
|
|
9410
|
+
}
|
|
9411
|
+
const isPipeableAtIndex = function* (index) {
|
|
9412
|
+
if (index === 0) {
|
|
9413
|
+
const subjectType = flow2.subject.outType;
|
|
9414
|
+
if (!subjectType) return false;
|
|
9415
|
+
const result = yield* pipe(
|
|
9416
|
+
typeParser.pipeableType(subjectType, flow2.subject.node),
|
|
9417
|
+
option
|
|
9418
|
+
);
|
|
9419
|
+
return result._tag === "Some";
|
|
9420
|
+
} else {
|
|
9421
|
+
const t = flow2.transformations[index - 1];
|
|
9422
|
+
if (!t.outType) return false;
|
|
9423
|
+
const result = yield* pipe(
|
|
9424
|
+
typeParser.pipeableType(t.outType, flow2.node),
|
|
9425
|
+
option
|
|
9426
|
+
);
|
|
9427
|
+
return result._tag === "Some";
|
|
9428
|
+
}
|
|
9429
|
+
};
|
|
9430
|
+
let searchStartIndex = 0;
|
|
9431
|
+
while (searchStartIndex <= flow2.transformations.length) {
|
|
9432
|
+
let firstPipeableIndex = -1;
|
|
9433
|
+
for (let i = searchStartIndex; i <= flow2.transformations.length; i++) {
|
|
9434
|
+
if (yield* isPipeableAtIndex(i)) {
|
|
9435
|
+
firstPipeableIndex = i;
|
|
9436
|
+
break;
|
|
8601
9437
|
}
|
|
8602
9438
|
}
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
const
|
|
8609
|
-
if (!
|
|
8610
|
-
const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
|
|
8611
|
-
if (pipeableType) {
|
|
8612
|
-
report({
|
|
8613
|
-
location: parentChain[0],
|
|
8614
|
-
messageText: `Nested function calls can be converted to pipeable style for better readability.`,
|
|
8615
|
-
fixes: [{
|
|
8616
|
-
fixName: "missedPipeableOpportunity_fix",
|
|
8617
|
-
description: "Convert to pipe style",
|
|
8618
|
-
apply: gen(function* () {
|
|
8619
|
-
const changeTracker = yield* service(ChangeTracker);
|
|
8620
|
-
changeTracker.replaceNode(
|
|
8621
|
-
sourceFile,
|
|
8622
|
-
parentChain[0],
|
|
8623
|
-
ts.factory.createCallExpression(
|
|
8624
|
-
ts.factory.createPropertyAccessExpression(
|
|
8625
|
-
subject,
|
|
8626
|
-
"pipe"
|
|
8627
|
-
),
|
|
8628
|
-
void 0,
|
|
8629
|
-
pipe(
|
|
8630
|
-
parentChain,
|
|
8631
|
-
filter(ts.isCallExpression),
|
|
8632
|
-
map4((call) => call.expression),
|
|
8633
|
-
reverse2
|
|
8634
|
-
)
|
|
8635
|
-
)
|
|
8636
|
-
);
|
|
8637
|
-
})
|
|
8638
|
-
}]
|
|
8639
|
-
});
|
|
8640
|
-
originalParentChain.forEach((node2) => callChainNodes.delete(node2));
|
|
9439
|
+
if (firstPipeableIndex === -1) {
|
|
9440
|
+
break;
|
|
9441
|
+
}
|
|
9442
|
+
const pipeableTransformations = [];
|
|
9443
|
+
for (let i = firstPipeableIndex; i < flow2.transformations.length; i++) {
|
|
9444
|
+
const t = flow2.transformations[i];
|
|
9445
|
+
if (!isSafelyPipeableCallee(t.callee)) {
|
|
8641
9446
|
break;
|
|
8642
9447
|
}
|
|
9448
|
+
pipeableTransformations.push(t);
|
|
9449
|
+
}
|
|
9450
|
+
const callKindCount = pipeableTransformations.filter((t) => t.kind === "call").length;
|
|
9451
|
+
if (callKindCount >= options.pipeableMinArgCount) {
|
|
9452
|
+
const pipeableEndIndex = firstPipeableIndex + pipeableTransformations.length;
|
|
9453
|
+
const pipeableSubjectNode = firstPipeableIndex === 0 ? flow2.subject.node : typeParser.reconstructPipingFlow({
|
|
9454
|
+
subject: flow2.subject,
|
|
9455
|
+
transformations: flow2.transformations.slice(0, firstPipeableIndex)
|
|
9456
|
+
});
|
|
9457
|
+
const afterTransformations = flow2.transformations.slice(pipeableEndIndex);
|
|
9458
|
+
report({
|
|
9459
|
+
location: flow2.node,
|
|
9460
|
+
messageText: `Nested function calls can be converted to pipeable style for better readability.`,
|
|
9461
|
+
fixes: [{
|
|
9462
|
+
fixName: "missedPipeableOpportunity_fix",
|
|
9463
|
+
description: "Convert to pipe style",
|
|
9464
|
+
apply: gen(function* () {
|
|
9465
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
9466
|
+
const pipeArgs = pipeableTransformations.map((t) => {
|
|
9467
|
+
if (t.args) {
|
|
9468
|
+
return ts.factory.createCallExpression(
|
|
9469
|
+
t.callee,
|
|
9470
|
+
void 0,
|
|
9471
|
+
t.args
|
|
9472
|
+
);
|
|
9473
|
+
} else {
|
|
9474
|
+
return t.callee;
|
|
9475
|
+
}
|
|
9476
|
+
});
|
|
9477
|
+
const pipeNode = ts.factory.createCallExpression(
|
|
9478
|
+
ts.factory.createPropertyAccessExpression(
|
|
9479
|
+
pipeableSubjectNode,
|
|
9480
|
+
"pipe"
|
|
9481
|
+
),
|
|
9482
|
+
void 0,
|
|
9483
|
+
pipeArgs
|
|
9484
|
+
);
|
|
9485
|
+
const newNode = afterTransformations.length > 0 ? typeParser.reconstructPipingFlow({
|
|
9486
|
+
subject: { node: pipeNode, outType: void 0 },
|
|
9487
|
+
transformations: afterTransformations
|
|
9488
|
+
}) : pipeNode;
|
|
9489
|
+
changeTracker.replaceNode(sourceFile, flow2.node, newNode);
|
|
9490
|
+
})
|
|
9491
|
+
}]
|
|
9492
|
+
});
|
|
9493
|
+
break;
|
|
8643
9494
|
}
|
|
9495
|
+
searchStartIndex = firstPipeableIndex + pipeableTransformations.length + 1;
|
|
8644
9496
|
}
|
|
8645
|
-
ts.forEachChild(node, prependNodeToVisit);
|
|
8646
9497
|
}
|
|
8647
9498
|
})
|
|
8648
9499
|
});
|
|
@@ -9141,28 +9992,34 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
9141
9992
|
"effect",
|
|
9142
9993
|
"Layer"
|
|
9143
9994
|
) || "Layer";
|
|
9144
|
-
const
|
|
9145
|
-
|
|
9146
|
-
const layer = node.arguments[0];
|
|
9147
|
-
const type = typeCheckerUtils.getTypeAtLocation(layer);
|
|
9148
|
-
if (!type) return void_;
|
|
9149
|
-
return pipe(
|
|
9150
|
-
typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression),
|
|
9151
|
-
flatMap4(() => typeParser.layerType(type, layer)),
|
|
9152
|
-
map8(() => ({ layer, node })),
|
|
9153
|
-
orElse2(() => void_)
|
|
9154
|
-
);
|
|
9155
|
-
}
|
|
9156
|
-
return void_;
|
|
9157
|
-
};
|
|
9158
|
-
const parsePipeCall = (node) => gen(function* () {
|
|
9159
|
-
const { args: args2 } = yield* typeParser.pipeCall(node);
|
|
9995
|
+
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
9996
|
+
for (const flow2 of flows) {
|
|
9160
9997
|
let currentChunk = 0;
|
|
9161
9998
|
const previousLayers = [[]];
|
|
9162
|
-
for (const
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
previousLayers
|
|
9999
|
+
for (const transformation of flow2.transformations) {
|
|
10000
|
+
if (!transformation.args || transformation.args.length === 0) {
|
|
10001
|
+
currentChunk++;
|
|
10002
|
+
previousLayers.push([]);
|
|
10003
|
+
continue;
|
|
10004
|
+
}
|
|
10005
|
+
const isProvideCall = yield* pipe(
|
|
10006
|
+
typeParser.isNodeReferenceToEffectModuleApi("provide")(transformation.callee),
|
|
10007
|
+
option
|
|
10008
|
+
);
|
|
10009
|
+
if (isSome2(isProvideCall)) {
|
|
10010
|
+
const layer = transformation.args[0];
|
|
10011
|
+
const type = typeCheckerUtils.getTypeAtLocation(layer);
|
|
10012
|
+
const node = ts.findAncestor(transformation.callee, ts.isCallExpression);
|
|
10013
|
+
const isLayerType = type ? yield* pipe(
|
|
10014
|
+
typeParser.layerType(type, layer),
|
|
10015
|
+
option
|
|
10016
|
+
) : none2();
|
|
10017
|
+
if (isSome2(isLayerType) && node) {
|
|
10018
|
+
previousLayers[currentChunk].push({ layer, node });
|
|
10019
|
+
} else {
|
|
10020
|
+
currentChunk++;
|
|
10021
|
+
previousLayers.push([]);
|
|
10022
|
+
}
|
|
9166
10023
|
} else {
|
|
9167
10024
|
currentChunk++;
|
|
9168
10025
|
previousLayers.push([]);
|
|
@@ -9202,19 +10059,6 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
9202
10059
|
}]
|
|
9203
10060
|
});
|
|
9204
10061
|
}
|
|
9205
|
-
});
|
|
9206
|
-
const nodeToVisit = [];
|
|
9207
|
-
const appendNodeToVisit = (node) => {
|
|
9208
|
-
nodeToVisit.push(node);
|
|
9209
|
-
return void 0;
|
|
9210
|
-
};
|
|
9211
|
-
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
9212
|
-
while (nodeToVisit.length > 0) {
|
|
9213
|
-
const node = nodeToVisit.shift();
|
|
9214
|
-
ts.forEachChild(node, appendNodeToVisit);
|
|
9215
|
-
if (ts.isCallExpression(node)) {
|
|
9216
|
-
yield* pipe(parsePipeCall(node), ignore);
|
|
9217
|
-
}
|
|
9218
10062
|
}
|
|
9219
10063
|
})
|
|
9220
10064
|
});
|
|
@@ -9495,6 +10339,140 @@ var overriddenSchemaConstructor = createDiagnostic({
|
|
|
9495
10339
|
})
|
|
9496
10340
|
});
|
|
9497
10341
|
|
|
10342
|
+
// src/diagnostics/preferSchemaOverJson.ts
|
|
10343
|
+
var preferSchemaOverJson = createDiagnostic({
|
|
10344
|
+
name: "preferSchemaOverJson",
|
|
10345
|
+
code: 44,
|
|
10346
|
+
description: "Suggests using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify which may throw",
|
|
10347
|
+
severity: "suggestion",
|
|
10348
|
+
apply: fn("preferSchemaOverJson.apply")(function* (sourceFile, report) {
|
|
10349
|
+
const ts = yield* service(TypeScriptApi);
|
|
10350
|
+
const typeParser = yield* service(TypeParser);
|
|
10351
|
+
const parseJsonMethod = (node) => gen(function* () {
|
|
10352
|
+
if (!ts.isCallExpression(node)) return yield* fail3("node is not a call expression");
|
|
10353
|
+
const expression = node.expression;
|
|
10354
|
+
if (!ts.isPropertyAccessExpression(expression)) return yield* fail3("expression is not a property access");
|
|
10355
|
+
const objectExpr = expression.expression;
|
|
10356
|
+
const methodName = ts.idText(expression.name);
|
|
10357
|
+
if (!ts.isIdentifier(objectExpr) || ts.idText(objectExpr) !== "JSON") {
|
|
10358
|
+
return yield* fail3("object is not JSON");
|
|
10359
|
+
}
|
|
10360
|
+
if (methodName !== "parse" && methodName !== "stringify") {
|
|
10361
|
+
return yield* fail3("method is not parse or stringify");
|
|
10362
|
+
}
|
|
10363
|
+
return { node, methodName };
|
|
10364
|
+
});
|
|
10365
|
+
const effectTrySimple = (node) => gen(function* () {
|
|
10366
|
+
if (!ts.isCallExpression(node)) return yield* fail3("node is not a call expression");
|
|
10367
|
+
yield* typeParser.isNodeReferenceToEffectModuleApi("try")(node.expression);
|
|
10368
|
+
if (node.arguments.length === 0) return yield* fail3("Effect.try has no arguments");
|
|
10369
|
+
const lazyFn = yield* typeParser.lazyExpression(node.arguments[0]);
|
|
10370
|
+
const jsonMethod = yield* parseJsonMethod(lazyFn.expression);
|
|
10371
|
+
return { node: jsonMethod.node, methodName: jsonMethod.methodName };
|
|
10372
|
+
});
|
|
10373
|
+
const effectTryObject = (node) => gen(function* () {
|
|
10374
|
+
if (!ts.isCallExpression(node)) return yield* fail3("node is not a call expression");
|
|
10375
|
+
yield* typeParser.isNodeReferenceToEffectModuleApi("try")(node.expression);
|
|
10376
|
+
if (node.arguments.length === 0) return yield* fail3("Effect.try has no arguments");
|
|
10377
|
+
const arg = node.arguments[0];
|
|
10378
|
+
if (!ts.isObjectLiteralExpression(arg)) return yield* fail3("argument is not an object literal");
|
|
10379
|
+
const tryProp = arg.properties.find(
|
|
10380
|
+
(p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && ts.idText(p.name) === "try"
|
|
10381
|
+
);
|
|
10382
|
+
if (!tryProp) return yield* fail3("object has no 'try' property");
|
|
10383
|
+
const lazyFn = yield* typeParser.lazyExpression(tryProp.initializer);
|
|
10384
|
+
const jsonMethod = yield* parseJsonMethod(lazyFn.expression);
|
|
10385
|
+
return { node: jsonMethod.node, methodName: jsonMethod.methodName };
|
|
10386
|
+
});
|
|
10387
|
+
const jsonMethodInEffectGen = (node) => gen(function* () {
|
|
10388
|
+
const jsonMethod = yield* parseJsonMethod(node);
|
|
10389
|
+
const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
|
|
10390
|
+
if (!effectGen || effectGen.body.statements.length === 0) {
|
|
10391
|
+
return yield* fail3("not inside an Effect generator");
|
|
10392
|
+
}
|
|
10393
|
+
if (scopeNode && scopeNode !== effectGen.generatorFunction) {
|
|
10394
|
+
return yield* fail3("inside a nested function scope");
|
|
10395
|
+
}
|
|
10396
|
+
return { node: jsonMethod.node, methodName: jsonMethod.methodName };
|
|
10397
|
+
});
|
|
10398
|
+
const nodeToVisit = [];
|
|
10399
|
+
const appendNodeToVisit = (node) => {
|
|
10400
|
+
nodeToVisit.push(node);
|
|
10401
|
+
return void 0;
|
|
10402
|
+
};
|
|
10403
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
10404
|
+
while (nodeToVisit.length > 0) {
|
|
10405
|
+
const node = nodeToVisit.shift();
|
|
10406
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
10407
|
+
const match3 = yield* pipe(
|
|
10408
|
+
firstSuccessOf([
|
|
10409
|
+
effectTrySimple(node),
|
|
10410
|
+
effectTryObject(node),
|
|
10411
|
+
jsonMethodInEffectGen(node)
|
|
10412
|
+
]),
|
|
10413
|
+
option
|
|
10414
|
+
);
|
|
10415
|
+
if (isSome2(match3)) {
|
|
10416
|
+
report({
|
|
10417
|
+
location: match3.value.node,
|
|
10418
|
+
messageText: "Consider using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify",
|
|
10419
|
+
fixes: []
|
|
10420
|
+
});
|
|
10421
|
+
}
|
|
10422
|
+
}
|
|
10423
|
+
})
|
|
10424
|
+
});
|
|
10425
|
+
|
|
10426
|
+
// src/diagnostics/redundantSchemaTagIdentifier.ts
|
|
10427
|
+
var redundantSchemaTagIdentifier = createDiagnostic({
|
|
10428
|
+
name: "redundantSchemaTagIdentifier",
|
|
10429
|
+
code: 42,
|
|
10430
|
+
description: "Suggests removing redundant identifier argument when it equals the tag value in Schema.TaggedClass/TaggedError/TaggedRequest",
|
|
10431
|
+
severity: "suggestion",
|
|
10432
|
+
apply: fn("redundantSchemaTagIdentifier.apply")(function* (sourceFile, report) {
|
|
10433
|
+
const ts = yield* service(TypeScriptApi);
|
|
10434
|
+
const typeParser = yield* service(TypeParser);
|
|
10435
|
+
const nodeToVisit = [];
|
|
10436
|
+
const appendNodeToVisit = (node) => {
|
|
10437
|
+
nodeToVisit.push(node);
|
|
10438
|
+
return void 0;
|
|
10439
|
+
};
|
|
10440
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
10441
|
+
while (nodeToVisit.length > 0) {
|
|
10442
|
+
const node = nodeToVisit.shift();
|
|
10443
|
+
if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
|
|
10444
|
+
const result = yield* pipe(
|
|
10445
|
+
typeParser.extendsSchemaTaggedClass(node),
|
|
10446
|
+
orElse2(() => typeParser.extendsSchemaTaggedError(node)),
|
|
10447
|
+
orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
|
|
10448
|
+
orElse2(() => void_)
|
|
10449
|
+
);
|
|
10450
|
+
if (result && result.keyStringLiteral && result.tagStringLiteral) {
|
|
10451
|
+
const { keyStringLiteral, tagStringLiteral } = result;
|
|
10452
|
+
if (keyStringLiteral.text === tagStringLiteral.text) {
|
|
10453
|
+
report({
|
|
10454
|
+
location: keyStringLiteral,
|
|
10455
|
+
messageText: `Identifier '${keyStringLiteral.text}' is redundant since it equals the _tag value`,
|
|
10456
|
+
fixes: [{
|
|
10457
|
+
fixName: "redundantSchemaTagIdentifier_removeIdentifier",
|
|
10458
|
+
description: `Remove redundant identifier '${keyStringLiteral.text}'`,
|
|
10459
|
+
apply: gen(function* () {
|
|
10460
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
10461
|
+
changeTracker.deleteRange(sourceFile, {
|
|
10462
|
+
pos: ts.getTokenPosOfNode(keyStringLiteral, sourceFile),
|
|
10463
|
+
end: keyStringLiteral.end
|
|
10464
|
+
});
|
|
10465
|
+
})
|
|
10466
|
+
}]
|
|
10467
|
+
});
|
|
10468
|
+
}
|
|
10469
|
+
}
|
|
10470
|
+
}
|
|
10471
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
10472
|
+
}
|
|
10473
|
+
})
|
|
10474
|
+
});
|
|
10475
|
+
|
|
9498
10476
|
// src/diagnostics/returnEffectInGen.ts
|
|
9499
10477
|
var returnEffectInGen = createDiagnostic({
|
|
9500
10478
|
name: "returnEffectInGen",
|
|
@@ -9597,108 +10575,91 @@ var runEffectInsideEffect = createDiagnostic({
|
|
|
9597
10575
|
option
|
|
9598
10576
|
);
|
|
9599
10577
|
if (isNone2(isEffectRunCall)) continue;
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
if (ts.isFunctionExpression(possiblyEffectGen) || ts.isFunctionDeclaration(possiblyEffectGen) || ts.isMethodDeclaration(possiblyEffectGen) || ts.isArrowFunction(possiblyEffectGen)) {
|
|
9606
|
-
nodeIntroduceScope = possiblyEffectGen;
|
|
9607
|
-
continue;
|
|
9608
|
-
}
|
|
9609
|
-
}
|
|
9610
|
-
const isInEffectGen = yield* pipe(
|
|
9611
|
-
typeParser.effectGen(possiblyEffectGen),
|
|
9612
|
-
orElse2(() => typeParser.effectFnUntracedGen(possiblyEffectGen)),
|
|
9613
|
-
orElse2(() => typeParser.effectFnGen(possiblyEffectGen)),
|
|
9614
|
-
option
|
|
10578
|
+
const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
|
|
10579
|
+
if (effectGen && effectGen.body.statements.length > 0) {
|
|
10580
|
+
const nodeText = sourceFile.text.substring(
|
|
10581
|
+
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
10582
|
+
node.expression.end
|
|
9615
10583
|
);
|
|
9616
|
-
if (
|
|
9617
|
-
const
|
|
9618
|
-
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
const
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
if (ts.
|
|
9633
|
-
|
|
9634
|
-
typeParser.isNodeReferenceToEffectModuleApi("runtime")(yieldedExpression.expression),
|
|
9635
|
-
option
|
|
9636
|
-
);
|
|
9637
|
-
if (isSome2(maybeEffectRuntime) && ts.isIdentifier(declaration.name)) {
|
|
9638
|
-
runtimeIdentifier = ts.idText(declaration.name);
|
|
9639
|
-
}
|
|
10584
|
+
if (scopeNode && scopeNode !== effectGen.generatorFunction) {
|
|
10585
|
+
const fixAddRuntime = gen(function* () {
|
|
10586
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
10587
|
+
const runtimeModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Runtime") || "Runtime";
|
|
10588
|
+
const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Effect") || "Effect";
|
|
10589
|
+
let runtimeIdentifier = void 0;
|
|
10590
|
+
for (const statement of effectGen.generatorFunction.body.statements) {
|
|
10591
|
+
if (ts.isVariableStatement(statement) && statement.declarationList.declarations.length === 1) {
|
|
10592
|
+
const declaration = statement.declarationList.declarations[0];
|
|
10593
|
+
if (declaration.initializer && ts.isYieldExpression(declaration.initializer) && declaration.initializer.asteriskToken && declaration.initializer.expression) {
|
|
10594
|
+
const yieldedExpression = declaration.initializer.expression;
|
|
10595
|
+
if (ts.isCallExpression(yieldedExpression)) {
|
|
10596
|
+
const maybeEffectRuntime = yield* pipe(
|
|
10597
|
+
typeParser.isNodeReferenceToEffectModuleApi("runtime")(yieldedExpression.expression),
|
|
10598
|
+
option
|
|
10599
|
+
);
|
|
10600
|
+
if (isSome2(maybeEffectRuntime) && ts.isIdentifier(declaration.name)) {
|
|
10601
|
+
runtimeIdentifier = ts.idText(declaration.name);
|
|
9640
10602
|
}
|
|
9641
10603
|
}
|
|
9642
10604
|
}
|
|
9643
10605
|
}
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
10606
|
+
}
|
|
10607
|
+
if (!runtimeIdentifier) {
|
|
10608
|
+
changeTracker.insertNodeAt(
|
|
10609
|
+
sourceFile,
|
|
10610
|
+
effectGen.body.statements[0].pos,
|
|
10611
|
+
ts.factory.createVariableStatement(
|
|
10612
|
+
void 0,
|
|
10613
|
+
ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(
|
|
10614
|
+
"effectRuntime",
|
|
9649
10615
|
void 0,
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
),
|
|
9661
|
-
[ts.factory.createTypeReferenceNode("never")],
|
|
9662
|
-
[]
|
|
9663
|
-
)
|
|
10616
|
+
void 0,
|
|
10617
|
+
ts.factory.createYieldExpression(
|
|
10618
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
10619
|
+
ts.factory.createCallExpression(
|
|
10620
|
+
ts.factory.createPropertyAccessExpression(
|
|
10621
|
+
ts.factory.createIdentifier(effectModuleIdentifier),
|
|
10622
|
+
"runtime"
|
|
10623
|
+
),
|
|
10624
|
+
[ts.factory.createTypeReferenceNode("never")],
|
|
10625
|
+
[]
|
|
9664
10626
|
)
|
|
9665
|
-
)
|
|
9666
|
-
),
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
}
|
|
9673
|
-
changeTracker.deleteRange(sourceFile, {
|
|
9674
|
-
pos: ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
9675
|
-
end: node.arguments[0].pos
|
|
9676
|
-
});
|
|
9677
|
-
changeTracker.insertText(
|
|
9678
|
-
sourceFile,
|
|
9679
|
-
node.arguments[0].pos,
|
|
9680
|
-
`${runtimeModuleIdentifier}.${isEffectRunCall.value.methodName}(${runtimeIdentifier || "effectRuntime"}, `
|
|
10627
|
+
)
|
|
10628
|
+
)], ts.NodeFlags.Const)
|
|
10629
|
+
),
|
|
10630
|
+
{
|
|
10631
|
+
prefix: "\n",
|
|
10632
|
+
suffix: "\n"
|
|
10633
|
+
}
|
|
9681
10634
|
);
|
|
10635
|
+
}
|
|
10636
|
+
changeTracker.deleteRange(sourceFile, {
|
|
10637
|
+
pos: ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
10638
|
+
end: node.arguments[0].pos
|
|
9682
10639
|
});
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
10640
|
+
changeTracker.insertText(
|
|
10641
|
+
sourceFile,
|
|
10642
|
+
node.arguments[0].pos,
|
|
10643
|
+
`${runtimeModuleIdentifier}.${isEffectRunCall.value.methodName}(${runtimeIdentifier || "effectRuntime"}, `
|
|
10644
|
+
);
|
|
10645
|
+
});
|
|
10646
|
+
report({
|
|
10647
|
+
location: node.expression,
|
|
10648
|
+
messageText: `Using ${nodeText} inside an Effect is not recommended. The same runtime should generally be used instead to run child effects.
|
|
9686
10649
|
Consider extracting the Runtime by using for example Effect.runtime and then use Runtime.${isEffectRunCall.value.methodName} with the extracted runtime instead.`,
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
}
|
|
10650
|
+
fixes: [{
|
|
10651
|
+
fixName: "runEffectInsideEffect_fix",
|
|
10652
|
+
description: "Use a runtime to run the Effect",
|
|
10653
|
+
apply: fixAddRuntime
|
|
10654
|
+
}]
|
|
10655
|
+
});
|
|
10656
|
+
} else {
|
|
10657
|
+
report({
|
|
10658
|
+
location: node.expression,
|
|
10659
|
+
messageText: `Using ${nodeText} inside an Effect is not recommended. Effects inside generators can usually just be yielded.`,
|
|
10660
|
+
fixes: []
|
|
10661
|
+
});
|
|
9700
10662
|
}
|
|
9701
|
-
currentParent = currentParent.parent;
|
|
9702
10663
|
}
|
|
9703
10664
|
}
|
|
9704
10665
|
})
|
|
@@ -9784,6 +10745,59 @@ var schemaStructWithTag = createDiagnostic({
|
|
|
9784
10745
|
})
|
|
9785
10746
|
});
|
|
9786
10747
|
|
|
10748
|
+
// src/diagnostics/schemaSyncInEffect.ts
|
|
10749
|
+
var syncToEffectMethod = {
|
|
10750
|
+
decodeSync: "decode",
|
|
10751
|
+
decodeUnknownSync: "decodeUnknown",
|
|
10752
|
+
encodeSync: "encode",
|
|
10753
|
+
encodeUnknownSync: "encodeUnknown"
|
|
10754
|
+
};
|
|
10755
|
+
var schemaSyncInEffect = createDiagnostic({
|
|
10756
|
+
name: "schemaSyncInEffect",
|
|
10757
|
+
code: 43,
|
|
10758
|
+
description: "Suggests using Effect-based Schema methods instead of sync methods inside Effect generators",
|
|
10759
|
+
severity: "suggestion",
|
|
10760
|
+
apply: fn("schemaSyncInEffect.apply")(function* (sourceFile, report) {
|
|
10761
|
+
const ts = yield* service(TypeScriptApi);
|
|
10762
|
+
const typeParser = yield* service(TypeParser);
|
|
10763
|
+
const parseSchemaSyncMethod = (node, methodName) => pipe(
|
|
10764
|
+
typeParser.isNodeReferenceToEffectParseResultModuleApi(methodName)(node),
|
|
10765
|
+
map8(() => ({ node, methodName }))
|
|
10766
|
+
);
|
|
10767
|
+
const nodeToVisit = [];
|
|
10768
|
+
const appendNodeToVisit = (node) => {
|
|
10769
|
+
nodeToVisit.push(node);
|
|
10770
|
+
return void 0;
|
|
10771
|
+
};
|
|
10772
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
10773
|
+
while (nodeToVisit.length > 0) {
|
|
10774
|
+
const node = nodeToVisit.shift();
|
|
10775
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
10776
|
+
if (!ts.isCallExpression(node)) continue;
|
|
10777
|
+
const isSchemaSyncCall = yield* pipe(
|
|
10778
|
+
firstSuccessOf(
|
|
10779
|
+
Object.keys(syncToEffectMethod).map((methodName) => parseSchemaSyncMethod(node.expression, methodName))
|
|
10780
|
+
),
|
|
10781
|
+
option
|
|
10782
|
+
);
|
|
10783
|
+
if (isNone2(isSchemaSyncCall)) continue;
|
|
10784
|
+
const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
|
|
10785
|
+
if (!effectGen || effectGen.body.statements.length === 0) continue;
|
|
10786
|
+
if (scopeNode && scopeNode !== effectGen.generatorFunction) continue;
|
|
10787
|
+
const nodeText = sourceFile.text.substring(
|
|
10788
|
+
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
10789
|
+
node.expression.end
|
|
10790
|
+
);
|
|
10791
|
+
const effectMethodName = syncToEffectMethod[isSchemaSyncCall.value.methodName];
|
|
10792
|
+
report({
|
|
10793
|
+
location: node.expression,
|
|
10794
|
+
messageText: `Using ${nodeText} inside an Effect generator is not recommended. Use Schema.${effectMethodName} instead to get properly typed ParseError in the error channel.`,
|
|
10795
|
+
fixes: []
|
|
10796
|
+
});
|
|
10797
|
+
}
|
|
10798
|
+
})
|
|
10799
|
+
});
|
|
10800
|
+
|
|
9787
10801
|
// src/diagnostics/schemaUnionOfLiterals.ts
|
|
9788
10802
|
var schemaUnionOfLiterals = createDiagnostic({
|
|
9789
10803
|
name: "schemaUnionOfLiterals",
|
|
@@ -10495,7 +11509,12 @@ var diagnostics = [
|
|
|
10495
11509
|
schemaStructWithTag,
|
|
10496
11510
|
globalErrorInEffectCatch,
|
|
10497
11511
|
globalErrorInEffectFailure,
|
|
10498
|
-
layerMergeAllWithDependencies
|
|
11512
|
+
layerMergeAllWithDependencies,
|
|
11513
|
+
effectMapVoid,
|
|
11514
|
+
effectFnOpportunity,
|
|
11515
|
+
redundantSchemaTagIdentifier,
|
|
11516
|
+
schemaSyncInEffect,
|
|
11517
|
+
preferSchemaOverJson
|
|
10499
11518
|
];
|
|
10500
11519
|
|
|
10501
11520
|
// src/completions/effectDiagnosticsComment.ts
|
|
@@ -10600,7 +11619,7 @@ var effectSchemaSelfInClasses = createCompletion({
|
|
|
10600
11619
|
completions2.push({
|
|
10601
11620
|
name: `TaggedError<${name}>`,
|
|
10602
11621
|
kind: ts.ScriptElementKind.constElement,
|
|
10603
|
-
insertText: isFullyQualified ? `${schemaIdentifier}.TaggedError<${name}>(
|
|
11622
|
+
insertText: isFullyQualified ? `${schemaIdentifier}.TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}` : `TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}`,
|
|
10604
11623
|
replacementSpan,
|
|
10605
11624
|
isSnippet: true
|
|
10606
11625
|
});
|
|
@@ -10615,7 +11634,7 @@ var effectSchemaSelfInClasses = createCompletion({
|
|
|
10615
11634
|
completions2.push({
|
|
10616
11635
|
name: `TaggedClass<${name}>`,
|
|
10617
11636
|
kind: ts.ScriptElementKind.constElement,
|
|
10618
|
-
insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>(
|
|
11637
|
+
insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>()("${name}", {${"${0}"}}){}` : `TaggedClass<${name}>()("${name}", {${"${0}"}}){}`,
|
|
10619
11638
|
replacementSpan,
|
|
10620
11639
|
isSnippet: true
|
|
10621
11640
|
});
|
|
@@ -10630,7 +11649,7 @@ var effectSchemaSelfInClasses = createCompletion({
|
|
|
10630
11649
|
completions2.push({
|
|
10631
11650
|
name: `TaggedRequest<${name}>`,
|
|
10632
11651
|
kind: ts.ScriptElementKind.constElement,
|
|
10633
|
-
insertText: isFullyQualified ? `${schemaIdentifier}.TaggedRequest<${name}>(
|
|
11652
|
+
insertText: isFullyQualified ? `${schemaIdentifier}.TaggedRequest<${name}>()("${name}", {${"${0}"}}){}` : `TaggedRequest<${name}>()("${name}", {${"${0}"}}){}`,
|
|
10634
11653
|
replacementSpan,
|
|
10635
11654
|
isSnippet: true
|
|
10636
11655
|
});
|
|
@@ -16382,6 +17401,23 @@ var extractOutlineGraph = fn("extractOutlineGraph")(function* (layerGraph) {
|
|
|
16382
17401
|
}
|
|
16383
17402
|
return endMutation2(mutableGraph);
|
|
16384
17403
|
});
|
|
17404
|
+
var collectOutlineGraphActualProvides = fn("collectOutlineGraphActualProvides")(
|
|
17405
|
+
function* (outlineGraph) {
|
|
17406
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
17407
|
+
const seenTypes = /* @__PURE__ */ new Set();
|
|
17408
|
+
const result = [];
|
|
17409
|
+
for (const nodeInfo of values2(nodes(outlineGraph))) {
|
|
17410
|
+
for (const actualProvide of nodeInfo.actualProvides) {
|
|
17411
|
+
if (!seenTypes.has(actualProvide)) {
|
|
17412
|
+
seenTypes.add(actualProvide);
|
|
17413
|
+
result.push(actualProvide);
|
|
17414
|
+
}
|
|
17415
|
+
}
|
|
17416
|
+
}
|
|
17417
|
+
result.sort(typeCheckerUtils.deterministicTypeOrder);
|
|
17418
|
+
return result;
|
|
17419
|
+
}
|
|
17420
|
+
);
|
|
16385
17421
|
var formatLayerOutlineGraph = fn("formatLayerOutlineGraph")(
|
|
16386
17422
|
function* (layerOutlineGraph, fromSourceFile) {
|
|
16387
17423
|
const tsUtils = yield* service(TypeScriptUtils);
|
|
@@ -16448,11 +17484,12 @@ var dfsPostOrderWithOrder = (graph, config) => {
|
|
|
16448
17484
|
}));
|
|
16449
17485
|
};
|
|
16450
17486
|
var convertOutlineGraphToLayerMagic = fn("convertOutlineGraphToLayerMagic")(
|
|
16451
|
-
function* (outlineGraph,
|
|
17487
|
+
function* (outlineGraph, targetOutputs) {
|
|
16452
17488
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
16453
17489
|
const ts = yield* service(TypeScriptApi);
|
|
16454
17490
|
const result = [];
|
|
16455
|
-
const
|
|
17491
|
+
const outputTypes = flatten(map4(targetOutputs, (_) => typeCheckerUtils.unrollUnionMembers(_)));
|
|
17492
|
+
const missingOutputTypes = new Set(outputTypes);
|
|
16456
17493
|
const currentRequiredTypes = /* @__PURE__ */ new Set();
|
|
16457
17494
|
const orderByProvidedCount = mapInput(
|
|
16458
17495
|
reverse(number2),
|
|
@@ -17361,7 +18398,7 @@ var layerMagic = createRefactor({
|
|
|
17361
18398
|
const { layerMagicNodes, missingOutputTypes } = yield* pipe(
|
|
17362
18399
|
convertOutlineGraphToLayerMagic(
|
|
17363
18400
|
extractedLayers,
|
|
17364
|
-
_targetLayer.ROut
|
|
18401
|
+
[_targetLayer.ROut]
|
|
17365
18402
|
),
|
|
17366
18403
|
provideService(TypeCheckerApi, typeChecker),
|
|
17367
18404
|
provideService(TypeCheckerUtils, typeCheckerUtils),
|