@effect/language-service 0.49.0 → 0.51.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 +4 -0
- package/cli.js +119 -3
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +120 -3
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +119 -3
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +120 -3
- package/transform.js.map +1 -1
|
@@ -771,6 +771,7 @@ var unsafeGet = /* @__PURE__ */ dual(2, (self, index) => {
|
|
|
771
771
|
});
|
|
772
772
|
var headNonEmpty = /* @__PURE__ */ unsafeGet(0);
|
|
773
773
|
var tailNonEmpty = (self) => self.slice(1);
|
|
774
|
+
var reverse = (self) => Array.from(self).reverse();
|
|
774
775
|
var sort = /* @__PURE__ */ dual(2, (self, O) => {
|
|
775
776
|
const out = Array.from(self);
|
|
776
777
|
out.sort(O);
|
|
@@ -1197,7 +1198,8 @@ var defaults = {
|
|
|
1197
1198
|
pattern: "default",
|
|
1198
1199
|
skipLeadingPath: ["src/"]
|
|
1199
1200
|
}],
|
|
1200
|
-
extendedKeyDetection: false
|
|
1201
|
+
extendedKeyDetection: false,
|
|
1202
|
+
pipeableMinArgCount: 1
|
|
1201
1203
|
};
|
|
1202
1204
|
function parseKeyPatterns(patterns) {
|
|
1203
1205
|
const result = [];
|
|
@@ -1232,7 +1234,8 @@ function parse(config) {
|
|
|
1232
1234
|
renames: isObject(config) && hasProperty(config, "renames") && isBoolean(config.renames) ? config.renames : defaults.renames,
|
|
1233
1235
|
noExternal: isObject(config) && hasProperty(config, "noExternal") && isBoolean(config.noExternal) ? config.noExternal : defaults.noExternal,
|
|
1234
1236
|
keyPatterns: isObject(config) && hasProperty(config, "keyPatterns") && isArray(config.keyPatterns) ? parseKeyPatterns(config.keyPatterns) : defaults.keyPatterns,
|
|
1235
|
-
extendedKeyDetection: isObject(config) && hasProperty(config, "extendedKeyDetection") && isBoolean(config.extendedKeyDetection) ? config.extendedKeyDetection : defaults.extendedKeyDetection
|
|
1237
|
+
extendedKeyDetection: isObject(config) && hasProperty(config, "extendedKeyDetection") && isBoolean(config.extendedKeyDetection) ? config.extendedKeyDetection : defaults.extendedKeyDetection,
|
|
1238
|
+
pipeableMinArgCount: isObject(config) && hasProperty(config, "pipeableMinArgCount") && isNumber(config.pipeableMinArgCount) ? config.pipeableMinArgCount : defaults.pipeableMinArgCount
|
|
1236
1239
|
};
|
|
1237
1240
|
}
|
|
1238
1241
|
|
|
@@ -4271,6 +4274,74 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
|
|
|
4271
4274
|
})
|
|
4272
4275
|
});
|
|
4273
4276
|
|
|
4277
|
+
// src/diagnostics/missedPipeableOpportunity.ts
|
|
4278
|
+
var missedPipeableOpportunity = createDiagnostic({
|
|
4279
|
+
name: "missedPipeableOpportunity",
|
|
4280
|
+
code: 26,
|
|
4281
|
+
severity: "off",
|
|
4282
|
+
apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
|
|
4283
|
+
const ts = yield* service(TypeScriptApi);
|
|
4284
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
4285
|
+
const typeParser = yield* service(TypeParser);
|
|
4286
|
+
const options = yield* service(LanguageServicePluginOptions);
|
|
4287
|
+
const nodeToVisit = [sourceFile];
|
|
4288
|
+
const prependNodeToVisit = (node) => {
|
|
4289
|
+
nodeToVisit.unshift(node);
|
|
4290
|
+
return void 0;
|
|
4291
|
+
};
|
|
4292
|
+
const callChainNodes = /* @__PURE__ */ new WeakMap();
|
|
4293
|
+
while (nodeToVisit.length > 0) {
|
|
4294
|
+
const node = nodeToVisit.shift();
|
|
4295
|
+
if (ts.isCallExpression(node) && node.arguments.length === 1 && node.parent) {
|
|
4296
|
+
const parentChain = callChainNodes.get(node.parent) || [];
|
|
4297
|
+
callChainNodes.set(node, parentChain.concat(node));
|
|
4298
|
+
} else if (node.parent && callChainNodes.has(node.parent) && ts.isExpression(node)) {
|
|
4299
|
+
const parentChain = callChainNodes.get(node.parent) || [];
|
|
4300
|
+
const originalParentChain = parentChain.slice();
|
|
4301
|
+
parentChain.push(node);
|
|
4302
|
+
while (parentChain.length > options.pipeableMinArgCount) {
|
|
4303
|
+
const subject = parentChain.pop();
|
|
4304
|
+
const resultType = typeChecker.getTypeAtLocation(subject);
|
|
4305
|
+
const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
|
|
4306
|
+
if (pipeableType) {
|
|
4307
|
+
report({
|
|
4308
|
+
location: parentChain[0],
|
|
4309
|
+
messageText: `Nested function calls can be converted to pipeable style for better readability.`,
|
|
4310
|
+
fixes: [{
|
|
4311
|
+
fixName: "missedPipeableOpportunity_fix",
|
|
4312
|
+
description: "Convert to pipe style",
|
|
4313
|
+
apply: gen(function* () {
|
|
4314
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
4315
|
+
changeTracker.replaceNode(
|
|
4316
|
+
sourceFile,
|
|
4317
|
+
parentChain[0],
|
|
4318
|
+
ts.factory.createCallExpression(
|
|
4319
|
+
ts.factory.createPropertyAccessExpression(
|
|
4320
|
+
subject,
|
|
4321
|
+
"pipe"
|
|
4322
|
+
),
|
|
4323
|
+
void 0,
|
|
4324
|
+
pipe(
|
|
4325
|
+
parentChain,
|
|
4326
|
+
filter(ts.isCallExpression),
|
|
4327
|
+
map3((call) => call.expression),
|
|
4328
|
+
reverse
|
|
4329
|
+
)
|
|
4330
|
+
)
|
|
4331
|
+
);
|
|
4332
|
+
})
|
|
4333
|
+
}]
|
|
4334
|
+
});
|
|
4335
|
+
originalParentChain.forEach((node2) => callChainNodes.delete(node2));
|
|
4336
|
+
break;
|
|
4337
|
+
}
|
|
4338
|
+
}
|
|
4339
|
+
}
|
|
4340
|
+
ts.forEachChild(node, prependNodeToVisit);
|
|
4341
|
+
}
|
|
4342
|
+
})
|
|
4343
|
+
});
|
|
4344
|
+
|
|
4274
4345
|
// src/diagnostics/missingEffectContext.ts
|
|
4275
4346
|
var missingEffectContext = createDiagnostic({
|
|
4276
4347
|
name: "missingEffectContext",
|
|
@@ -5550,6 +5621,50 @@ var strictBooleanExpressions = createDiagnostic({
|
|
|
5550
5621
|
})
|
|
5551
5622
|
});
|
|
5552
5623
|
|
|
5624
|
+
// src/diagnostics/strictEffectProvide.ts
|
|
5625
|
+
var strictEffectProvide = createDiagnostic({
|
|
5626
|
+
name: "strictEffectProvide",
|
|
5627
|
+
code: 27,
|
|
5628
|
+
severity: "off",
|
|
5629
|
+
apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
|
|
5630
|
+
const ts = yield* service(TypeScriptApi);
|
|
5631
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
5632
|
+
const typeParser = yield* service(TypeParser);
|
|
5633
|
+
const parseEffectProvideWithLayer = (node) => gen(function* () {
|
|
5634
|
+
if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression) || !ts.isIdentifier(node.expression.name) || ts.idText(node.expression.name) !== "provide" || node.arguments.length === 0) {
|
|
5635
|
+
return yield* typeParserIssue("Not an Effect.provide call");
|
|
5636
|
+
}
|
|
5637
|
+
yield* typeParser.importedEffectModule(node.expression.expression);
|
|
5638
|
+
return yield* firstSuccessOf(
|
|
5639
|
+
node.arguments.map((arg) => {
|
|
5640
|
+
const argType = typeChecker.getTypeAtLocation(arg);
|
|
5641
|
+
return typeParser.layerType(argType, arg);
|
|
5642
|
+
})
|
|
5643
|
+
);
|
|
5644
|
+
});
|
|
5645
|
+
const nodeToVisit = [];
|
|
5646
|
+
const appendNodeToVisit = (node) => {
|
|
5647
|
+
nodeToVisit.push(node);
|
|
5648
|
+
return void 0;
|
|
5649
|
+
};
|
|
5650
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
5651
|
+
while (nodeToVisit.length > 0) {
|
|
5652
|
+
const node = nodeToVisit.shift();
|
|
5653
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
5654
|
+
if (ts.isCallExpression(node)) {
|
|
5655
|
+
const layerCheck = yield* pipe(parseEffectProvideWithLayer(node), option);
|
|
5656
|
+
if (isSome2(layerCheck)) {
|
|
5657
|
+
report({
|
|
5658
|
+
location: node,
|
|
5659
|
+
messageText: "Effect.provide with a Layer should only be used at application entry points. If this is an entry point, you can safely disable this diagnostic. Otherwise, using Effect.provide may break scope lifetimes. Compose all layers at your entry point and provide them at once.",
|
|
5660
|
+
fixes: []
|
|
5661
|
+
});
|
|
5662
|
+
}
|
|
5663
|
+
}
|
|
5664
|
+
}
|
|
5665
|
+
})
|
|
5666
|
+
});
|
|
5667
|
+
|
|
5553
5668
|
// src/diagnostics/tryCatchInEffectGen.ts
|
|
5554
5669
|
var tryCatchInEffectGen = createDiagnostic({
|
|
5555
5670
|
name: "tryCatchInEffectGen",
|
|
@@ -5839,7 +5954,9 @@ var diagnostics = [
|
|
|
5839
5954
|
overriddenSchemaConstructor,
|
|
5840
5955
|
unsupportedServiceAccessors,
|
|
5841
5956
|
nonObjectEffectServiceType,
|
|
5842
|
-
deterministicKeys
|
|
5957
|
+
deterministicKeys,
|
|
5958
|
+
missedPipeableOpportunity,
|
|
5959
|
+
strictEffectProvide
|
|
5843
5960
|
];
|
|
5844
5961
|
|
|
5845
5962
|
// src/effect-lsp-patch-utils.ts
|