@effect/language-service 0.55.5 → 0.57.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.
@@ -90,6 +90,8 @@ var dual = function(arity, body) {
90
90
  }
91
91
  };
92
92
  var identity = (a) => a;
93
+ var constant = (value) => () => value;
94
+ var constUndefined = /* @__PURE__ */ constant(void 0);
93
95
  function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
94
96
  switch (arguments.length) {
95
97
  case 1:
@@ -738,8 +740,10 @@ var none2 = () => none;
738
740
  var some2 = some;
739
741
  var isNone2 = isNone;
740
742
  var isSome2 = isSome;
743
+ var getOrElse2 = /* @__PURE__ */ dual(2, (self, onNone) => isNone2(self) ? onNone() : self.value);
741
744
  var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
742
745
  var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
746
+ var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
743
747
 
744
748
  // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Record.js
745
749
  var map2 = /* @__PURE__ */ dual(2, (self, f) => {
@@ -2601,6 +2605,51 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2601
2605
  if (!symbol3) return typeParserIssue("Node has no symbol", void 0, givenNode);
2602
2606
  return isSymbolExportOfPackageModule(symbol3, packageName, memberName, isCorrectSourceFile);
2603
2607
  };
2608
+ const findSymbolsMatchingPackageAndExportedName = (packageName, exportedSymbolName) => cachedBy(
2609
+ fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* (_fromSourceFile) {
2610
+ const result = [];
2611
+ for (const sourceFile of program.getSourceFiles()) {
2612
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
2613
+ if (!moduleSymbol) continue;
2614
+ const symbol3 = typeChecker.tryGetMemberInModuleExports(exportedSymbolName, moduleSymbol);
2615
+ if (!symbol3) continue;
2616
+ const packageInfo = yield* getSourceFilePackageInfo(sourceFile);
2617
+ if (!packageInfo || packageInfo.name.toLowerCase() !== packageName.toLowerCase()) continue;
2618
+ result.push([symbol3, sourceFile]);
2619
+ }
2620
+ return result;
2621
+ }),
2622
+ `TypeParser.findSymbolsMatchingPackageAndExportedName(${packageName}, ${exportedSymbolName})`,
2623
+ (sourceFile) => sourceFile
2624
+ );
2625
+ const isCauseTypeSourceFile = cachedBy(
2626
+ fn("TypeParser.isCauseTypeSourceFile")(function* (sourceFile) {
2627
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
2628
+ if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
2629
+ const causeTypeSymbol = typeChecker.tryGetMemberInModuleExports("Cause", moduleSymbol);
2630
+ if (!causeTypeSymbol) return yield* typeParserIssue("Cause type not found", void 0, sourceFile);
2631
+ const type = typeChecker.getDeclaredTypeOfSymbol(causeTypeSymbol);
2632
+ yield* pipeableType(type, sourceFile);
2633
+ return sourceFile;
2634
+ }),
2635
+ "TypeParser.isCauseTypeSourceFile",
2636
+ (sourceFile) => sourceFile
2637
+ );
2638
+ const effectCauseYieldableErrorTypes = cachedBy(
2639
+ fn("TypeParser.effectCauseYieldableErrorTypes")(function* (fromSourceFile) {
2640
+ const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")(fromSourceFile);
2641
+ const result = [];
2642
+ for (const [symbol3, sourceFile] of symbols) {
2643
+ const causeFile = yield* isCauseTypeSourceFile(sourceFile);
2644
+ if (!causeFile) continue;
2645
+ const type = typeChecker.getDeclaredTypeOfSymbol(symbol3);
2646
+ result.push(type);
2647
+ }
2648
+ return result;
2649
+ }),
2650
+ "TypeParser.effectCauseYieldableErrorTypes",
2651
+ (fromSourceFile) => fromSourceFile
2652
+ );
2604
2653
  function covariantTypeArgument(type) {
2605
2654
  const signatures = typeChecker.getSignaturesOfType(type, ts.SignatureKind.Call);
2606
2655
  if (signatures.length !== 1) {
@@ -3590,6 +3639,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3590
3639
  effectGen,
3591
3640
  effectFnUntracedGen,
3592
3641
  effectFnGen,
3642
+ effectCauseYieldableErrorTypes,
3593
3643
  unnecessaryEffectGen: unnecessaryEffectGen2,
3594
3644
  effectSchemaType,
3595
3645
  contextTag,
@@ -5508,8 +5558,93 @@ var accessors = createCodegen({
5508
5558
  })
5509
5559
  });
5510
5560
 
5561
+ // src/codegens/annotate.ts
5562
+ var annotate = createCodegen({
5563
+ name: "annotate",
5564
+ apply: fn("annotate.apply")(function* (sourceFile, textRange) {
5565
+ const ts = yield* service(TypeScriptApi);
5566
+ const tsUtils = yield* service(TypeScriptUtils);
5567
+ const typeChecker = yield* service(TypeCheckerApi);
5568
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
5569
+ const parse3 = (node) => gen(function* () {
5570
+ let variableDeclarations = [];
5571
+ const result = [];
5572
+ if (ts.isVariableStatement(node)) {
5573
+ variableDeclarations = [...variableDeclarations, ...node.declarationList.declarations];
5574
+ } else if (ts.isVariableDeclarationList(node)) {
5575
+ variableDeclarations = [...variableDeclarations, ...node.declarations];
5576
+ } else if (ts.isVariableDeclaration(node)) {
5577
+ variableDeclarations = [...variableDeclarations, node];
5578
+ }
5579
+ if (variableDeclarations.length === 0) {
5580
+ return yield* fail(new CodegenNotApplicableError("not a variable declaration"));
5581
+ }
5582
+ for (const variableDeclaration of variableDeclarations) {
5583
+ if (!variableDeclaration.initializer) continue;
5584
+ const initializerType = typeChecker.getTypeAtLocation(variableDeclaration.initializer);
5585
+ const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
5586
+ initializerType,
5587
+ node,
5588
+ ts.NodeBuilderFlags.NoTruncation
5589
+ )).pipe(
5590
+ orElse(
5591
+ () => fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
5592
+ initializerType,
5593
+ void 0,
5594
+ ts.NodeBuilderFlags.NoTruncation
5595
+ ))
5596
+ ),
5597
+ getOrUndefined
5598
+ );
5599
+ if (!initializerTypeNode) continue;
5600
+ const typeNodeString = typeChecker.typeToString(initializerType, void 0, ts.TypeFormatFlags.NoTruncation);
5601
+ const hash3 = cyrb53(typeNodeString);
5602
+ result.push({ variableDeclaration, initializerTypeNode, hash: hash3 });
5603
+ }
5604
+ if (result.length === 0) {
5605
+ return yield* fail(new CodegenNotApplicableError("no variable declarations with initializers"));
5606
+ }
5607
+ const hash2 = cyrb53(result.map((_) => _.hash).join("/"));
5608
+ return {
5609
+ hash: hash2,
5610
+ result
5611
+ };
5612
+ });
5613
+ const nodeAndCommentRange = tsUtils.findNodeWithLeadingCommentAtPosition(sourceFile, textRange.pos);
5614
+ if (!nodeAndCommentRange) return yield* fail(new CodegenNotApplicableError("no node and comment range"));
5615
+ return yield* pipe(
5616
+ parse3(nodeAndCommentRange.node),
5617
+ map4(
5618
+ (_) => ({
5619
+ hash: _.hash,
5620
+ description: "Annotate with type",
5621
+ apply: gen(function* () {
5622
+ const changeTracker = yield* service(ChangeTracker);
5623
+ for (const { initializerTypeNode, variableDeclaration } of _.result) {
5624
+ if (variableDeclaration.type) {
5625
+ changeTracker.deleteRange(sourceFile, {
5626
+ pos: variableDeclaration.name.end,
5627
+ end: variableDeclaration.type.end
5628
+ });
5629
+ }
5630
+ changeTracker.insertNodeAt(
5631
+ sourceFile,
5632
+ variableDeclaration.name.end,
5633
+ initializerTypeNode,
5634
+ {
5635
+ prefix: ": "
5636
+ }
5637
+ );
5638
+ }
5639
+ })
5640
+ })
5641
+ )
5642
+ );
5643
+ })
5644
+ });
5645
+
5511
5646
  // src/codegens.ts
