@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
package/transform.js
CHANGED
|
@@ -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");
|
|
@@ -2563,6 +2570,8 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
|
|
|
2563
2570
|
}
|
|
2564
2571
|
|
|
2565
2572
|
// src/core/TypeParser.ts
|
|
2573
|
+
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
2574
|
+
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
2566
2575
|
var TypeParser = Tag("@effect/language-service/TypeParser");
|
|
2567
2576
|
var nanoLayer3 = (fa) => gen(function* () {
|
|
2568
2577
|
const ts = yield* service(TypeScriptApi);
|
|
@@ -2583,6 +2592,42 @@ function typeParserIssue(_message, _type, _node) {
|
|
|
2583
2592
|
return TypeParserIssue.issue;
|
|
2584
2593
|
}
|
|
2585
2594
|
function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
2595
|
+
function supportedEffect() {
|
|
2596
|
+
for (const fileName of program.getRootFileNames()) {
|
|
2597
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
2598
|
+
if (!sourceFile) continue;
|
|
2599
|
+
const resolvedPackages = getEffectRelatedPackages(sourceFile);
|
|
2600
|
+
const effectPkgs = resolvedPackages["effect"];
|
|
2601
|
+
if (!effectPkgs) continue;
|
|
2602
|
+
for (const version of Object.keys(effectPkgs)) {
|
|
2603
|
+
if (String(version).startsWith("4")) return "v4";
|
|
2604
|
+
if (String(version).startsWith("3")) return "v3";
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
return "v3";
|
|
2608
|
+
}
|
|
2609
|
+
function getEffectRelatedPackages(sourceFile) {
|
|
2610
|
+
let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
|
|
2611
|
+
const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
|
|
2612
|
+
const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
|
|
2613
|
+
if (newResolvedModuleSize !== oldResolvedSize) {
|
|
2614
|
+
const seenPackages = /* @__PURE__ */ new Set();
|
|
2615
|
+
resolvedPackages = {};
|
|
2616
|
+
program.getSourceFiles().map((_) => {
|
|
2617
|
+
const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
|
|
2618
|
+
if (!packageInfo) return;
|
|
2619
|
+
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
2620
|
+
if (seenPackages.has(packageNameAndVersion)) return;
|
|
2621
|
+
seenPackages.add(packageNameAndVersion);
|
|
2622
|
+
if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
|
|
2623
|
+
resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
|
|
2624
|
+
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
|
|
2625
|
+
});
|
|
2626
|
+
checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
|
|
2627
|
+
programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
|
|
2628
|
+
}
|
|
2629
|
+
return resolvedPackages;
|
|
2630
|
+
}
|
|
2586
2631
|
const getSourceFilePackageInfo = cachedBy(
|
|
2587
2632
|
fn("TypeParser.getSourceFilePackageInfo")(function* (sourceFile) {
|
|
2588
2633
|
return tsUtils.resolveModuleWithPackageInfoFromSourceFile(program, sourceFile);
|
|
@@ -2811,19 +2856,28 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2811
2856
|
);
|
|
2812
2857
|
const effectType = cachedBy(
|
|
2813
2858
|
fn("TypeParser.effectType")(function* (type, atLocation) {
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2859
|
+
if (supportedEffect() === "v4") {
|
|
2860
|
+
const typeIdSymbol = typeChecker.getPropertyOfType(type, "~effect/Effect");
|
|
2861
|
+
if (typeIdSymbol) {
|
|
2862
|
+
const typeIdType = typeChecker.getTypeOfSymbolAtLocation(typeIdSymbol, atLocation);
|
|
2863
|
+
return yield* effectVarianceStruct(typeIdType, atLocation);
|
|
2864
|
+
}
|
|
2865
|
+
return yield* typeParserIssue("Type is not an effect", type, atLocation);
|
|
2866
|
+
} else {
|
|
2867
|
+
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
2868
|
+
(_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
|
|
2869
|
+
);
|
|
2870
|
+
if (propertiesSymbols.length === 0) {
|
|
2871
|
+
return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
|
|
2872
|
+
}
|
|
2873
|
+
propertiesSymbols.sort(
|
|
2874
|
+
(a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
|
|
2875
|
+
);
|
|
2876
|
+
return yield* firstSuccessOf(propertiesSymbols.map((propertySymbol) => {
|
|
2877
|
+
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2878
|
+
return effectVarianceStruct(propertyType, atLocation);
|
|
2879
|
+
}));
|
|
2819
2880
|
}
|
|
2820
|
-
propertiesSymbols.sort(
|
|
2821
|
-
(a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
|
|
2822
|
-
);
|
|
2823
|
-
return yield* firstSuccessOf(propertiesSymbols.map((propertySymbol) => {
|
|
2824
|
-
const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
|
|
2825
|
-
return effectVarianceStruct(propertyType, atLocation);
|
|
2826
|
-
}));
|
|
2827
2881
|
}),
|
|
2828
2882
|
"TypeParser.effectType",
|
|
2829
2883
|
(type) => type
|
|
@@ -2952,7 +3006,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2952
3006
|
fn("TypeParser.isEffectDataSourceFile")(function* (sourceFile) {
|
|
2953
3007
|
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
2954
3008
|
if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
|
|
2955
|
-
const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol);
|
|
3009
|
+
const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol) || typeChecker.tryGetMemberInModuleExports("taggedEnum", moduleSymbol);
|
|
2956
3010
|
if (!taggedEnumSymbol) return yield* typeParserIssue("TaggedEnum not found", void 0, sourceFile);
|
|
2957
3011
|
const taggedErrorSymbol = typeChecker.tryGetMemberInModuleExports("TaggedError", moduleSymbol);
|
|
2958
3012
|
if (!taggedErrorSymbol) return yield* typeParserIssue("TaggedError not found", void 0, sourceFile);
|
|
@@ -3143,10 +3197,10 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3143
3197
|
}))
|
|
3144
3198
|
)
|
|
3145
3199
|
),
|
|
3146
|
-
|
|
3200
|
+
orUndefined
|
|
3147
3201
|
);
|
|
3148
|
-
if (
|
|
3149
|
-
effectGenResult = isEffectGen
|
|
3202
|
+
if (isEffectGen) {
|
|
3203
|
+
effectGenResult = isEffectGen;
|
|
3150
3204
|
}
|
|
3151
3205
|
}
|
|
3152
3206
|
if (scopeNode && effectGenResult) {
|
|
@@ -3266,6 +3320,21 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3266
3320
|
const effectSchemaType = cachedBy(
|
|
3267
3321
|
fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
|
|
3268
3322
|
yield* pipeableType(type, atLocation);
|
|
3323
|
+
const typeId = typeChecker.getPropertyOfType(type, "~effect/Schema/Schema");
|
|
3324
|
+
if (typeId) {
|
|
3325
|
+
const typeKey = typeChecker.getPropertyOfType(type, "Type");
|
|
3326
|
+
const encodedKey = typeChecker.getPropertyOfType(type, "Encoded");
|
|
3327
|
+
if (typeKey && encodedKey) {
|
|
3328
|
+
const typeType = typeChecker.getTypeOfSymbolAtLocation(typeKey, atLocation);
|
|
3329
|
+
const encodedType = typeChecker.getTypeOfSymbolAtLocation(encodedKey, atLocation);
|
|
3330
|
+
return {
|
|
3331
|
+
A: typeType,
|
|
3332
|
+
I: encodedType,
|
|
3333
|
+
R: typeChecker.getNeverType()
|
|
3334
|
+
};
|
|
3335
|
+
}
|
|
3336
|
+
return yield* typeParserIssue("missing Type and Encoded");
|
|
3337
|
+
}
|
|
3269
3338
|
const ast = typeChecker.getPropertyOfType(type, "ast");
|
|
3270
3339
|
if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
|
|
3271
3340
|
const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
|
|
@@ -3484,9 +3553,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3484
3553
|
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
3485
3554
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3486
3555
|
isNodeReferenceToEffectSchemaModuleApi("Class")(schemaCall.expression),
|
|
3487
|
-
|
|
3556
|
+
orUndefined
|
|
3488
3557
|
);
|
|
3489
|
-
if (
|
|
3558
|
+
if (isEffectSchemaModuleApi) {
|
|
3490
3559
|
return {
|
|
3491
3560
|
className: atLocation.name,
|
|
3492
3561
|
selfTypeNode: schemaCall.typeArguments[0]
|
|
@@ -3521,9 +3590,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3521
3590
|
const selfTypeNode = schemaTaggedClassTCall.typeArguments[0];
|
|
3522
3591
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3523
3592
|
isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(schemaTaggedClassTCall.expression),
|
|
3524
|
-
|
|
3593
|
+
orUndefined
|
|
3525
3594
|
);
|
|
3526
|
-
if (
|
|
3595
|
+
if (isEffectSchemaModuleApi) {
|
|
3527
3596
|
return {
|
|
3528
3597
|
className: atLocation.name,
|
|
3529
3598
|
selfTypeNode,
|
|
@@ -3560,9 +3629,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3560
3629
|
const selfTypeNode = schemaTaggedErrorTCall.typeArguments[0];
|
|
3561
3630
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3562
3631
|
isNodeReferenceToEffectSchemaModuleApi("TaggedError")(schemaTaggedErrorTCall.expression),
|
|
3563
|
-
|
|
3632
|
+
orUndefined
|
|
3564
3633
|
);
|
|
3565
|
-
if (
|
|
3634
|
+
if (isEffectSchemaModuleApi) {
|
|
3566
3635
|
return {
|
|
3567
3636
|
className: atLocation.name,
|
|
3568
3637
|
selfTypeNode,
|
|
@@ -3582,6 +3651,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3582
3651
|
);
|
|
3583
3652
|
const extendsSchemaTaggedRequest = cachedBy(
|
|
3584
3653
|
fn("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
|
|
3654
|
+
if (supportedEffect() === "v4") {
|
|
3655
|
+
return yield* typeParserIssue("Schema.TaggedClass is not supported in Effect v4", void 0, atLocation);
|
|
3656
|
+
}
|
|
3585
3657
|
if (!atLocation.name) {
|
|
3586
3658
|
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
3587
3659
|
}
|
|
@@ -3599,9 +3671,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3599
3671
|
const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
|
|
3600
3672
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3601
3673
|
isNodeReferenceToEffectSchemaModuleApi("TaggedRequest")(schemaTaggedRequestTCall.expression),
|
|
3602
|
-
|
|
3674
|
+
orUndefined
|
|
3603
3675
|
);
|
|
3604
|
-
if (
|
|
3676
|
+
if (isEffectSchemaModuleApi) {
|
|
3605
3677
|
return {
|
|
3606
3678
|
className: atLocation.name,
|
|
3607
3679
|
selfTypeNode,
|
|
@@ -3619,6 +3691,48 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3619
3691
|
"TypeParser.extendsSchemaTaggedRequest",
|
|
3620
3692
|
(atLocation) => atLocation
|
|
3621
3693
|
);
|
|
3694
|
+
const extendsSchemaRequestClass = cachedBy(
|
|
3695
|
+
fn("TypeParser.extendsSchemaRequestClass")(function* (atLocation) {
|
|
3696
|
+
if (supportedEffect() === "v3") {
|
|
3697
|
+
return yield* typeParserIssue("Schema.RequestClass is not supported in Effect v3", void 0, atLocation);
|
|
3698
|
+
}
|
|
3699
|
+
if (!atLocation.name) {
|
|
3700
|
+
return yield* typeParserIssue("Class has no name", void 0, atLocation);
|
|
3701
|
+
}
|
|
3702
|
+
const heritageClauses = atLocation.heritageClauses;
|
|
3703
|
+
if (!heritageClauses) {
|
|
3704
|
+
return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
|
|
3705
|
+
}
|
|
3706
|
+
for (const heritageClause of heritageClauses) {
|
|
3707
|
+
for (const typeX of heritageClause.types) {
|
|
3708
|
+
if (ts.isExpressionWithTypeArguments(typeX)) {
|
|
3709
|
+
const expression = typeX.expression;
|
|
3710
|
+
if (ts.isCallExpression(expression)) {
|
|
3711
|
+
const schemaTaggedRequestTCall = expression.expression;
|
|
3712
|
+
if (ts.isCallExpression(schemaTaggedRequestTCall) && schemaTaggedRequestTCall.typeArguments && schemaTaggedRequestTCall.typeArguments.length > 0) {
|
|
3713
|
+
const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
|
|
3714
|
+
const isEffectSchemaModuleApi = yield* pipe(
|
|
3715
|
+
isNodeReferenceToEffectSchemaModuleApi("RequestClass")(schemaTaggedRequestTCall.expression),
|
|
3716
|
+
orUndefined
|
|
3717
|
+
);
|
|
3718
|
+
if (isEffectSchemaModuleApi) {
|
|
3719
|
+
return {
|
|
3720
|
+
className: atLocation.name,
|
|
3721
|
+
selfTypeNode,
|
|
3722
|
+
tagStringLiteral: void 0,
|
|
3723
|
+
keyStringLiteral: schemaTaggedRequestTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedRequestTCall.arguments[0]) ? schemaTaggedRequestTCall.arguments[0] : void 0
|
|
3724
|
+
};
|
|
3725
|
+
}
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
return yield* typeParserIssue("Class does not extend Schema.RequestClass", void 0, atLocation);
|
|
3732
|
+
}),
|
|
3733
|
+
"TypeParser.extendsSchemaRequestClass",
|
|
3734
|
+
(atLocation) => atLocation
|
|
3735
|
+
);
|
|
3622
3736
|
const extendsDataTaggedError = cachedBy(
|
|
3623
3737
|
fn("TypeParser.extendsDataTaggedError")(function* (atLocation) {
|
|
3624
3738
|
if (!atLocation.name) {
|
|
@@ -3638,13 +3752,13 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3638
3752
|
if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedError") {
|
|
3639
3753
|
const parsedDataModule = yield* pipe(
|
|
3640
3754
|
importedDataModule(dataIdentifier.expression),
|
|
3641
|
-
|
|
3755
|
+
orUndefined
|
|
3642
3756
|
);
|
|
3643
|
-
if (
|
|
3757
|
+
if (parsedDataModule) {
|
|
3644
3758
|
return {
|
|
3645
3759
|
className: atLocation.name,
|
|
3646
3760
|
keyStringLiteral: dataTaggedErrorCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedErrorCall.arguments[0]) ? dataTaggedErrorCall.arguments[0] : void 0,
|
|
3647
|
-
Data: parsedDataModule
|
|
3761
|
+
Data: parsedDataModule
|
|
3648
3762
|
};
|
|
3649
3763
|
}
|
|
3650
3764
|
}
|
|
@@ -3676,13 +3790,13 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3676
3790
|
if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedClass") {
|
|
3677
3791
|
const parsedDataModule = yield* pipe(
|
|
3678
3792
|
importedDataModule(dataIdentifier.expression),
|
|
3679
|
-
|
|
3793
|
+
orUndefined
|
|
3680
3794
|
);
|
|
3681
|
-
if (
|
|
3795
|
+
if (parsedDataModule) {
|
|
3682
3796
|
return {
|
|
3683
3797
|
className: atLocation.name,
|
|
3684
3798
|
keyStringLiteral: dataTaggedClassCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedClassCall.arguments[0]) ? dataTaggedClassCall.arguments[0] : void 0,
|
|
3685
|
-
Data: parsedDataModule
|
|
3799
|
+
Data: parsedDataModule
|
|
3686
3800
|
};
|
|
3687
3801
|
}
|
|
3688
3802
|
}
|
|
@@ -3716,9 +3830,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3716
3830
|
if (ts.isPropertyAccessExpression(contextTagIdentifier) && ts.isIdentifier(contextTagIdentifier.name) && ts.idText(contextTagIdentifier.name) === "Tag") {
|
|
3717
3831
|
const parsedContextModule = yield* pipe(
|
|
3718
3832
|
importedContextModule(contextTagIdentifier.expression),
|
|
3719
|
-
|
|
3833
|
+
orUndefined
|
|
3720
3834
|
);
|
|
3721
|
-
if (
|
|
3835
|
+
if (parsedContextModule) {
|
|
3722
3836
|
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
3723
3837
|
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
3724
3838
|
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
@@ -3729,7 +3843,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3729
3843
|
keyStringLiteral: ts.isStringLiteral(contextTagCall.arguments[0]) ? contextTagCall.arguments[0] : void 0,
|
|
3730
3844
|
args: contextTagCall.arguments,
|
|
3731
3845
|
Identifier: tagType.Identifier,
|
|
3732
|
-
Tag: parsedContextModule
|
|
3846
|
+
Tag: parsedContextModule
|
|
3733
3847
|
};
|
|
3734
3848
|
}
|
|
3735
3849
|
}
|
|
@@ -3767,9 +3881,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3767
3881
|
const selfTypeNode = wholeCall.typeArguments[0];
|
|
3768
3882
|
const isEffectTag = yield* pipe(
|
|
3769
3883
|
isNodeReferenceToEffectModuleApi("Tag")(effectTagIdentifier),
|
|
3770
|
-
|
|
3884
|
+
orUndefined
|
|
3771
3885
|
);
|
|
3772
|
-
if (
|
|
3886
|
+
if (isEffectTag) {
|
|
3773
3887
|
return {
|
|
3774
3888
|
className: atLocation.name,
|
|
3775
3889
|
selfTypeNode,
|
|
@@ -3809,17 +3923,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3809
3923
|
const selfTypeNode = effectServiceCall.typeArguments[0];
|
|
3810
3924
|
const isEffectService = yield* pipe(
|
|
3811
3925
|
isNodeReferenceToEffectModuleApi("Service")(effectServiceIdentifier),
|
|
3812
|
-
|
|
3926
|
+
orUndefined
|
|
3813
3927
|
);
|
|
3814
|
-
if (
|
|
3928
|
+
if (isEffectService) {
|
|
3815
3929
|
const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
|
|
3816
3930
|
if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
|
|
3817
3931
|
const type = typeChecker.getTypeOfSymbol(classSym);
|
|
3818
3932
|
const parsedContextTag = yield* pipe(
|
|
3819
3933
|
contextTag(type, atLocation),
|
|
3820
|
-
|
|
3934
|
+
orUndefined
|
|
3821
3935
|
);
|
|
3822
|
-
if (
|
|
3936
|
+
if (parsedContextTag) {
|
|
3823
3937
|
let accessors2 = void 0;
|
|
3824
3938
|
let dependencies = void 0;
|
|
3825
3939
|
if (wholeCall.arguments.length >= 2) {
|
|
@@ -3836,7 +3950,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3836
3950
|
}
|
|
3837
3951
|
}
|
|
3838
3952
|
return {
|
|
3839
|
-
...parsedContextTag
|
|
3953
|
+
...parsedContextTag,
|
|
3840
3954
|
className: atLocation.name,
|
|
3841
3955
|
selfTypeNode,
|
|
3842
3956
|
args: wholeCall.arguments,
|
|
@@ -3906,9 +4020,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
3906
4020
|
if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
|
|
3907
4021
|
const isEffectSchemaModuleApi = yield* pipe(
|
|
3908
4022
|
isNodeReferenceToEffectSqlModelModuleApi("Class")(schemaCall.expression),
|
|
3909
|
-
|
|
4023
|
+
orUndefined
|
|
3910
4024
|
);
|
|
3911
|
-
if (
|
|
4025
|
+
if (isEffectSchemaModuleApi) {
|
|
3912
4026
|
return {
|
|
3913
4027
|
className: atLocation.name,
|
|
3914
4028
|
selfTypeNode: schemaCall.typeArguments[0]
|
|
@@ -4031,19 +4145,18 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4031
4145
|
map4((s) => ({ _tag: "call", ...s }))
|
|
4032
4146
|
)
|
|
4033
4147
|
),
|
|
4034
|
-
|
|
4148
|
+
orUndefined
|
|
4035
4149
|
);
|
|
4036
|
-
if (
|
|
4037
|
-
const result2 = parsed.value;
|
|
4150
|
+
if (parsed) {
|
|
4038
4151
|
let transformations;
|
|
4039
4152
|
let flowNode;
|
|
4040
4153
|
let childrenToTraverse = [];
|
|
4041
|
-
if (
|
|
4042
|
-
const signature = typeChecker.getResolvedSignature(
|
|
4154
|
+
if (parsed._tag === "pipe") {
|
|
4155
|
+
const signature = typeChecker.getResolvedSignature(parsed.node);
|
|
4043
4156
|
const typeArguments = signature ? typeChecker.getTypeArgumentsForResolvedSignature(signature) : void 0;
|
|
4044
4157
|
transformations = [];
|
|
4045
|
-
for (let i = 0; i <
|
|
4046
|
-
const arg =
|
|
4158
|
+
for (let i = 0; i < parsed.args.length; i++) {
|
|
4159
|
+
const arg = parsed.args[i];
|
|
4047
4160
|
const outType = typeArguments?.[i + 1];
|
|
4048
4161
|
if (ts.isCallExpression(arg)) {
|
|
4049
4162
|
transformations.push({
|
|
@@ -4052,7 +4165,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4052
4165
|
args: Array.from(arg.arguments),
|
|
4053
4166
|
// e.g., [(x) => x + 1]
|
|
4054
4167
|
outType,
|
|
4055
|
-
kind:
|
|
4168
|
+
kind: parsed.kind
|
|
4056
4169
|
});
|
|
4057
4170
|
} else {
|
|
4058
4171
|
transformations.push({
|
|
@@ -4060,17 +4173,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4060
4173
|
// e.g., Effect.asVoid
|
|
4061
4174
|
args: void 0,
|
|
4062
4175
|
outType,
|
|
4063
|
-
kind:
|
|
4176
|
+
kind: parsed.kind
|
|
4064
4177
|
});
|
|
4065
4178
|
}
|
|
4066
4179
|
}
|
|
4067
|
-
flowNode =
|
|
4068
|
-
childrenToTraverse =
|
|
4180
|
+
flowNode = parsed.node;
|
|
4181
|
+
childrenToTraverse = parsed.args;
|
|
4069
4182
|
} else {
|
|
4070
4183
|
const callSignature = typeChecker.getResolvedSignature(node);
|
|
4071
4184
|
const outType = callSignature ? typeChecker.getReturnTypeOfSignature(callSignature) : void 0;
|
|
4072
4185
|
transformations = [{
|
|
4073
|
-
callee:
|
|
4186
|
+
callee: parsed.callee,
|
|
4074
4187
|
args: void 0,
|
|
4075
4188
|
outType,
|
|
4076
4189
|
kind: "call"
|
|
@@ -4080,20 +4193,20 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4080
4193
|
if (parentFlow) {
|
|
4081
4194
|
parentFlow.transformations.unshift(...transformations);
|
|
4082
4195
|
parentFlow.subject = {
|
|
4083
|
-
node:
|
|
4084
|
-
outType: typeCheckerUtils.getTypeAtLocation(
|
|
4196
|
+
node: parsed.subject,
|
|
4197
|
+
outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
|
|
4085
4198
|
};
|
|
4086
|
-
workQueue.push([
|
|
4199
|
+
workQueue.push([parsed.subject, parentFlow]);
|
|
4087
4200
|
} else {
|
|
4088
4201
|
const newFlow = {
|
|
4089
4202
|
node: flowNode,
|
|
4090
4203
|
subject: {
|
|
4091
|
-
node:
|
|
4092
|
-
outType: typeCheckerUtils.getTypeAtLocation(
|
|
4204
|
+
node: parsed.subject,
|
|
4205
|
+
outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
|
|
4093
4206
|
},
|
|
4094
4207
|
transformations
|
|
4095
4208
|
};
|
|
4096
|
-
workQueue.push([
|
|
4209
|
+
workQueue.push([parsed.subject, newFlow]);
|
|
4097
4210
|
}
|
|
4098
4211
|
for (const child of childrenToTraverse) {
|
|
4099
4212
|
ts.forEachChild(child, (c) => {
|
|
@@ -4103,17 +4216,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4103
4216
|
continue;
|
|
4104
4217
|
}
|
|
4105
4218
|
if (includeEffectFn) {
|
|
4106
|
-
const
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
if (
|
|
4116
|
-
const fnResult =
|
|
4219
|
+
const effectFnKind = yield* pipe(
|
|
4220
|
+
map4(effectFnGen(node), (_) => ({ kind: "effectFnGen", ..._ })),
|
|
4221
|
+
orElse2(
|
|
4222
|
+
() => map4(effectFnUntracedGen(node), (_) => ({ kind: "effectFnUntracedGen", ..._ }))
|
|
4223
|
+
),
|
|
4224
|
+
orElse2(() => map4(effectFn(node), (_) => ({ kind: "effectFn", ..._ }))),
|
|
4225
|
+
orUndefined
|
|
4226
|
+
);
|
|
4227
|
+
if (effectFnKind && (effectFnKind.kind === "effectFnGen" || effectFnKind.kind === "effectFnUntracedGen")) {
|
|
4228
|
+
if (effectFnKind.pipeArguments.length > 0) {
|
|
4229
|
+
const fnResult = effectFnKind;
|
|
4117
4230
|
const pipeArgs = fnResult.pipeArguments;
|
|
4118
4231
|
const transformations = [];
|
|
4119
4232
|
let subjectType;
|
|
@@ -4133,14 +4246,14 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4133
4246
|
callee: arg.expression,
|
|
4134
4247
|
args: Array.from(arg.arguments),
|
|
4135
4248
|
outType,
|
|
4136
|
-
kind:
|
|
4249
|
+
kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
|
|
4137
4250
|
});
|
|
4138
4251
|
} else {
|
|
4139
4252
|
transformations.push({
|
|
4140
4253
|
callee: arg,
|
|
4141
4254
|
args: void 0,
|
|
4142
4255
|
outType,
|
|
4143
|
-
kind:
|
|
4256
|
+
kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
|
|
4144
4257
|
});
|
|
4145
4258
|
}
|
|
4146
4259
|
}
|
|
@@ -4162,8 +4275,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4162
4275
|
continue;
|
|
4163
4276
|
}
|
|
4164
4277
|
}
|
|
4165
|
-
if (
|
|
4166
|
-
const fnResult =
|
|
4278
|
+
if (effectFnKind && effectFnKind.kind === "effectFn" && effectFnKind.pipeArguments.length > 0) {
|
|
4279
|
+
const fnResult = effectFnKind;
|
|
4167
4280
|
const pipeArgs = fnResult.pipeArguments;
|
|
4168
4281
|
const transformations = [];
|
|
4169
4282
|
let subjectType;
|
|
@@ -4309,11 +4422,14 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
4309
4422
|
extendsDataTaggedError,
|
|
4310
4423
|
extendsDataTaggedClass,
|
|
4311
4424
|
extendsSchemaTaggedRequest,
|
|
4425
|
+
extendsSchemaRequestClass,
|
|
4312
4426
|
extendsEffectSqlModelClass,
|
|
4313
4427
|
lazyExpression,
|
|
4314
4428
|
emptyFunction,
|
|
4315
4429
|
pipingFlows,
|
|
4316
|
-
reconstructPipingFlow
|
|
4430
|
+
reconstructPipingFlow,
|
|
4431
|
+
getEffectRelatedPackages,
|
|
4432
|
+
supportedEffect
|
|
4317
4433
|
};
|
|
4318
4434
|
}
|
|
4319
4435
|
|
|
@@ -4429,6 +4545,7 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4429
4545
|
apply: fn("catchAllToMapError.apply")(function* (sourceFile, report) {
|
|
4430
4546
|
const ts = yield* service(TypeScriptApi);
|
|
4431
4547
|
const typeParser = yield* service(TypeParser);
|
|
4548
|
+
const catchAllName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
|
|
4432
4549
|
const getFunctionBody = (node) => {
|
|
4433
4550
|
if (ts.isArrowFunction(node)) {
|
|
4434
4551
|
return node.body;
|
|
@@ -4443,10 +4560,10 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4443
4560
|
if (ts.isCallExpression(body)) {
|
|
4444
4561
|
const isFailCall = yield* pipe(
|
|
4445
4562
|
typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
|
|
4446
|
-
|
|
4563
|
+
orUndefined
|
|
4447
4564
|
);
|
|
4448
|
-
if (
|
|
4449
|
-
return
|
|
4565
|
+
if (isFailCall && body.arguments.length >= 1) {
|
|
4566
|
+
return { failCall: body, failArg: body.arguments[0] };
|
|
4450
4567
|
}
|
|
4451
4568
|
}
|
|
4452
4569
|
if (ts.isBlock(body)) {
|
|
@@ -4456,15 +4573,14 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4456
4573
|
if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
|
|
4457
4574
|
const isFailCall = yield* pipe(
|
|
4458
4575
|
typeParser.isNodeReferenceToEffectModuleApi("fail")(stmt.expression.expression),
|
|
4459
|
-
|
|
4576
|
+
orUndefined
|
|
4460
4577
|
);
|
|
4461
|
-
if (
|
|
4462
|
-
return
|
|
4578
|
+
if (isFailCall && stmt.expression.arguments.length >= 1) {
|
|
4579
|
+
return { failCall: stmt.expression, failArg: stmt.expression.arguments[0] };
|
|
4463
4580
|
}
|
|
4464
4581
|
}
|
|
4465
4582
|
}
|
|
4466
4583
|
}
|
|
4467
|
-
return none2();
|
|
4468
4584
|
});
|
|
4469
4585
|
};
|
|
4470
4586
|
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
@@ -4474,10 +4590,10 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4474
4590
|
continue;
|
|
4475
4591
|
}
|
|
4476
4592
|
const isCatchAllCall = yield* pipe(
|
|
4477
|
-
typeParser.isNodeReferenceToEffectModuleApi(
|
|
4478
|
-
|
|
4593
|
+
typeParser.isNodeReferenceToEffectModuleApi(catchAllName)(transformation.callee),
|
|
4594
|
+
orUndefined
|
|
4479
4595
|
);
|
|
4480
|
-
if (
|
|
4596
|
+
if (!isCatchAllCall) {
|
|
4481
4597
|
continue;
|
|
4482
4598
|
}
|
|
4483
4599
|
const callback = transformation.args[0];
|
|
@@ -4485,11 +4601,11 @@ var catchAllToMapError = createDiagnostic({
|
|
|
4485
4601
|
const functionBody = getFunctionBody(callback);
|
|
4486
4602
|
if (!functionBody) continue;
|
|
4487
4603
|
const failCallInfo = yield* getEffectFailCallInfo(functionBody);
|
|
4488
|
-
if (
|
|
4489
|
-
const { failArg, failCall } = failCallInfo
|
|
4604
|
+
if (!failCallInfo) continue;
|
|
4605
|
+
const { failArg, failCall } = failCallInfo;
|
|
4490
4606
|
report({
|
|
4491
4607
|
location: transformation.callee,
|
|
4492
|
-
messageText: `You can use Effect.mapError instead of Effect
|
|
4608
|
+
messageText: `You can use Effect.mapError instead of Effect.${catchAllName} + Effect.fail to transform the error type.`,
|
|
4493
4609
|
fixes: [{
|
|
4494
4610
|
fixName: "catchAllToMapError_fix",
|
|
4495
4611
|
description: "Replace with Effect.mapError",
|
|
@@ -4520,7 +4636,7 @@ var catchUnfailableEffect = createDiagnostic({
|
|
|
4520
4636
|
apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
|
|
4521
4637
|
const ts = yield* service(TypeScriptApi);
|
|
4522
4638
|
const typeParser = yield* service(TypeParser);
|
|
4523
|
-
const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
|
|
4639
|
+
const catchFunctions = typeParser.supportedEffect() === "v3" ? ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"] : ["catch", "catchIf", "catchTag", "catchTags"];
|
|
4524
4640
|
const flows = yield* typeParser.pipingFlows(true)(sourceFile);
|
|
4525
4641
|
for (const flow2 of flows) {
|
|
4526
4642
|
for (let i = 0; i < flow2.transformations.length; i++) {
|
|
@@ -4585,7 +4701,12 @@ var classSelfMismatch = createDiagnostic({
|
|
|
4585
4701
|
orElse2(() => typeParser.extendsSchemaClass(node)),
|
|
4586
4702
|
orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
|
|
4587
4703
|
orElse2(() => typeParser.extendsSchemaTaggedError(node)),
|
|
4588
|
-
orElse2(
|
|
4704
|
+
orElse2(
|
|
4705
|
+
() => pipe(
|
|
4706
|
+
typeParser.extendsSchemaTaggedRequest(node),
|
|
4707
|
+
orElse2(() => typeParser.extendsSchemaRequestClass(node))
|
|
4708
|
+
)
|
|
4709
|
+
),
|
|
4589
4710
|
orElse2(() => typeParser.extendsEffectSqlModelClass(node)),
|
|
4590
4711
|
orElse2(() => void_)
|
|
4591
4712
|
);
|
|
@@ -4812,39 +4933,18 @@ var deterministicKeys = createDiagnostic({
|
|
|
4812
4933
|
});
|
|
4813
4934
|
|
|
4814
4935
|
// src/diagnostics/duplicatePackage.ts
|
|
4815
|
-
var checkedPackagesCache = /* @__PURE__ */ new Map();
|
|
4816
|
-
var programResolvedCacheSize = /* @__PURE__ */ new Map();
|
|
4817
4936
|
var duplicatePackage = createDiagnostic({
|
|
4818
4937
|
name: "duplicatePackage",
|
|
4819
4938
|
code: 6,
|
|
4820
4939
|
description: "Detects when multiple versions of the same Effect package are loaded",
|
|
4821
4940
|
severity: "warning",
|
|
4822
4941
|
apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
|
|
4823
|
-
const
|
|
4824
|
-
const tsUtils = yield* service(TypeScriptUtils);
|
|
4942
|
+
const typeParser = yield* service(TypeParser);
|
|
4825
4943
|
const options = yield* service(LanguageServicePluginOptions);
|
|
4826
4944
|
if (sourceFile.statements.length < 1) return;
|
|
4827
|
-
|
|
4828
|
-
const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
|
|
4829
|
-
const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
|
|
4830
|
-
if (newResolvedModuleSize !== oldResolvedSize) {
|
|
4831
|
-
const seenPackages = /* @__PURE__ */ new Set();
|
|
4832
|
-
resolvedPackages = {};
|
|
4833
|
-
program.getSourceFiles().map((_) => {
|
|
4834
|
-
const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
|
|
4835
|
-
if (!packageInfo) return;
|
|
4836
|
-
const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
|
|
4837
|
-
if (seenPackages.has(packageNameAndVersion)) return;
|
|
4838
|
-
seenPackages.add(packageNameAndVersion);
|
|
4839
|
-
if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
|
|
4840
|
-
if (options.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
|
|
4841
|
-
resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
|
|
4842
|
-
resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
|
|
4843
|
-
});
|
|
4844
|
-
checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
|
|
4845
|
-
programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
|
|
4846
|
-
}
|
|
4945
|
+
const resolvedPackages = typeParser.getEffectRelatedPackages(sourceFile);
|
|
4847
4946
|
for (const packageName of Object.keys(resolvedPackages)) {
|
|
4947
|
+
if (options.allowedDuplicatedPackages.indexOf(packageName) > -1) return;
|
|
4848
4948
|
if (Object.keys(resolvedPackages[packageName]).length > 1) {
|
|
4849
4949
|
const versions = Object.keys(resolvedPackages[packageName]);
|
|
4850
4950
|
report({
|
|
@@ -5668,23 +5768,25 @@ var globalErrorInEffectCatch = createDiagnostic({
|
|
|
5668
5768
|
if (isEffectWithCatch) {
|
|
5669
5769
|
const signature = typeChecker.getResolvedSignature(node);
|
|
5670
5770
|
if (signature) {
|
|
5671
|
-
const
|
|
5672
|
-
const
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5771
|
+
const firstParameterType = typeChecker.getParameterType(signature, 0);
|
|
5772
|
+
for (const objectType of typeCheckerUtils.unrollUnionMembers(firstParameterType)) {
|
|
5773
|
+
const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
|
|
5774
|
+
if (catchFunctionSymbol) {
|
|
5775
|
+
const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
|
|
5776
|
+
const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
|
|
5777
|
+
if (signatures.length > 0) {
|
|
5778
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
|
|
5779
|
+
if (returnType && typeCheckerUtils.isGlobalErrorType(returnType)) {
|
|
5780
|
+
const nodeText = sourceFile.text.substring(
|
|
5781
|
+
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
5782
|
+
node.expression.end
|
|
5783
|
+
);
|
|
5784
|
+
report({
|
|
5785
|
+
location: node.expression,
|
|
5786
|
+
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.`,
|
|
5787
|
+
fixes: []
|
|
5788
|
+
});
|
|
5789
|
+
}
|
|
5688
5790
|
}
|
|
5689
5791
|
}
|
|
5690
5792
|
}
|
|
@@ -6497,22 +6599,23 @@ var missingEffectError = createDiagnostic({
|
|
|
6497
6599
|
map4((result) => {
|
|
6498
6600
|
if (result.missingErrorTypes.length === 0) return;
|
|
6499
6601
|
const fixes = [];
|
|
6500
|
-
|
|
6602
|
+
const catchAllErrorsName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
|
|
6603
|
+
if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never && catchAllErrorsName) {
|
|
6501
6604
|
fixes.push({
|
|
6502
|
-
fixName:
|
|
6503
|
-
description:
|
|
6605
|
+
fixName: `missingEffectError_${catchAllErrorsName}`,
|
|
6606
|
+
description: `Catch all errors with Effect.${catchAllErrorsName}`,
|
|
6504
6607
|
apply: gen(function* () {
|
|
6505
6608
|
const changeTracker = yield* service(ChangeTracker);
|
|
6506
6609
|
changeTracker.insertText(
|
|
6507
6610
|
sourceFile,
|
|
6508
6611
|
ts.getTokenPosOfNode(valueNode, sourceFile),
|
|
6509
|
-
effectModuleIdentifier +
|
|
6612
|
+
effectModuleIdentifier + `.${catchAllErrorsName}(`
|
|
6510
6613
|
);
|
|
6511
6614
|
changeTracker.insertText(sourceFile, valueNode.end, ", () => ");
|
|
6512
6615
|
changeTracker.insertNodeAt(
|
|
6513
6616
|
sourceFile,
|
|
6514
6617
|
valueNode.end,
|
|
6515
|
-
createDieMessage(
|
|
6618
|
+
createDieMessage(`TODO: ${catchAllErrorsName} not implemented`)
|
|
6516
6619
|
);
|
|
6517
6620
|
changeTracker.insertText(sourceFile, valueNode.end, ")");
|
|
6518
6621
|
})
|
|
@@ -6594,6 +6697,7 @@ var missingEffectServiceDependency = createDiagnostic({
|
|
|
6594
6697
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
6595
6698
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
6596
6699
|
const typeParser = yield* service(TypeParser);
|
|
6700
|
+
if (typeParser.supportedEffect() !== "v3") return;
|
|
6597
6701
|
const nodeToVisit = [];
|
|
6598
6702
|
const appendNodeToVisit = (node) => {
|
|
6599
6703
|
nodeToVisit.push(node);
|
|
@@ -8813,6 +8917,7 @@ var scopeInLayerEffect = createDiagnostic({
|
|
|
8813
8917
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
8814
8918
|
const typeParser = yield* service(TypeParser);
|
|
8815
8919
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
8920
|
+
if (typeParser.supportedEffect() !== "v3") return;
|
|
8816
8921
|
const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
8817
8922
|
sourceFile,
|
|
8818
8923
|
"effect",
|
|
@@ -9021,6 +9126,17 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
9021
9126
|
apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
|
|
9022
9127
|
const ts = yield* service(TypeScriptApi);
|
|
9023
9128
|
const typeParser = yield* service(TypeParser);
|
|
9129
|
+
const alternatives = typeParser.supportedEffect() === "v4" ? [
|
|
9130
|
+
"Effect.try",
|
|
9131
|
+
"Effect.tryPromise",
|
|
9132
|
+
"Effect.catch",
|
|
9133
|
+
"Effect.catchTag"
|
|
9134
|
+
] : [
|
|
9135
|
+
"Effect.try",
|
|
9136
|
+
"Effect.tryPromise",
|
|
9137
|
+
"Effect.catchAll",
|
|
9138
|
+
"Effect.catchTag"
|
|
9139
|
+
];
|
|
9024
9140
|
const nodeToVisit = [];
|
|
9025
9141
|
const appendNodeToVisit = (node) => {
|
|
9026
9142
|
nodeToVisit.push(node);
|
|
@@ -9046,7 +9162,7 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
9046
9162
|
map4(() => {
|
|
9047
9163
|
report({
|
|
9048
9164
|
location: node,
|
|
9049
|
-
messageText:
|
|
9165
|
+
messageText: `Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g. ${alternatives.join(", ")}).`,
|
|
9050
9166
|
fixes: []
|
|
9051
9167
|
});
|
|
9052
9168
|
}),
|
|
@@ -9068,6 +9184,7 @@ var unknownInEffectCatch = createDiagnostic({
|
|
|
9068
9184
|
const ts = yield* service(TypeScriptApi);
|
|
9069
9185
|
const typeParser = yield* service(TypeParser);
|
|
9070
9186
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
9187
|
+
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
9071
9188
|
const nodeToVisit = [];
|
|
9072
9189
|
const appendNodeToVisit = (node) => {
|
|
9073
9190
|
nodeToVisit.push(node);
|
|
@@ -9088,24 +9205,26 @@ var unknownInEffectCatch = createDiagnostic({
|
|
|
9088
9205
|
if (isEffectWithCatch) {
|
|
9089
9206
|
const signature = typeChecker.getResolvedSignature(node);
|
|
9090
9207
|
if (signature) {
|
|
9091
|
-
const
|
|
9092
|
-
const
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9208
|
+
const parameterType = typeChecker.getParameterType(signature, 0);
|
|
9209
|
+
for (const objectType of typeCheckerUtils.unrollUnionMembers(parameterType)) {
|
|
9210
|
+
const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
|
|
9211
|
+
if (catchFunctionSymbol) {
|
|
9212
|
+
const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
|
|
9213
|
+
const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
|
|
9214
|
+
if (signatures.length > 0) {
|
|
9215
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
|
|
9216
|
+
if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
|
|
9217
|
+
const nodeText = sourceFile.text.substring(
|
|
9218
|
+
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
9219
|
+
node.expression.end
|
|
9220
|
+
);
|
|
9221
|
+
report({
|
|
9222
|
+
location: node.expression,
|
|
9223
|
+
messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
|
|
9106
9224
|
Consider wrapping unknown errors into Effect's Data.TaggedError for example, or narrow down the type to the specific error raised.`,
|
|
9107
|
-
|
|
9108
|
-
|
|
9225
|
+
fixes: []
|
|
9226
|
+
});
|
|
9227
|
+
}
|
|
9109
9228
|
}
|
|
9110
9229
|
}
|
|
9111
9230
|
}
|