@effect/language-service 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +102 -6
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -64,6 +64,8 @@ var dual = function(arity, body) {
|
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
var identity = (a) => a;
|
|
67
|
+
var constant = (value) => () => value;
|
|
68
|
+
var constUndefined = /* @__PURE__ */ constant(void 0);
|
|
67
69
|
function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
|
|
68
70
|
switch (arguments.length) {
|
|
69
71
|
case 1:
|
|
@@ -649,6 +651,7 @@ var isSome2 = isSome;
|
|
|
649
651
|
var getOrElse = /* @__PURE__ */ dual(2, (self, onNone) => isNone2(self) ? onNone() : self.value);
|
|
650
652
|
var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : self);
|
|
651
653
|
var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
|
|
654
|
+
var getOrUndefined = /* @__PURE__ */ getOrElse(constUndefined);
|
|
652
655
|
var map = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : some2(f(self.value)));
|
|
653
656
|
var flatMap = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : f(self.value));
|
|
654
657
|
var all = (input) => {
|
|
@@ -1434,12 +1437,47 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
1434
1437
|
}
|
|
1435
1438
|
});
|
|
1436
1439
|
|
|
1440
|
+
// src/diagnostics/unnecessaryEffectGen.ts
|
|
1441
|
+
var unnecessaryEffectGen = createDiagnostic({
|
|
1442
|
+
code: 5,
|
|
1443
|
+
apply: (ts, program) => (sourceFile) => {
|
|
1444
|
+
const typeChecker = program.getTypeChecker();
|
|
1445
|
+
const effectDiagnostics = [];
|
|
1446
|
+
const brokenGenerators = /* @__PURE__ */ new Set();
|
|
1447
|
+
const visit = (node) => {
|
|
1448
|
+
const effectGenLike = effectGen(ts, typeChecker)(node);
|
|
1449
|
+
if (isSome2(effectGenLike)) {
|
|
1450
|
+
const body = effectGenLike.value.body;
|
|
1451
|
+
if (body.statements.length === 1 && ts.isReturnStatement(body.statements[0]) && body.statements[0].expression && ts.isYieldExpression(body.statements[0].expression) && body.statements[0].expression.expression) {
|
|
1452
|
+
const nodeToCheck = body.statements[0].expression.expression;
|
|
1453
|
+
const type = typeChecker.getTypeAtLocation(nodeToCheck);
|
|
1454
|
+
const maybeEffect = effectType(ts, typeChecker)(type, nodeToCheck);
|
|
1455
|
+
if (isSome2(maybeEffect)) {
|
|
1456
|
+
brokenGenerators.add(node);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
ts.forEachChild(node, visit);
|
|
1461
|
+
};
|
|
1462
|
+
ts.forEachChild(sourceFile, visit);
|
|
1463
|
+
brokenGenerators.forEach(
|
|
1464
|
+
(node) => effectDiagnostics.push({
|
|
1465
|
+
node,
|
|
1466
|
+
category: ts.DiagnosticCategory.Warning,
|
|
1467
|
+
messageText: `This Effect.gen is useless here because it only contains a single return statement.`
|
|
1468
|
+
})
|
|
1469
|
+
);
|
|
1470
|
+
return effectDiagnostics;
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
|
|
1437
1474
|
// src/diagnostics.ts
|
|
1438
1475
|
var diagnostics = {
|
|
1439
1476
|
missingEffectContext,
|
|
1440
1477
|
missingEffectError,
|
|
1441
1478
|
floatingEffect,
|
|
1442
|
-
missingStarInYieldEffectGen
|
|
1479
|
+
missingStarInYieldEffectGen,
|
|
1480
|
+
unnecessaryEffectGen
|
|
1443
1481
|
};
|
|
1444
1482
|
|
|
1445
1483
|
// src/quickinfo.ts
|
|
@@ -1458,6 +1496,47 @@ function dedupeJsDocTags(quickInfo) {
|
|
|
1458
1496
|
}
|
|
1459
1497
|
return quickInfo;
|
|
1460
1498
|
}
|
|
1499
|
+
function formatTypeForQuickInfo(ts, typeChecker) {
|
|
1500
|
+
return (channelType, channelName) => {
|
|
1501
|
+
const stringRepresentation = typeChecker.typeToString(
|
|
1502
|
+
channelType,
|
|
1503
|
+
void 0,
|
|
1504
|
+
ts.TypeFormatFlags.NoTruncation
|
|
1505
|
+
);
|
|
1506
|
+
return `type ${channelName} = ${stringRepresentation}`;
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
function prependEffectTypeArguments(ts, program) {
|
|
1510
|
+
return (sourceFileName, position, quickInfo) => {
|
|
1511
|
+
const sourceFile = program.getSourceFile(sourceFileName);
|
|
1512
|
+
if (!sourceFile) return quickInfo;
|
|
1513
|
+
const hasTruncationHappened = ts.displayPartsToString(quickInfo.displayParts).indexOf("...") > -1;
|
|
1514
|
+
if (!hasTruncationHappened) return quickInfo;
|
|
1515
|
+
const typeChecker = program.getTypeChecker();
|
|
1516
|
+
const effectTypeArgsDocumentation = pipe(
|
|
1517
|
+
getNodesContainingRange(ts)(sourceFile, toTextRange(position)),
|
|
1518
|
+
head,
|
|
1519
|
+
flatMap(
|
|
1520
|
+
(_) => effectType(ts, typeChecker)(typeChecker.getTypeAtLocation(_), _)
|
|
1521
|
+
),
|
|
1522
|
+
map((_) => [{
|
|
1523
|
+
kind: "text",
|
|
1524
|
+
text: "```ts\n/* Effect Type Parameters */\n" + formatTypeForQuickInfo(ts, typeChecker)(_.A, "Success") + "\n" + formatTypeForQuickInfo(ts, typeChecker)(_.E, "Failure") + "\n" + formatTypeForQuickInfo(ts, typeChecker)(_.R, "Requirements") + "\n```\n"
|
|
1525
|
+
}]),
|
|
1526
|
+
getOrElse(() => [])
|
|
1527
|
+
);
|
|
1528
|
+
if (quickInfo.documentation) {
|
|
1529
|
+
return {
|
|
1530
|
+
...quickInfo,
|
|
1531
|
+
documentation: effectTypeArgsDocumentation.concat(quickInfo.documentation)
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
return {
|
|
1535
|
+
...quickInfo,
|
|
1536
|
+
documentation: effectTypeArgsDocumentation
|
|
1537
|
+
};
|
|
1538
|
+
};
|
|
1539
|
+
}
|
|
1461
1540
|
|
|
1462
1541
|
// src/refactors/asyncAwaitToGen.ts
|
|
1463
1542
|
var asyncAwaitToGen = createRefactor({
|
|
@@ -1800,7 +1879,9 @@ var toggleTypeAnnotation = createRefactor({
|
|
|
1800
1879
|
description: "Toggle type annotation",
|
|
1801
1880
|
apply: (ts, program) => (sourceFile, textRange) => pipe(
|
|
1802
1881
|
getNodesContainingRange(ts)(sourceFile, textRange),
|
|
1803
|
-
filter(
|
|
1882
|
+
filter(
|
|
1883
|
+
(node) => ts.isVariableDeclaration(node) || ts.isPropertyDeclaration(node)
|
|
1884
|
+
),
|
|
1804
1885
|
filter((node) => isNodeInRange(textRange)(node.name)),
|
|
1805
1886
|
filter((node) => !!node.initializer),
|
|
1806
1887
|
head,
|
|
@@ -1816,10 +1897,19 @@ var toggleTypeAnnotation = createRefactor({
|
|
|
1816
1897
|
}
|
|
1817
1898
|
const initializer = node.initializer;
|
|
1818
1899
|
const initializerType = typeChecker.getTypeAtLocation(initializer);
|
|
1819
|
-
const initializerTypeNode = typeChecker.typeToTypeNode(
|
|
1900
|
+
const initializerTypeNode = fromNullable(typeChecker.typeToTypeNode(
|
|
1820
1901
|
initializerType,
|
|
1821
1902
|
node,
|
|
1822
1903
|
ts.NodeBuilderFlags.NoTruncation
|
|
1904
|
+
)).pipe(
|
|
1905
|
+
orElse(
|
|
1906
|
+
() => fromNullable(typeChecker.typeToTypeNode(
|
|
1907
|
+
initializerType,
|
|
1908
|
+
void 0,
|
|
1909
|
+
ts.NodeBuilderFlags.NoTruncation
|
|
1910
|
+
))
|
|
1911
|
+
),
|
|
1912
|
+
getOrUndefined
|
|
1823
1913
|
);
|
|
1824
1914
|
if (initializerTypeNode) {
|
|
1825
1915
|
changeTracker.insertNodeAt(
|
|
@@ -1872,7 +1962,8 @@ var init = (modules) => {
|
|
|
1872
1962
|
function create(info) {
|
|
1873
1963
|
const languageService = info.languageService;
|
|
1874
1964
|
const pluginOptions = {
|
|
1875
|
-
diagnostics: info.config && "diagnostics" in info.config && typeof info.config.diagnostics === "boolean" ? info.config.diagnostics : true
|
|
1965
|
+
diagnostics: info.config && "diagnostics" in info.config && typeof info.config.diagnostics === "boolean" ? info.config.diagnostics : true,
|
|
1966
|
+
quickinfo: info.config && "quickinfo" in info.config && typeof info.config.quickinfo === "boolean" ? info.config.quickinfo : true
|
|
1876
1967
|
};
|
|
1877
1968
|
const proxy = /* @__PURE__ */ Object.create(null);
|
|
1878
1969
|
for (const k of Object.keys(info.languageService)) {
|
|
@@ -2005,8 +2096,13 @@ var init = (modules) => {
|
|
|
2005
2096
|
};
|
|
2006
2097
|
proxy.getQuickInfoAtPosition = (fileName, position, ...args) => {
|
|
2007
2098
|
const quickInfo = languageService.getQuickInfoAtPosition(fileName, position, ...args);
|
|
2008
|
-
if (quickInfo) {
|
|
2009
|
-
|
|
2099
|
+
if (pluginOptions.quickinfo && quickInfo) {
|
|
2100
|
+
const dedupedTagsQuickInfo = dedupeJsDocTags(quickInfo);
|
|
2101
|
+
const program = languageService.getProgram();
|
|
2102
|
+
if (program) {
|
|
2103
|
+
return prependEffectTypeArguments(ts, program)(fileName, position, dedupedTagsQuickInfo);
|
|
2104
|
+
}
|
|
2105
|
+
return dedupedTagsQuickInfo;
|
|
2010
2106
|
}
|
|
2011
2107
|
return quickInfo;
|
|
2012
2108
|
};
|