5512
- var codegens = [accessors];
5647
+ var codegens = [accessors, annotate];
5513
5648
 
5514
5649
  // src/diagnostics/outdatedEffectCodegen.ts
5515
5650
  var outdatedEffectCodegen = createDiagnostic({
@@ -6241,6 +6376,66 @@ var unnecessaryEffectGen = createDiagnostic({
6241
6376
  })
6242
6377
  });
6243
6378
 
6379
+ // src/diagnostics/unnecessaryFailYieldableError.ts
6380
+ var unnecessaryFailYieldableError = createDiagnostic({
6381
+ name: "unnecessaryFailYieldableError",
6382
+ code: 29,
6383
+ severity: "suggestion",
6384
+ apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
6385
+ const ts = yield* service(TypeScriptApi);
6386
+ const typeParser = yield* service(TypeParser);
6387
+ const typeChecker = yield* service(TypeCheckerApi);
6388
+ const yieldableErrorTypes = yield* pipe(
6389
+ typeParser.effectCauseYieldableErrorTypes(sourceFile),
6390
+ orElse2(() => succeed([]))
6391
+ );
6392
+ const nodeToVisit = [];
6393
+ const appendNodeToVisit = (node) => {
6394
+ nodeToVisit.push(node);
6395
+ return void 0;
6396
+ };
6397
+ ts.forEachChild(sourceFile, appendNodeToVisit);
6398
+ while (nodeToVisit.length > 0) {
6399
+ const node = nodeToVisit.shift();
6400
+ ts.forEachChild(node, appendNodeToVisit);
6401
+ if (ts.isYieldExpression(node) && node.asteriskToken && node.expression && ts.isCallExpression(node.expression)) {
6402
+ const callExpression = node.expression;
6403
+ yield* pipe(
6404
+ typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpression.expression),
6405
+ map4(() => {
6406
+ if (callExpression.arguments.length > 0) {
6407
+ const failArgument = callExpression.arguments[0];
6408
+ const argumentType = typeChecker.getTypeAtLocation(failArgument);
6409
+ const isYieldableError = yieldableErrorTypes.some(
6410
+ (yieldableType) => typeChecker.isTypeAssignableTo(argumentType, yieldableType)
6411
+ );
6412
+ if (isYieldableError) {
6413
+ report({
6414
+ location: node,
6415
+ messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
6416
+ fixes: [{
6417
+ fixName: "unnecessaryFailYieldableError_fix",
6418
+ description: "Replace yield* Effect.fail with yield*",
6419
+ apply: gen(function* () {
6420
+ const changeTracker = yield* service(ChangeTracker);
6421
+ changeTracker.replaceNode(
6422
+ sourceFile,
6423
+ callExpression,
6424
+ failArgument
6425
+ );
6426
+ })
6427
+ }]
6428
+ });
6429
+ }
6430
+ }
6431
+ }),
6432
+ ignore
6433
+ );
6434
+ }
6435
+ }
6436
+ })
6437
+ });
6438
+
6244
6439
  // src/diagnostics/unnecessaryPipe.ts
6245
6440
  var unnecessaryPipe = createDiagnostic({
6246
6441
  name: "unnecessaryPipe",
@@ -6428,6 +6623,7 @@ var diagnostics = [
6428
6623
  floatingEffect,
6429
6624
  missingStarInYieldEffectGen,
6430
6625
  unnecessaryEffectGen,
6626
+ unnecessaryFailYieldableError,
6431
6627
  missingReturnYieldStar,
6432
6628
  leakingRequirements,
6433
6629
  unnecessaryPipe,