@effect/language-service 0.49.0 → 0.50.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/language-service",
3
- "version": "0.49.0",
3
+ "version": "0.50.0",
4
4
  "description": "A Language-Service Plugin to Refactor and Diagnostic effect-ts projects",
5
5
  "main": "index.cjs",
6
6
  "bin": {
package/transform.js CHANGED
@@ -1202,7 +1202,8 @@ var defaults = {
1202
1202
  pattern: "default",
1203
1203
  skipLeadingPath: ["src/"]
1204
1204
  }],
1205
- extendedKeyDetection: false
1205
+ extendedKeyDetection: false,
1206
+ pipeableMinArgCount: 1
1206
1207
  };
1207
1208
  function parseKeyPatterns(patterns) {
1208
1209
  const result = [];
@@ -1237,7 +1238,8 @@ function parse(config) {
1237
1238
  renames: isObject(config) && hasProperty(config, "renames") && isBoolean(config.renames) ? config.renames : defaults.renames,
1238
1239
  noExternal: isObject(config) && hasProperty(config, "noExternal") && isBoolean(config.noExternal) ? config.noExternal : defaults.noExternal,
1239
1240
  keyPatterns: isObject(config) && hasProperty(config, "keyPatterns") && isArray(config.keyPatterns) ? parseKeyPatterns(config.keyPatterns) : defaults.keyPatterns,
1240
- extendedKeyDetection: isObject(config) && hasProperty(config, "extendedKeyDetection") && isBoolean(config.extendedKeyDetection) ? config.extendedKeyDetection : defaults.extendedKeyDetection
1241
+ extendedKeyDetection: isObject(config) && hasProperty(config, "extendedKeyDetection") && isBoolean(config.extendedKeyDetection) ? config.extendedKeyDetection : defaults.extendedKeyDetection,
1242
+ pipeableMinArgCount: isObject(config) && hasProperty(config, "pipeableMinArgCount") && isNumber(config.pipeableMinArgCount) ? config.pipeableMinArgCount : defaults.pipeableMinArgCount
1241
1243
  };
1242
1244
  }
1243
1245
 
@@ -4271,6 +4273,69 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4271
4273
  })
4272
4274
  });
4273
4275
 
4276
+ // src/diagnostics/missedPipeableOpportunity.ts
4277
+ var missedPipeableOpportunity = createDiagnostic({
4278
+ name: "missedPipeableOpportunity",
4279
+ code: 26,
4280
+ severity: "off",
4281
+ apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
4282
+ const ts = yield* service(TypeScriptApi);
4283
+ const typeChecker = yield* service(TypeCheckerApi);
4284
+ const typeParser = yield* service(TypeParser);
4285
+ const options = yield* service(LanguageServicePluginOptions);
4286
+ const nodeToVisit = [sourceFile];
4287
+ const prependNodeToVisit = (node) => {
4288
+ nodeToVisit.unshift(node);
4289
+ return void 0;
4290
+ };
4291
+ const callChainNodes = /* @__PURE__ */ new WeakMap();
4292
+ while (nodeToVisit.length > 0) {
4293
+ const node = nodeToVisit.shift();
4294
+ if (ts.isCallExpression(node) && node.arguments.length === 1 && node.parent) {
4295
+ const parentChain = callChainNodes.get(node.parent) || [];
4296
+ callChainNodes.set(node, parentChain.concat(node));
4297
+ } else if (node.parent && callChainNodes.has(node.parent) && ts.isExpression(node)) {
4298
+ const parentChain = callChainNodes.get(node.parent) || [];
4299
+ const originalParentChain = parentChain.slice();
4300
+ parentChain.push(node);
4301
+ while (parentChain.length > options.pipeableMinArgCount) {
4302
+ const subject = parentChain.pop();
4303
+ const resultType = typeChecker.getTypeAtLocation(subject);
4304
+ const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
4305
+ if (pipeableType) {
4306
+ report({
4307
+ location: parentChain[0],
4308
+ messageText: `Nested function calls can be converted to pipeable style for better readability.`,
4309
+ fixes: [{
4310
+ fixName: "missedPipeableOpportunity_fix",
4311
+ description: "Convert to pipe style",
4312
+ apply: gen(function* () {
4313
+ const changeTracker = yield* service(ChangeTracker);
4314
+ changeTracker.replaceNode(
4315
+ sourceFile,
4316
+ parentChain[0],
4317
+ ts.factory.createCallExpression(
4318
+ ts.factory.createPropertyAccessExpression(
4319
+ subject,
4320
+ "pipe"
4321
+ ),
4322
+ void 0,
4323
+ parentChain.filter(ts.isCallExpression).map((call) => call.expression)
4324
+ )
4325
+ );
4326
+ })
4327
+ }]
4328
+ });
4329
+ originalParentChain.forEach((node2) => callChainNodes.delete(node2));
4330
+ break;
4331
+ }
4332
+ }
4333
+ }
4334
+ ts.forEachChild(node, prependNodeToVisit);
4335
+ }
4336
+ })
4337
+ });
4338
+
4274
4339
  // src/diagnostics/missingEffectContext.ts
4275
4340
  var missingEffectContext = createDiagnostic({
4276
4341
  name: "missingEffectContext",
@@ -5839,7 +5904,8 @@ var diagnostics = [
5839
5904
  overriddenSchemaConstructor,
5840
5905
  unsupportedServiceAccessors,
5841
5906
  nonObjectEffectServiceType,
5842
- deterministicKeys
5907
+ deterministicKeys,
5908
+ missedPipeableOpportunity
5843
5909
  ];
5844
5910
 
5845
5911
  // src/transform.ts