@effect/language-service 0.72.0 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +279 -183
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +275 -156
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +441 -227
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +275 -156
- package/transform.js.map +1 -1
|
@@ -1161,6 +1161,13 @@ var option = (fa) => {
|
|
|
1161
1161
|
nano[contE] = (_) => _ instanceof NanoDefectException ? fail(_) : succeed(none2());
|
|
1162
1162
|
return nano;
|
|
1163
1163
|
};
|
|
1164
|
+
var orUndefined = (fa) => {
|
|
1165
|
+
const nano = Object.create(MatchProto);
|
|
1166
|
+
nano[args] = fa;
|
|
1167
|
+
nano[contA] = (_) => succeed(_);
|
|
1168
|
+
nano[contE] = (_) => _ instanceof NanoDefectException ? fail(_) : succeed(void 0);
|
|
1169
|
+
return nano;
|
|
1170
|
+
};
|
|
1164
1171
|
var ignore = (fa) => {
|
|
1165
1172
|
const nano = Object.create(MatchProto);
|
|
1166
1173
|
nano[args] = fa;
|
|
@@ -1352,7 +1359,7 @@ function makeTypeScriptUtils(ts) {
|
|
|
1352
1359
|
if (!hasProperty(packageJsonScope, "packageDirectory")) return;
|
|
1353
1360
|
if (!isString(packageJsonScope.packageDirectory)) return;
|
|
1354
1361
|
const { name } = packageJsonContent;
|
|
1355
|
-
const version = hasProperty(
|
|
1362
|
+
const version = hasProperty(packageJsonContent, "version") ? packageJsonContent.version : "unknown";
|
|
1356
1363
|
if (!isString(name)) return;
|
|
1357
1364
|
if (!isString(version)) return;
|
|
1358
1365
|
const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
|
|
@@ -2568,6 +2575,8 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
|
|
|
2568
2575
|
}
|
|
2569
2576
|
|
|
2570
2577
|
// src/core/TypeParser.ts
|
|
2578
|
+
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
2579
|
+
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
2571
2580
|
var TypeParser = Tag("@effect/language-service/TypeParser");
|
|
2572
2581
|
var nanoLayer3 = (fa) => gen(function* () {
|
|
2573
2582
|
const ts = yield* service(TypeScriptApi);
|
|
@@ -2588,6 +2597,42 @@ function typeParserIssue(_message, _type, _node) {
|
|
|
2588
2597
|
return TypeParserIssue.issue;
|
|
2589
2598
|
}
|
|
2590
2599
|
function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
2600
|
+
function supportedEffect() {
|
|
2601
|
+
for (const fileName of program.getRootFileNames()) {
|
|
2602
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
2603
|
+
if (!sourceFile) continue;
|
|
2604
|
+
const resolvedPackages = getEffectRelatedPackages(sourceFile);
|
|
2605
|
+
const effectPkgs = resolvedPackages["effect"];
|
|
2606
|
+
if (!effectPkgs) continue;
|
|
2607
|
+
for (const version of Object.keys(effectPkgs)) {
|
|
2608
|
+
if (String(version).startsWith("4")) return "v4";
|
|
2609
|
+
if (String(version).startsWith("3")) return "v3";
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
return "v3";
|
|
2613
|
+
}
|
|
2614
|
+
function getEffectRelatedPackages(sourceFile) {
|
|
2615
|
+
let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
|
|
2616
|
+
const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
|
|
2617
|
+
const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
|
|
2618
|
+
if (newResolvedModuleSize !== oldResolvedSize) {
|
|
2619
|
+
const seenPackages = /* @__PURE__ */ new Set();
|
|
2620
|
+
resolvedPackages = {};
|
|
2621
|
+
program.getSourceFiles().map((_) => {
|
|
2622
|
+
const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
|
|
2623
|
+
if (!packageInfo) return;
|
|
2624
|
+
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
2625
|
+
if (seenPackages.has(packageNameAndVersion)) return;
|
|
2626
|
+
seenPackages.add(packageNameAndVersion);
|
|
2627
|
+
if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
|
|
2628
|
+
resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
|
|
2629
|
+
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
|
|
2630
|
+
});
|
|
2631
|
+
checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
|
|
2632
|
+
programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
|
|
2633
|
+
}
|
|
2634
|
+
return resolvedPackages;
|
|
2635
|
+
}
|
|
2591
2636
|
const getSourceFilePackageInfo = cachedBy(
|
|
2592
2637
|
fn("TypeParser.getSourceFilePackageInfo")(function* (sourceFile) {
|
|
2593
2638
|
return tsUtils.resolveModuleWithPackageInfoFromSourceFile(program, sourceFile);
|
|
@@ -2816,19 +2861,28 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2816
2861
|
);
|
|
2817
2862
|
const effectType = cachedBy(
|
|
2818
2863
|
fn("TypeParser.effectType")(function* (type, atLocation) {
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2864
|
+
if (supportedEffect() === "v4") {
|
|
2865
|
+
const typeIdSymbol = typeChecker.getPropertyOfType(type, "~effect/Effect");
|
|
2866
|
+
if (typeIdSymbol) {
|
|
2867
|
+
const typeIdType = typeChecker.getTypeOfSymbolAtLocation(typeIdSymbol, atLocation);
|
|
2868
|
+
return yield* effectVarianceStruct(typeIdType, atLocation);
|
|
2869
|
+
}
|
|
2870
|
+
return yield* typeParserIssue("Type is not an effect", type, atLocation);
|
|
2871
|
+
} else {
|
|
2872
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2873
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
|
|
2874
|
+
);
|
|
2875
|
+
if (propertiesSymbols.length === 0) {
|
|
2876
|
+
return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
|
|
2877
|
+
}
|
|
2878
|
+
propertiesSymbols.sort(
|
|
2879
|
+
(a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
|
|
2880
|
+
);
|
|
2881
|
+
return yield* firstSuccessOf(propertiesSymbols.map((propertySymbol) => {
|
|
2882
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2883
|
+
return effectVarianceStruct(propertyType, atLocation);
|
|
2884
|
+
}));
|
|
2824
2885
|
}
|
|
2825
|
-
propertiesSymbols.sort(
|
|
2826
|
-
(a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
|
|
2827
|
-
);
|
|
2828
|
-
return yield* firstSuccessOf(propertiesSymbols.map((propertySymbol) => {
|
|
2829
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2830
|
-
return effectVarianceStruct(propertyType, atLocation);
|
|
2831
|
-
}));
|
|
2832
2886
|
}),
|
|
2833
2887
|
"TypeParser.effectType",
|
|
2834
2888
|
(type) => type
|
|
@@ -2957,7 +3011,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2957
3011
|
fn("TypeParser.isEffectDataSourceFile")(function* (sourceFile) {
|
|
2958
3012
|
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
2959
3013
|
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
2960
|
-
const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol);
|
|
3014
|
+
const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol) || typeChecker.tryGetMemberInModuleExports("taggedEnum", moduleSymbol);
|
|
2961
3015
|
if (!taggedEnumSymbol) return yield* typeParserIssue("TaggedEnum not found", void 0, sourceFile);
|
|
2962
3016
|
const taggedErrorSymbol = typeChecker.tryGetMemberInModuleExports("TaggedError", moduleSymbol);
|
|
2963
3017
|
if (!taggedErrorSymbol) return yield* typeParserIssue("TaggedError not found", void 0, sourceFile);
|
|
@@ -3148,10 +3202,10 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3148
3202
|
}))
|
|
3149
3203
|
)
|
|
3150
3204
|
),
|
|
3151
|
-
|
|
3205
|
+
orUndefined
|
|
3152
3206
|
);
|
|
3153
|
-
if (
|
|
3154
|
-
effectGenResult = isEffectGen
|
|
3207
|
+
if (isEffectGen) {
|
|
3208
|
+
effectGenResult = isEffectGen;
|
|
3155
3209
|
}
|
|
3156
3210
|
}
|
|
3157
3211
|
if (scopeNode && effectGenResult) {
|
|
@@ -3271,6 +3325,21 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3271
3325
|
const effectSchemaType = cachedBy(
|
|
3272
3326
|
fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
|
|
3273
3327
|
yield* pipeableType(type, atLocation);
|
|
3328
|
+
const typeId = typeChecker.getPropertyOfType(type, "~effect/Schema/Schema");
|
|
3329
|
+
if (typeId) {
|
|
3330
|
+
const typeKey = typeChecker.getPropertyOfType(type, "Type");
|
|
3331
|
+
const encodedKey = typeChecker.getPropertyOfType(type, "Encoded");
|
|
3332
|
+
if (typeKey && encodedKey) {
|
|
3333
|
+
const typeType = typeChecker.getTypeOfSymbolAtLocation(typeKey, atLocation);
|
|
3334
|
+
const encodedType = typeChecker.getTypeOfSymbolAtLocation(encodedKey, atLocation);
|
|
3335
|
+
return {
|
|
3336
|
+
A: typeType,
|
|
3337
|
+
I: encodedType,
|
|
3338
|
+
R: typeChecker.getNeverType()
|
|
3339
|
+
};
|
|
3340
|
+
}
|
|
3341
|
+
return yield* typeParserIssue("missing Type and Encoded");
|
|
3342
|
+
}
|
|
3274
3343
|
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
3275
3344
|
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
3276
3345
|
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
@@ -3489,9 +3558,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3489
3558
|
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
3490
3559
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3491
3560
|
isNodeReferenceToEffectSchemaModuleApi("Class")(schemaCall.expression),
|
|
3492
|
-
|
|
3561
|
+
orUndefined
|
|
3493
3562
|
);
|
|
3494
|
-
if (
|
|
3563
|
+
if (isEffectSchemaModuleApi) {
|
|
3495
3564
|
return {
|
|
3496
3565
|
className: atLocation.name,
|
|
3497
3566
|
selfTypeNode: schemaCall.typeArguments[0]
|
|
@@ -3526,9 +3595,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3526
3595
|
const selfTypeNode = schemaTaggedClassTCall.typeArguments[0];
|
|
3527
3596
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3528
3597
|
isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(schemaTaggedClassTCall.expression),
|
|
3529
|
-
|
|
3598
|
+
orUndefined
|
|
3530
3599
|
);
|
|
3531
|
-
if (
|
|
3600
|
+
if (isEffectSchemaModuleApi) {
|
|
3532
3601
|
return {
|
|
3533
3602
|
className: atLocation.name,
|
|
3534
3603
|
selfTypeNode,
|
|
@@ -3565,9 +3634,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3565
3634
|
const selfTypeNode = schemaTaggedErrorTCall.typeArguments[0];
|
|
3566
3635
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3567
3636
|
isNodeReferenceToEffectSchemaModuleApi("TaggedError")(schemaTaggedErrorTCall.expression),
|
|
3568
|
-
|
|
3637
|
+
orUndefined
|
|
3569
3638
|
);
|
|
3570
|
-
if (
|
|
3639
|
+
if (isEffectSchemaModuleApi) {
|
|
3571
3640
|
return {
|
|
3572
3641
|
className: atLocation.name,
|
|
3573
3642
|
selfTypeNode,
|
|
@@ -3587,6 +3656,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3587
3656
|
);
|
|
3588
3657
|
const extendsSchemaTaggedRequest = cachedBy(
|
|
3589
3658
|
fn("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
|
|
3659
|
+
if (supportedEffect() === "v4") {
|
|
3660
|
+
return yield* typeParserIssue("Schema.TaggedClass is not supported in Effect v4", void 0, atLocation);
|
|
3661
|
+
}
|
|
3590
3662
|
if (!atLocation.name) {
|
|
3591
3663
|
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
3592
3664
|
}
|
|
@@ -3604,9 +3676,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3604
3676
|
const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
|
|
3605
3677
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3606
3678
|
isNodeReferenceToEffectSchemaModuleApi("TaggedRequest")(schemaTaggedRequestTCall.expression),
|
|
3607
|
-
|
|
3679
|
+
orUndefined
|
|
3608
3680
|
);
|
|
3609
|
-
if (
|
|
3681
|
+
if (isEffectSchemaModuleApi) {
|
|
3610
3682
|
return {
|
|
3611
3683
|
className: atLocation.name,
|
|
3612
3684
|
selfTypeNode,
|
|
@@ -3624,6 +3696,48 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3624
3696
|
"TypeParser.extendsSchemaTaggedRequest",
|
|
3625
3697
|
(atLocation) => atLocation
|
|
3626
3698
|
);
|
|
3699
|
+
const extendsSchemaRequestClass = cachedBy(
|
|
3700
|
+
fn("TypeParser.extendsSchemaRequestClass")(function* (atLocation) {
|
|
3701
|
+
if (supportedEffect() === "v3") {
|
|
3702
|
+
return yield* typeParserIssue("Schema.RequestClass is not supported in Effect v3", void 0, atLocation);
|
|
3703
|
+
}
|
|
3704
|
+
if (!atLocation.name) {
|
|
3705
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
3706
|
+
}
|
|
3707
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
3708
|
+
if (!heritageClauses) {
|
|
3709
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
3710
|
+
}
|
|
3711
|
+
for (const heritageClause of heritageClauses) {
|
|
3712
|
+
for (const typeX of heritageClause.types) {
|
|
3713
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
3714
|
+
const expression = typeX.expression;
|
|
3715
|
+
if (ts.isCallExpression(expression)) {
|
|
3716
|
+
const schemaTaggedRequestTCall = expression.expression;
|
|
3717
|
+
if (ts.isCallExpression(schemaTaggedRequestTCall) && schemaTaggedRequestTCall.typeArguments && schemaTaggedRequestTCall.typeArguments.length > 0) {
|
|
3718
|
+
const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
|
|
3719
|
+
const isEffectSchemaModuleApi = yield* pipe(
|
|
3720
|
+
isNodeReferenceToEffectSchemaModuleApi("RequestClass")(schemaTaggedRequestTCall.expression),
|
|
3721
|
+
orUndefined
|
|
3722
|
+
);
|
|
3723
|
+
if (isEffectSchemaModuleApi) {
|
|
3724
|
+
return {
|
|
3725
|
+
className: atLocation.name,
|
|
3726
|
+
selfTypeNode,
|
|
3727
|
+
tagStringLiteral: void 0,
|
|
3728
|
+
keyStringLiteral: schemaTaggedRequestTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedRequestTCall.arguments[0]) ? schemaTaggedRequestTCall.arguments[0] : void 0
|
|
3729
|
+
};
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
return yield* typeParserIssue("Class does not extend Schema.RequestClass", void 0, atLocation);
|
|
3737
|
+
}),
|
|
3738
|
+
"TypeParser.extendsSchemaRequestClass",
|
|
3739
|
+
(atLocation) => atLocation
|
|
3740
|
+
);
|
|
3627
3741
|
const extendsDataTaggedError = cachedBy(
|
|
3628
3742
|
fn("TypeParser.extendsDataTaggedError")(function* (atLocation) {
|
|
3629
3743
|
if (!atLocation.name) {
|
|
@@ -3643,13 +3757,13 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3643
3757
|
if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedError") {
|
|
3644
3758
|
const parsedDataModule = yield* pipe(
|
|
3645
3759
|
importedDataModule(dataIdentifier.expression),
|
|
3646
|
-
|
|
3760
|
+
orUndefined
|
|
3647
3761
|
);
|
|
3648
|
-
if (
|
|
3762
|
+
if (parsedDataModule) {
|
|
3649
3763
|
return {
|
|
3650
3764
|
className: atLocation.name,
|
|
3651
3765
|
keyStringLiteral: dataTaggedErrorCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedErrorCall.arguments[0]) ? dataTaggedErrorCall.arguments[0] : void 0,
|
|
3652
|
-
Data: parsedDataModule
|
|
3766
|
+
Data: parsedDataModule
|
|
3653
3767
|
};
|
|
3654
3768
|
}
|
|
3655
3769
|
}
|
|
@@ -3681,13 +3795,13 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3681
3795
|
if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedClass") {
|
|
3682
3796
|
const parsedDataModule = yield* pipe(
|
|
3683
3797
|
importedDataModule(dataIdentifier.expression),
|
|
3684
|
-
|
|
3798
|
+
orUndefined
|
|
3685
3799
|
);
|
|
3686
|
-
if (
|
|
3800
|
+
if (parsedDataModule) {
|
|
3687
3801
|
return {
|
|
3688
3802
|
className: atLocation.name,
|
|
3689
3803
|
keyStringLiteral: dataTaggedClassCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedClassCall.arguments[0]) ? dataTaggedClassCall.arguments[0] : void 0,
|
|
3690
|
-
Data: parsedDataModule
|
|
3804
|
+
Data: parsedDataModule
|
|
3691
3805
|
};
|
|
3692
3806
|
}
|
|
3693
3807
|
}
|
|
@@ -3721,9 +3835,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3721
3835
|
if (ts.isPropertyAccessExpression(contextTagIdentifier) && ts.isIdentifier(contextTagIdentifier.name) && ts.idText(contextTagIdentifier.name) === "Tag") {
|
|
3722
3836
|
const parsedContextModule = yield* pipe(
|
|
3723
3837
|
importedContextModule(contextTagIdentifier.expression),
|
|
3724
|
-
|
|
3838
|
+
orUndefined
|
|
3725
3839
|
);
|
|
3726
|
-
if (
|
|
3840
|
+
if (parsedContextModule) {
|
|
3727
3841
|
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
3728
3842
|
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
3729
3843
|
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
@@ -3734,7 +3848,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3734
3848
|
keyStringLiteral: ts.isStringLiteral(contextTagCall.arguments[0]) ? contextTagCall.arguments[0] : void 0,
|
|
3735
3849
|
args: contextTagCall.arguments,
|
|
3736
3850
|
Identifier: tagType.Identifier,
|
|
3737
|
-
Tag: parsedContextModule
|
|
3851
|
+
Tag: parsedContextModule
|
|
3738
3852
|
};
|
|
3739
3853
|
}
|
|
3740
3854
|
}
|
|
@@ -3772,9 +3886,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3772
3886
|
const selfTypeNode = wholeCall.typeArguments[0];
|
|
3773
3887
|
const isEffectTag = yield* pipe(
|
|
3774
3888
|
isNodeReferenceToEffectModuleApi("Tag")(effectTagIdentifier),
|
|
3775
|
-
|
|
3889
|
+
orUndefined
|
|
3776
3890
|
);
|
|
3777
|
-
if (
|
|
3891
|
+
if (isEffectTag) {
|
|
3778
3892
|
return {
|
|
3779
3893
|
className: atLocation.name,
|
|
3780
3894
|
selfTypeNode,
|
|
@@ -3814,17 +3928,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3814
3928
|
const selfTypeNode = effectServiceCall.typeArguments[0];
|
|
3815
3929
|
const isEffectService = yield* pipe(
|
|
3816
3930
|
isNodeReferenceToEffectModuleApi("Service")(effectServiceIdentifier),
|
|
3817
|
-
|
|
3931
|
+
orUndefined
|
|
3818
3932
|
);
|
|
3819
|
-
if (
|
|
3933
|
+
if (isEffectService) {
|
|
3820
3934
|
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
3821
3935
|
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
3822
3936
|
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
3823
3937
|
const parsedContextTag = yield* pipe(
|
|
3824
3938
|
contextTag(type, atLocation),
|
|
3825
|
-
|
|
3939
|
+
orUndefined
|
|
3826
3940
|
);
|
|
3827
|
-
if (
|
|
3941
|
+
if (parsedContextTag) {
|
|
3828
3942
|
let accessors2 = void 0;
|
|
3829
3943
|
let dependencies = void 0;
|
|
3830
3944
|
if (wholeCall.arguments.length >= 2) {
|
|
@@ -3841,7 +3955,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3841
3955
|
}
|
|
3842
3956
|
}
|
|
3843
3957
|
return {
|
|
3844
|
-
...parsedContextTag
|
|
3958
|
+
...parsedContextTag,
|
|
3845
3959
|
className: atLocation.name,
|
|
3846
3960
|
selfTypeNode,
|
|
3847
3961
|
args: wholeCall.arguments,
|
|
@@ -3911,9 +4025,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3911
4025
|
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
3912
4026
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3913
4027
|
isNodeReferenceToEffectSqlModelModuleApi("Class")(schemaCall.expression),
|
|
3914
|
-
|
|
4028
|
+
orUndefined
|
|
3915
4029
|
);
|
|
3916
|
-
if (
|
|
4030
|
+
if (isEffectSchemaModuleApi) {
|
|
3917
4031
|
return {
|
|
3918
4032
|
className: atLocation.name,
|
|
3919
4033
|
selfTypeNode: schemaCall.typeArguments[0]
|
|
@@ -4036,19 +4150,18 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4036
4150
|
map4((s) => ({ _tag: "call", ...s }))
|
|
4037
4151
|
)
|
|
4038
4152
|
),
|
|
4039
|
-
|
|
4153
|
+
orUndefined
|
|
4040
4154
|
);
|
|
4041
|
-
if (
|
|
4042
|
-
const result2 = parsed.value;
|
|
4155
|
+
if (parsed) {
|
|
4043
4156
|
let transformations;
|
|
4044
4157
|
let flowNode;
|
|
4045
4158
|
let childrenToTraverse = [];
|
|
4046
|
-
if (
|
|
4047
|
-
const signature = typeChecker.getResolvedSignature(
|
|
4159
|
+
if (parsed._tag === "pipe") {
|
|
4160
|
+
const signature = typeChecker.getResolvedSignature(parsed.node);
|
|
4048
4161
|
const typeArguments = signature ? typeChecker.getTypeArgumentsForResolvedSignature(signature) : void 0;
|
|
4049
4162
|
transformations = [];
|
|
4050
|
-
for (let i = 0; i <
|
|
4051
|
-
const arg =
|
|
4163
|
+
for (let i = 0; i < parsed.args.length; i++) {
|
|
4164
|
+
const arg = parsed.args[i];
|
|
4052
4165
|
const outType = typeArguments?.[i + 1];
|
|
4053
4166
|
if (ts.isCallExpression(arg)) {
|
|
4054
4167
|
transformations.push({
|
|
@@ -4057,7 +4170,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4057
4170
|
args: Array.from(arg.arguments),
|
|
4058
4171
|
// e.g., [(x) => x + 1]
|
|
4059
4172
|
outType,
|
|
4060
|
-
kind:
|
|
4173
|
+
kind: parsed.kind
|
|
4061
4174
|
});
|
|
4062
4175
|
} else {
|
|
4063
4176
|
transformations.push({
|
|
@@ -4065,17 +4178,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4065
4178
|
// e.g., Effect.asVoid
|
|
4066
4179
|
args: void 0,
|
|
4067
4180
|
outType,
|
|
4068
|
-
kind:
|
|
4181
|
+
kind: parsed.kind
|
|
4069
4182
|
});
|
|
4070
4183
|
}
|
|
4071
4184
|
}
|
|
4072
|
-
flowNode =
|
|
4073
|
-
childrenToTraverse =
|
|
4185
|
+
flowNode = parsed.node;
|
|
4186
|
+
childrenToTraverse = parsed.args;
|
|
4074
4187
|
} else {
|
|
4075
4188
|
const callSignature = typeChecker.getResolvedSignature(node);
|
|
4076
4189
|
const outType = callSignature ? typeChecker.getReturnTypeOfSignature(callSignature) : void 0;
|
|
4077
4190
|
transformations = [{
|
|
4078
|
-
callee:
|
|
4191
|
+
callee: parsed.callee,
|
|
4079
4192
|
args: void 0,
|
|
4080
4193
|
outType,
|
|
4081
4194
|
kind: "call"
|
|
@@ -4085,20 +4198,20 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4085
4198
|
if (parentFlow) {
|
|
4086
4199
|
parentFlow.transformations.unshift(...transformations);
|
|
4087
4200
|
parentFlow.subject = {
|
|
4088
|
-
node:
|
|
4089
|
-
outType: typeCheckerUtils.getTypeAtLocation(
|
|
4201
|
+
node: parsed.subject,
|
|
4202
|
+
outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
|
|
4090
4203
|
};
|
|
4091
|
-
workQueue.push([
|
|
4204
|
+
workQueue.push([parsed.subject, parentFlow]);
|
|
4092
4205
|
} else {
|
|
4093
4206
|
const newFlow = {
|
|
4094
4207
|
node: flowNode,
|
|
4095
4208
|
subject: {
|
|
4096
|
-
node:
|
|
4097
|
-
outType: typeCheckerUtils.getTypeAtLocation(
|
|
4209
|
+
node: parsed.subject,
|
|
4210
|
+
outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
|
|
4098
4211
|
},
|
|
4099
4212
|
transformations
|
|
4100
4213
|
};
|
|
4101
|
-
workQueue.push([
|
|
4214
|
+
workQueue.push([parsed.subject, newFlow]);
|
|
4102
4215
|
}
|
|
4103
4216
|
for (const child of childrenToTraverse) {
|
|
4104
4217
|
ts.forEachChild(child, (c) => {
|
|
@@ -4108,17 +4221,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4108
4221
|
continue;
|
|
4109
4222
|
}
|
|
4110
4223
|
if (includeEffectFn) {
|
|
4111
|
-
const
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
if (
|
|
4121
|
-
const fnResult =
|
|
4224
|
+
const effectFnKind = yield* pipe(
|
|
4225
|
+
map4(effectFnGen(node), (_) => ({ kind: "effectFnGen", ..._ })),
|
|
4226
|
+
orElse2(
|
|
4227
|
+
() => map4(effectFnUntracedGen(node), (_) => ({ kind: "effectFnUntracedGen", ..._ }))
|
|
4228
|
+
),
|
|
4229
|
+
orElse2(() => map4(effectFn(node), (_) => ({ kind: "effectFn", ..._ }))),
|
|
4230
|
+
orUndefined
|
|
4231
|
+
);
|
|
4232
|
+
if (effectFnKind && (effectFnKind.kind === "effectFnGen" || effectFnKind.kind === "effectFnUntracedGen")) {
|
|
4233
|
+
if (effectFnKind.pipeArguments.length > 0) {
|
|
4234
|
+
const fnResult = effectFnKind;
|
|
4122
4235
|
const pipeArgs = fnResult.pipeArguments;
|
|
4123
4236
|
const transformations = [];
|
|
4124
4237
|
let subjectType;
|
|
@@ -4138,14 +4251,14 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4138
4251
|
callee: arg.expression,
|
|
4139
4252
|
args: Array.from(arg.arguments),
|
|
4140
4253
|
outType,
|
|
4141
|
-
kind:
|
|
4254
|
+
kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
|
|
4142
4255
|
});
|
|
4143
4256
|
} else {
|
|
4144
4257
|
transformations.push({
|
|
4145
4258
|
callee: arg,
|
|
4146
4259
|
args: void 0,
|
|
4147
4260
|
outType,
|
|
4148
|
-
kind:
|
|
4261
|
+
kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
|
|
4149
4262
|
});
|
|
4150
4263
|
}
|
|
4151
4264
|
}
|
|
@@ -4167,8 +4280,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4167
4280
|
continue;
|
|
4168
4281
|
}
|
|
4169
4282
|
}
|
|
4170
|
-
if (
|
|
4171
|
-
const fnResult =
|
|
4283
|
+
if (effectFnKind && effectFnKind.kind === "effectFn" && effectFnKind.pipeArguments.length > 0) {
|
|
4284
|
+
const fnResult = effectFnKind;
|
|
4172
4285
|
const pipeArgs = fnResult.pipeArguments;
|
|
4173
4286
|
const transformations = [];
|
|
4174
4287
|
let subjectType;
|
|
@@ -4314,11 +4427,14 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4314
4427
|
extendsDataTaggedError,
|
|
4315
4428
|
extendsDataTaggedClass,
|
|
4316
4429
|
extendsSchemaTaggedRequest,
|
|
4430
|
+
extendsSchemaRequestClass,
|
|
4317
4431
|
extendsEffectSqlModelClass,
|
|
4318
4432
|
lazyExpression,
|
|
4319
4433
|
emptyFunction,
|
|
4320
4434
|
pipingFlows,
|
|
4321
|
-
reconstructPipingFlow
|
|
4435
|
+
reconstructPipingFlow,
|
|
4436
|
+
getEffectRelatedPackages,
|
|
4437
|
+
supportedEffect
|
|
4322
4438
|
};
|
|
4323
4439
|
}
|
|
4324
4440
|
|
|
@@ -4434,6 +4550,7 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4434
4550
|
apply: fn("catchAllToMapError.apply")(function* (sourceFile, report) {
|
|
4435
4551
|
const ts = yield* service(TypeScriptApi);
|
|
4436
4552
|
const typeParser = yield* service(TypeParser);
|
|
4553
|
+
const catchAllName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
|
|
4437
4554
|
const getFunctionBody = (node) => {
|
|
4438
4555
|
if (ts.isArrowFunction(node)) {
|
|
4439
4556
|
return node.body;
|
|
@@ -4448,10 +4565,10 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4448
4565
|
if (ts.isCallExpression(body)) {
|
|
4449
4566
|
const isFailCall = yield* pipe(
|
|
4450
4567
|
typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
|
|
4451
|
-
|
|
4568
|
+
orUndefined
|
|
4452
4569
|
);
|
|
4453
|
-
if (
|
|
4454
|
-
return
|
|
4570
|
+
if (isFailCall && body.arguments.length >= 1) {
|
|
4571
|
+
return { failCall: body, failArg: body.arguments[0] };
|
|
4455
4572
|
}
|
|
4456
4573
|
}
|
|
4457
4574
|
if (ts.isBlock(body)) {
|
|
@@ -4461,15 +4578,14 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4461
4578
|
if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
|
|
4462
4579
|
const isFailCall = yield* pipe(
|
|
4463
4580
|
typeParser.isNodeReferenceToEffectModuleApi("fail")(stmt.expression.expression),
|
|
4464
|
-
|
|
4581
|
+
orUndefined
|
|
4465
4582
|
);
|
|
4466
|
-
if (
|
|
4467
|
-
return
|
|
4583
|
+
if (isFailCall && stmt.expression.arguments.length >= 1) {
|
|
4584
|
+
return { failCall: stmt.expression, failArg: stmt.expression.arguments[0] };
|
|
4468
4585
|
}
|
|
4469
4586
|
}
|
|
4470
4587
|
}
|
|
4471
4588
|
}
|
|
4472
|
-
return none2();
|
|
4473
4589
|
});
|
|
4474
4590
|
};
|
|
4475
4591
|
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
@@ -4479,10 +4595,10 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4479
4595
|
continue;
|
|
4480
4596
|
}
|
|
4481
4597
|
const isCatchAllCall = yield* pipe(
|
|
4482
|
-
typeParser.isNodeReferenceToEffectModuleApi(
|
|
4483
|
-
|
|
4598
|
+
typeParser.isNodeReferenceToEffectModuleApi(catchAllName)(transformation.callee),
|
|
4599
|
+
orUndefined
|
|
4484
4600
|
);
|
|
4485
|
-
if (
|
|
4601
|
+
if (!isCatchAllCall) {
|
|
4486
4602
|
continue;
|
|
4487
4603
|
}
|
|
4488
4604
|
const callback = transformation.args[0];
|
|
@@ -4490,11 +4606,11 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4490
4606
|
const functionBody = getFunctionBody(callback);
|
|
4491
4607
|
if (!functionBody) continue;
|
|
4492
4608
|
const failCallInfo = yield* getEffectFailCallInfo(functionBody);
|
|
4493
|
-
if (
|
|
4494
|
-
const { failArg, failCall } = failCallInfo
|
|
4609
|
+
if (!failCallInfo) continue;
|
|
4610
|
+
const { failArg, failCall } = failCallInfo;
|
|
4495
4611
|
report({
|
|
4496
4612
|
location: transformation.callee,
|
|
4497
|
-
messageText: `You can use Effect.mapError instead of Effect
|
|
4613
|
+
messageText: `You can use Effect.mapError instead of Effect.${catchAllName} + Effect.fail to transform the error type.`,
|
|
4498
4614
|
fixes: [{
|
|
4499
4615
|
fixName: "catchAllToMapError_fix",
|
|
4500
4616
|
description: "Replace with Effect.mapError",
|
|
@@ -4525,7 +4641,7 @@ var catchUnfailableEffect = createDiagnostic({
|
|
|
4525
4641
|
apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
|
|
4526
4642
|
const ts = yield* service(TypeScriptApi);
|
|
4527
4643
|
const typeParser = yield* service(TypeParser);
|
|
4528
|
-
const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
|
|
4644
|
+
const catchFunctions = typeParser.supportedEffect() === "v3" ? ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"] : ["catch", "catchIf", "catchTag", "catchTags"];
|
|
4529
4645
|
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
4530
4646
|
for (const flow2 of flows) {
|
|
4531
4647
|
for (let i = 0; i < flow2.transformations.length; i++) {
|
|
@@ -4590,7 +4706,12 @@ var classSelfMismatch = createDiagnostic({
|
|
|
4590
4706
|
orElse2(() => typeParser.extendsSchemaClass(node)),
|
|
4591
4707
|
orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
|
|
4592
4708
|
orElse2(() => typeParser.extendsSchemaTaggedError(node)),
|
|
4593
|
-
orElse2(
|
|
4709
|
+
orElse2(
|
|
4710
|
+
() => pipe(
|
|
4711
|
+
typeParser.extendsSchemaTaggedRequest(node),
|
|
4712
|
+
orElse2(() => typeParser.extendsSchemaRequestClass(node))
|
|
4713
|
+
)
|
|
4714
|
+
),
|
|
4594
4715
|
orElse2(() => typeParser.extendsEffectSqlModelClass(node)),
|
|
4595
4716
|
orElse2(() => void_)
|
|
4596
4717
|
);
|
|
@@ -4817,39 +4938,18 @@ var deterministicKeys = createDiagnostic({
|
|
|
4817
4938
|
});
|
|
4818
4939
|
|
|
4819
4940
|
// src/diagnostics/duplicatePackage.ts
|
|
4820
|
-
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
4821
|
-
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
4822
4941
|
var duplicatePackage = createDiagnostic({
|
|
4823
4942
|
name: "duplicatePackage",
|
|
4824
4943
|
code: 6,
|
|
4825
4944
|
description: "Detects when multiple versions of the same Effect package are loaded",
|
|
4826
4945
|
severity: "warning",
|
|
4827
4946
|
apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
|
|
4828
|
-
const
|
|
4829
|
-
const tsUtils = yield* service(TypeScriptUtils);
|
|
4947
|
+
const typeParser = yield* service(TypeParser);
|
|
4830
4948
|
const options = yield* service(LanguageServicePluginOptions);
|
|
4831
4949
|
if (sourceFile.statements.length < 1) return;
|
|
4832
|
-
|
|
4833
|
-
const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
|
|
4834
|
-
const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
|
|
4835
|
-
if (newResolvedModuleSize !== oldResolvedSize) {
|
|
4836
|
-
const seenPackages = /* @__PURE__ */ new Set();
|
|
4837
|
-
resolvedPackages = {};
|
|
4838
|
-
program.getSourceFiles().map((_) => {
|
|
4839
|
-
const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
|
|
4840
|
-
if (!packageInfo) return;
|
|
4841
|
-
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
4842
|
-
if (seenPackages.has(packageNameAndVersion)) return;
|
|
4843
|
-
seenPackages.add(packageNameAndVersion);
|
|
4844
|
-
if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
|
|
4845
|
-
if (options.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
|
|
4846
|
-
resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
|
|
4847
|
-
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
|
|
4848
|
-
});
|
|
4849
|
-
checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
|
|
4850
|
-
programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
|
|
4851
|
-
}
|
|
4950
|
+
const resolvedPackages = typeParser.getEffectRelatedPackages(sourceFile);
|
|
4852
4951
|
for (const packageName of Object.keys(resolvedPackages)) {
|
|
4952
|
+
if (options.allowedDuplicatedPackages.indexOf(packageName) > -1) return;
|
|
4853
4953
|
if (Object.keys(resolvedPackages[packageName]).length > 1) {
|
|
4854
4954
|
const versions = Object.keys(resolvedPackages[packageName]);
|
|
4855
4955
|
report({
|
|
@@ -5673,23 +5773,25 @@ var globalErrorInEffectCatch = createDiagnostic({
|
|
|
5673
5773
|
if (isEffectWithCatch) {
|
|
5674
5774
|
const signature = typeChecker.getResolvedSignature(node);
|
|
5675
5775
|
if (signature) {
|
|
5676
|
-
const
|
|
5677
|
-
const
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5776
|
+
const firstParameterType = typeChecker.getParameterType(signature, 0);
|
|
5777
|
+
for (const objectType of typeCheckerUtils.unrollUnionMembers(firstParameterType)) {
|
|
5778
|
+
const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
|
|
5779
|
+
if (catchFunctionSymbol) {
|
|
5780
|
+
const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
|
|
5781
|
+
const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
|
|
5782
|
+
if (signatures.length > 0) {
|
|
5783
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
|
|
5784
|
+
if (returnType && typeCheckerUtils.isGlobalErrorType(returnType)) {
|
|
5785
|
+
const nodeText = sourceFile.text.substring(
|
|
5786
|
+
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
5787
|
+
node.expression.end
|
|
5788
|
+
);
|
|
5789
|
+
report({
|
|
5790
|
+
location: node.expression,
|
|
5791
|
+
messageText: `The 'catch' callback in ${nodeText} returns global 'Error', which loses type safety as untagged errors merge together. Consider using a tagged error and optionally wrapping the original in a 'cause' property.`,
|
|
5792
|
+
fixes: []
|
|
5793
|
+
});
|
|
5794
|
+
}
|
|
5693
5795
|
}
|
|
5694
5796
|
}
|
|
5695
5797
|
}
|
|
@@ -6502,22 +6604,23 @@ var missingEffectError = createDiagnostic({
|
|
|
6502
6604
|
map4((result) => {
|
|
6503
6605
|
if (result.missingErrorTypes.length === 0) return;
|
|
6504
6606
|
const fixes = [];
|
|
6505
|
-
|
|
6607
|
+
const catchAllErrorsName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
|
|
6608
|
+
if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never && catchAllErrorsName) {
|
|
6506
6609
|
fixes.push({
|
|
6507
|
-
fixName:
|
|
6508
|
-
description:
|
|
6610
|
+
fixName: `missingEffectError_${catchAllErrorsName}`,
|
|
6611
|
+
description: `Catch all errors with Effect.${catchAllErrorsName}`,
|
|
6509
6612
|
apply: gen(function* () {
|
|
6510
6613
|
const changeTracker = yield* service(ChangeTracker);
|
|
6511
6614
|
changeTracker.insertText(
|
|
6512
6615
|
sourceFile,
|
|
6513
6616
|
ts.getTokenPosOfNode(valueNode, sourceFile),
|
|
6514
|
-
effectModuleIdentifier +
|
|
6617
|
+
effectModuleIdentifier + `.${catchAllErrorsName}(`
|
|
6515
6618
|
);
|
|
6516
6619
|
changeTracker.insertText(sourceFile, valueNode.end, ", () => ");
|
|
6517
6620
|
changeTracker.insertNodeAt(
|
|
6518
6621
|
sourceFile,
|
|
6519
6622
|
valueNode.end,
|
|
6520
|
-
createDieMessage(
|
|
6623
|
+
createDieMessage(`TODO: ${catchAllErrorsName} not implemented`)
|
|
6521
6624
|
);
|
|
6522
6625
|
changeTracker.insertText(sourceFile, valueNode.end, ")");
|
|
6523
6626
|
})
|
|
@@ -6599,6 +6702,7 @@ var missingEffectServiceDependency = createDiagnostic({
|
|
|
6599
6702
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
6600
6703
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
6601
6704
|
const typeParser = yield* service(TypeParser);
|
|
6705
|
+
if (typeParser.supportedEffect() !== "v3") return;
|
|
6602
6706
|
const nodeToVisit = [];
|
|
6603
6707
|
const appendNodeToVisit = (node) => {
|
|
6604
6708
|
nodeToVisit.push(node);
|
|
@@ -8818,6 +8922,7 @@ var scopeInLayerEffect = createDiagnostic({
|
|
|
8818
8922
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
8819
8923
|
const typeParser = yield* service(TypeParser);
|
|
8820
8924
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
8925
|
+
if (typeParser.supportedEffect() !== "v3") return;
|
|
8821
8926
|
const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
8822
8927
|
sourceFile,
|
|
8823
8928
|
"effect",
|
|
@@ -9026,6 +9131,17 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
9026
9131
|
apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
|
|
9027
9132
|
const ts = yield* service(TypeScriptApi);
|
|
9028
9133
|
const typeParser = yield* service(TypeParser);
|
|
9134
|
+
const alternatives = typeParser.supportedEffect() === "v4" ? [
|
|
9135
|
+
"Effect.try",
|
|
9136
|
+
"Effect.tryPromise",
|
|
9137
|
+
"Effect.catch",
|
|
9138
|
+
"Effect.catchTag"
|
|
9139
|
+
] : [
|
|
9140
|
+
"Effect.try",
|
|
9141
|
+
"Effect.tryPromise",
|
|
9142
|
+
"Effect.catchAll",
|
|
9143
|
+
"Effect.catchTag"
|
|
9144
|
+
];
|
|
9029
9145
|
const nodeToVisit = [];
|
|
9030
9146
|
const appendNodeToVisit = (node) => {
|
|
9031
9147
|
nodeToVisit.push(node);
|
|
@@ -9051,7 +9167,7 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
9051
9167
|
map4(() => {
|
|
9052
9168
|
report({
|
|
9053
9169
|
location: node,
|
|
9054
|
-
messageText:
|
|
9170
|
+
messageText: `Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g. ${alternatives.join(", ")}).`,
|
|
9055
9171
|
fixes: []
|
|
9056
9172
|
});
|
|
9057
9173
|
}),
|
|
@@ -9073,6 +9189,7 @@ var unknownInEffectCatch = createDiagnostic({
|
|
|
9073
9189
|
const ts = yield* service(TypeScriptApi);
|
|
9074
9190
|
const typeParser = yield* service(TypeParser);
|
|
9075
9191
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
9192
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
9076
9193
|
const nodeToVisit = [];
|
|
9077
9194
|
const appendNodeToVisit = (node) => {
|
|
9078
9195
|
nodeToVisit.push(node);
|
|
@@ -9093,24 +9210,26 @@ var unknownInEffectCatch = createDiagnostic({
|
|
|
9093
9210
|
if (isEffectWithCatch) {
|
|
9094
9211
|
const signature = typeChecker.getResolvedSignature(node);
|
|
9095
9212
|
if (signature) {
|
|
9096
|
-
const
|
|
9097
|
-
const
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9213
|
+
const parameterType = typeChecker.getParameterType(signature, 0);
|
|
9214
|
+
for (const objectType of typeCheckerUtils.unrollUnionMembers(parameterType)) {
|
|
9215
|
+
const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
|
|
9216
|
+
if (catchFunctionSymbol) {
|
|
9217
|
+
const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
|
|
9218
|
+
const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
|
|
9219
|
+
if (signatures.length > 0) {
|
|
9220
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
|
|
9221
|
+
if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
|
|
9222
|
+
const nodeText = sourceFile.text.substring(
|
|
9223
|
+
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
9224
|
+
node.expression.end
|
|
9225
|
+
);
|
|
9226
|
+
report({
|
|
9227
|
+
location: node.expression,
|
|
9228
|
+
messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
|
|
9111
9229
|
Consider wrapping unknown errors into Effect's Data.TaggedError for example, or narrow down the type to the specific error raised.`,
|
|
9112
|
-
|
|
9113
|
-
|
|
9230
|
+
fixes: []
|
|
9231
|
+
});
|
|
9232
|
+
}
|
|
9114
9233
|
}
|
|
9115
9234
|
}
|
|
9116
9235
|
}
|