@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/README.md +2 -0
- package/index.js +562 -51
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +517 -29
- package/transform.js.map +1 -1
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
|
|
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
|
|
1067
|
-
while ((
|
|
1068
|
-
const nextLineCaptureGroup =
|
|
1069
|
-
const rulesCaptureGroup =
|
|
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(
|
|
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:
|
|
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
|
|
2146
|
+
var unnecessaryEffectGen = fn("TypeParser.unnecessaryEffectGen")(function* (node) {
|
|
1704
2147
|
const ts = yield* service(TypeScriptApi);
|
|
1705
2148
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
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
|
-
"
|
|
2205
|
+
"Not an handled node",
|
|
1714
2206
|
void 0,
|
|
1715
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1929
|
-
|
|
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
|
|
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*
|
|
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
|
-
|
|
2518
|
+
unnecessaryEffectGen2
|
|
2031
2519
|
];
|
|
2032
2520
|
|
|
2033
2521
|
// src/transform.ts
|