@effect/language-service 0.55.2 → 0.55.4
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/cli.js +183 -21
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +178 -12
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +267 -37
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +183 -21
- package/transform.js.map +1 -1
package/index.js
CHANGED
|
@@ -909,8 +909,9 @@ var contAll = Symbol.for("Nano.contAll");
|
|
|
909
909
|
var NanoYield = Symbol.for("Nano.yield");
|
|
910
910
|
var args = Symbol.for("Nano.args");
|
|
911
911
|
var NanoDefectException = class {
|
|
912
|
-
constructor(message) {
|
|
912
|
+
constructor(message, lastSpan) {
|
|
913
913
|
this.message = message;
|
|
914
|
+
this.lastSpan = lastSpan;
|
|
914
915
|
}
|
|
915
916
|
_tag = "@effect/language-service/NanoDefectException";
|
|
916
917
|
};
|
|
@@ -968,6 +969,7 @@ var NanoFiber = class {
|
|
|
968
969
|
_services = {};
|
|
969
970
|
_cache = {};
|
|
970
971
|
_perf = false;
|
|
972
|
+
_lastSpan = "";
|
|
971
973
|
runLoop(nano) {
|
|
972
974
|
let current = nano;
|
|
973
975
|
while (true) {
|
|
@@ -998,17 +1000,21 @@ var WithSpanProto = {
|
|
|
998
1000
|
[evaluate](fiber) {
|
|
999
1001
|
const [fa, name] = this[args];
|
|
1000
1002
|
if (!fiber._perf) return fa;
|
|
1003
|
+
const previousSpan = fiber._lastSpan;
|
|
1004
|
+
fiber._lastSpan = name;
|
|
1001
1005
|
const start = performance.now();
|
|
1002
1006
|
timingsCount[name] = (timingsCount[name] || 0) + 1;
|
|
1003
1007
|
return match(fa, {
|
|
1004
1008
|
onSuccess: (_) => {
|
|
1005
1009
|
const end = performance.now();
|
|
1006
1010
|
timings[name] = (timings[name] || 0) + (end - start);
|
|
1011
|
+
fiber._lastSpan = previousSpan;
|
|
1007
1012
|
return succeed(_);
|
|
1008
1013
|
},
|
|
1009
1014
|
onFailure: (_) => {
|
|
1010
1015
|
const end = performance.now();
|
|
1011
1016
|
timings[name] = (timings[name] || 0) + (end - start);
|
|
1017
|
+
fiber._lastSpan = previousSpan;
|
|
1012
1018
|
return fail(_);
|
|
1013
1019
|
}
|
|
1014
1020
|
});
|
|
@@ -1019,19 +1025,16 @@ var withSpan = (name) => (fa) => {
|
|
|
1019
1025
|
nano[args] = [fa, name];
|
|
1020
1026
|
return nano;
|
|
1021
1027
|
};
|
|
1022
|
-
var unsafeRun = (nano) => {
|
|
1023
|
-
const fiber = new NanoFiber();
|
|
1024
|
-
const result = fiber.runLoop(nano);
|
|
1025
|
-
if (result._tag === "Success") {
|
|
1026
|
-
return right2(result.value);
|
|
1027
|
-
}
|
|
1028
|
-
return left2(result.value);
|
|
1029
|
-
};
|
|
1030
1028
|
var run = (nano) => {
|
|
1029
|
+
const fiber = new NanoFiber();
|
|
1031
1030
|
try {
|
|
1032
|
-
|
|
1031
|
+
const result = fiber.runLoop(nano);
|
|
1032
|
+
if (result._tag === "Success") {
|
|
1033
|
+
return right2(result.value);
|
|
1034
|
+
}
|
|
1035
|
+
return left2(result.value);
|
|
1033
1036
|
} catch (e) {
|
|
1034
|
-
return left2(new NanoDefectException(e));
|
|
1037
|
+
return left2(new NanoDefectException(e, fiber._lastSpan));
|
|
1035
1038
|
}
|
|
1036
1039
|
};
|
|
1037
1040
|
var OnSuccessProto = {
|
|
@@ -1138,7 +1141,7 @@ var ServiceProto = {
|
|
|
1138
1141
|
return cont2 ? cont2[contA](value, fiber) : fiber.yieldWith(succeed(value));
|
|
1139
1142
|
}
|
|
1140
1143
|
const cont = fiber.getCont(contE);
|
|
1141
|
-
return cont ? cont[contE](tag, fiber) : fiber.yieldWith(fail(new NanoDefectException(`Service ${tag.key} not found
|
|
1144
|
+
return cont ? cont[contE](tag, fiber) : fiber.yieldWith(fail(new NanoDefectException(`Service ${tag.key} not found`, fiber._lastSpan)));
|
|
1142
1145
|
}
|
|
1143
1146
|
};
|
|
1144
1147
|
var service = (tag) => {
|
|
@@ -1818,6 +1821,30 @@ function makeTypeScriptUtils(ts) {
|
|
|
1818
1821
|
}
|
|
1819
1822
|
return node;
|
|
1820
1823
|
}
|
|
1824
|
+
function isOuterExpression(node, kinds = ts.OuterExpressionKinds.All) {
|
|
1825
|
+
switch (node.kind) {
|
|
1826
|
+
case ts.SyntaxKind.ParenthesizedExpression:
|
|
1827
|
+
return (kinds & ts.OuterExpressionKinds.Parentheses) !== 0;
|
|
1828
|
+
case ts.SyntaxKind.TypeAssertionExpression:
|
|
1829
|
+
case ts.SyntaxKind.AsExpression:
|
|
1830
|
+
return (kinds & ts.OuterExpressionKinds.TypeAssertions) !== 0;
|
|
1831
|
+
case ts.SyntaxKind.SatisfiesExpression:
|
|
1832
|
+
return (kinds & (ts.OuterExpressionKinds.TypeAssertions | ts.OuterExpressionKinds.Satisfies)) !== 0;
|
|
1833
|
+
case ts.SyntaxKind.ExpressionWithTypeArguments:
|
|
1834
|
+
return (kinds & ts.OuterExpressionKinds.ExpressionsWithTypeArguments) !== 0;
|
|
1835
|
+
case ts.SyntaxKind.NonNullExpression:
|
|
1836
|
+
return (kinds & ts.OuterExpressionKinds.NonNullAssertions) !== 0;
|
|
1837
|
+
case ts.SyntaxKind.PartiallyEmittedExpression:
|
|
1838
|
+
return (kinds & ts.OuterExpressionKinds.PartiallyEmittedExpressions) !== 0;
|
|
1839
|
+
}
|
|
1840
|
+
return false;
|
|
1841
|
+
}
|
|
1842
|
+
function skipOuterExpressions(node, kinds = ts.OuterExpressionKinds.All) {
|
|
1843
|
+
while (isOuterExpression(node, kinds)) {
|
|
1844
|
+
node = node.expression;
|
|
1845
|
+
}
|
|
1846
|
+
return node;
|
|
1847
|
+
}
|
|
1821
1848
|
return {
|
|
1822
1849
|
findNodeAtPositionIncludingTrivia,
|
|
1823
1850
|
parsePackageContentNameAndVersionFromScope,
|
|
@@ -1838,7 +1865,9 @@ function makeTypeScriptUtils(ts) {
|
|
|
1838
1865
|
createEffectGenCallExpressionWithBlock,
|
|
1839
1866
|
createReturnYieldStarStatement,
|
|
1840
1867
|
parseAccessedExpressionForCompletion,
|
|
1841
|
-
getSourceFileOfNode
|
|
1868
|
+
getSourceFileOfNode,
|
|
1869
|
+
isOuterExpression,
|
|
1870
|
+
skipOuterExpressions
|
|
1842
1871
|
};
|
|
1843
1872
|
}
|
|
1844
1873
|
|
|
@@ -1938,6 +1967,14 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
1938
1967
|
result = node2;
|
|
1939
1968
|
return;
|
|
1940
1969
|
}
|
|
1970
|
+
if (ts.isPropertyAssignment(node2)) {
|
|
1971
|
+
const realStart = ts.getTokenPosOfNode(node2, sourceFile);
|
|
1972
|
+
const starts = sourceFile.getLineStarts().filter((start) => start >= node2.pos && start <= realStart);
|
|
1973
|
+
if (starts.length > 0) {
|
|
1974
|
+
result = node2;
|
|
1975
|
+
return;
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1941
1978
|
if (result) return;
|
|
1942
1979
|
if (node2.parent) find(node2.parent);
|
|
1943
1980
|
}
|
|
@@ -2685,6 +2722,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2685
2722
|
const getSourceFilesDeclaringSymbolModule = (packageName) => cachedBy(
|
|
2686
2723
|
fn("TypeParser.getSourceFilesDeclaringSymbolModule")(function* (symbol3) {
|
|
2687
2724
|
const result = [];
|
|
2725
|
+
if (!symbol3) return result;
|
|
2688
2726
|
if (!symbol3.declarations) return yield* typeParserIssue("Symbol has no declarations", void 0, void 0);
|
|
2689
2727
|
for (const sourceFile of symbol3.declarations) {
|
|
2690
2728
|
if (!ts.isSourceFile(sourceFile)) continue;
|
|
@@ -2722,6 +2760,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2722
2760
|
const getSourceFilesDeclaringSymbolExportedUnderPackageModule = (packageName, memberName) => cachedBy(
|
|
2723
2761
|
fn("TypeParser.getSourceFilesDeclaringSymbolUnderPackageExportedMember")(function* (symbol3) {
|
|
2724
2762
|
const result = [];
|
|
2763
|
+
if (!symbol3) return result;
|
|
2725
2764
|
if (!symbol3.declarations) return yield* typeParserIssue("Symbol has no declarations", void 0, void 0);
|
|
2726
2765
|
for (const declaration of symbol3.declarations) {
|
|
2727
2766
|
const sourceFile = tsUtils.getSourceFileOfNode(declaration);
|
|
@@ -2943,14 +2982,14 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2943
2982
|
);
|
|
2944
2983
|
const importedContextModule = cachedBy(
|
|
2945
2984
|
fn("TypeParser.importedContextModule")(function* (node) {
|
|
2985
|
+
if (!ts.isIdentifier(node)) {
|
|
2986
|
+
return yield* typeParserIssue("Node is not an identifier", void 0, node);
|
|
2987
|
+
}
|
|
2946
2988
|
const type = typeChecker.getTypeAtLocation(node);
|
|
2947
2989
|
const propertySymbol = typeChecker.getPropertyOfType(type, "Tag");
|
|
2948
2990
|
if (!propertySymbol) {
|
|
2949
2991
|
return yield* typeParserIssue("Type has no 'Tag' property", type, node);
|
|
2950
2992
|
}
|
|
2951
|
-
if (!ts.isIdentifier(node)) {
|
|
2952
|
-
return yield* typeParserIssue("Node is not an identifier", type, node);
|
|
2953
|
-
}
|
|
2954
2993
|
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
2955
2994
|
if (!sourceFile) {
|
|
2956
2995
|
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
@@ -2977,14 +3016,14 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
|
|
|
2977
3016
|
);
|
|
2978
3017
|
const importedDataModule = cachedBy(
|
|
2979
3018
|
fn("TypeParser.importedDataModule")(function* (node) {
|
|
3019
|
+
if (!ts.isIdentifier(node)) {
|
|
3020
|
+
return yield* typeParserIssue("Node is not an expression", void 0, node);
|
|
3021
|
+
}
|
|
2980
3022
|
const type = typeChecker.getTypeAtLocation(node);
|
|
2981
3023
|
const propertySymbol = typeChecker.getPropertyOfType(type, "TaggedError");
|
|
2982
3024
|
if (!propertySymbol) {
|
|
2983
3025
|
return yield* typeParserIssue("Type has no 'TaggedError' property", type, node);
|
|
2984
3026
|
}
|
|
2985
|
-
if (!ts.isIdentifier(node)) {
|
|
2986
|
-
return yield* typeParserIssue("Node is not an expression", type, node);
|
|
2987
|
-
}
|
|
2988
3027
|
const sourceFile = tsUtils.getSourceFileOfNode(node);
|
|
2989
3028
|
if (!sourceFile) {
|
|
2990
3029
|
return yield* typeParserIssue("Node is not in a source file", void 0, node);
|
|
@@ -4122,6 +4161,103 @@ var effectDataClasses = createCompletion({
|
|
|
4122
4161
|
})
|
|
4123
4162
|
});
|
|
4124
4163
|
|
|
4164
|
+
// src/diagnostics/anyUnknownInErrorContext.ts
|
|
4165
|
+
var anyUnknownInErrorContext = createDiagnostic({
|
|
4166
|
+
name: "anyUnknownInErrorContext",
|
|
4167
|
+
code: 28,
|
|
4168
|
+
severity: "off",
|
|
4169
|
+
apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
|
|
4170
|
+
const ts = yield* service(TypeScriptApi);
|
|
4171
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
4172
|
+
const typeParser = yield* service(TypeParser);
|
|
4173
|
+
const isAnyOrUnknown = (type) => (type.flags & ts.TypeFlags.Any) > 0 || (type.flags & ts.TypeFlags.Unknown) > 0;
|
|
4174
|
+
const matchingNodes = [];
|
|
4175
|
+
const nodeToVisit = [sourceFile];
|
|
4176
|
+
const appendNodeToVisit = (node) => {
|
|
4177
|
+
nodeToVisit.push(node);
|
|
4178
|
+
return void 0;
|
|
4179
|
+
};
|
|
4180
|
+
while (nodeToVisit.length > 0) {
|
|
4181
|
+
const node = nodeToVisit.pop();
|
|
4182
|
+
if (ts.isTypeNode(node)) continue;
|
|
4183
|
+
if (ts.isTypeAliasDeclaration(node)) continue;
|
|
4184
|
+
if (ts.isInterfaceDeclaration(node)) continue;
|
|
4185
|
+
if (ts.isAsExpression(node) && node.type && node.type.kind === ts.SyntaxKind.AnyKeyword) {
|
|
4186
|
+
continue;
|
|
4187
|
+
}
|
|
4188
|
+
if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
|
|
4189
|
+
if (node.type) {
|
|
4190
|
+
const type2 = typeChecker.getTypeAtLocation(node.type);
|
|
4191
|
+
const expectedEffect = yield* pipe(
|
|
4192
|
+
typeParser.strictEffectType(type2, node.type),
|
|
4193
|
+
orElse2(() => void_)
|
|
4194
|
+
);
|
|
4195
|
+
if (expectedEffect) continue;
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
4199
|
+
if (!ts.isExpression(node)) continue;
|
|
4200
|
+
let type = typeChecker.getTypeAtLocation(node);
|
|
4201
|
+
if (ts.isCallExpression(node)) {
|
|
4202
|
+
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
4203
|
+
if (resolvedSignature) {
|
|
4204
|
+
type = typeChecker.getReturnTypeOfSignature(resolvedSignature);
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
if (!type) continue;
|
|
4208
|
+
yield* pipe(
|
|
4209
|
+
typeParser.strictEffectType(type, node),
|
|
4210
|
+
map5((effect) => {
|
|
4211
|
+
const { E, R } = effect;
|
|
4212
|
+
const hasAnyUnknownR = isAnyOrUnknown(R);
|
|
4213
|
+
const hasAnyUnknownE = isAnyOrUnknown(E);
|
|
4214
|
+
if (hasAnyUnknownR || hasAnyUnknownE) {
|
|
4215
|
+
const channels = [];
|
|
4216
|
+
if (hasAnyUnknownR) {
|
|
4217
|
+
const typeName = R.flags & ts.TypeFlags.Any ? "any" : "unknown";
|
|
4218
|
+
channels.push(`${typeName} in the requirements channel`);
|
|
4219
|
+
}
|
|
4220
|
+
if (hasAnyUnknownE) {
|
|
4221
|
+
const typeName = E.flags & ts.TypeFlags.Any ? "any" : "unknown";
|
|
4222
|
+
channels.push(`${typeName} in the error channel`);
|
|
4223
|
+
}
|
|
4224
|
+
const nodeStart = ts.getTokenPosOfNode(node, sourceFile);
|
|
4225
|
+
const nodeEnd = node.end;
|
|
4226
|
+
for (let i = matchingNodes.length - 1; i >= 0; i--) {
|
|
4227
|
+
const existing = matchingNodes[i];
|
|
4228
|
+
const existingStart = ts.getTokenPosOfNode(existing.node, sourceFile);
|
|
4229
|
+
const existingEnd = existing.node.end;
|
|
4230
|
+
if (existingStart <= nodeStart && existingEnd >= nodeEnd) {
|
|
4231
|
+
matchingNodes.splice(i, 1);
|
|
4232
|
+
}
|
|
4233
|
+
}
|
|
4234
|
+
const suggestions = [`This Effect has ${channels.join(" and ")} which is not recommended.`];
|
|
4235
|
+
if (hasAnyUnknownR) {
|
|
4236
|
+
suggestions.push(`Only service identifiers should appear in the requirements channel.`);
|
|
4237
|
+
}
|
|
4238
|
+
if (hasAnyUnknownE) {
|
|
4239
|
+
suggestions.push(
|
|
4240
|
+
`Having an unknown or any error type is not useful. Consider instead using specific error types baked by Data.TaggedError for example.`
|
|
4241
|
+
);
|
|
4242
|
+
}
|
|
4243
|
+
channels.push(`If you plan to later on manually cast the type, you can safely disable this diagnostic.`);
|
|
4244
|
+
const messageText = suggestions.join("\n");
|
|
4245
|
+
matchingNodes.push({ messageText, node, type });
|
|
4246
|
+
}
|
|
4247
|
+
}),
|
|
4248
|
+
ignore
|
|
4249
|
+
);
|
|
4250
|
+
}
|
|
4251
|
+
for (const { messageText, node } of matchingNodes) {
|
|
4252
|
+
report({
|
|
4253
|
+
location: node,
|
|
4254
|
+
messageText,
|
|
4255
|
+
fixes: []
|
|
4256
|
+
});
|
|
4257
|
+
}
|
|
4258
|
+
})
|
|
4259
|
+
});
|
|
4260
|
+
|
|
4125
4261
|
// src/diagnostics/catchUnfailableEffect.ts
|
|
4126
4262
|
var catchUnfailableEffect = createDiagnostic({
|
|
4127
4263
|
name: "catchUnfailableEffect",
|
|
@@ -7082,9 +7218,10 @@ var leakingRequirements = createDiagnostic({
|
|
|
7082
7218
|
(type) => {
|
|
7083
7219
|
let symbol3 = type.symbol;
|
|
7084
7220
|
if (symbol3 && symbol3.flags & ts.SymbolFlags.Alias) {
|
|
7085
|
-
symbol3 = typeChecker.getAliasedSymbol(symbol3);
|
|
7221
|
+
symbol3 = typeChecker.getAliasedSymbol(symbol3) || symbol3;
|
|
7086
7222
|
}
|
|
7087
|
-
|
|
7223
|
+
if (!symbol3) return false;
|
|
7224
|
+
return !(symbol3?.declarations || []).some((declaration) => {
|
|
7088
7225
|
const declarationSource = tsUtils.getSourceFileOfNode(declaration);
|
|
7089
7226
|
if (!declarationSource) return false;
|
|
7090
7227
|
return declarationSource.text.substring(declaration.pos, declaration.end).toLowerCase().indexOf(
|
|
@@ -7885,6 +8022,26 @@ var overriddenSchemaConstructor = createDiagnostic({
|
|
|
7885
8022
|
const ts = yield* service(TypeScriptApi);
|
|
7886
8023
|
const typeParser = yield* service(TypeParser);
|
|
7887
8024
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
8025
|
+
function isAllowedConstructor(node) {
|
|
8026
|
+
if (node.body && node.body.statements.length === 1) {
|
|
8027
|
+
const expressionStatement = node.body.statements[0];
|
|
8028
|
+
if (ts.isExpressionStatement(expressionStatement)) {
|
|
8029
|
+
const maybeCallSuper = expressionStatement.expression;
|
|
8030
|
+
if (ts.isCallExpression(maybeCallSuper)) {
|
|
8031
|
+
if (maybeCallSuper.expression.kind === ts.SyntaxKind.SuperKeyword) {
|
|
8032
|
+
const expectedNames = node.parameters.map((_) => _.name).filter(ts.isIdentifier).map((_) => ts.idText(_));
|
|
8033
|
+
if (expectedNames.length === 2 && expectedNames.length === node.parameters.length) {
|
|
8034
|
+
const givenNames = maybeCallSuper.arguments.filter(ts.isIdentifier).map((_) => ts.idText(_));
|
|
8035
|
+
if (givenNames.length === expectedNames.length && givenNames.every((name, index) => name === expectedNames[index])) {
|
|
8036
|
+
return true;
|
|
8037
|
+
}
|
|
8038
|
+
}
|
|
8039
|
+
}
|
|
8040
|
+
}
|
|
8041
|
+
}
|
|
8042
|
+
}
|
|
8043
|
+
return false;
|
|
8044
|
+
}
|
|
7888
8045
|
const nodeToVisit = [];
|
|
7889
8046
|
const appendNodeToVisit = (node) => {
|
|
7890
8047
|
nodeToVisit.push(node);
|
|
@@ -7916,6 +8073,9 @@ var overriddenSchemaConstructor = createDiagnostic({
|
|
|
7916
8073
|
const members = node.members;
|
|
7917
8074
|
for (const member of members) {
|
|
7918
8075
|
if (ts.isConstructorDeclaration(member)) {
|
|
8076
|
+
if (isAllowedConstructor(member)) {
|
|
8077
|
+
continue;
|
|
8078
|
+
}
|
|
7919
8079
|
const fixAsStaticNew = {
|
|
7920
8080
|
fixName: "overriddenSchemaConstructor_static",
|
|
7921
8081
|
description: "Rewrite using the static 'new' pattern",
|
|
@@ -8324,6 +8484,7 @@ var strictBooleanExpressions = createDiagnostic({
|
|
|
8324
8484
|
for (const nodeToCheck of nodes2) {
|
|
8325
8485
|
if (!nodeToCheck) continue;
|
|
8326
8486
|
if (!conditionChecks.has(nodeToCheck.parent)) continue;
|
|
8487
|
+
if (!ts.isExpression(nodeToCheck)) continue;
|
|
8327
8488
|
const nodeType = typeChecker.getTypeAtLocation(nodeToCheck);
|
|
8328
8489
|
const constrainedType = typeChecker.getBaseConstraintOfType(nodeType);
|
|
8329
8490
|
let typesToCheck = [constrainedType || nodeType];
|
|
@@ -8713,6 +8874,7 @@ var unsupportedServiceAccessors = createDiagnostic({
|
|
|
8713
8874
|
|
|
8714
8875
|
// src/diagnostics.ts
|
|
8715
8876
|
var diagnostics = [
|
|
8877
|
+
anyUnknownInErrorContext,
|
|
8716
8878
|
catchUnfailableEffect,
|
|
8717
8879
|
classSelfMismatch,
|
|
8718
8880
|
duplicatePackage,
|
|
@@ -9828,6 +9990,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9828
9990
|
const ts = yield* service(TypeScriptApi);
|
|
9829
9991
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
9830
9992
|
const typeParser = yield* service(TypeParser);
|
|
9993
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
9831
9994
|
const options = yield* service(LanguageServicePluginOptions);
|
|
9832
9995
|
if (options.quickinfoEffectParameters === "never") return quickInfo2;
|
|
9833
9996
|
function formatTypeForQuickInfo(channelType, channelName) {
|
|
@@ -9855,6 +10018,73 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9855
10018
|
text: "```ts\n/* " + title + " */\n" + formatTypeForQuickInfo(A, "Success") + "\n" + formatTypeForQuickInfo(E, "Failure") + "\n" + formatTypeForQuickInfo(R, "Requirements") + "\n```\n"
|
|
9856
10019
|
}];
|
|
9857
10020
|
}
|
|
10021
|
+
function isRightSideOfPropertyAccess(node2) {
|
|
10022
|
+
return node2.parent && ts.isPropertyAccessExpression(node2.parent) && node2.parent.name === node2;
|
|
10023
|
+
}
|
|
10024
|
+
function isArgumentExpressionOfElementAccess(node2) {
|
|
10025
|
+
return node2.parent && ts.isElementAccessExpression(node2.parent) && node2.parent.argumentExpression === node2;
|
|
10026
|
+
}
|
|
10027
|
+
function isCalleeWorker(node2, pred, calleeSelector, includeElementAccess, skipPastOuterExpressions) {
|
|
10028
|
+
let target = includeElementAccess ? climbPastPropertyOrElementAccess(node2) : climbPastPropertyAccess(node2);
|
|
10029
|
+
if (skipPastOuterExpressions) {
|
|
10030
|
+
target = tsUtils.skipOuterExpressions(target);
|
|
10031
|
+
}
|
|
10032
|
+
return !!target && !!target.parent && pred(target.parent) && calleeSelector(target.parent) === target;
|
|
10033
|
+
}
|
|
10034
|
+
function climbPastPropertyAccess(node2) {
|
|
10035
|
+
return isRightSideOfPropertyAccess(node2) ? node2.parent : node2;
|
|
10036
|
+
}
|
|
10037
|
+
function climbPastPropertyOrElementAccess(node2) {
|
|
10038
|
+
return isRightSideOfPropertyAccess(node2) || isArgumentExpressionOfElementAccess(node2) ? node2.parent : node2;
|
|
10039
|
+
}
|
|
10040
|
+
function selectExpressionOfCallOrNewExpressionOrDecorator(node2) {
|
|
10041
|
+
return node2.expression;
|
|
10042
|
+
}
|
|
10043
|
+
function isCallExpressionTarget(node2, includeElementAccess = false, skipPastOuterExpressions = false) {
|
|
10044
|
+
return isCalleeWorker(
|
|
10045
|
+
node2,
|
|
10046
|
+
ts.isCallExpression,
|
|
10047
|
+
selectExpressionOfCallOrNewExpressionOrDecorator,
|
|
10048
|
+
includeElementAccess,
|
|
10049
|
+
skipPastOuterExpressions
|
|
10050
|
+
);
|
|
10051
|
+
}
|
|
10052
|
+
function isNewExpressionTarget(node2, includeElementAccess = false, skipPastOuterExpressions = false) {
|
|
10053
|
+
return isCalleeWorker(
|
|
10054
|
+
node2,
|
|
10055
|
+
ts.isNewExpression,
|
|
10056
|
+
selectExpressionOfCallOrNewExpressionOrDecorator,
|
|
10057
|
+
includeElementAccess,
|
|
10058
|
+
skipPastOuterExpressions
|
|
10059
|
+
);
|
|
10060
|
+
}
|
|
10061
|
+
function getSignatureForQuickInfo(location) {
|
|
10062
|
+
if (location.parent && location.parent.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
|
10063
|
+
const right3 = location.parent.name;
|
|
10064
|
+
if (right3 === location || right3 && right3.getFullWidth() === 0) {
|
|
10065
|
+
location = location.parent;
|
|
10066
|
+
}
|
|
10067
|
+
}
|
|
10068
|
+
let callExpressionLike;
|
|
10069
|
+
if (ts.isCallOrNewExpression(location)) {
|
|
10070
|
+
callExpressionLike = location;
|
|
10071
|
+
} else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) {
|
|
10072
|
+
callExpressionLike = location.parent;
|
|
10073
|
+
}
|
|
10074
|
+
if (callExpressionLike) {
|
|
10075
|
+
const signature = typeChecker.getResolvedSignature(callExpressionLike);
|
|
10076
|
+
if (signature) {
|
|
10077
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signature);
|
|
10078
|
+
if (returnType) {
|
|
10079
|
+
return {
|
|
10080
|
+
callExpressionLike,
|
|
10081
|
+
location,
|
|
10082
|
+
returnType
|
|
10083
|
+
};
|
|
10084
|
+
}
|
|
10085
|
+
}
|
|
10086
|
+
}
|
|
10087
|
+
}
|
|
9858
10088
|
function getNodeForQuickInfo(node2) {
|
|
9859
10089
|
if (ts.isNewExpression(node2.parent) && node2.pos === node2.parent.pos) {
|
|
9860
10090
|
return node2.parent.expression;
|
|
@@ -9875,6 +10105,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9875
10105
|
if (ts.isToken(adjustedNode) && adjustedNode.kind === ts.SyntaxKind.YieldKeyword) {
|
|
9876
10106
|
if (ts.isYieldExpression(adjustedNode.parent) && adjustedNode.parent.asteriskToken && adjustedNode.parent.expression) {
|
|
9877
10107
|
return {
|
|
10108
|
+
label: "Effect Type Parameters",
|
|
9878
10109
|
type: typeChecker.getTypeAtLocation(adjustedNode.parent.expression),
|
|
9879
10110
|
atLocation: adjustedNode.parent.expression,
|
|
9880
10111
|
node: adjustedNode.parent,
|
|
@@ -9882,7 +10113,18 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9882
10113
|
};
|
|
9883
10114
|
}
|
|
9884
10115
|
}
|
|
10116
|
+
const nodeSignature = getSignatureForQuickInfo(adjustedNode);
|
|
10117
|
+
if (nodeSignature) {
|
|
10118
|
+
return {
|
|
10119
|
+
label: "Returned Effect Type Parameters",
|
|
10120
|
+
type: nodeSignature.returnType,
|
|
10121
|
+
atLocation: nodeSignature.location,
|
|
10122
|
+
node: nodeSignature.callExpressionLike,
|
|
10123
|
+
shouldTry: options.quickinfoEffectParameters === "always" && quickInfo2 ? true : quickInfo2 && ts.displayPartsToString(quickInfo2.displayParts).indexOf("...") > -1
|
|
10124
|
+
};
|
|
10125
|
+
}
|
|
9885
10126
|
return {
|
|
10127
|
+
label: "Effect Type Parameters",
|
|
9886
10128
|
type: typeChecker.getTypeAtLocation(adjustedNode),
|
|
9887
10129
|
atLocation: adjustedNode,
|
|
9888
10130
|
node: adjustedNode,
|
|
@@ -9891,25 +10133,13 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9891
10133
|
}
|
|
9892
10134
|
const data = getDataForQuickInfo();
|
|
9893
10135
|
if (!(data && data.shouldTry)) return quickInfo2;
|
|
9894
|
-
const { atLocation, node, type } = data;
|
|
10136
|
+
const { atLocation, label, node, type } = data;
|
|
9895
10137
|
const effectTypeArgsDocumentation = yield* pipe(
|
|
9896
10138
|
typeParser.effectType(
|
|
9897
10139
|
type,
|
|
9898
10140
|
atLocation
|
|
9899
10141
|
),
|
|
9900
|
-
map5((_) => makeSymbolDisplayParts(
|
|
9901
|
-
orElse2(() => {
|
|
9902
|
-
const callSignatues = typeChecker.getSignaturesOfType(type, ts.SignatureKind.Call);
|
|
9903
|
-
if (callSignatues.length !== 1) return succeed([]);
|
|
9904
|
-
const returnType = typeChecker.getReturnTypeOfSignature(callSignatues[0]);
|
|
9905
|
-
return pipe(
|
|
9906
|
-
typeParser.effectType(
|
|
9907
|
-
returnType,
|
|
9908
|
-
atLocation
|
|
9909
|
-
),
|
|
9910
|
-
map5((_) => makeSymbolDisplayParts("Returned Effect Type Parameters", _.A, _.E, _.R))
|
|
9911
|
-
);
|
|
9912
|
-
})
|
|
10142
|
+
map5((_) => makeSymbolDisplayParts(label, _.A, _.E, _.R))
|
|
9913
10143
|
);
|
|
9914
10144
|
if (!quickInfo2) {
|
|
9915
10145
|
const start = ts.getTokenPosOfNode(node, sourceFile);
|
|
@@ -14167,7 +14397,7 @@ var extractLayerGraph = fn("extractLayerGraph")(function* (node, opts) {
|
|
|
14167
14397
|
}
|
|
14168
14398
|
}
|
|
14169
14399
|
}
|
|
14170
|
-
} else {
|
|
14400
|
+
} else if (ts.isExpression(node2)) {
|
|
14171
14401
|
layerType = typeChecker.getTypeAtLocation(node2);
|
|
14172
14402
|
}
|
|
14173
14403
|
if (layerType) {
|
|
@@ -14279,7 +14509,7 @@ var extractLayerGraph = fn("extractLayerGraph")(function* (node, opts) {
|
|
|
14279
14509
|
let symbol3 = typeChecker.getSymbolAtLocation(node2);
|
|
14280
14510
|
if (symbol3) {
|
|
14281
14511
|
if (symbol3.flags & ts.SymbolFlags.Alias) {
|
|
14282
|
-
symbol3 = typeChecker.getAliasedSymbol(symbol3);
|
|
14512
|
+
symbol3 = typeChecker.getAliasedSymbol(symbol3) || symbol3;
|
|
14283
14513
|
}
|
|
14284
14514
|
if (symbol3.declarations && symbol3.declarations.length === 1) {
|
|
14285
14515
|
const declarationNode = getAdjustedNode2(symbol3.declarations[0]);
|