@effect/language-service 0.23.5 → 0.24.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 +12 -11
- package/cli.js +30946 -0
- package/cli.js.map +1 -0
- package/index.js +4686 -267
- package/index.js.map +1 -1
- package/package.json +4 -1
- package/transform.js +248 -44
- package/transform.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/language-service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "A Language-Service Plugin to Refactor and Diagnostic effect-ts projects",
|
|
5
5
|
"main": "index.cjs",
|
|
6
|
+
"bin": {
|
|
7
|
+
"effect-language-service": "cli.js"
|
|
8
|
+
},
|
|
6
9
|
"repository": {
|
|
7
10
|
"type": "git",
|
|
8
11
|
"url": "https://github.com/Effect-TS/language-service.git"
|
package/transform.js
CHANGED
|
@@ -24,7 +24,7 @@ __export(transform_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(transform_exports);
|
|
26
26
|
|
|
27
|
-
// node_modules/.pnpm/effect@3.16.
|
|
27
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Function.js
|
|
28
28
|
var isFunction = (input) => typeof input === "function";
|
|
29
29
|
var dual = function(arity, body) {
|
|
30
30
|
if (typeof arity === "function") {
|
|
@@ -118,11 +118,11 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
// node_modules/.pnpm/effect@3.16.
|
|
122
|
-
var moduleVersion = "3.16.
|
|
121
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/version.js
|
|
122
|
+
var moduleVersion = "3.16.12";
|
|
123
123
|
var getCurrentVersion = () => moduleVersion;
|
|
124
124
|
|
|
125
|
-
// node_modules/.pnpm/effect@3.16.
|
|
125
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/GlobalValue.js
|
|
126
126
|
var globalStoreId = `effect/GlobalValue/globalStoreId/${/* @__PURE__ */ getCurrentVersion()}`;
|
|
127
127
|
var globalStore;
|
|
128
128
|
var globalValue = (id, compute) => {
|
|
@@ -136,7 +136,7 @@ var globalValue = (id, compute) => {
|
|
|
136
136
|
return globalStore.get(id);
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
-
// node_modules/.pnpm/effect@3.16.
|
|
139
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Predicate.js
|
|
140
140
|
var isString = (input) => typeof input === "string";
|
|
141
141
|
var isNumber = (input) => typeof input === "number";
|
|
142
142
|
var isBoolean = (input) => typeof input === "boolean";
|
|
@@ -146,10 +146,10 @@ var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
|
|
|
146
146
|
var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
|
|
147
147
|
var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
|
|
148
148
|
|
|
149
|
-
// node_modules/.pnpm/effect@3.16.
|
|
149
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/errors.js
|
|
150
150
|
var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
|
|
151
151
|
|
|
152
|
-
// node_modules/.pnpm/effect@3.16.
|
|
152
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Utils.js
|
|
153
153
|
var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
|
|
154
154
|
var isGenKind = (u) => isObject(u) && GenKindTypeId in u;
|
|
155
155
|
var GenKindImpl = class {
|
|
@@ -278,7 +278,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
|
|
|
278
278
|
var genConstructor = function* () {
|
|
279
279
|
}.constructor;
|
|
280
280
|
|
|
281
|
-
// node_modules/.pnpm/effect@3.16.
|
|
281
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Hash.js
|
|
282
282
|
var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
|
|
283
283
|
var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
|
|
284
284
|
var hash = (self) => {
|
|
@@ -377,7 +377,7 @@ var cached = function() {
|
|
|
377
377
|
return hash2;
|
|
378
378
|
};
|
|
379
379
|
|
|
380
|
-
// node_modules/.pnpm/effect@3.16.
|
|
380
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Equal.js
|
|
381
381
|
var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
|
|
382
382
|
function equals() {
|
|
383
383
|
if (arguments.length === 1) {
|
|
@@ -431,7 +431,7 @@ function compareBoth(self, that) {
|
|
|
431
431
|
var isEqual = (u) => hasProperty(u, symbol2);
|
|
432
432
|
var equivalence = () => equals;
|
|
433
433
|
|
|
434
|
-
// node_modules/.pnpm/effect@3.16.
|
|
434
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Inspectable.js
|
|
435
435
|
var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
436
436
|
var toJSON = (x) => {
|
|
437
437
|
try {
|
|
@@ -483,7 +483,7 @@ var redact = (u) => {
|
|
|
483
483
|
return u;
|
|
484
484
|
};
|
|
485
485
|
|
|
486
|
-
// node_modules/.pnpm/effect@3.16.
|
|
486
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Pipeable.js
|
|
487
487
|
var pipeArguments = (self, args) => {
|
|
488
488
|
switch (args.length) {
|
|
489
489
|
case 0:
|
|
@@ -516,10 +516,10 @@ var pipeArguments = (self, args) => {
|
|
|
516
516
|
}
|
|
517
517
|
};
|
|
518
518
|
|
|
519
|
-
// node_modules/.pnpm/effect@3.16.
|
|
519
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/opCodes/effect.js
|
|
520
520
|
var OP_COMMIT = "Commit";
|
|
521
521
|
|
|
522
|
-
// node_modules/.pnpm/effect@3.16.
|
|
522
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/effectable.js
|
|
523
523
|
var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
|
|
524
524
|
var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
|
|
525
525
|
var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
|
|
@@ -606,7 +606,7 @@ var StructuralCommitPrototype = {
|
|
|
606
606
|
...StructuralPrototype
|
|
607
607
|
};
|
|
608
608
|
|
|
609
|
-
// node_modules/.pnpm/effect@3.16.
|
|
609
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/option.js
|
|
610
610
|
var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
|
|
611
611
|
var CommonProto = {
|
|
612
612
|
...EffectPrototype,
|
|
@@ -664,7 +664,7 @@ var some = (value) => {
|
|
|
664
664
|
return a;
|
|
665
665
|
};
|
|
666
666
|
|
|
667
|
-
// node_modules/.pnpm/effect@3.16.
|
|
667
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/either.js
|
|
668
668
|
var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
|
|
669
669
|
var CommonProto2 = {
|
|
670
670
|
...EffectPrototype,
|
|
@@ -726,7 +726,7 @@ var right = (right3) => {
|
|
|
726
726
|
return a;
|
|
727
727
|
};
|
|
728
728
|
|
|
729
|
-
// node_modules/.pnpm/effect@3.16.
|
|
729
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Either.js
|
|
730
730
|
var right2 = right;
|
|
731
731
|
var left2 = left;
|
|
732
732
|
var isLeft2 = isLeft;
|
|
@@ -734,13 +734,14 @@ var isRight2 = isRight;
|
|
|
734
734
|
var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
|
|
735
735
|
var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
|
|
736
736
|
|
|
737
|
-
// node_modules/.pnpm/effect@3.16.
|
|
737
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/internal/array.js
|
|
738
738
|
var isNonEmptyArray = (self) => self.length > 0;
|
|
739
739
|
|
|
740
|
-
// node_modules/.pnpm/effect@3.16.
|
|
740
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Order.js
|
|
741
741
|
var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
|
|
742
|
+
var string2 = /* @__PURE__ */ make((self, that) => self < that ? -1 : 1);
|
|
742
743
|
|
|
743
|
-
// node_modules/.pnpm/effect@3.16.
|
|
744
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Option.js
|
|
744
745
|
var none2 = () => none;
|
|
745
746
|
var some2 = some;
|
|
746
747
|
var isNone2 = isNone;
|
|
@@ -752,7 +753,7 @@ var match = /* @__PURE__ */ dual(2, (self, {
|
|
|
752
753
|
var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
|
|
753
754
|
var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
|
|
754
755
|
|
|
755
|
-
// node_modules/.pnpm/effect@3.16.
|
|
756
|
+
// node_modules/.pnpm/effect@3.16.12/node_modules/effect/dist/esm/Array.js
|
|
756
757
|
var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
|
|
757
758
|
var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
|
|
758
759
|
var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
|
|
@@ -921,6 +922,7 @@ var orElse2 = (f) => (fa) => make2((ctx) => {
|
|
|
921
922
|
if (result._tag === "Left") return f(result.value).run(ctx);
|
|
922
923
|
return result;
|
|
923
924
|
});
|
|
925
|
+
var firstSuccessOf = (arr) => arr.slice(1).reduce((arr2, fa) => orElse2(() => fa)(arr2), arr[0]);
|
|
924
926
|
var service = (tag) => make2(
|
|
925
927
|
(ctx) => tag.key in ctx.value ? ctx.value[tag.key] : makeInternalDefect(`Cannot find service ${tag.key}`)
|
|
926
928
|
);
|
|
@@ -2027,22 +2029,16 @@ function make3(ts, typeChecker) {
|
|
|
2027
2029
|
);
|
|
2028
2030
|
const effectType = cachedBy(
|
|
2029
2031
|
fn("TypeParser.effectType")(function* (type, atLocation) {
|
|
2030
|
-
|
|
2032
|
+
let result = typeParserIssue("Type has no effect variance struct", type, atLocation);
|
|
2031
2033
|
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2032
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2034
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
|
|
2033
2035
|
);
|
|
2034
2036
|
propertiesSymbols.sort((a, b) => b.name.indexOf("EffectTypeId") - a.name.indexOf("EffectTypeId"));
|
|
2035
2037
|
for (const propertySymbol of propertiesSymbols) {
|
|
2036
2038
|
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2037
|
-
|
|
2038
|
-
propertyType,
|
|
2039
|
-
atLocation
|
|
2040
|
-
));
|
|
2041
|
-
if (isSome2(varianceArgs)) {
|
|
2042
|
-
return varianceArgs.value;
|
|
2043
|
-
}
|
|
2039
|
+
result = pipe(result, orElse2(() => effectVarianceStruct(propertyType, atLocation)));
|
|
2044
2040
|
}
|
|
2045
|
-
return yield*
|
|
2041
|
+
return yield* result;
|
|
2046
2042
|
}),
|
|
2047
2043
|
"TypeParser.effectType",
|
|
2048
2044
|
(type) => type
|
|
@@ -2061,7 +2057,7 @@ function make3(ts, typeChecker) {
|
|
|
2061
2057
|
fn("TypeParser.layerType")(function* (type, atLocation) {
|
|
2062
2058
|
yield* pipeableType(type, atLocation);
|
|
2063
2059
|
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2064
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2060
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
|
|
2065
2061
|
);
|
|
2066
2062
|
propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
|
|
2067
2063
|
for (const propertySymbol of propertiesSymbols) {
|
|
@@ -2345,7 +2341,7 @@ function make3(ts, typeChecker) {
|
|
|
2345
2341
|
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
2346
2342
|
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
2347
2343
|
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2348
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2344
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
|
|
2349
2345
|
);
|
|
2350
2346
|
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2351
2347
|
for (const propertySymbol of propertiesSymbols) {
|
|
@@ -2374,7 +2370,7 @@ function make3(ts, typeChecker) {
|
|
|
2374
2370
|
fn("TypeParser.contextTag")(function* (type, atLocation) {
|
|
2375
2371
|
yield* pipeableType(type, atLocation);
|
|
2376
2372
|
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2377
|
-
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
|
|
2373
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
|
|
2378
2374
|
);
|
|
2379
2375
|
propertiesSymbols.sort((a, b) => b.name.indexOf("TypeId") - a.name.indexOf("TypeId"));
|
|
2380
2376
|
for (const propertySymbol of propertiesSymbols) {
|
|
@@ -2406,6 +2402,25 @@ function make3(ts, typeChecker) {
|
|
|
2406
2402
|
"TypeParser.pipeCall",
|
|
2407
2403
|
(node) => node
|
|
2408
2404
|
);
|
|
2405
|
+
const scopeType = cachedBy(
|
|
2406
|
+
fn("TypeParser.scopeType")(function* (type, atLocation) {
|
|
2407
|
+
yield* pipeableType(type, atLocation);
|
|
2408
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2409
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration && ts.isPropertySignature(_.valueDeclaration) && ts.isComputedPropertyName(_.valueDeclaration.name)
|
|
2410
|
+
);
|
|
2411
|
+
propertiesSymbols.sort((a, b) => b.name.indexOf("ScopeTypeId") - a.name.indexOf("ScopeTypeId"));
|
|
2412
|
+
for (const propertySymbol of propertiesSymbols) {
|
|
2413
|
+
const computedPropertyExpression = propertySymbol.valueDeclaration.name;
|
|
2414
|
+
const symbol3 = typeChecker.getSymbolAtLocation(computedPropertyExpression.expression);
|
|
2415
|
+
if (symbol3 && symbol3.name === "ScopeTypeId") {
|
|
2416
|
+
return type;
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
return yield* typeParserIssue("Type has no scope type id", type, atLocation);
|
|
2420
|
+
}),
|
|
2421
|
+
"TypeParser.scopeType",
|
|
2422
|
+
(type) => type
|
|
2423
|
+
);
|
|
2409
2424
|
return {
|
|
2410
2425
|
effectType,
|
|
2411
2426
|
strictEffectType,
|
|
@@ -2419,7 +2434,8 @@ function make3(ts, typeChecker) {
|
|
|
2419
2434
|
unnecessaryEffectGen: unnecessaryEffectGen2,
|
|
2420
2435
|
effectSchemaType,
|
|
2421
2436
|
contextTag,
|
|
2422
|
-
pipeCall
|
|
2437
|
+
pipeCall,
|
|
2438
|
+
scopeType
|
|
2423
2439
|
};
|
|
2424
2440
|
}
|
|
2425
2441
|
|
|
@@ -2860,18 +2876,39 @@ var missingEffectError = createDiagnostic({
|
|
|
2860
2876
|
code: 1,
|
|
2861
2877
|
severity: "error",
|
|
2862
2878
|
apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
|
|
2879
|
+
const ts = yield* service(TypeScriptApi);
|
|
2863
2880
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
2864
2881
|
const typeParser = yield* service(TypeParser);
|
|
2865
2882
|
const typeOrder = yield* deterministicTypeOrder;
|
|
2883
|
+
const effectModuleIdentifier = yield* pipe(
|
|
2884
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
2885
|
+
sourceFile,
|
|
2886
|
+
"effect",
|
|
2887
|
+
"Effect"
|
|
2888
|
+
),
|
|
2889
|
+
map3((_) => _.text),
|
|
2890
|
+
orElse2(() => succeed("Effect"))
|
|
2891
|
+
);
|
|
2892
|
+
const createDieMessage = (message) => ts.factory.createCallExpression(
|
|
2893
|
+
ts.factory.createPropertyAccessExpression(
|
|
2894
|
+
ts.factory.createIdentifier(effectModuleIdentifier),
|
|
2895
|
+
"dieMessage"
|
|
2896
|
+
),
|
|
2897
|
+
void 0,
|
|
2898
|
+
[ts.factory.createStringLiteral(message)]
|
|
2899
|
+
);
|
|
2866
2900
|
const checkForMissingErrorTypes = (node, expectedType, valueNode, realType) => pipe(
|
|
2867
2901
|
all(
|
|
2868
2902
|
typeParser.effectType(expectedType, node),
|
|
2869
2903
|
typeParser.effectType(realType, valueNode)
|
|
2870
2904
|
),
|
|
2871
2905
|
flatMap2(
|
|
2872
|
-
([expectedEffect, realEffect]) =>
|
|
2873
|
-
|
|
2874
|
-
|
|
2906
|
+
([expectedEffect, realEffect]) => pipe(
|
|
2907
|
+
getMissingTypeEntriesInTargetType(
|
|
2908
|
+
realEffect.E,
|
|
2909
|
+
expectedEffect.E
|
|
2910
|
+
),
|
|
2911
|
+
map3((missingErrorTypes) => ({ missingErrorTypes, expectedErrorType: expectedEffect.E }))
|
|
2875
2912
|
)
|
|
2876
2913
|
)
|
|
2877
2914
|
);
|
|
@@ -2886,15 +2923,79 @@ var missingEffectError = createDiagnostic({
|
|
|
2886
2923
|
valueNode,
|
|
2887
2924
|
realType
|
|
2888
2925
|
),
|
|
2889
|
-
map3(
|
|
2890
|
-
(
|
|
2926
|
+
map3((result) => {
|
|
2927
|
+
if (result.missingErrorTypes.length === 0) return;
|
|
2928
|
+
const fixes = [];
|
|
2929
|
+
if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never) {
|
|
2930
|
+
fixes.push({
|
|
2931
|
+
fixName: "missingEffectError_catchAll",
|
|
2932
|
+
description: "Catch all errors with Effect.catchAll",
|
|
2933
|
+
apply: gen(function* () {
|
|
2934
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
2935
|
+
changeTracker.insertText(sourceFile, valueNode.getStart(), effectModuleIdentifier + ".catchAll(");
|
|
2936
|
+
changeTracker.insertText(sourceFile, valueNode.getEnd(), ", () => ");
|
|
2937
|
+
changeTracker.insertNodeAt(
|
|
2938
|
+
sourceFile,
|
|
2939
|
+
valueNode.getEnd(),
|
|
2940
|
+
createDieMessage("TODO: catchAll not implemented")
|
|
2941
|
+
);
|
|
2942
|
+
changeTracker.insertText(sourceFile, valueNode.getEnd(), ")");
|
|
2943
|
+
})
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
if (ts.isExpression(valueNode)) {
|
|
2947
|
+
const propertyAssignments = pipe(
|
|
2948
|
+
result.missingErrorTypes,
|
|
2949
|
+
map2((_) => typeChecker.getPropertyOfType(_, "_tag")),
|
|
2950
|
+
filter((_) => !!_),
|
|
2951
|
+
map2((_) => typeChecker.getTypeOfSymbolAtLocation(_, valueNode)),
|
|
2952
|
+
filter((_) => !!(_.flags & ts.TypeFlags.Literal)),
|
|
2953
|
+
map2((_) => typeChecker.typeToTypeNode(_, void 0, ts.NodeBuilderFlags.NoTruncation)),
|
|
2954
|
+
filter((_) => !!_ && ts.isLiteralTypeNode(_)),
|
|
2955
|
+
map2((_) => _.literal),
|
|
2956
|
+
filter((_) => ts.isLiteralExpression(_)),
|
|
2957
|
+
map2((_) => _.text),
|
|
2958
|
+
sort(string2),
|
|
2959
|
+
map2(
|
|
2960
|
+
(_) => ts.factory.createPropertyAssignment(
|
|
2961
|
+
ts.factory.createIdentifier(_),
|
|
2962
|
+
ts.factory.createArrowFunction(
|
|
2963
|
+
void 0,
|
|
2964
|
+
void 0,
|
|
2965
|
+
[],
|
|
2966
|
+
void 0,
|
|
2967
|
+
void 0,
|
|
2968
|
+
createDieMessage(`TODO: catchTags() not implemented for ${_}`)
|
|
2969
|
+
)
|
|
2970
|
+
)
|
|
2971
|
+
)
|
|
2972
|
+
);
|
|
2973
|
+
if (propertyAssignments.length === result.missingErrorTypes.length) {
|
|
2974
|
+
fixes.push({
|
|
2975
|
+
fixName: "missingEffectError_tagged",
|
|
2976
|
+
description: "Catch unexpected errors with Effect.catchTag",
|
|
2977
|
+
apply: gen(function* () {
|
|
2978
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
2979
|
+
changeTracker.insertText(sourceFile, valueNode.getStart(), effectModuleIdentifier + ".catchTags(");
|
|
2980
|
+
changeTracker.insertText(sourceFile, valueNode.getEnd(), ", ");
|
|
2981
|
+
changeTracker.insertNodeAt(
|
|
2982
|
+
sourceFile,
|
|
2983
|
+
valueNode.getEnd(),
|
|
2984
|
+
ts.factory.createObjectLiteralExpression(propertyAssignments)
|
|
2985
|
+
);
|
|
2986
|
+
changeTracker.insertText(sourceFile, valueNode.getEnd(), ")");
|
|
2987
|
+
})
|
|
2988
|
+
});
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
report(
|
|
2891
2992
|
{
|
|
2892
2993
|
node,
|
|
2893
|
-
messageText: `Missing '${sortTypes(
|
|
2894
|
-
fixes
|
|
2994
|
+
messageText: `Missing '${sortTypes(result.missingErrorTypes).map((_) => typeChecker.typeToString(_)).join(" | ")}' in the expected Effect errors.`,
|
|
2995
|
+
fixes
|
|
2895
2996
|
}
|
|
2896
|
-
)
|
|
2897
|
-
),
|
|
2997
|
+
);
|
|
2998
|
+
}),
|
|
2898
2999
|
ignore
|
|
2899
3000
|
);
|
|
2900
3001
|
}
|
|
@@ -3106,6 +3207,108 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
|
|
|
3106
3207
|
})
|
|
3107
3208
|
});
|
|
3108
3209
|
|
|
3210
|
+
// src/diagnostics/scopeInLayerEffect.ts
|
|
3211
|
+
var scopeInLayerEffect = createDiagnostic({
|
|
3212
|
+
name: "scopeInLayerEffect",
|
|
3213
|
+
code: 13,
|
|
3214
|
+
severity: "warning",
|
|
3215
|
+
apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
|
|
3216
|
+
const ts = yield* service(TypeScriptApi);
|
|
3217
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
3218
|
+
const typeParser = yield* service(TypeParser);
|
|
3219
|
+
const layerModuleIdentifier = yield* pipe(
|
|
3220
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
3221
|
+
sourceFile,
|
|
3222
|
+
"effect",
|
|
3223
|
+
"Layer"
|
|
3224
|
+
),
|
|
3225
|
+
map3((_) => _.text),
|
|
3226
|
+
orElse2(() => succeed("Layer"))
|
|
3227
|
+
);
|
|
3228
|
+
function parseLayerEffectApiCall(node) {
|
|
3229
|
+
if (!ts.isCallExpression(node)) return;
|
|
3230
|
+
const expression = node.expression;
|
|
3231
|
+
if (!ts.isPropertyAccessExpression(expression)) return;
|
|
3232
|
+
const calledModule = expression.expression;
|
|
3233
|
+
if (!(ts.isIdentifier(calledModule) && calledModule.text === layerModuleIdentifier)) return;
|
|
3234
|
+
const methodIdentifier = expression.name;
|
|
3235
|
+
if (!(ts.isIdentifier(methodIdentifier) && methodIdentifier.text.toLowerCase().startsWith("effect"))) return;
|
|
3236
|
+
return { methodIdentifier };
|
|
3237
|
+
}
|
|
3238
|
+
const reportIfLayerRequireScope = (type, node, methodIdentifier) => {
|
|
3239
|
+
let toCheck = [type];
|
|
3240
|
+
const entries = [];
|
|
3241
|
+
while (toCheck.length > 0) {
|
|
3242
|
+
const type2 = toCheck.pop();
|
|
3243
|
+
if (type2.isUnion()) {
|
|
3244
|
+
toCheck = toCheck.concat(type2.types);
|
|
3245
|
+
} else {
|
|
3246
|
+
entries.push(type2);
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
return pipe(
|
|
3250
|
+
firstSuccessOf(entries.map((type2) => typeParser.scopeType(type2, node))),
|
|
3251
|
+
map3(
|
|
3252
|
+
() => report({
|
|
3253
|
+
node,
|
|
3254
|
+
messageText: `Seems like you are constructing a layer with a scope in the requirements.
|
|
3255
|
+
Consider using "scoped" instead to get ride of the scope in the requirements.`,
|
|
3256
|
+
fixes: methodIdentifier ? [{
|
|
3257
|
+
fixName: "scopeInLayerEffect_scoped",
|
|
3258
|
+
description: "Use scoped for Layer creation",
|
|
3259
|
+
apply: gen(function* () {
|
|
3260
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
3261
|
+
changeTracker.replaceNode(
|
|
3262
|
+
sourceFile,
|
|
3263
|
+
methodIdentifier,
|
|
3264
|
+
ts.factory.createIdentifier("scoped")
|
|
3265
|
+
);
|
|
3266
|
+
})
|
|
3267
|
+
}] : []
|
|
3268
|
+
})
|
|
3269
|
+
),
|
|
3270
|
+
ignore
|
|
3271
|
+
);
|
|
3272
|
+
};
|
|
3273
|
+
const nodeToVisit = [];
|
|
3274
|
+
const appendNodeToVisit = (node) => {
|
|
3275
|
+
nodeToVisit.push(node);
|
|
3276
|
+
return void 0;
|
|
3277
|
+
};
|
|
3278
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
3279
|
+
while (nodeToVisit.length > 0) {
|
|
3280
|
+
const node = nodeToVisit.shift();
|
|
3281
|
+
const layerEffectApiCall = parseLayerEffectApiCall(node);
|
|
3282
|
+
if (layerEffectApiCall) {
|
|
3283
|
+
const type = typeChecker.getTypeAtLocation(node);
|
|
3284
|
+
yield* pipe(
|
|
3285
|
+
typeParser.layerType(type, node),
|
|
3286
|
+
flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
|
|
3287
|
+
ignore
|
|
3288
|
+
);
|
|
3289
|
+
continue;
|
|
3290
|
+
}
|
|
3291
|
+
if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
|
|
3292
|
+
const classSym = typeChecker.getSymbolAtLocation(node.name);
|
|
3293
|
+
if (classSym) {
|
|
3294
|
+
const classType = typeChecker.getTypeOfSymbol(classSym);
|
|
3295
|
+
const defaultLayer = typeChecker.getPropertyOfType(classType, "Default");
|
|
3296
|
+
if (defaultLayer) {
|
|
3297
|
+
const type = typeChecker.getTypeOfSymbolAtLocation(defaultLayer, node);
|
|
3298
|
+
yield* pipe(
|
|
3299
|
+
typeParser.layerType(type, node),
|
|
3300
|
+
flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, void 0)),
|
|
3301
|
+
ignore
|
|
3302
|
+
);
|
|
3303
|
+
continue;
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
3308
|
+
}
|
|
3309
|
+
})
|
|
3310
|
+
});
|
|
3311
|
+
|
|
3109
3312
|
// src/diagnostics/unnecessaryEffectGen.ts
|
|
3110
3313
|
var unnecessaryEffectGen = createDiagnostic({
|
|
3111
3314
|
name: "unnecessaryEffectGen",
|
|
@@ -3207,7 +3410,8 @@ var diagnostics = [
|
|
|
3207
3410
|
unnecessaryPipe,
|
|
3208
3411
|
genericEffectServices,
|
|
3209
3412
|
returnEffectInGen,
|
|
3210
|
-
importFromBarrel
|
|
3413
|
+
importFromBarrel,
|
|
3414
|
+
scopeInLayerEffect
|
|
3211
3415
|
];
|
|
3212
3416
|
|
|
3213
3417
|
// src/transform.ts
|