@effect/language-service 0.21.6 → 0.21.8

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/index.js CHANGED
@@ -3051,7 +3051,9 @@ var leakingRequirements = createDiagnostic({
3051
3051
  report({
3052
3052
  node,
3053
3053
  category: ts.DiagnosticCategory.Warning,
3054
- messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement`,
3054
+ messageText: `This Service is leaking the ${requirements.map((_) => typeChecker.typeToString(_)).join(" | ")} requirement.
3055
+ If these requirements cannot be cached and are expected to be provided per method invocation (e.g. HttpServerRequest), you can safely disable this diagnostic for this line through quickfixes.
3056
+ More info at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage`,
3055
3057
  fixes: []
3056
3058
  });
3057
3059
  }
@@ -3064,7 +3066,7 @@ var leakingRequirements = createDiagnostic({
3064
3066
  while (nodeToVisit.length > 0) {
3065
3067
  const node = nodeToVisit.shift();
3066
3068
  const typesToCheck = [];
3067
- if (ts.isCallExpression(node)) {
3069
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && node.expression.name.text === "GenericTag") {
3068
3070
  typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
3069
3071
  } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
3070
3072
  const classSym = typeChecker.getSymbolAtLocation(node.name);
@@ -3377,7 +3379,9 @@ var returnEffectInGen = createDiagnostic({
3377
3379
  report({
3378
3380
  node,
3379
3381
  category: ts.DiagnosticCategory.Suggestion,
3380
- messageText: `You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>. Maybe you wanted to return yield* instead? Nested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect.`,
3382
+ messageText: `You are returning an Effect-able type inside a generator function, and will result in nested Effect<Effect<...>>.
3383
+ Maybe you wanted to return yield* instead?
3384
+ Nested Effect-able types may be intended if you plan to later manually flatten or unwrap this Effect, if so you can safely disable this diagnostic for this line through quickfixes.`,
3381
3385
  fixes: fix
3382
3386
  });
3383
3387
  }),
@@ -3615,41 +3619,82 @@ function dedupeJsDocs(quickInfo2) {
3615
3619
  }
3616
3620
 
3617
3621
  // src/quickinfo/effectTypeArgs.ts
3618
- function formatTypeForQuickInfo(channelType, channelName) {
3619
- return gen2(function* () {
3620
- const ts = yield* service(TypeScriptApi);
3621
- const typeChecker = yield* service(TypeCheckerApi);
3622
- const stringRepresentation = typeChecker.typeToString(
3623
- channelType,
3624
- void 0,
3625
- ts.TypeFormatFlags.NoTruncation
3626
- );
3627
- return `type ${channelName} = ${stringRepresentation}`;
3628
- });
3629
- }
3630
3622
  function effectTypeArgs(sourceFile, position, quickInfo2) {
3631
3623
  return pipe(
3632
3624
  gen2(function* () {
3633
3625
  const ts = yield* service(TypeScriptApi);
3634
3626
  const typeChecker = yield* service(TypeCheckerApi);
3635
3627
  const typeParser = yield* service(TypeParser);
3636
- const maybeNode = pipe(
3637
- yield* getAncestorNodesInRange(sourceFile, toTextRange(position)),
3638
- head
3639
- );
3640
- if (isNone2(maybeNode)) return quickInfo2;
3641
- const node = maybeNode.value;
3642
- const hasTruncationHappened = quickInfo2 && ts.displayPartsToString(quickInfo2.displayParts).indexOf("...") > -1;
3643
- const nodeForType = !quickInfo2 && ts.isYieldExpression(node) && node.asteriskToken && node.expression ? node.expression : hasTruncationHappened ? node : void 0;
3644
- if (!nodeForType) return quickInfo2;
3645
- const effectType = yield* typeParser.effectType(
3646
- typeChecker.getTypeAtLocation(nodeForType),
3647
- nodeForType
3628
+ function formatTypeForQuickInfo(channelType, channelName) {
3629
+ const stringRepresentation = typeChecker.typeToString(
3630
+ channelType,
3631
+ void 0,
3632
+ ts.TypeFormatFlags.NoTruncation
3633
+ );
3634
+ return `type ${channelName} = ${stringRepresentation}`;
3635
+ }
3636
+ function makeSymbolDisplayParts(title, A, E, R) {
3637
+ return [{
3638
+ kind: "text",
3639
+ text: "```ts\n/* " + title + " */\n" + formatTypeForQuickInfo(A, "Success") + "\n" + formatTypeForQuickInfo(E, "Failure") + "\n" + formatTypeForQuickInfo(R, "Requirements") + "\n```\n"
3640
+ }];
3641
+ }
3642
+ function getNodeForQuickInfo(node2) {
3643
+ if (ts.isNewExpression(node2.parent) && node2.pos === node2.parent.pos) {
3644
+ return node2.parent.expression;
3645
+ }
3646
+ if (ts.isNamedTupleMember(node2.parent) && node2.pos === node2.parent.pos) {
3647
+ return node2.parent;
3648
+ }
3649
+ if (ts.isJsxNamespacedName(node2.parent)) {
3650
+ return node2.parent;
3651
+ }
3652
+ return node2;
3653
+ }
3654
+ function getDataForQuickInfo() {
3655
+ if (!("getTouchingPropertyName" in ts && typeof ts.getTouchingPropertyName === "function")) return;
3656
+ const touchingNode = ts.getTouchingPropertyName(sourceFile, position);
3657
+ if (touchingNode === sourceFile) return;
3658
+ const adjustedNode = getNodeForQuickInfo(touchingNode);
3659
+ if (ts.isToken(adjustedNode) && adjustedNode.kind === ts.SyntaxKind.YieldKeyword) {
3660
+ if (ts.isYieldExpression(adjustedNode.parent) && adjustedNode.parent.asteriskToken && adjustedNode.parent.expression) {
3661
+ return {
3662
+ type: typeChecker.getTypeAtLocation(adjustedNode.parent.expression),
3663
+ atLocation: adjustedNode.parent.expression,
3664
+ node: adjustedNode.parent,
3665
+ shouldTry: true
3666
+ };
3667
+ }
3668
+ }
3669
+ return {
3670
+ type: typeChecker.getTypeAtLocation(adjustedNode),
3671
+ atLocation: adjustedNode,
3672
+ node: adjustedNode,
3673
+ shouldTry: quickInfo2 && ts.displayPartsToString(quickInfo2.displayParts).indexOf("...") > -1
3674
+ };
3675
+ }
3676
+ const data = getDataForQuickInfo();
3677
+ if (!(data && data.shouldTry)) return quickInfo2;
3678
+ const { atLocation, node, type } = data;
3679
+ const effectTypeArgsDocumentation = yield* pipe(
3680
+ typeParser.effectType(
3681
+ type,
3682
+ atLocation
3683
+ ),
3684
+ map4((_) => makeSymbolDisplayParts("Effect Type Parameters", _.A, _.E, _.R)),
3685
+ orElse3(() => {
3686
+ const callSignatues = type.getCallSignatures();
3687
+ if (callSignatues.length !== 1) return succeed([]);
3688
+ const returnType = callSignatues[0].getReturnType();
3689
+ return pipe(
3690
+ typeParser.effectType(
3691
+ returnType,
3692
+ atLocation
3693
+ ),
3694
+ map4((_) => makeSymbolDisplayParts("Returned Effect Type Parameters", _.A, _.E, _.R))
3695
+ );
3696
+ })
3648
3697
  );
3649
- const effectTypeArgsDocumentation = [{
3650
- kind: "text",
3651
- text: "```ts\n/* Effect Type Parameters */\n" + (yield* formatTypeForQuickInfo(effectType.A, "Success")) + "\n" + (yield* formatTypeForQuickInfo(effectType.E, "Failure")) + "\n" + (yield* formatTypeForQuickInfo(effectType.R, "Requirements")) + "\n```\n"
3652
- }];
3653
3698
  if (!quickInfo2) {
3654
3699
  const start = node.getStart();
3655
3700
  const end = node.getEnd();