@effect/language-service 0.38.0 → 0.38.2

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
@@ -960,7 +960,7 @@ var match = (fa, opts) => {
960
960
  var orElse2 = (f) => (fa) => {
961
961
  const nano = Object.create(MatchProto);
962
962
  nano[args] = fa;
963
- nano[contE] = f;
963
+ nano[contE] = (_) => _ instanceof NanoDefectException ? fail(_) : f(_);
964
964
  return nano;
965
965
  };
966
966
  var firstSuccessOf = (arr) => arr.slice(1).reduce((arr2, fa) => orElse2(() => fa)(arr2), arr[0]);
@@ -1148,6 +1148,19 @@ var filter = /* @__PURE__ */ dual(2, (self, predicate) => {
1148
1148
  }
1149
1149
  return out;
1150
1150
  });
1151
+ var partition = /* @__PURE__ */ dual(2, (self, predicate) => {
1152
+ const left3 = [];
1153
+ const right3 = [];
1154
+ const as = fromIterable(self);
1155
+ for (let i = 0; i < as.length; i++) {
1156
+ if (predicate(as[i], i)) {
1157
+ right3.push(as[i]);
1158
+ } else {
1159
+ left3.push(as[i]);
1160
+ }
1161
+ }
1162
+ return [left3, right3];
1163
+ });
1151
1164
  var every = /* @__PURE__ */ dual(2, (self, refinement) => self.every(refinement));
1152
1165
  var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
1153
1166
  const input = fromIterable(self);
@@ -1746,18 +1759,21 @@ var getApplicableRefactors = fn("LSP.getApplicableRefactors")(function* (refacto
1746
1759
  const textRange = typeof positionOrRange === "number" ? { pos: positionOrRange, end: positionOrRange } : positionOrRange;
1747
1760
  const effectRefactors = [];
1748
1761
  for (const refactor of refactors2) {
1749
- const result = yield* option(refactor.apply(sourceFile, textRange));
1750
- if (isSome2(result)) {
1751
- effectRefactors.push({
1752
- name: refactorNameToFullyQualifiedName(refactor.name),
1753
- description: refactor.description,
1754
- actions: [{
1762
+ yield* pipe(
1763
+ refactor.apply(sourceFile, textRange),
1764
+ map3(
1765
+ (result) => effectRefactors.push({
1755
1766
  name: refactorNameToFullyQualifiedName(refactor.name),
1756
- description: result.value.description,
1757
- kind: result.value.kind
1758
- }]
1759
- });
1760
- }
1767
+ description: refactor.description,
1768
+ actions: [{
1769
+ name: refactorNameToFullyQualifiedName(refactor.name),
1770
+ description: result.description,
1771
+ kind: result.kind
1772
+ }]
1773
+ })
1774
+ ),
1775
+ ignore
1776
+ );
1761
1777
  }
1762
1778
  return effectRefactors;
1763
1779
  });
@@ -2622,8 +2638,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
2622
2638
  node,
2623
2639
  effectModule,
2624
2640
  generatorFunction,
2625
- body: generatorFunction.body,
2626
- functionStar: generatorFunction.getFirstToken()
2641
+ body: generatorFunction.body
2627
2642
  }))
2628
2643
  );
2629
2644
  },
@@ -2670,8 +2685,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
2670
2685
  node,
2671
2686
  effectModule,
2672
2687
  generatorFunction,
2673
- body: generatorFunction.body,
2674
- functionStar: generatorFunction.getFirstToken()
2688
+ body: generatorFunction.body
2675
2689
  }))
2676
2690
  );
2677
2691
  },
@@ -2723,8 +2737,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
2723
2737
  node,
2724
2738
  generatorFunction,
2725
2739
  effectModule,
2726
- body: generatorFunction.body,
2727
- functionStar: generatorFunction.getFirstToken()
2740
+ body: generatorFunction.body
2728
2741
  }))
2729
2742
  );
2730
2743
  },
@@ -3229,6 +3242,55 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
3229
3242
  "TypeParser.extendsContextTag",
3230
3243
  (atLocation) => atLocation
3231
3244
  );
