@effect/language-service 0.18.0 → 0.19.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
@@ -740,9 +740,17 @@ 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
750
  // node_modules/.pnpm/effect@3.16.3/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;
@@ -1063,10 +1072,10 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1063
1072
  const sectionOverrides = {};
1064
1073
  const skippedRules = [];
1065
1074
  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];
1075
+ let match2;
1076
+ while ((match2 = regex.exec(sourceFile.text)) !== null) {
1077
+ const nextLineCaptureGroup = match2[1];
1078
+ const rulesCaptureGroup = match2[2];
1070
1079
  if (rulesCaptureGroup) {
1071
1080
  const trimmedRuleString = rulesCaptureGroup.trim();
1072
1081
  if (trimmedRuleString) {
@@ -1078,7 +1087,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1078
1087
  if (ruleLevel === "skip-file") skippedRules.push(ruleName);
1079
1088
  const isOverrideNextLine = nextLineCaptureGroup && nextLineCaptureGroup.trim().toLowerCase() === "-next-line";
1080
1089
  if (isOverrideNextLine) {
1081
- const node = findNodeWithLeadingCommentAtPosition(match.index);
1090
+ const node = findNodeWithLeadingCommentAtPosition(match2.index);
1082
1091
  if (node) {
1083
1092
  lineOverrides[ruleName] = lineOverrides[ruleName] || [];
1084
1093
  lineOverrides[ruleName].unshift({
@@ -1090,7 +1099,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
1090
1099
  } else {
1091
1100
  sectionOverrides[ruleName] = sectionOverrides[ruleName] || [];
1092
1101
  sectionOverrides[ruleName].unshift({
1093
- pos: match.index,
1102
+ pos: match2.index,
1094
1103
  level: ruleLevel
1095
1104
  });
1096
1105
  }
@@ -1376,6 +1385,51 @@ var expectedAndRealType = fn("TypeCheckerApi.expectedAndRealType")(function* (so
1376
1385
  cache.expectedAndRealType.set(sourceFile, result);
1377
1386
  return result;
1378
1387
  });
1388
+ var appendToUniqueTypesMap = fn(
1389
+ "TypeCheckerApi.appendToUniqueTypesMap"
1390
+ )(
1391
+ function* (memory, initialType, excludeNever) {
1392
+ const ts = yield* service(TypeScriptApi);
1393
+ const typeChecker = yield* service(TypeCheckerApi);
1394
+ const newIndexes = /* @__PURE__ */ new Set();
1395
+ const knownIndexes = /* @__PURE__ */ new Set();
1396
+ let toTest = [initialType];
1397
+ while (toTest.length > 0) {
1398
+ const type = toTest.pop();
1399
+ if (!type) break;
1400
+ if (excludeNever && type.flags & ts.TypeFlags.Never) {
1401
+ continue;
1402
+ }
1403
+ if (type.isUnion()) {
1404
+ toTest = toTest.concat(type.types);
1405
+ } else {
1406
+ const foundMatch = [];
1407
+ for (const [typeId, knownType] of memory.entries()) {
1408
+ const areSame = typeChecker.isTypeAssignableTo(knownType, type) && typeChecker.isTypeAssignableTo(type, knownType);
1409
+ if (areSame) {
1410
+ foundMatch.push(typeId);
1411
+ break;
1412
+ }
1413
+ }
1414
+ if (foundMatch.length === 0) {
1415
+ const newId = "t" + (memory.size + 1);
1416
+ memory.set(newId, type);
1417
+ newIndexes.add(newId);
1418
+ } else {
1419
+ knownIndexes.add(foundMatch[0]);
1420
+ }
1421
+ }
1422
+ }
1423
+ return {
1424
+ newIndexes,
1425
+ knownIndexes,
1426
+ allIndexes: pipe(
1427
+ fromIterable(newIndexes),
1428
+ appendAll(fromIterable(knownIndexes))
1429
+ )
1430
+ };
1431
+ }
1432
+ );
1379
1433
 
1380
1434
  // src/diagnostics/duplicatePackage.ts
1381
1435
  var checkedPackagesCache = /* @__PURE__ */ new Map();
@@ -1447,6 +1501,348 @@ 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
+
1450
1846
  // src/utils/TypeParser.ts
1451
1847
  var TypeParserIssue = class {
1452
1848
  constructor(type, node, message) {
@@ -1466,6 +1862,13 @@ function covariantTypeArgument(type) {
1466
1862
  }
1467
1863
  return succeed(signatures[0].getReturnType());
1468
1864
  }
1865
+ function contravariantTypeArgument(type) {
1866
+ const signatures = type.getCallSignatures();
1867
+ if (signatures.length !== 1) {
1868
+ return typeParserIssue("Contravariant type has no call signature", type);
1869
+ }
1870
+ return succeed(signatures[0].getTypeParameterAtPosition(0));
1871
+ }
1469
1872
  function invariantTypeArgument(type) {
1470
1873
  const signatures = type.getCallSignatures();
1471
1874
  if (signatures.length !== 1) {
@@ -1497,6 +1900,19 @@ var varianceStructCovariantType = fn("TypeParser.varianceStructCovariantType")(
1497
1900
  return yield* covariantTypeArgument(propertyType);
1498
1901
  }
1499
1902
  );
1903
+ var varianceStructContravariantType = fn(
1904
+ "TypeParser.varianceStructContravariantType"
1905
+ )(
1906
+ function* (type, atLocation, propertyName) {
1907
+ const typeChecker = yield* service(TypeCheckerApi);
1908
+ const propertySymbol = typeChecker.getPropertyOfType(type, propertyName);
1909
+ if (!propertySymbol) {
1910
+ return yield* typeParserIssue(`Type has no '${propertyName}' property`, type, atLocation);
1911
+ }
1912
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
1913
+ return yield* contravariantTypeArgument(propertyType);
1914
+ }
1915
+ );
1500
1916
  var varianceStructInvariantType = fn("TypeParser.varianceStructInvariantType")(
1501
1917
  function* (type, atLocation, propertyName) {
1502
1918
  const typeChecker = yield* service(TypeCheckerApi);
@@ -1515,6 +1931,13 @@ var effectVarianceStruct = fn("TypeParser.effectVarianceStruct")(function* (type
1515
1931
  R: yield* varianceStructCovariantType(type, atLocation, "_R")
1516
1932
  };
1517
1933
  });
1934
+ var layerVarianceStruct = fn("TypeParser.layerVarianceStruct")(function* (type, atLocation) {
1935
+ return {
1936
+ ROut: yield* varianceStructContravariantType(type, atLocation, "_ROut"),
1937
+ E: yield* varianceStructCovariantType(type, atLocation, "_E"),
1938
+ RIn: yield* varianceStructCovariantType(type, atLocation, "_RIn")
1939
+ };
1940
+ });
1518
1941
  var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
1519
1942
  const ts = yield* service(TypeScriptApi);
1520
1943
  const typeChecker = yield* service(TypeCheckerApi);
@@ -1535,6 +1958,26 @@ var effectType = fn("TypeParser.effectType")(function* (type, atLocation) {
1535
1958
  }
1536
1959
  return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
1537
1960
  });
1961
+ var layerType = fn("TypeParser.layerType")(function* (type, atLocation) {
1962
+ const ts = yield* service(TypeScriptApi);
1963
+ const typeChecker = yield* service(TypeCheckerApi);
1964
+ yield* pipeableType(type, atLocation);
1965
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
1966
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional)
1967
+ );
1968
+ propertiesSymbols.sort((a, b) => b.name.indexOf("LayerTypeId") - a.name.indexOf("LayerTypeId"));
1969
+ for (const propertySymbol of propertiesSymbols) {
1970
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
1971
+ const varianceArgs = yield* option(layerVarianceStruct(
1972
+ propertyType,
1973
+ atLocation
1974
+ ));
1975
+ if (isSome2(varianceArgs)) {
1976
+ return varianceArgs.value;
1977
+ }
1978
+ }
1979
+ return yield* typeParserIssue("Type has no layer variance struct", type, atLocation);
1980
+ });
1538
1981
  var fiberType = fn("TypeParser.fiberType")(function* (type, atLocation) {
1539
1982
  const typeChecker = yield* service(TypeCheckerApi);
1540
1983
  const awaitSymbol = typeChecker.getPropertyOfType(type, "await");
@@ -1700,19 +2143,68 @@ var effectFnGen = fn("TypeParser.effectFnGen")(function* (node) {
1700
2143
  functionStar: generatorFunction.getFirstToken()
1701
2144
  };
1702
2145
  });
1703
- var returnYieldEffectBlock = fn("TypeParser.returnYieldEffectBlock")(function* (body) {
2146
+ var unnecessaryEffectGen = fn("TypeParser.unnecessaryEffectGen")(function* (node) {
1704
2147
  const ts = yield* service(TypeScriptApi);
1705
2148
  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;
2149
+ const { body } = yield* effectGen(node);
2150
+ if (body.statements.length !== 1) {
2151
+ return yield* typeParserIssue(
2152
+ "Generator body should have a single statement",
2153
+ void 0,
2154
+ node
2155
+ );
2156
+ }
2157
+ let explicitReturn = false;
2158
+ let nodeToCheck = body.statements[0];
2159
+ while (nodeToCheck) {
2160
+ if (ts.isReturnStatement(nodeToCheck) && nodeToCheck.expression) {
2161
+ nodeToCheck = nodeToCheck.expression;
2162
+ explicitReturn = true;
2163
+ continue;
2164
+ }
2165
+ if (ts.isExpressionStatement(nodeToCheck)) {
2166
+ nodeToCheck = nodeToCheck.expression;
2167
+ continue;
2168
+ }
2169
+ if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
2170
+ const yieldedExpression = nodeToCheck.expression;
2171
+ const type = typeChecker.getTypeAtLocation(yieldedExpression);
2172
+ const { A: successType } = yield* effectType(type, yieldedExpression);
2173
+ let replacementNode = succeed(yieldedExpression);
2174
+ if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
2175
+ replacementNode = pipe(
2176
+ gen(function* () {
2177
+ const effectIdentifier = pipe(
2178
+ yield* option(
2179
+ findImportedModuleIdentifierByPackageAndNameOrBarrel(node.getSourceFile(), "effect", "Effect")
2180
+ ),
2181
+ match({
2182
+ onNone: () => "Effect",
2183
+ onSome: (_) => _.text
2184
+ })
2185
+ );
2186
+ return ts.factory.createCallExpression(
2187
+ ts.factory.createPropertyAccessExpression(
2188
+ ts.factory.createIdentifier(effectIdentifier),
2189
+ "asVoid"
2190
+ ),
2191
+ void 0,
2192
+ [
2193
+ yieldedExpression
2194
+ ]
2195
+ );
2196
+ }),
2197
+ provideService(TypeScriptApi, ts)
2198
+ );
2199
+ }
2200
+ return { node, body, yieldedExpression, replacementNode };
2201
+ }
2202
+ break;
1711
2203
  }
1712
2204
  return yield* typeParserIssue(
1713
- "Node is not a return statement with a yield expression",
2205
+ "Not an handled node",
1714
2206
  void 0,
1715
- body
2207
+ node
1716
2208
  );
1717
2209
  });
1718
2210
  var effectSchemaVarianceStruct = fn("TypeParser.effectSchemaVarianceStruct")(
@@ -1777,7 +2269,7 @@ var floatingEffect = createDiagnostic({
1777
2269
  if (isSome2(effect)) {
1778
2270
  const allowedFloatingEffects = yield* pipe(
1779
2271
  fiberType(type, node.expression),
1780
- orElse(() => effectSubtype(type, node.expression)),
2272
+ orElse2(() => effectSubtype(type, node.expression)),
1781
2273
  option
1782
2274
  );
1783
2275
  if (isNone2(allowedFloatingEffects)) {
@@ -1829,7 +2321,7 @@ var missingEffectContext = createDiagnostic({
1829
2321
  valueNode,
1830
2322
  realType
1831
2323
  ),
1832
- orElse(() => succeed([]))
2324
+ orElse2(() => succeed([]))
1833
2325
  );
1834
2326
  if (missingContext.length > 0) {
1835
2327
  effectDiagnostics.push(
@@ -1881,7 +2373,7 @@ var missingEffectError = createDiagnostic({
1881
2373
  valueNode,
1882
2374
  realType
1883
2375
  ),
1884
- orElse(() => succeed([]))
2376
+ orElse2(() => succeed([]))
1885
2377
  );
1886
2378
  if (missingContext.length > 0) {
1887
2379
  effectDiagnostics.push(
@@ -1925,8 +2417,8 @@ var missingStarInYieldEffectGen = createDiagnostic({
1925
2417
  const effectGenNode = functionStarNode.parent;
1926
2418
  const effectGenLike = yield* pipe(
1927
2419
  effectGen(effectGenNode),
1928
- orElse(() => effectFnUntracedGen(effectGenNode)),
1929
- orElse(() => effectFnGen(effectGenNode)),
2420
+ orElse2(() => effectFnUntracedGen(effectGenNode)),
2421
+ orElse2(() => effectFnGen(effectGenNode)),
1930
2422
  option
1931
2423
  );
1932
2424
  if (isSome2(effectGenLike)) {
@@ -1974,7 +2466,7 @@ var missingStarInYieldEffectGen = createDiagnostic({
1974
2466
  });
1975
2467
 
1976
2468
  // src/diagnostics/unnecessaryEffectGen.ts
1977
- var unnecessaryEffectGen = createDiagnostic({
2469
+ var unnecessaryEffectGen2 = createDiagnostic({
1978
2470
  name: "unnecessaryEffectGen",
1979
2471
  code: 5,
1980
2472
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile) {
@@ -1990,13 +2482,9 @@ var unnecessaryEffectGen = createDiagnostic({
1990
2482
  while (nodeToVisit.length > 0) {
1991
2483
  const node = nodeToVisit.shift();
1992
2484
  ts.forEachChild(node, appendNodeToVisit);
1993
- const maybeNode = yield* pipe(
1994
- effectGen(node),
1995
- flatMap2(({ body }) => returnYieldEffectBlock(body)),
1996
- option
1997
- );
2485
+ const maybeNode = yield* option(unnecessaryEffectGen(node));
1998
2486
  if (isSome2(maybeNode)) {
1999
- unnecessaryGenerators.set(node, maybeNode.value);
2487
+ unnecessaryGenerators.set(node, maybeNode.value.replacementNode);
2000
2488
  }
2001
2489
  }
2002
2490
  unnecessaryGenerators.forEach(
@@ -2011,7 +2499,7 @@ var unnecessaryEffectGen = createDiagnostic({
2011
2499
  const textChanges = yield* service(
2012
2500
  ChangeTracker
2013
2501
  );
2014
- textChanges.replaceNode(sourceFile, effectGenCall, yieldedResult);
2502
+ textChanges.replaceNode(sourceFile, effectGenCall, yield* yieldedResult);
2015
2503
  })
2016
2504
  }]
2017
2505
  })
@@ -2027,7 +2515,7 @@ var diagnostics = [
2027
2515
  missingEffectError,
2028
2516
  floatingEffect,
2029
2517
  missingStarInYieldEffectGen,
2030
- unnecessaryEffectGen
2518
+ unnecessaryEffectGen2
2031
2519
  ];
2032
2520
 
2033
2521
  // src/transform.ts