@effect/language-service 0.18.0 → 0.20.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/transform.js CHANGED
@@ -24,7 +24,7 @@ __export(transform_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(transform_exports);
26
26
 
27
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Function.js
27
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Function.js
28
28
  var isFunction = (input) => typeof input === "function";
29
29
  var dual = function(arity, body) {
30
30
  if (typeof arity === "function") {
@@ -118,11 +118,11 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
118
118
  }
119
119
  }
120
120
 
121
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/version.js
122
- var moduleVersion = "3.16.3";
121
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/version.js
122
+ var moduleVersion = "3.16.5";
123
123
  var getCurrentVersion = () => moduleVersion;
124
124
 
125
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/GlobalValue.js
125
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/GlobalValue.js
126
126
  var globalStoreId = `effect/GlobalValue/globalStoreId/${/* @__PURE__ */ getCurrentVersion()}`;
127
127
  var globalStore;
128
128
  var globalValue = (id, compute) => {
@@ -136,7 +136,7 @@ var globalValue = (id, compute) => {
136
136
  return globalStore.get(id);
137
137
  };
138
138
 
139
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Predicate.js
139
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Predicate.js
140
140
  var isString = (input) => typeof input === "string";
141
141
  var isNumber = (input) => typeof input === "number";
142
142
  var isBoolean = (input) => typeof input === "boolean";
@@ -145,10 +145,10 @@ var isRecordOrArray = (input) => typeof input === "object" && input !== null;
145
145
  var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
146
146
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
147
147
 
148
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/errors.js
148
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/errors.js
149
149
  var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
150
150
 
151
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Utils.js
151
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Utils.js
152
152
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
153
153
  var isGenKind = (u) => isObject(u) && GenKindTypeId in u;
154
154
  var GenKindImpl = class {
@@ -277,7 +277,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
277
277
  var genConstructor = function* () {
278
278
  }.constructor;
279
279
 
280
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Hash.js
280
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Hash.js
281
281
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
282
282
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
283
283
  var hash = (self) => {
@@ -376,7 +376,7 @@ var cached = function() {
376
376
  return hash2;
377
377
  };
378
378
 
379
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Equal.js
379
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Equal.js
380
380
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
381
381
  function equals() {
382
382
  if (arguments.length === 1) {
@@ -429,7 +429,7 @@ function compareBoth(self, that) {
429
429
  }
430
430
  var isEqual = (u) => hasProperty(u, symbol2);
431
431
 
432
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Inspectable.js
432
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Inspectable.js
433
433
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
434
434
  var toJSON = (x) => {
435
435
  try {
@@ -481,7 +481,7 @@ var redact = (u) => {
481
481
  return u;
482
482
  };
483
483
 
484
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Pipeable.js
484
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Pipeable.js
485
485
  var pipeArguments = (self, args) => {
486
486
  switch (args.length) {
487
487
  case 0:
@@ -514,10 +514,10 @@ var pipeArguments = (self, args) => {
514
514
  }
515
515
  };
516
516
 
517
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/opCodes/effect.js
517
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/opCodes/effect.js
518
518
  var OP_COMMIT = "Commit";
519
519
 
520
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/effectable.js
520
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/effectable.js
521
521
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
522
522
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
523
523
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -604,7 +604,7 @@ var StructuralCommitPrototype = {
604
604
  ...StructuralPrototype
605
605
  };
606
606
 
607
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/option.js
607
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/option.js
608
608
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
609
609
  var CommonProto = {
610
610
  ...EffectPrototype,
@@ -662,7 +662,7 @@ var some = (value) => {
662
662
  return a;
663
663
  };
664
664
 
665
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/internal/either.js
665
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/internal/either.js
666
666
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
667
667
  var CommonProto2 = {
668
668
  ...EffectPrototype,
@@ -724,7 +724,7 @@ var right = (right3) => {
724
724
  return a;
725
725
  };
726
726
 
727
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Either.js
727
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Either.js
728
728
  var right2 = right;
729
729
  var left2 = left;
730
730
  var isLeft2 = isLeft;
@@ -732,17 +732,25 @@ var isRight2 = isRight;
732
732
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
733
733
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
734
734
 
735
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Order.js
735
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Order.js
736
736
  var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
737
737
 
738
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Option.js
738
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Option.js
739
739
  var none2 = () => none;
740
740
  var some2 = some;
741
741
  var isNone2 = isNone;
742
742
  var isSome2 = isSome;
743
+ var match = /* @__PURE__ */ dual(2, (self, {
744
+ onNone,
745
+ onSome
746
+ }) => isNone2(self) ? onNone() : onSome(self.value));
747
+ var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
748
+ var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
743
749
 
744
- // node_modules/.pnpm/effect@3.16.3/node_modules/effect/dist/esm/Array.js
750
+ // node_modules/.pnpm/effect@3.16.5/node_modules/effect/dist/esm/Array.js
745
751
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
752
+ var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
753
+ var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
746
754
  var isArray = Array.isArray;
747
755
  var isEmptyArray = (self) => self.length === 0;
748
756
  var isEmptyReadonlyArray = isEmptyArray;
@@ -751,6 +759,7 @@ var sort = /* @__PURE__ */ dual(2, (self, O) => {
751
759
  out.sort(O);
752
760
  return out;
753
761
  });
762
+ var empty = () => [];
754
763
  var map2 = /* @__PURE__ */ dual(2, (self, f) => self.map(f));
755
764
  var flatMap = /* @__PURE__ */ dual(2, (self, f) => {
756
765
  if (isEmptyReadonlyArray(self)) {
@@ -858,7 +867,7 @@ var map3 = dual(2, (fa, f) => make2((ctx) => {
858
867
  if (result._tag !== "Right") return result;
859
868
  return makeInternalSuccess(f(result.value));
860
869
  }));
861
- var orElse = (f) => (fa) => make2((ctx) => {
870
+ var orElse2 = (f) => (fa) => make2((ctx) => {
862
871
  const result = fa.run(ctx);
863
872
  if (result._tag === "Left") return f(result.value).run(ctx);
864
873
  return result;
@@ -928,6 +937,27 @@ function parse(config) {
928
937
  var TypeScriptApi = Tag("TypeScriptApi");
929
938
  var TypeScriptProgram = Tag("TypeScriptProgram");
930
939
  var ChangeTracker = Tag("ChangeTracker");
940
+ function parsePackageContentNameAndVersionFromScope(v) {
941
+ if (!isObject(v)) return;
942
+ if (!hasProperty(v, "packageJsonScope")) return;
943
+ if (!v.packageJsonScope) return;
944
+ const packageJsonScope = v.packageJsonScope;
945
+ if (!hasProperty(packageJsonScope, "contents")) return;
946
+ if (!hasProperty(packageJsonScope.contents, "packageJsonContent")) return;
947
+ const packageJsonContent = packageJsonScope.contents.packageJsonContent;
948
+ if (!hasProperty(packageJsonContent, "name")) return;
949
+ if (!hasProperty(packageJsonContent, "version")) return;
950
+ const { name, version } = packageJsonContent;
951
+ if (!isString(name)) return;
952
+ if (!isString(version)) return;
953
+ const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
954
+ return {
955
+ name: name.toLowerCase(),
956
+ version: version.toLowerCase(),
957
+ hasEffectInPeerDependencies,
958
+ contents: packageJsonContent
959
+ };
960
+ }
931
961
 
932
962
  // src/core/LSP.ts
933
963
  var RefactorNotApplicableError = class {
@@ -1063,10 +1093,10 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1063
1093
  const sectionOverrides = {};
1064
1094
  const skippedRules = [];
1065
1095
  const regex = /@effect-diagnostics(-next-line)?((?:\s[a-zA-Z0-9/]+:(?:off|warning|error|message|suggestion|skip-file))+)?/gm;
1066
- let match;
1067
- while ((match = regex.exec(sourceFile.text)) !== null) {
1068
- const nextLineCaptureGroup = match[1];
1069
- const rulesCaptureGroup = match[2];
1096
+ let match2;
1097
+ while ((match2 = regex.exec(sourceFile.text)) !== null) {
1098
+ const nextLineCaptureGroup = match2[1];
1099
+ const rulesCaptureGroup = match2[2];
1070
1100
  if (rulesCaptureGroup) {
1071
1101
  const trimmedRuleString = rulesCaptureGroup.trim();
1072
1102
  if (trimmedRuleString) {
@@ -1078,7 +1108,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1078
1108
  if (ruleLevel === "skip-file") skippedRules.push(ruleName);
1079
1109
  const isOverrideNextLine = nextLineCaptureGroup && nextLineCaptureGroup.trim().toLowerCase() === "-next-line";
1080
1110
  if (isOverrideNextLine) {
1081
- const node = findNodeWithLeadingCommentAtPosition(match.index);
1111
+ const node = findNodeWithLeadingCommentAtPosition(match2.index);
1082
1112
  if (node) {
1083
1113
  lineOverrides[ruleName] = lineOverrides[ruleName] || [];
1084
1114
  lineOverrides[ruleName].unshift({
@@ -1090,7 +1120,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1090
1120
  } else {
1091
1121
  sectionOverrides[ruleName] = sectionOverrides[ruleName] || [];
1092
1122
  sectionOverrides[ruleName].unshift({
1093
- pos: match.index,
1123
+ pos: match2.index,
1094
1124
  level: ruleLevel
1095
1125
  });
1096
1126
  }
@@ -1376,31 +1406,55 @@ var expectedAndRealType = fn("TypeCheckerApi.expectedAndRealType")(function* (so
1376
1406
  cache.expectedAndRealType.set(sourceFile, result);
1377
1407
  return result;
1378
1408
  });
1409
+ var appendToUniqueTypesMap = fn(
1410
+ "TypeCheckerApi.appendToUniqueTypesMap"
1411
+ )(
1412
+ function* (memory, initialType, excludeNever) {
1413
+ const ts = yield* service(TypeScriptApi);
1414
+ const typeChecker = yield* service(TypeCheckerApi);
1415
+ const newIndexes = /* @__PURE__ */ new Set();
1416
+ const knownIndexes = /* @__PURE__ */ new Set();
1417
+ let toTest = [initialType];
1418
+ while (toTest.length > 0) {
1419
+ const type = toTest.pop();
1420
+ if (!type) break;
1421
+ if (excludeNever && type.flags & ts.TypeFlags.Never) {
1422
+ continue;
1423
+ }
1424
+ if (type.isUnion()) {
1425
+ toTest = toTest.concat(type.types);
1426
+ } else {
1427
+ const foundMatch = [];
1428
+ for (const [typeId, knownType] of memory.entries()) {
1429
+ const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
1430
+ if (areSame) {
1431
+ foundMatch.push(typeId);
1432
+ break;
1433
+ }
1434
+ }
1435
+ if (foundMatch.length === 0) {
1436
+ const newId = "t" + (memory.size + 1);
1437
+ memory.set(newId, type);
1438
+ newIndexes.add(newId);
1439
+ } else {
1440
+ knownIndexes.add(foundMatch[0]);
1441
+ }
1442
+ }
1443
+ }
1444
+ return {
1445
+ newIndexes,
1446
+ knownIndexes,
1447
+ allIndexes: pipe(
1448
+ fromIterable(newIndexes),
1449
+ appendAll(fromIterable(knownIndexes))
1450
+ )
1451
+ };
1452
+ }
1453
+ );
1379
1454
 
1380
1455
  // src/diagnostics/duplicatePackage.ts
1381
1456
  var checkedPackagesCache = /* @__PURE__ */ new Map();
1382
1457
  var programResolvedCacheSize = /* @__PURE__ */ new Map();
1383
- function parsePackageContentNameAndVersion(v) {
1384
- if (!isObject(v)) return;
1385
- if (!hasProperty(v, "packageJsonScope")) return;
1386
- if (!v.packageJsonScope) return;
1387
- const packageJsonScope = v.packageJsonScope;
1388
- if (!hasProperty(packageJsonScope, "contents")) return;
1389
- if (!hasProperty(packageJsonScope.contents, "packageJsonContent")) return;
1390
- const packageJsonContent = packageJsonScope.contents.packageJsonContent;
1391
- if (!hasProperty(packageJsonContent, "name")) return;
1392
- if (!hasProperty(packageJsonContent, "version")) return;
1393
- const { name, version } = packageJsonContent;
1394
- if (!isString(name)) return;
1395
- if (!isString(version)) return;
1396
- const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
1397
- return {
1398
- name: name.toLowerCase(),
1399
- version: version.toLowerCase(),
1400
- hasEffectInPeerDependencies,
1401
- contents: packageJsonContent
1402
- };
1403
- }
1404
1458
  var duplicatePackage = createDiagnostic({
1405
1459
  name: "duplicatePackage",
1406
1460
  code: 6,
@@ -1417,7 +1471,7 @@ var duplicatePackage = createDiagnostic({
1417
1471
  const seenPackages = /* @__PURE__ */ new Set();
1418
1472
  resolvedPackages = {};
1419
1473
  program.getSourceFiles().map((_) => {
1420
- const packageInfo = parsePackageContentNameAndVersion(_);
1474
+ const packageInfo = parsePackageContentNameAndVersionFromScope(_);
1421
1475
  if (!packageInfo) return;
1422
1476
  const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
1423
1477
  if (seenPackages.has(packageNameAndVersion)) return;
@@ -1447,6 +1501,361 @@ If this is intended set the LSP config "allowedDuplicatedPackages" to ${JSON.str
1447
1501
  })
1448
1502
  });
1449
1503
 
1504
+ // src/core/AST.ts
1505
+ function collectSelfAndAncestorNodesInRange(node, textRange) {
1506
+ return sync(() => {
1507
+ let result = empty();
1508
+ let parent = node;
1509
+ while (parent) {
1510
+ if (parent.end >= textRange.end) {
1511
+ result = pipe(result, append(parent));
1512
+ }
1513
+ parent = parent.parent;
1514
+ }
1515
+ return result;
1516
+ });
1517
+ }
1518
+ var getAncestorNodesInRange = fn("AST.getAncestorNodesInRange")(function* (sourceFile, textRange) {
1519
+ const nodeAtPosition = yield* option(findNodeAtPosition(sourceFile, textRange.pos));
1520
+ if (isNone2(nodeAtPosition)) return empty();
1521
+ return yield* collectSelfAndAncestorNodesInRange(nodeAtPosition.value, textRange);
1522
+ });
1523
+ var NodeNotFoundError = class {
1524
+ _tag = "@effect/language-service/NodeNotFoundError";
1525
+ };
1526
+ var findNodeAtPosition = fn("AST.findNodeAtPosition")(function* (sourceFile, position) {
1527
+ const ts = yield* service(TypeScriptApi);
1528
+ function find(node) {
1529
+ if (position >= node.getStart() && position < node.getEnd()) {
1530
+ return ts.forEachChild(node, find) || node;
1531
+ }
1532
+ return void 0;
1533
+ }
1534
+ const result = find(sourceFile);
1535
+ if (!result) return yield* fail(new NodeNotFoundError());
1536
+ return result;
1537
+ });
1538
+ var getCommentAtPosition = fn("TypeScriptApi.getCommentAtPosition")(function* (sourceFile, pos) {
1539
+ const ts = yield* service(TypeScriptApi);
1540
+ const token = yield* findNodeAtPosition(sourceFile, pos);
1541
+ if (token === void 0 || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || "").length) {
1542
+ return yield* fail(new NodeNotFoundError());
1543
+ }
1544
+ const startPos = token.pos === 0 ? (ts.getShebang(sourceFile.text) || "").length : token.pos;
1545
+ if (startPos === 0) return yield* fail(new NodeNotFoundError());
1546
+ const result = ts.forEachTrailingCommentRange(sourceFile.text, startPos, isCommentInRange, pos) || ts.forEachLeadingCommentRange(sourceFile.text, startPos, isCommentInRange, pos);
1547
+ if (!result) return yield* fail(new NodeNotFoundError());
1548
+ return result;
1549
+ });
1550
+ function isCommentInRange(pos, end, kind, _nl, at) {
1551
+ return at >= pos && at < end ? { pos, end, kind } : void 0;
1552
+ }
1553
+ var transformAsyncAwaitToEffectGen = fn("AST.transformAsyncAwaitToEffectGen")(
1554
+ function* (node, effectModuleName, onAwait) {
1555
+ const ts = yield* service(TypeScriptApi);
1556
+ function visitor(_) {
1557
+ if (ts.isAwaitExpression(_)) {
1558
+ const expression = ts.visitEachChild(_.expression, visitor, ts.nullTransformationContext);
1559
+ return ts.factory.createYieldExpression(
1560
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
1561
+ onAwait(expression)
1562
+ );
1563
+ }
1564
+ return ts.visitEachChild(_, visitor, ts.nullTransformationContext);
1565
+ }
1566
+ const generatorBody = visitor(node.body);
1567
+ const effectGenCallExp = yield* createEffectGenCallExpression(effectModuleName, generatorBody);
1568
+ let currentFlags = ts.getCombinedModifierFlags(node);
1569
+ currentFlags &= ~ts.ModifierFlags.Async;
1570
+ const newModifiers = ts.factory.createModifiersFromModifierFlags(currentFlags);
1571
+ if (ts.isArrowFunction(node)) {
1572
+ return ts.factory.createArrowFunction(
1573
+ newModifiers,
1574
+ node.typeParameters,
1575
+ node.parameters,
1576
+ void 0,
1577
+ node.equalsGreaterThanToken,
1578
+ effectGenCallExp
1579
+ );
1580
+ }
1581
+ const newBody = ts.factory.createBlock([
1582
+ ts.factory.createReturnStatement(effectGenCallExp)
1583
+ ]);
1584
+ if (ts.isFunctionDeclaration(node)) {
1585
+ return ts.factory.createFunctionDeclaration(
1586
+ newModifiers,
1587
+ node.asteriskToken,
1588
+ node.name,
1589
+ node.typeParameters,
1590
+ node.parameters,
1591
+ void 0,
1592
+ newBody
1593
+ );
1594
+ }
1595
+ return ts.factory.createFunctionExpression(
1596
+ newModifiers,
1597
+ node.asteriskToken,
1598
+ node.name,
1599
+ node.typeParameters,
1600
+ node.parameters,
1601
+ void 0,
1602
+ newBody
1603
+ );
1604
+ }
1605
+ );
1606
+ var addReturnTypeAnnotation = fn("AST.addReturnTypeAnnotation")(function* (sourceFile, declaration, typeNode) {
1607
+ const ts = yield* service(TypeScriptApi);
1608
+ const changes = yield* service(ChangeTracker);
1609
+ const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
1610
+ const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
1611
+ const endNode = needParens ? declaration.parameters[0] : closeParen;
1612
+ if (endNode) {
1613
+ if (needParens) {
1614
+ changes.insertNodeBefore(
1615
+ sourceFile,
1616
+ endNode,
1617
+ ts.factory.createToken(ts.SyntaxKind.OpenParenToken)
1618
+ );
1619
+ changes.insertNodeAfter(
1620
+ sourceFile,
1621
+ endNode,
1622
+ ts.factory.createToken(ts.SyntaxKind.CloseParenToken)
1623
+ );
1624
+ }
1625
+ changes.insertNodeAt(sourceFile, endNode.end, typeNode, { prefix: ": " });
1626
+ }
1627
+ });
1628
+ var removeReturnTypeAnnotation = fn("AST.removeReturnTypeAnnotation")(function* (sourceFile, declaration) {
1629
+ const ts = yield* service(TypeScriptApi);
1630
+ const changes = yield* service(ChangeTracker);
1631
+ const closeParen = ts.findChildOfKind(declaration, ts.SyntaxKind.CloseParenToken, sourceFile);
1632
+ const needParens = ts.isArrowFunction(declaration) && closeParen === void 0;
1633
+ const endNode = needParens ? declaration.parameters[0] : closeParen;
1634
+ if (endNode && declaration.type) {
1635
+ changes.deleteRange(sourceFile, { pos: endNode.end, end: declaration.type.end });
1636
+ }
1637
+ });
1638
+ var ImportModuleIdentifierNotFoundError = class {
1639
+ _tag = "@effect/language-service/ImportModuleIdentifierNotFoundError";
1640
+ };
1641
+ var findImportedModuleIdentifier = fn("AST.findImportedModuleIdentifier")(
1642
+ function* (sourceFile, test) {
1643
+ const ts = yield* service(TypeScriptApi);
1644
+ for (const statement of sourceFile.statements) {
1645
+ if (!ts.isImportDeclaration(statement)) continue;
1646
+ const importClause = statement.importClause;
1647
+ if (!importClause) continue;
1648
+ const namedBindings = importClause.namedBindings;
1649
+ if (!namedBindings) continue;
1650
+ if (ts.isNamespaceImport(namedBindings)) {
1651
+ if (yield* test(namedBindings.name, statement.moduleSpecifier, none2())) {
1652
+ return namedBindings.name;
1653
+ }
1654
+ } else if (ts.isNamedImports(namedBindings)) {
1655
+ for (const importSpecifier of namedBindings.elements) {
1656
+ const importProperty = fromNullable(importSpecifier.propertyName).pipe(
1657
+ orElse(() => some2(importSpecifier.name))
1658
+ );
1659
+ if (yield* test(importSpecifier.name, statement.moduleSpecifier, importProperty)) {
1660
+ return importSpecifier.name;
1661
+ }
1662
+ }
1663
+ }
1664
+ }
1665
+ return yield* fail(new ImportModuleIdentifierNotFoundError());
1666
+ }
1667
+ );
1668
+ function findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, packageName, moduleName) {
1669
+ return findImportedModuleIdentifier(
1670
+ sourceFile,
1671
+ fn(
1672
+ "AST.findImportedModuleIdentifierByPackageAndNameOrBarrel.findImportedModuleIdentifier"
1673
+ )(function* (_, fromModule, importProperty) {
1674
+ const ts = yield* service(TypeScriptApi);
1675
+ if (isNone2(importProperty) && ts.isStringLiteral(fromModule) && fromModule.text === packageName + "/" + moduleName) {
1676
+ return true;
1677
+ }
1678
+ if (isSome2(importProperty) && ts.isIdentifier(importProperty.value) && importProperty.value.text === moduleName && ts.isStringLiteral(fromModule) && fromModule.text === packageName) {
1679
+ return true;
1680
+ }
1681
+ return false;
1682
+ })
1683
+ );
1684
+ }
1685
+ var simplifyTypeNode = fn("AST.simplifyTypeNode")(function* (typeNode) {
1686
+ const ts = yield* service(TypeScriptApi);
1687
+ function collectCallable(typeNode2) {
1688
+ if (ts.isParenthesizedTypeNode(typeNode2)) return collectCallable(typeNode2.type);
1689
+ if (ts.isFunctionTypeNode(typeNode2)) {
1690
+ return some2([
1691
+ ts.factory.createCallSignature(typeNode2.typeParameters, typeNode2.parameters, typeNode2.type)
1692
+ ]);
1693
+ }
1694
+ if (ts.isTypeLiteralNode(typeNode2)) {
1695
+ const allCallSignatures = typeNode2.members.every(ts.isCallSignatureDeclaration);
1696
+ if (allCallSignatures) {
1697
+ return some2(typeNode2.members);
1698
+ }
1699
+ }
1700
+ if (ts.isIntersectionTypeNode(typeNode2)) {
1701
+ const members = typeNode2.types.map((node) => collectCallable(node));
1702
+ if (members.every(isSome2)) {
1703
+ return some2(members.map((_) => isSome2(_) ? _.value : []).flat());
1704
+ }
1705
+ }
1706
+ return none2();
1707
+ }
1708
+ const callSignatures = collectCallable(typeNode);
1709
+ if (isSome2(callSignatures) && callSignatures.value.length > 1) {
1710
+ return ts.factory.createTypeLiteralNode(callSignatures.value);
1711
+ }
1712
+ return typeNode;
1713
+ });
1714
+ var tryPreserveDeclarationSemantics = fn("AST.tryPreserveDeclarationSemantics")(
1715
+ function* (nodeToReplace, node) {
1716
+ const ts = yield* service(TypeScriptApi);
1717
+ if (!ts.isExpression(node)) return node;
1718
+ if (ts.isFunctionDeclaration(nodeToReplace)) {
1719
+ if (!nodeToReplace.name) return node;
1720
+ return ts.factory.createVariableStatement(
1721
+ nodeToReplace.modifiers,
1722
+ ts.factory.createVariableDeclarationList(
1723
+ [ts.factory.createVariableDeclaration(
1724
+ nodeToReplace.name,
1725
+ void 0,
1726
+ void 0,
1727
+ node
1728
+ )],
1729
+ ts.NodeFlags.Const
1730
+ )
1731
+ );
1732
+ } else if (ts.isMethodDeclaration(nodeToReplace)) {
1733
+ return ts.factory.createPropertyDeclaration(
1734
+ nodeToReplace.modifiers,
1735
+ nodeToReplace.name,
1736
+ void 0,
1737
+ void 0,
1738
+ node
1739
+ );
1740
+ }
1741
+ return node;
1742
+ }
1743
+ );
1744
+ var parseAccessedExpressionForCompletion = fn(
1745
+ "AST.parseAccessedExpressionForCompletion"
1746
+ )(
1747
+ function* (sourceFile, position) {
1748
+ const ts = yield* service(TypeScriptApi);
1749
+ const precedingToken = ts.findPrecedingToken(position, sourceFile, void 0, true);
1750
+ if (!precedingToken) return yield* fail(new NodeNotFoundError());
1751
+ let accessedObject = precedingToken;
1752
+ let replacementSpan = ts.createTextSpan(position, 0);
1753
+ let outerNode = precedingToken;
1754
+ if (ts.isIdentifier(precedingToken) && precedingToken.parent && ts.isPropertyAccessExpression(precedingToken.parent)) {
1755
+ replacementSpan = ts.createTextSpan(
1756
+ precedingToken.parent.getStart(sourceFile),
1757
+ precedingToken.end - precedingToken.parent.getStart(sourceFile)
1758
+ );
1759
+ accessedObject = precedingToken.parent.expression;
1760
+ outerNode = precedingToken.parent;
1761
+ } else if (ts.isToken(precedingToken) && precedingToken.kind === ts.SyntaxKind.DotToken && ts.isPropertyAccessExpression(precedingToken.parent)) {
1762
+ replacementSpan = ts.createTextSpan(
1763
+ precedingToken.parent.getStart(sourceFile),
1764
+ precedingToken.end - precedingToken.parent.getStart(sourceFile)
1765
+ );
1766
+ accessedObject = precedingToken.parent.expression;
1767
+ outerNode = precedingToken.parent;
1768
+ } else if (ts.isIdentifier(precedingToken) && precedingToken.parent) {
1769
+ replacementSpan = ts.createTextSpan(
1770
+ precedingToken.getStart(sourceFile),
1771
+ precedingToken.end - precedingToken.getStart(sourceFile)
1772
+ );
1773
+ accessedObject = precedingToken;
1774
+ outerNode = precedingToken;
1775
+ } else {
1776
+ return yield* fail(new NodeNotFoundError());
1777
+ }
1778
+ return { accessedObject, outerNode, replacementSpan };
1779
+ }
1780
+ );
1781
+ var parseDataForExtendsClassCompletion = fn(
1782
+ "AST.parseDataForExtendsClassCompletion"
1783
+ )(function* (sourceFile, position) {
1784
+ const ts = yield* service(TypeScriptApi);
1785
+ const { accessedObject, outerNode, replacementSpan } = yield* parseAccessedExpressionForCompletion(
1786
+ sourceFile,
1787
+ position
1788
+ );
1789
+ if (!ts.isIdentifier(accessedObject)) return yield* fail(new NodeNotFoundError());
1790
+ let classDeclaration = outerNode.parent;
1791
+ while (ts.isExpressionWithTypeArguments(classDeclaration) || ts.isHeritageClause(classDeclaration)) {
1792
+ if (!classDeclaration.parent) break;
1793
+ classDeclaration = classDeclaration.parent;
1794
+ }
1795
+ if (!ts.isClassDeclaration(classDeclaration)) return yield* fail(new NodeNotFoundError());
1796
+ if (!classDeclaration.name) return yield* fail(new NodeNotFoundError());
1797
+ return {
1798
+ accessedObject,
1799
+ classDeclaration,
1800
+ className: classDeclaration.name,
1801
+ replacementSpan
1802
+ };
1803
+ });
1804
+ var createEffectGenCallExpression = fn("AST.createEffectGenCallExpression")(function* (effectModuleIdentifierName, node) {
1805
+ const ts = yield* service(TypeScriptApi);
1806
+ const generator = ts.factory.createFunctionExpression(
1807
+ void 0,
1808
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
1809
+ void 0,
1810
+ [],
1811
+ [],
1812
+ void 0,
1813
+ node
1814
+ // NOTE(mattia): intended, to use same routine for both ConciseBody and Body
1815
+ );
1816
+ return ts.factory.createCallExpression(
1817
+ ts.factory.createPropertyAccessExpression(
1818
+ ts.factory.createIdentifier(effectModuleIdentifierName),
1819
+ "gen"
1820
+ ),
1821
+ void 0,
1822
+ [generator]
1823
+ );
1824
+ });
1825
+ var createEffectGenCallExpressionWithBlock = fn(
1826
+ "AST.createEffectGenCallExpressionWithBlock"
1827
+ )(function* (effectModuleIdentifierName, statement) {
1828
+ const ts = yield* service(TypeScriptApi);
1829
+ return yield* createEffectGenCallExpression(
1830
+ effectModuleIdentifierName,
1831
+ ts.factory.createBlock(Array.isArray(statement) ? statement : [statement], false)
1832
+ );
1833
+ });
1834
+ var createReturnYieldStarStatement = fn("AST.createReturnYieldStarStatement")(
1835
+ function* (expr) {
1836
+ const ts = yield* service(TypeScriptApi);
1837
+ return ts.factory.createReturnStatement(
1838
+ ts.factory.createYieldExpression(
1839
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
1840
+ expr
1841
+ )
1842
+ );
1843
+ }
1844
+ );
1845
+ var parsePipeCall = fn("AST.parsePipeCall")(
1846
+ function* (node) {
1847
+ const ts = yield* service(TypeScriptApi);
1848
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && node.expression.name.text === "pipe") {
1849
+ return { node, subject: node.expression.expression, args: node.arguments };
1850
+ }
1851
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "pipe" && node.arguments.length > 0) {
1852
+ const [subject, ...args] = node.arguments;
1853
+ return { node, subject, args };
1854
+ }
1855
+ return yield* fail(new NodeNotFoundError());
1856
+ }
1857
+ );
1858
+
1450
1859
  // src/utils/TypeParser.ts
1451
1860
  var TypeParserIssue = class {
1452
1861
  constructor(type, node, message) {
@@ -1466,6 +1875,13 @@ function covariantTypeArgument(type) {
1466
1875
  }
1467
1876
  return succeed(signatures[0].getReturnType());
1468
1877
  }
1878
+ function contravariantTypeArgument(type) {
1879
+ const signatures = type.getCallSignatures();
1880
+ if (signatures.length !== 1) {
1881
+ return typeParserIssue("Contravariant type has no call signature", type);
1882
+ }
1883
+ return succeed(signatures[0].getTypeParameterAtPosition(0));
1884
+ }
1469
1885
  function invariantTypeArgument(type) {
1470
1886
  const signatures = type.getCallSignatures();
1471
1887
  if (signatures.length !== 1) {
@@ -1497,6 +1913,19 @@ var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
1497
1913
  return yield* covariantTypeArgument(propertyType);
1498
1914
  }
1499
1915
  );
1916
+ var varianceStructContravariantType = fn(
1917
+ "TypeParser.varianceStructContravariantType"
1918
+ )(
1919
+ function* (type, atLocation, propertyName) {
1920
+ const typeChecker = yield* service(TypeCheckerApi);
1921
+ const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
1922
+ if (!propertySymbol) {
1923
+ return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
1924
+ }
1925
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
1926
+ return yield* contravariantTypeArgument(propertyType);
1927
+ }
1928
+ );
1500
1929
  var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
1501
1930
  function* (type, atLocation, propertyName) {
1502
1931
  const typeChecker = yield* service(TypeCheckerApi);
@@ -1515,6 +1944,13 @@ var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type
1515
1944
  R: yield* varianceStructCovariantType(type, atLocation, "_R")
1516
1945
  };
1517
1946
  });
1947
+ var layerVarianceStruct = fn("TypeParser.layerVarianceStruct")(function* (type, atLocation) {
1948
+ return {
1949
+ ROut: yield* varianceStructContravariantType(type, atLocation, "_ROut"),
1950
+ E: yield* varianceStructCovariantType(type, atLocation, "_E"),
1951
+ RIn: yield* varianceStructCovariantType(type, atLocation, "_RIn")
1952
+ };
1953
+ });
1518
1954
  var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
1519
1955
  const ts = yield* service(TypeScriptApi);
1520
1956
  const typeChecker = yield* service(TypeCheckerApi);
@@ -1535,6 +1971,26 @@ var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
1535
1971
  }
1536
1972
  return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
1537
1973
  });
1974
+ var layerType = fn("TypeParser.layerType")(function* (type, atLocation) {
1975
+ const ts = yield* service(TypeScriptApi);
1976
+ const typeChecker = yield* service(TypeCheckerApi);
1977
+ yield* pipeableType(type, atLocation);
1978
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
1979
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
1980
+ );
1981
+ propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
1982
+ for (const propertySymbol of propertiesSymbols) {
1983
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
1984
+ const varianceArgs = yield* option(layerVarianceStruct(
1985
+ propertyType,
1986
+ atLocation
1987
+ ));
1988
+ if (isSome2(varianceArgs)) {
1989
+ return varianceArgs.value;
1990
+ }
1991
+ }
1992
+ return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
1993
+ });
1538
1994
  var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
1539
1995
  const typeChecker = yield* service(TypeCheckerApi);
1540
1996
  const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
@@ -1700,19 +2156,68 @@ var effectFnGen = fn("TypeParser.effectFnGen")(function* (node) {
1700
2156
  functionStar: generatorFunction.getFirstToken()
1701
2157
  };
1702
2158
  });
1703
- var returnYieldEffectBlock = fn("TypeParser.returnYieldEffectBlock")(function* (body) {
2159
+ var unnecessaryEffectGen = fn("TypeParser.unnecessaryEffectGen")(function* (node) {
1704
2160
  const ts = yield* service(TypeScriptApi);
1705
2161
  const typeChecker = yield* service(TypeCheckerApi);
1706
- if (ts.isBlock(body) && body.statements.length === 1 && ts.isReturnStatement(body.statements[0]) && body.statements[0].expression && ts.isYieldExpression(body.statements[0].expression) && body.statements[0].expression.expression) {
1707
- const nodeToCheck = body.statements[0].expression.expression;
1708
- const type = typeChecker.getTypeAtLocation(nodeToCheck);
1709
- yield* effectType(type, nodeToCheck);
1710
- return nodeToCheck;
2162
+ const { body } = yield* effectGen(node);
2163
+ if (body.statements.length !== 1) {
2164
+ return yield* typeParserIssue(
2165
+ "Generator body should have a single statement",
2166
+ void 0,
2167
+ node
2168
+ );
2169
+ }
2170
+ let explicitReturn = false;
2171
+ let nodeToCheck = body.statements[0];
2172
+ while (nodeToCheck) {
2173
+ if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
2174
+ nodeToCheck = nodeToCheck.expression;
2175
+ explicitReturn = true;
2176
+ continue;
2177
+ }
2178
+ if (ts.isExpressionStatement(nodeToCheck)) {
2179
+ nodeToCheck = nodeToCheck.expression;
2180
+ continue;
2181
+ }
2182
+ if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
2183
+ const yieldedExpression = nodeToCheck.expression;
2184
+ const type = typeChecker.getTypeAtLocation(yieldedExpression);
2185
+ const { A: successType } = yield* effectType(type, yieldedExpression);
2186
+ let replacementNode = succeed(yieldedExpression);
2187
+ if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
2188
+ replacementNode = pipe(
2189
+ gen(function* () {
2190
+ const effectIdentifier = pipe(
2191
+ yield* option(
2192
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(node.getSourceFile(), "effect", "Effect")
2193
+ ),
2194
+ match({
2195
+ onNone: () => "Effect",
2196
+ onSome: (_) => _.text
2197
+ })
2198
+ );
2199
+ return ts.factory.createCallExpression(
2200
+ ts.factory.createPropertyAccessExpression(
2201
+ ts.factory.createIdentifier(effectIdentifier),
2202
+ "asVoid"
2203
+ ),
2204
+ void 0,
2205
+ [
2206
+ yieldedExpression
2207
+ ]
2208
+ );
2209
+ }),
2210
+ provideService(TypeScriptApi, ts)
2211
+ );
2212
+ }
2213
+ return { node, body, yieldedExpression, replacementNode };
2214
+ }
2215
+ break;
1711
2216
  }
1712
2217
  return yield* typeParserIssue(
1713
- "Node is not a return statement with a yield expression",
2218
+ "Not an handled node",
1714
2219
  void 0,
1715
- body
2220
+ node
1716
2221
  );
1717
2222
  });
1718
2223
  var effectSchemaVarianceStruct = fn("TypeParser.effectSchemaVarianceStruct")(
@@ -1777,7 +2282,7 @@ var floatingEffect = createDiagnostic({
1777
2282
  if (isSome2(effect)) {
1778
2283
  const allowedFloatingEffects = yield* pipe(
1779
2284
  fiberType(type, node.expression),
1780
- orElse(() => effectSubtype(type, node.expression)),
2285
+ orElse2(() => effectSubtype(type, node.expression)),
1781
2286
  option
1782
2287
  );
1783
2288
  if (isNone2(allowedFloatingEffects)) {
@@ -1829,7 +2334,7 @@ var missingEffectContext = createDiagnostic({
1829
2334
  valueNode,
1830
2335
  realType
1831
2336
  ),
1832
- orElse(() => succeed([]))
2337
+ orElse2(() => succeed([]))
1833
2338
  );
1834
2339
  if (missingContext.length > 0) {
1835
2340
  effectDiagnostics.push(
@@ -1881,7 +2386,7 @@ var missingEffectError = createDiagnostic({
1881
2386
  valueNode,
1882
2387
  realType
1883
2388
  ),
1884
- orElse(() => succeed([]))
2389
+ orElse2(() => succeed([]))
1885
2390
  );
1886
2391
  if (missingContext.length > 0) {
1887
2392
  effectDiagnostics.push(
@@ -1898,6 +2403,75 @@ var missingEffectError = createDiagnostic({
1898
2403
  })
1899
2404
  });
1900
2405
 
2406
+ // src/diagnostics/missingReturnYieldStar.ts
2407
+ var missingReturnYieldStar = createDiagnostic({
2408
+ name: "missingReturnYieldStar",
2409
+ code: 7,
2410
+ apply: fn("missingReturnYieldStar.apply")(function* (sourceFile) {
2411
+ const ts = yield* service(TypeScriptApi);
2412
+ const typeChecker = yield* service(TypeCheckerApi);
2413
+ const effectDiagnostics = [];
2414
+ const brokenYields = /* @__PURE__ */ new Set();
2415
+ const nodeToVisit = [];
2416
+ const appendNodeToVisit = (node) => {
2417
+ nodeToVisit.push(node);
2418
+ return void 0;
2419
+ };
2420
+ ts.forEachChild(sourceFile, appendNodeToVisit);
2421
+ while (nodeToVisit.length > 0) {
2422
+ const node = nodeToVisit.shift();
2423
+ ts.forEachChild(node, appendNodeToVisit);
2424
+ if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
2425
+ const type = typeChecker.getTypeAtLocation(node.expression);
2426
+ const maybeEffect = yield* option(effectType(type, node.expression));
2427
+ if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
2428
+ const generatorFunctionOrReturnStatement = ts.findAncestor(
2429
+ node,
2430
+ (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_)
2431
+ );
2432
+ if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement)) {
2433
+ if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
2434
+ const effectGenNode = generatorFunctionOrReturnStatement.parent;
2435
+ const effectGenLike = yield* pipe(
2436
+ effectGen(effectGenNode),
2437
+ orElse2(() => effectFnUntracedGen(effectGenNode)),
2438
+ orElse2(() => effectFnGen(effectGenNode)),
2439
+ option
2440
+ );
2441
+ if (isSome2(effectGenLike)) {
2442
+ brokenYields.add(node);
2443
+ }
2444
+ }
2445
+ }
2446
+ }
2447
+ }
2448
+ }
2449
+ brokenYields.forEach((node) => {
2450
+ const fix = node.expression ? [{
2451
+ fixName: "missingReturnYieldStar_fix",
2452
+ description: "Add return statement",
2453
+ apply: gen(function* () {
2454
+ const changeTracker = yield* service(ChangeTracker);
2455
+ changeTracker.replaceNode(
2456
+ sourceFile,
2457
+ node,
2458
+ ts.factory.createReturnStatement(
2459
+ node
2460
+ )
2461
+ );
2462
+ })
2463
+ }] : [];
2464
+ effectDiagnostics.push({
2465
+ node,
2466
+ category: ts.DiagnosticCategory.Error,
2467
+ messageText: `Yielded Effect never completes, so it is best to use a 'return yield*' instead.`,
2468
+ fixes: fix
2469
+ });
2470
+ });
2471
+ return effectDiagnostics;
2472
+ })
2473
+ });
2474
+
1901
2475
  // src/diagnostics/missingStarInYieldEffectGen.ts
1902
2476
  var missingStarInYieldEffectGen = createDiagnostic({
1903
2477
  name: "missingStarInYieldEffectGen",
@@ -1925,8 +2499,8 @@ var missingStarInYieldEffectGen = createDiagnostic({
1925
2499
  const effectGenNode = functionStarNode.parent;
1926
2500
  const effectGenLike = yield* pipe(
1927
2501
  effectGen(effectGenNode),
1928
- orElse(() => effectFnUntracedGen(effectGenNode)),
1929
- orElse(() => effectFnGen(effectGenNode)),
2502
+ orElse2(() => effectFnUntracedGen(effectGenNode)),
2503
+ orElse2(() => effectFnGen(effectGenNode)),
1930
2504
  option
1931
2505
  );
1932
2506
  if (isSome2(effectGenLike)) {
@@ -1974,7 +2548,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
1974
2548
  });
1975
2549
 
1976
2550
  // src/diagnostics/unnecessaryEffectGen.ts
1977
- var unnecessaryEffectGen = createDiagnostic({
2551
+ var unnecessaryEffectGen2 = createDiagnostic({
1978
2552
  name: "unnecessaryEffectGen",
1979
2553
  code: 5,
1980
2554
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
@@ -1990,13 +2564,9 @@ var unnecessaryEffectGen = createDiagnostic({
1990
2564
  while (nodeToVisit.length > 0) {
1991
2565
  const node = nodeToVisit.shift();
1992
2566
  ts.forEachChild(node, appendNodeToVisit);
1993
- const maybeNode = yield* pipe(
1994
- effectGen(node),
1995
- flatMap2(({ body }) => returnYieldEffectBlock(body)),
1996
- option
1997
- );
2567
+ const maybeNode = yield* option(unnecessaryEffectGen(node));
1998
2568
  if (isSome2(maybeNode)) {
1999
- unnecessaryGenerators.set(node, maybeNode.value);
2569
+ unnecessaryGenerators.set(node, maybeNode.value.replacementNode);
2000
2570
  }
2001
2571
  }
2002
2572
  unnecessaryGenerators.forEach(
@@ -2011,7 +2581,7 @@ var unnecessaryEffectGen = createDiagnostic({
2011
2581
  const textChanges = yield* service(
2012
2582
  ChangeTracker
2013
2583
  );
2014
- textChanges.replaceNode(sourceFile, effectGenCall, yieldedResult);
2584
+ textChanges.replaceNode(sourceFile, effectGenCall, yield* yieldedResult);
2015
2585
  })
2016
2586
  }]
2017
2587
  })
@@ -2027,7 +2597,8 @@ var diagnostics = [
2027
2597
  missingEffectError,
2028
2598
  floatingEffect,
2029
2599
  missingStarInYieldEffectGen,
2030
- unnecessaryEffectGen
2600
+ unnecessaryEffectGen2,
2601
+ missingReturnYieldStar
2031
2602
  ];
2032
2603
 
2033
2604
  // src/transform.ts