@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/README.md CHANGED
@@ -64,6 +64,7 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
64
64
  - Warn when `Effect.Service` is used with a primitive type instead of an object type
65
65
  - Warn when schema classes override the default constructor behavior
66
66
  - Warn when `@effect-diagnostics-next-line` comments have no effect (i.e., they don't suppress any diagnostic)
67
+ - Detect nested function calls that can be converted to pipeable style for better readability
67
68
 
68
69
  ### Completions
69
70
 
package/cli.js CHANGED
@@ -31198,7 +31198,8 @@ var defaults = {
31198
31198
  pattern: "default",
31199
31199
  skipLeadingPath: ["src/"]
31200
31200
  }],
31201
- extendedKeyDetection: false
31201
+ extendedKeyDetection: false,
31202
+ pipeableMinArgCount: 1
31202
31203
  };
31203
31204
  function parseKeyPatterns(patterns) {
31204
31205
  const result = [];
@@ -31233,7 +31234,8 @@ function parse4(config2) {
31233
31234
  renames: isObject(config2) && hasProperty(config2, "renames") && isBoolean(config2.renames) ? config2.renames : defaults.renames,
31234
31235
  noExternal: isObject(config2) && hasProperty(config2, "noExternal") && isBoolean(config2.noExternal) ? config2.noExternal : defaults.noExternal,
31235
31236
  keyPatterns: isObject(config2) && hasProperty(config2, "keyPatterns") && isArray(config2.keyPatterns) ? parseKeyPatterns(config2.keyPatterns) : defaults.keyPatterns,
31236
- extendedKeyDetection: isObject(config2) && hasProperty(config2, "extendedKeyDetection") && isBoolean(config2.extendedKeyDetection) ? config2.extendedKeyDetection : defaults.extendedKeyDetection
31237
+ extendedKeyDetection: isObject(config2) && hasProperty(config2, "extendedKeyDetection") && isBoolean(config2.extendedKeyDetection) ? config2.extendedKeyDetection : defaults.extendedKeyDetection,
31238
+ pipeableMinArgCount: isObject(config2) && hasProperty(config2, "pipeableMinArgCount") && isNumber(config2.pipeableMinArgCount) ? config2.pipeableMinArgCount : defaults.pipeableMinArgCount
31237
31239
  };
31238
31240
  }
31239
31241
 
@@ -33724,6 +33726,69 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
33724
33726
  })
33725
33727
  });
33726
33728
 
33729
+ // src/diagnostics/missedPipeableOpportunity.ts
33730
+ var missedPipeableOpportunity = createDiagnostic({
33731
+ name: "missedPipeableOpportunity",
33732
+ code: 26,
33733
+ severity: "off",
33734
+ apply: fn2("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
33735
+ const ts = yield* service2(TypeScriptApi);
33736
+ const typeChecker = yield* service2(TypeCheckerApi);
33737
+ const typeParser = yield* service2(TypeParser);
33738
+ const options3 = yield* service2(LanguageServicePluginOptions);
33739
+ const nodeToVisit = [sourceFile];
33740
+ const prependNodeToVisit = (node) => {
33741
+ nodeToVisit.unshift(node);
33742
+ return void 0;
33743
+ };
33744
+ const callChainNodes = /* @__PURE__ */ new WeakMap();
33745
+ while (nodeToVisit.length > 0) {
33746
+ const node = nodeToVisit.shift();
33747
+ if (ts.isCallExpression(node) && node.arguments.length === 1 && node.parent) {
33748
+ const parentChain = callChainNodes.get(node.parent) || [];
33749
+ callChainNodes.set(node, parentChain.concat(node));
33750
+ } else if (node.parent && callChainNodes.has(node.parent) && ts.isExpression(node)) {
33751
+ const parentChain = callChainNodes.get(node.parent) || [];
33752
+ const originalParentChain = parentChain.slice();
33753
+ parentChain.push(node);
33754
+ while (parentChain.length > options3.pipeableMinArgCount) {
33755
+ const subject = parentChain.pop();
33756
+ const resultType = typeChecker.getTypeAtLocation(subject);
33757
+ const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse14(() => void_8));
33758
+ if (pipeableType) {
33759
+ report({
33760
+ location: parentChain[0],
33761
+ messageText: `Nested function calls can be converted to pipeable style for better readability.`,
33762
+ fixes: [{
33763
+ fixName: "missedPipeableOpportunity_fix",
33764
+ description: "Convert to pipe style",
33765
+ apply: gen3(function* () {
33766
+ const changeTracker = yield* service2(ChangeTracker);
33767
+ changeTracker.replaceNode(
33768
+ sourceFile,
33769
+ parentChain[0],
33770
+ ts.factory.createCallExpression(
33771
+ ts.factory.createPropertyAccessExpression(
33772
+ subject,
33773
+ "pipe"
33774
+ ),
33775
+ void 0,
33776
+ parentChain.filter(ts.isCallExpression).map((call) => call.expression)
33777
+ )
33778
+ );
33779
+ })
33780
+ }]
33781
+ });
33782
+ originalParentChain.forEach((node2) => callChainNodes.delete(node2));
33783
+ break;
33784
+ }
33785
+ }
33786
+ }
33787
+ ts.forEachChild(node, prependNodeToVisit);
33788
+ }
33789
+ })
33790
+ });
33791
+
33727
33792
  // src/diagnostics/missingEffectContext.ts
33728
33793
  var missingEffectContext = createDiagnostic({
33729
33794
  name: "missingEffectContext",
@@ -35292,7 +35357,8 @@ var diagnostics = [
35292
35357
  overriddenSchemaConstructor,
35293
35358
  unsupportedServiceAccessors,
35294
35359
  nonObjectEffectServiceType,
35295
- deterministicKeys
35360
+ deterministicKeys,
35361
+ missedPipeableOpportunity
35296
35362
  ];
35297
35363
 
35298
35364
  // src/cli/diagnostics.ts