@effect/language-service 0.57.0 → 0.58.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 +408 -115
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +90 -12
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +90 -12
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +90 -12
- package/transform.js.map +1 -1
|
@@ -5901,6 +5901,11 @@ var runEffectInsideEffect = createDiagnostic({
|
|
|
5901
5901
|
apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
|
|
5902
5902
|
const ts = yield* service(TypeScriptApi);
|
|
5903
5903
|
const typeParser = yield* service(TypeParser);
|
|
5904
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
5905
|
+
const parseEffectMethod = (node, methodName) => pipe(
|
|
5906
|
+
typeParser.isNodeReferenceToEffectModuleApi(methodName)(node),
|
|
5907
|
+
map4(() => ({ node, methodName }))
|
|
5908
|
+
);
|
|
5904
5909
|
const nodeToVisit = [];
|
|
5905
5910
|
const appendNodeToVisit = (node) => {
|
|
5906
5911
|
nodeToVisit.push(node);
|
|
@@ -5911,11 +5916,12 @@ var runEffectInsideEffect = createDiagnostic({
|
|
|
5911
5916
|
const node = nodeToVisit.shift();
|
|
5912
5917
|
ts.forEachChild(node, appendNodeToVisit);
|
|
5913
5918
|
if (!ts.isCallExpression(node)) continue;
|
|
5919
|
+
if (node.arguments.length === 0) continue;
|
|
5914
5920
|
const isEffectRunCall = yield* pipe(
|
|
5915
|
-
|
|
5916
|
-
orElse2(() =>
|
|
5917
|
-
orElse2(() =>
|
|
5918
|
-
orElse2(() =>
|
|
5921
|
+
parseEffectMethod(node.expression, "runPromise"),
|
|
5922
|
+
orElse2(() => parseEffectMethod(node.expression, "runSync")),
|
|
5923
|
+
orElse2(() => parseEffectMethod(node.expression, "runFork")),
|
|
5924
|
+
orElse2(() => parseEffectMethod(node.expression, "runCallback")),
|
|
5919
5925
|
option
|
|
5920
5926
|
);
|
|
5921
5927
|
if (isNone2(isEffectRunCall)) continue;
|
|
@@ -5935,18 +5941,90 @@ var runEffectInsideEffect = createDiagnostic({
|
|
|
5935
5941
|
orElse2(() => typeParser.effectFnGen(possiblyEffectGen)),
|
|
5936
5942
|
option
|
|
5937
5943
|
);
|
|
5938
|
-
if (isSome2(isInEffectGen)) {
|
|
5944
|
+
if (isSome2(isInEffectGen) && isInEffectGen.value.body.statements.length > 0) {
|
|
5939
5945
|
const nodeText = sourceFile.text.substring(
|
|
5940
5946
|
ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
5941
5947
|
node.expression.end
|
|
5942
5948
|
);
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5949
|
+
if (nodeIntroduceScope && nodeIntroduceScope !== isInEffectGen.value.generatorFunction) {
|
|
5950
|
+
const fixAddRuntime = gen(function* () {
|
|
5951
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
5952
|
+
const runtimeModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Runtime") || "Runtime";
|
|
5953
|
+
const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Effect") || "Effect";
|
|
5954
|
+
let runtimeIdentifier = void 0;
|
|
5955
|
+
for (const statement of isInEffectGen.value.generatorFunction.body.statements) {
|
|
5956
|
+
if (ts.isVariableStatement(statement) && statement.declarationList.declarations.length === 1) {
|
|
5957
|
+
const declaration = statement.declarationList.declarations[0];
|
|
5958
|
+
if (declaration.initializer && ts.isYieldExpression(declaration.initializer) && declaration.initializer.asteriskToken && declaration.initializer.expression) {
|
|
5959
|
+
const yieldedExpression = declaration.initializer.expression;
|
|
5960
|
+
if (ts.isCallExpression(yieldedExpression)) {
|
|
5961
|
+
const maybeEffectRuntime = yield* pipe(
|
|
5962
|
+
typeParser.isNodeReferenceToEffectModuleApi("runtime")(yieldedExpression.expression),
|
|
5963
|
+
option
|
|
5964
|
+
);
|
|
5965
|
+
if (isSome2(maybeEffectRuntime) && ts.isIdentifier(declaration.name)) {
|
|
5966
|
+
runtimeIdentifier = ts.idText(declaration.name);
|
|
5967
|
+
}
|
|
5968
|
+
}
|
|
5969
|
+
}
|
|
5970
|
+
}
|
|
5971
|
+
}
|
|
5972
|
+
if (!runtimeIdentifier) {
|
|
5973
|
+
changeTracker.insertNodeAt(
|
|
5974
|
+
sourceFile,
|
|
5975
|
+
isInEffectGen.value.body.statements[0].pos,
|
|
5976
|
+
ts.factory.createVariableStatement(
|
|
5977
|
+
void 0,
|
|
5978
|
+
ts.factory.createVariableDeclarationList([ts.factory.createVariableDeclaration(
|
|
5979
|
+
"effectRuntime",
|
|
5980
|
+
void 0,
|
|
5981
|
+
void 0,
|
|
5982
|
+
ts.factory.createYieldExpression(
|
|
5983
|
+
ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
|
|
5984
|
+
ts.factory.createCallExpression(
|
|
5985
|
+
ts.factory.createPropertyAccessExpression(
|
|
5986
|
+
ts.factory.createIdentifier(effectModuleIdentifier),
|
|
5987
|
+
"runtime"
|
|
5988
|
+
),
|
|
5989
|
+
[ts.factory.createTypeReferenceNode("never")],
|
|
5990
|
+
[]
|
|
5991
|
+
)
|
|
5992
|
+
)
|
|
5993
|
+
)], ts.NodeFlags.Const)
|
|
5994
|
+
),
|
|
5995
|
+
{
|
|
5996
|
+
prefix: "\n",
|
|
5997
|
+
suffix: "\n"
|
|
5998
|
+
}
|
|
5999
|
+
);
|
|
6000
|
+
}
|
|
6001
|
+
changeTracker.deleteRange(sourceFile, {
|
|
6002
|
+
pos: ts.getTokenPosOfNode(node.expression, sourceFile),
|
|
6003
|
+
end: node.arguments[0].pos
|
|
6004
|
+
});
|
|
6005
|
+
changeTracker.insertText(
|
|
6006
|
+
sourceFile,
|
|
6007
|
+
node.arguments[0].pos,
|
|
6008
|
+
`${runtimeModuleIdentifier}.${isEffectRunCall.value.methodName}(${runtimeIdentifier || "effectRuntime"}, `
|
|
6009
|
+
);
|
|
6010
|
+
});
|
|
6011
|
+
report({
|
|
6012
|
+
location: node.expression,
|
|
6013
|
+
messageText: `Using ${nodeText} inside an Effect is not recommended. The same runtime should generally be used instead to run child effects.
|
|
6014
|
+
Consider extracting the Runtime by using for example Effect.runtime and then use Runtime.${isEffectRunCall.value.methodName} with the extracted runtime instead.`,
|
|
6015
|
+
fixes: [{
|
|
6016
|
+
fixName: "runEffectInsideEffect_fix",
|
|
6017
|
+
description: "Use a runtime to run the Effect",
|
|
6018
|
+
apply: fixAddRuntime
|
|
6019
|
+
}]
|
|
6020
|
+
});
|
|
6021
|
+
} else {
|
|
6022
|
+
report({
|
|
6023
|
+
location: node.expression,
|
|
6024
|
+
messageText: `Using ${nodeText} inside an Effect is not recommended. Effects inside generators can usually just be yielded.`,
|
|
6025
|
+
fixes: []
|
|
6026
|
+
});
|
|
6027
|
+
}
|
|
5950
6028
|
}
|
|
5951
6029
|
currentParent = currentParent.parent;
|
|
5952
6030
|
}
|