@effect/language-service 0.53.3 → 0.54.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/README.md +1 -0
- package/cli.js +60 -2
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +62 -4
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +59 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +59 -1
- package/transform.js.map +1 -1
package/README.md
CHANGED
|
@@ -69,6 +69,7 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
|
|
|
69
69
|
- Warn when `@effect-diagnostics-next-line` comments have no effect (i.e., they don't suppress any diagnostic)
|
|
70
70
|
- Detect nested function calls that can be converted to pipeable style for better readability
|
|
71
71
|
- Warn when using catch functions (`catchAll`, `catch`, `catchIf`, `catchSome`, `catchTag`, `catchTags`) on effects that never fail
|
|
72
|
+
- Warn when catch callbacks in `Effect.tryPromise`, `Effect.tryMap`, or `Effect.tryMapPromise` return `unknown` or `any` types
|
|
72
73
|
|
|
73
74
|
### Completions
|
|
74
75
|
|
package/cli.js
CHANGED
|
@@ -35288,6 +35288,63 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
35288
35288
|
})
|
|
35289
35289
|
});
|
|
35290
35290
|
|
|
35291
|
+
// src/diagnostics/unknownInEffectCatch.ts
|
|
35292
|
+
var unknownInEffectCatch = createDiagnostic({
|
|
35293
|
+
name: "unknownInEffectCatch",
|
|
35294
|
+
code: 31,
|
|
35295
|
+
severity: "warning",
|
|
35296
|
+
apply: fn2("unknownInEffectCatch.apply")(function* (sourceFile, report) {
|
|
35297
|
+
const ts = yield* service2(TypeScriptApi);
|
|
35298
|
+
const typeParser = yield* service2(TypeParser);
|
|
35299
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
35300
|
+
const nodeToVisit = [];
|
|
35301
|
+
const appendNodeToVisit = (node) => {
|
|
35302
|
+
nodeToVisit.push(node);
|
|
35303
|
+
return void 0;
|
|
35304
|
+
};
|
|
35305
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
35306
|
+
while (nodeToVisit.length > 0) {
|
|
35307
|
+
const node = nodeToVisit.shift();
|
|
35308
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
35309
|
+
if (ts.isCallExpression(node)) {
|
|
35310
|
+
const isEffectWithCatch = yield* pipe(
|
|
35311
|
+
typeParser.isNodeReferenceToEffectModuleApi("tryPromise")(node.expression),
|
|
35312
|
+
orElse14(() => typeParser.isNodeReferenceToEffectModuleApi("try")(node.expression)),
|
|
35313
|
+
orElse14(() => typeParser.isNodeReferenceToEffectModuleApi("tryMap")(node.expression)),
|
|
35314
|
+
orElse14(() => typeParser.isNodeReferenceToEffectModuleApi("tryMapPromise")(node.expression)),
|
|
35315
|
+
orElse14(() => void_8)
|
|
35316
|
+
);
|
|
35317
|
+
if (isEffectWithCatch) {
|
|
35318
|
+
const signature = typeChecker.getResolvedSignature(node);
|
|
35319
|
+
if (signature) {
|
|
35320
|
+
const objectType = typeChecker.getParameterType(signature, 0);
|
|
35321
|
+
const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
|
|
35322
|
+
if (catchFunctionSymbol) {
|
|
35323
|
+
const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
|
|
35324
|
+
const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
|
|
35325
|
+
if (signatures.length > 0) {
|
|
35326
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
|
|
35327
|
+
if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
|
|
35328
|
+
const nodeText = sourceFile.text.substring(
|
|
35329
|
+
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
35330
|
+
node.expression.end
|
|
35331
|
+
);
|
|
35332
|
+
report({
|
|
35333
|
+
location: node.expression,
|
|
35334
|
+
messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
|
|
35335
|
+
Consider wrapping unknown errors into Effect's Data.TaggedError for example, or narrow down the type to the specific error raised.`,
|
|
35336
|
+
fixes: []
|
|
35337
|
+
});
|
|
35338
|
+
}
|
|
35339
|
+
}
|
|
35340
|
+
}
|
|
35341
|
+
}
|
|
35342
|
+
}
|
|
35343
|
+
}
|
|
35344
|
+
}
|
|
35345
|
+
})
|
|
35346
|
+
});
|
|
35347
|
+
|
|
35291
35348
|
// src/diagnostics/unnecessaryEffectGen.ts
|
|
35292
35349
|
var unnecessaryEffectGen = createDiagnostic({
|
|
35293
35350
|
name: "unnecessaryEffectGen",
|
|
@@ -35535,7 +35592,8 @@ var diagnostics = [
|
|
|
35535
35592
|
nonObjectEffectServiceType,
|
|
35536
35593
|
deterministicKeys,
|
|
35537
35594
|
missedPipeableOpportunity,
|
|
35538
|
-
strictEffectProvide
|
|
35595
|
+
strictEffectProvide,
|
|
35596
|
+
unknownInEffectCatch
|
|
35539
35597
|
];
|
|
35540
35598
|
|
|
35541
35599
|
// src/cli/diagnostics.ts
|
|
@@ -35794,7 +35852,7 @@ var getPatchesForModule = fn("getPatchesForModule")(
|
|
|
35794
35852
|
sourceFile.text,
|
|
35795
35853
|
insertCheckSourceFilePosition.value.position,
|
|
35796
35854
|
insertCheckSourceFilePosition.value.position,
|
|
35797
|
-
`effectLspPatchUtils().checkSourceFileWorker(${moduleName === "typescript" ? "module.exports" : "effectLspTypeScriptApis()"}, host, node, compilerOptions, diagnostics.add)
|
|
35855
|
+
`effectLspPatchUtils().checkSourceFileWorker(${moduleName === "typescript" ? "module.exports" : "effectLspTypeScriptApis()"}, host, node, compilerOptions, diagnostics.add, "${moduleName}")
|
|
35798
35856
|
`,
|
|
35799
35857
|
"\n",
|
|
35800
35858
|
version
|