3245
+ const extendsEffectTag = cachedBy(
3246
+ fn("TypeParser.extendsEffectTag")(function* (atLocation) {
3247
+ if (!atLocation.name) {
3248
+ return yield* typeParserIssue("Class has no name", void 0, atLocation);
3249
+ }
3250
+ const heritageClauses = atLocation.heritageClauses;
3251
+ if (!heritageClauses) {
3252
+ return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
3253
+ }
3254
+ for (const heritageClause of heritageClauses) {
3255
+ for (const typeX of heritageClause.types) {
3256
+ if (ts.isExpressionWithTypeArguments(typeX)) {
3257
+ const wholeCall = typeX.expression;
3258
+ if (ts.isCallExpression(wholeCall)) {
3259
+ const effectTagCall = wholeCall.expression;
3260
+ if (ts.isCallExpression(effectTagCall) && wholeCall.typeArguments && wholeCall.typeArguments.length > 0) {
3261
+ const effectTagIdentifier = effectTagCall.expression;
3262
+ const selfTypeNode = wholeCall.typeArguments[0];
3263
+ if (ts.isPropertyAccessExpression(effectTagIdentifier) && ts.isIdentifier(effectTagIdentifier.name) && ts.idText(effectTagIdentifier.name) === "Tag") {
3264
+ const parsedEffectModule = yield* pipe(
3265
+ importedEffectModule(effectTagIdentifier.expression),
3266
+ option
3267
+ );
3268
+ if (isSome2(parsedEffectModule)) {
3269
+ const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
3270
+ if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
3271
+ const type = typeChecker.getTypeOfSymbol(classSym);
3272
+ const tagType = yield* contextTag(type, atLocation);
3273
+ return {
3274
+ className: atLocation.name,
3275
+ selfTypeNode,
3276
+ keyStringLiteral: ts.isStringLiteral(effectTagCall.arguments[0]) ? effectTagCall.arguments[0] : void 0,
3277
+ args: effectTagCall.arguments,
3278
+ Identifier: tagType.Identifier,
3279
+ Service: tagType.Service,
3280
+ Tag: parsedEffectModule.value
3281
+ };
3282
+ }
3283
+ }
3284
+ }
3285
+ }
3286
+ }
3287
+ }
3288
+ }
3289
+ return yield* typeParserIssue("Class does not extend Effect.Tag", void 0, atLocation);
3290
+ }),
3291
+ "TypeParser.extendsEffectTag",
3292
+ (atLocation) => atLocation
3293
+ );
3232
3294
  const extendsEffectService = cachedBy(
3233
3295
  fn("TypeParser.extendsEffectService")(function* (atLocation) {
3234
3296
  if (!atLocation.name) {
@@ -3311,6 +3373,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils) {
3311
3373
  pipeCall,
3312
3374
  scopeType,
3313
3375
  promiseLike,
3376
+ extendsEffectTag,
3314
3377
  extendsEffectService,
3315
3378
  extendsContextTag,
3316
3379
  extendsSchemaClass,
@@ -3523,6 +3586,7 @@ var parse2 = fn("writeTagClassAccessors.parse")(function* (node) {
3523
3586
  if (!ts.isClassDeclaration(node)) return yield* fail("not a class declaration");
3524
3587
  const { Service, accessors: accessors2, className } = yield* pipe(
3525
3588
  typeParser.extendsEffectService(node),
3589
+ orElse2(() => map3(typeParser.extendsEffectTag(node), (_) => ({ accessors: true, ..._ }))),
3526
3590
  orElse2(() => fail("not a class extending Effect.Service call"))
3527
3591
  );
3528
3592
  if (accessors2 !== true) return yield* fail("accessors are not enabled in the Effect.Service call");
@@ -4564,6 +4628,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
4564
4628
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
4565
4629
  const ts = yield* service(TypeScriptApi);
4566
4630
  const typeParser = yield* service(TypeParser);
4631
+ const tsUtils = yield* service(TypeScriptUtils);
4567
4632
  const brokenGenerators = /* @__PURE__ */ new Set();
4568
4633
  const brokenYields = /* @__PURE__ */ new Set();
4569
4634
  const nodeToVisit = [];
@@ -4586,9 +4651,9 @@ var missingStarInYieldEffectGen = createDiagnostic({
4586
4651
  typeParser.effectGen(effectGenNode),
4587
4652
  orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
4588
4653
  orElse2(() => typeParser.effectFnGen(effectGenNode)),
4589
- map3(({ functionStar }) => {
4590
- if (functionStar) {
4591
- brokenGenerators.add(functionStar);
4654
+ map3(({ generatorFunction }) => {
4655
+ if (generatorFunction) {
4656
+ brokenGenerators.add(ts.getTokenPosOfNode(generatorFunction, tsUtils.getSourceFileOfNode(node)));
4592
4657
  }
4593
4658
  brokenYields.add(node);
4594
4659
  }),
@@ -4598,8 +4663,8 @@ var missingStarInYieldEffectGen = createDiagnostic({
4598
4663
  }
4599
4664
  }
4600
4665
  brokenGenerators.forEach(
4601
- (node) => report({
4602
- location: node,
4666
+ (pos) => report({
4667
+ location: { pos, end: pos + "function".length },
4603
4668
  messageText: `Seems like you used yield instead of yield* inside this Effect.gen.`,
4604
4669
  fixes: []
4605
4670
  })
@@ -10823,7 +10888,7 @@ function findInnermostGraphEdge(graph, kind, key) {
10823
10888
  }
10824
10889
  }
10825
10890
  function escapeMermaid(text) {
10826
- return text.replace(/"/mg, "#quot;").replace(/\n/mg, " ");
10891
+ return text.replace(/"/mg, "#quot;").replace(/\n/mg, " ").replace(/</mg, "#lt;").replace(/>/mg, "#gt;");
10827
10892
  }
10828
10893
  function processNodeMermaid(graph, ctx, ctxL) {
10829
10894
  return gen(function* () {
@@ -11680,12 +11745,35 @@ var layerMagic = createRefactor({
11680
11745
  (_) => succeed((_.flags & ts.TypeFlags.Never) !== 0)
11681
11746
  );
11682
11747
  }
11683
- const typeReferences = pipe(
11748
+ const previouslyProvided = yield* pipe(
11749
+ typeParser.layerType(typeChecker.getTypeAtLocation(atLocation), atLocation),
11750
+ map3((_) => _.ROut),
11751
+ option
11752
+ );
11753
+ const [existingBefore, newlyIntroduced] = pipe(
11684
11754
  fromIterable(memory.values()),
11685
11755
  sort(typeCheckerUtils.deterministicTypeOrder),
11756
+ partition(
11757
+ (_) => isNone2(previouslyProvided) || typeChecker.isTypeAssignableTo(_, previouslyProvided.value)
11758
+ )
11759
+ );
11760
+ const typeReferences = pipe(
11761
+ newlyIntroduced,
11686
11762
  map5((_) => typeChecker.typeToTypeNode(_, void 0, ts.NodeBuilderFlags.NoTruncation)),
11687
11763
  filter((_) => !!_)
11688
11764
  );
11765
+ const providesUnion = typeReferences.length === 0 ? ts.factory.createTypeReferenceNode("never") : ts.factory.createUnionTypeNode(typeReferences);
11766
+ const typeStrings = pipe(
11767
+ existingBefore,
11768
+ map5((_) => typeChecker.typeToString(_, void 0, ts.TypeFormatFlags.NoTruncation)),
11769
+ filter((_) => !!_)
11770
+ );
11771
+ const unionWithComment = typeStrings.length === 0 ? providesUnion : ts.addSyntheticTrailingComment(
11772
+ providesUnion,
11773
+ ts.SyntaxKind.MultiLineCommentTrivia,
11774
+ " " + typeStrings.join(" | ") + " ",
11775
+ false
11776
+ );
11689
11777
  const newDeclaration = ts.factory.createAsExpression(
11690
11778
  ts.factory.createAsExpression(
11691
11779
  ts.factory.createArrayLiteralExpression(extractedLayers.map((_) => _.node)),
@@ -11693,9 +11781,7 @@ var layerMagic = createRefactor({
11693
11781
  ),
11694
11782
  ts.factory.createTypeReferenceNode(
11695
11783
  ts.factory.createQualifiedName(ts.factory.createIdentifier(layerIdentifier), "Layer"),
11696
- typeReferences.length === 0 ? [
11697
- ts.factory.createTypeReferenceNode("never")
11698
- ] : [ts.factory.createUnionTypeNode(typeReferences)]
11784
+ [unionWithComment]
11699
11785
  )
11700
11786
  );
11701
11787
  changeTracker.replaceNode(sourceFile, atLocation, newDeclaration, {
@@ -13063,6 +13149,7 @@ var renameKeyStrings = (sourceFile, position, _findInStrings, _findInComments, _
13063
13149
  const baseIdentifier = yield* pipe(
13064
13150
  map3(typeParser.extendsContextTag(parentClass), (_) => [_.keyStringLiteral]),
13065
13151
  orElse2(() => map3(typeParser.extendsEffectService(parentClass), (_) => [_.keyStringLiteral])),
13152
+ orElse2(() => map3(typeParser.extendsEffectTag(parentClass), (_) => [_.keyStringLiteral])),
13066
13153
  orElse2(
13067
13154
  () => map3(typeParser.extendsSchemaTaggedClass(parentClass), (_) => [_.keyStringLiteral, _.tagStringLiteral])
13068
13155
  ),