@effect/language-service 0.28.1 → 0.28.2
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 +106 -1
- package/cli.js.map +1 -1
- package/index.js +106 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +106 -1
- package/transform.js.map +1 -1
package/README.md
CHANGED
|
@@ -45,6 +45,7 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
|
|
|
45
45
|
- Multiple versions of Effect in your project
|
|
46
46
|
- Warn on leaking requirements in Effect services
|
|
47
47
|
- Warn on Scope as requirement of a Layer
|
|
48
|
+
- Warn on subsequent `Effect.provide` anti-pattern
|
|
48
49
|
- Unnecessary usages of `Effect.gen` or `pipe()`
|
|
49
50
|
- Warn when importing from a barrel file instead of from the module directly
|
|
50
51
|
- Warn on usage of try/catch inside `Effect.gen` and family
|
package/cli.js
CHANGED
|
@@ -32291,6 +32291,110 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
32291
32291
|
})
|
|
32292
32292
|
});
|
|
32293
32293
|
|
|
32294
|
+
// src/diagnostics/multipleEffectProvide.ts
|
|
32295
|
+
var multipleEffectProvide = createDiagnostic({
|
|
32296
|
+
name: "multipleEffectProvide",
|
|
32297
|
+
code: 18,
|
|
32298
|
+
severity: "warning",
|
|
32299
|
+
apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
|
|
32300
|
+
const ts2 = yield* service2(TypeScriptApi);
|
|
32301
|
+
const typeChecker = yield* service2(TypeCheckerApi);
|
|
32302
|
+
const typeParser = yield* service2(TypeParser);
|
|
32303
|
+
const effectModuleIdentifier = yield* pipe(
|
|
32304
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
32305
|
+
sourceFile,
|
|
32306
|
+
"effect",
|
|
32307
|
+
"Effect"
|
|
32308
|
+
),
|
|
32309
|
+
map33((_) => _.text),
|
|
32310
|
+
orElse14(() => succeed17("Effect"))
|
|
32311
|
+
);
|
|
32312
|
+
const layerModuleIdentifier = yield* pipe(
|
|
32313
|
+
findImportedModuleIdentifierByPackageAndNameOrBarrel(
|
|
32314
|
+
sourceFile,
|
|
32315
|
+
"effect",
|
|
32316
|
+
"Layer"
|
|
32317
|
+
),
|
|
32318
|
+
map33((_) => _.text),
|
|
32319
|
+
orElse14(() => succeed17("Layer"))
|
|
32320
|
+
);
|
|
32321
|
+
const parseEffectProvideLayer = (node) => {
|
|
32322
|
+
if (ts2.isCallExpression(node) && ts2.isPropertyAccessExpression(node.expression) && ts2.isIdentifier(node.expression.name) && node.expression.name.text === "provide" && node.arguments.length > 0) {
|
|
32323
|
+
const layer12 = node.arguments[0];
|
|
32324
|
+
const type2 = typeChecker.getTypeAtLocation(layer12);
|
|
32325
|
+
return pipe(
|
|
32326
|
+
typeParser.importedEffectModule(node.expression.expression),
|
|
32327
|
+
flatMap18(() => typeParser.layerType(type2, layer12)),
|
|
32328
|
+
map33(() => ({ layer: layer12, node })),
|
|
32329
|
+
orElse14(() => void_8)
|
|
32330
|
+
);
|
|
32331
|
+
}
|
|
32332
|
+
return void_8;
|
|
32333
|
+
};
|
|
32334
|
+
const parsePipeCall = (node) => gen3(function* () {
|
|
32335
|
+
const { args: args3 } = yield* typeParser.pipeCall(node);
|
|
32336
|
+
let currentChunk = 0;
|
|
32337
|
+
const previousLayers = [[]];
|
|
32338
|
+
for (const pipeArg of args3) {
|
|
32339
|
+
const parsedProvide = yield* parseEffectProvideLayer(pipeArg);
|
|
32340
|
+
if (parsedProvide) {
|
|
32341
|
+
previousLayers[currentChunk].push(parsedProvide);
|
|
32342
|
+
} else {
|
|
32343
|
+
currentChunk++;
|
|
32344
|
+
previousLayers.push([]);
|
|
32345
|
+
}
|
|
32346
|
+
}
|
|
32347
|
+
for (const chunk4 of previousLayers) {
|
|
32348
|
+
if (chunk4.length < 2) continue;
|
|
32349
|
+
report({
|
|
32350
|
+
node: chunk4[0].node,
|
|
32351
|
+
messageText: "Calling multiple subsequent times Effect.provide is an anti-pattern and can lead to service lifecycle issues. You should combine the layers and provide them once instead.",
|
|
32352
|
+
fixes: [{
|
|
32353
|
+
fixName: "multipleEffectProvide_fix",
|
|
32354
|
+
description: "Combine into a single provide",
|
|
32355
|
+
apply: gen3(function* () {
|
|
32356
|
+
const changeTracker = yield* service2(ChangeTracker);
|
|
32357
|
+
changeTracker.deleteRange(sourceFile, {
|
|
32358
|
+
pos: chunk4[0].node.getStart(sourceFile),
|
|
32359
|
+
end: chunk4[chunk4.length - 1].node.getEnd()
|
|
32360
|
+
});
|
|
32361
|
+
const newNode = ts2.factory.createCallExpression(
|
|
32362
|
+
ts2.factory.createPropertyAccessExpression(
|
|
32363
|
+
ts2.factory.createIdentifier(effectModuleIdentifier),
|
|
32364
|
+
ts2.factory.createIdentifier("provide")
|
|
32365
|
+
),
|
|
32366
|
+
void 0,
|
|
32367
|
+
[ts2.factory.createCallExpression(
|
|
32368
|
+
ts2.factory.createPropertyAccessExpression(
|
|
32369
|
+
ts2.factory.createIdentifier(layerModuleIdentifier),
|
|
32370
|
+
ts2.factory.createIdentifier("mergeAll")
|
|
32371
|
+
),
|
|
32372
|
+
void 0,
|
|
32373
|
+
chunk4.map((c) => c.layer)
|
|
32374
|
+
)]
|
|
32375
|
+
);
|
|
32376
|
+
changeTracker.insertNodeAt(sourceFile, chunk4[0].node.getStart(sourceFile), newNode);
|
|
32377
|
+
})
|
|
32378
|
+
}]
|
|
32379
|
+
});
|
|
32380
|
+
}
|
|
32381
|
+
});
|
|
32382
|
+
const nodeToVisit = [];
|
|
32383
|
+
const appendNodeToVisit = (node) => {
|
|
32384
|
+
nodeToVisit.push(node);
|
|
32385
|
+
return void 0;
|
|
32386
|
+
};
|
|
32387
|
+
ts2.forEachChild(sourceFile, appendNodeToVisit);
|
|
32388
|
+
while (nodeToVisit.length > 0) {
|
|
32389
|
+
const node = nodeToVisit.shift();
|
|
32390
|
+
ts2.forEachChild(node, appendNodeToVisit);
|
|
32391
|
+
if (ts2.isCallExpression(node)) {
|
|
32392
|
+
yield* pipe(parsePipeCall(node), ignore3);
|
|
32393
|
+
}
|
|
32394
|
+
}
|
|
32395
|
+
})
|
|
32396
|
+
});
|
|
32397
|
+
|
|
32294
32398
|
// src/diagnostics/returnEffectInGen.ts
|
|
32295
32399
|
var returnEffectInGen = createDiagnostic({
|
|
32296
32400
|
name: "returnEffectInGen",
|
|
@@ -32752,7 +32856,8 @@ var diagnostics = [
|
|
|
32752
32856
|
scopeInLayerEffect,
|
|
32753
32857
|
effectInVoidSuccess,
|
|
32754
32858
|
unnecessaryPipeChain,
|
|
32755
|
-
strictBooleanExpressions
|
|
32859
|
+
strictBooleanExpressions,
|
|
32860
|
+
multipleEffectProvide
|
|
32756
32861
|
];
|
|
32757
32862
|
|
|
32758
32863
|
// src/cli.ts
|