@effect/language-service 0.55.1 → 0.55.3
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 +185 -15
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +180 -6
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +267 -29
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +185 -15
- 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
|
}
|
|
@@ -4122,6 +4159,103 @@ var effectDataClasses = createCompletion({
|
|
|
4122
4159
|
})
|
|
4123
4160
|
});
|
|
4124
4161
|
|
|
4162
|
+
// src/diagnostics/anyUnknownInErrorContext.ts
|
|
4163
|
+
var anyUnknownInErrorContext = createDiagnostic({
|
|
4164
|
+
name: "anyUnknownInErrorContext",
|
|
4165
|
+
code: 28,
|
|
4166
|
+
severity: "off",
|
|
4167
|
+
apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
|
|
4168
|
+
const ts = yield* service(TypeScriptApi);
|
|
4169
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
4170
|
+
const typeParser = yield* service(TypeParser);
|
|
4171
|
+
const isAnyOrUnknown = (type) => (type.flags & ts.TypeFlags.Any) > 0 || (type.flags & ts.TypeFlags.Unknown) > 0;
|
|
4172
|
+
const matchingNodes = [];
|
|
4173
|
+
const nodeToVisit = [sourceFile];
|
|
4174
|
+
const appendNodeToVisit = (node) => {
|
|
4175
|
+
nodeToVisit.push(node);
|
|
4176
|
+
return void 0;
|
|
4177
|
+
};
|
|
4178
|
+
while (nodeToVisit.length > 0) {
|
|
4179
|
+
const node = nodeToVisit.pop();
|
|
4180
|
+
if (ts.isTypeNode(node)) continue;
|
|
4181
|
+
if (ts.isTypeAliasDeclaration(node)) continue;
|
|
4182
|
+
if (ts.isInterfaceDeclaration(node)) continue;
|
|
4183
|
+
if (ts.isAsExpression(node) && node.type && node.type.kind === ts.SyntaxKind.AnyKeyword) {
|
|
4184
|
+
continue;
|
|
4185
|
+
}
|
|
4186
|
+
if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
|
|
4187
|
+
if (node.type) {
|
|
4188
|
+
const type2 = typeChecker.getTypeAtLocation(node.type);
|
|
4189
|
+
const expectedEffect = yield* pipe(
|
|
4190
|
+
typeParser.strictEffectType(type2, node.type),
|
|
4191
|
+
orElse2(() => void_)
|
|
4192
|
+
);
|
|
4193
|
+
if (expectedEffect) continue;
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
4197
|
+
if (!ts.isExpression(node)) continue;
|
|
4198
|
+
let type = typeChecker.getTypeAtLocation(node);
|
|
4199
|
+
if (ts.isCallExpression(node)) {
|
|
4200
|
+
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
4201
|
+
if (resolvedSignature) {
|
|
4202
|
+
type = typeChecker.getReturnTypeOfSignature(resolvedSignature);
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4205
|
+
if (!type) continue;
|
|
4206
|
+
yield* pipe(
|
|
4207
|
+
typeParser.strictEffectType(type, node),
|
|
4208
|
+
map5((effect) => {
|
|
4209
|
+
const { E, R } = effect;
|
|
4210
|
+
const hasAnyUnknownR = isAnyOrUnknown(R);
|
|
4211
|
+
const hasAnyUnknownE = isAnyOrUnknown(E);
|
|
4212
|
+
if (hasAnyUnknownR || hasAnyUnknownE) {
|
|
4213
|
+
const channels = [];
|
|
4214
|
+
if (hasAnyUnknownR) {
|
|
4215
|
+
const typeName = R.flags & ts.TypeFlags.Any ? "any" : "unknown";
|
|
4216
|
+
channels.push(`${typeName} in the requirements channel`);
|
|
4217
|
+
}
|
|
4218
|
+
if (hasAnyUnknownE) {
|
|
4219
|
+
const typeName = E.flags & ts.TypeFlags.Any ? "any" : "unknown";
|
|
4220
|
+
channels.push(`${typeName} in the error channel`);
|
|
4221
|
+
}
|
|
4222
|
+
const nodeStart = ts.getTokenPosOfNode(node, sourceFile);
|
|
4223
|
+
const nodeEnd = node.end;
|
|
4224
|
+
for (let i = matchingNodes.length - 1; i >= 0; i--) {
|
|
4225
|
+
const existing = matchingNodes[i];
|
|
4226
|
+
const existingStart = ts.getTokenPosOfNode(existing.node, sourceFile);
|
|
4227
|
+
const existingEnd = existing.node.end;
|
|
4228
|
+
if (existingStart <= nodeStart && existingEnd >= nodeEnd) {
|
|
4229
|
+
matchingNodes.splice(i, 1);
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
const suggestions = [`This Effect has ${channels.join(" and ")} which is not recommended.`];
|
|
4233
|
+
if (hasAnyUnknownR) {
|
|
4234
|
+
suggestions.push(`Only service identifiers should appear in the requirements channel.`);
|
|
4235
|
+
}
|
|
4236
|
+
if (hasAnyUnknownE) {
|
|
4237
|
+
suggestions.push(
|
|
4238
|
+
`Having an unknown or any error type is not useful. Consider instead using specific error types baked by Data.TaggedError for example.`
|
|
4239
|
+
);
|
|
4240
|
+
}
|
|
4241
|
+
channels.push(`If you plan to later on manually cast the type, you can safely disable this diagnostic.`);
|
|
4242
|
+
const messageText = suggestions.join("\n");
|
|
4243
|
+
matchingNodes.push({ messageText, node, type });
|
|
4244
|
+
}
|
|
4245
|
+
}),
|
|
4246
|
+
ignore
|
|
4247
|
+
);
|
|
4248
|
+
}
|
|
4249
|
+
for (const { messageText, node } of matchingNodes) {
|
|
4250
|
+
report({
|
|
4251
|
+
location: node,
|
|
4252
|
+
messageText,
|
|
4253
|
+
fixes: []
|
|
4254
|
+
});
|
|
4255
|
+
}
|
|
4256
|
+
})
|
|
4257
|
+
});
|
|
4258
|
+
|
|
4125
4259
|
// src/diagnostics/catchUnfailableEffect.ts
|
|
4126
4260
|
var catchUnfailableEffect = createDiagnostic({
|
|
4127
4261
|
name: "catchUnfailableEffect",
|
|
@@ -7169,8 +7303,20 @@ var missedPipeableOpportunity = createDiagnostic({
|
|
|
7169
7303
|
while (nodeToVisit.length > 0) {
|
|
7170
7304
|
const node = nodeToVisit.shift();
|
|
7171
7305
|
if (ts.isCallExpression(node) && node.arguments.length === 1) {
|
|
7172
|
-
const
|
|
7173
|
-
|
|
7306
|
+
const isPipeCall = yield* pipe(typeParser.pipeCall(node), orElse2(() => void_));
|
|
7307
|
+
if (!isPipeCall) {
|
|
7308
|
+
const resolvedSignature = typeChecker.getResolvedSignature(node);
|
|
7309
|
+
if (resolvedSignature) {
|
|
7310
|
+
const returnType = typeChecker.getReturnTypeOfSignature(resolvedSignature);
|
|
7311
|
+
if (returnType) {
|
|
7312
|
+
const callSignatures = typeChecker.getSignaturesOfType(returnType, ts.SignatureKind.Call);
|
|
7313
|
+
if (callSignatures.length === 0) {
|
|
7314
|
+
const parentChain = callChainNodes.get(node) || [];
|
|
7315
|
+
callChainNodes.set(node.arguments[0], parentChain.concat(node));
|
|
7316
|
+
}
|
|
7317
|
+
}
|
|
7318
|
+
}
|
|
7319
|
+
}
|
|
7174
7320
|
} else if (callChainNodes.has(node) && ts.isExpression(node)) {
|
|
7175
7321
|
const parentChain = (callChainNodes.get(node) || []).slice();
|
|
7176
7322
|
const originalParentChain = parentChain.slice();
|
|
@@ -7873,6 +8019,26 @@ var overriddenSchemaConstructor = createDiagnostic({
|
|
|
7873
8019
|
const ts = yield* service(TypeScriptApi);
|
|
7874
8020
|
const typeParser = yield* service(TypeParser);
|
|
7875
8021
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
8022
|
+
function isAllowedConstructor(node) {
|
|
8023
|
+
if (node.body && node.body.statements.length === 1) {
|
|
8024
|
+
const expressionStatement = node.body.statements[0];
|
|
8025
|
+
if (ts.isExpressionStatement(expressionStatement)) {
|
|
8026
|
+
const maybeCallSuper = expressionStatement.expression;
|
|
8027
|
+
if (ts.isCallExpression(maybeCallSuper)) {
|
|
8028
|
+
if (maybeCallSuper.expression.kind === ts.SyntaxKind.SuperKeyword) {
|
|
8029
|
+
const expectedNames = node.parameters.map((_) => _.name).filter(ts.isIdentifier).map((_) => ts.idText(_));
|
|
8030
|
+
if (expectedNames.length === 2 && expectedNames.length === node.parameters.length) {
|
|
8031
|
+
const givenNames = maybeCallSuper.arguments.filter(ts.isIdentifier).map((_) => ts.idText(_));
|
|
8032
|
+
if (givenNames.length === expectedNames.length && givenNames.every((name, index) => name === expectedNames[index])) {
|
|
8033
|
+
return true;
|
|
8034
|
+
}
|
|
8035
|
+
}
|
|
8036
|
+
}
|
|
8037
|
+
}
|
|
8038
|
+
}
|
|
8039
|
+
}
|
|
8040
|
+
return false;
|
|
8041
|
+
}
|
|
7876
8042
|
const nodeToVisit = [];
|
|
7877
8043
|
const appendNodeToVisit = (node) => {
|
|
7878
8044
|
nodeToVisit.push(node);
|
|
@@ -7904,6 +8070,9 @@ var overriddenSchemaConstructor = createDiagnostic({
|
|
|
7904
8070
|
const members = node.members;
|
|
7905
8071
|
for (const member of members) {
|
|
7906
8072
|
if (ts.isConstructorDeclaration(member)) {
|
|
8073
|
+
if (isAllowedConstructor(member)) {
|
|
8074
|
+
continue;
|
|
8075
|
+
}
|
|
7907
8076
|
const fixAsStaticNew = {
|
|
7908
8077
|
fixName: "overriddenSchemaConstructor_static",
|
|
7909
8078
|
description: "Rewrite using the static 'new' pattern",
|
|
@@ -8701,6 +8870,7 @@ var unsupportedServiceAccessors = createDiagnostic({
|
|
|
8701
8870
|
|
|
8702
8871
|
// src/diagnostics.ts
|
|
8703
8872
|
var diagnostics = [
|
|
8873
|
+
anyUnknownInErrorContext,
|
|
8704
8874
|
catchUnfailableEffect,
|
|
8705
8875
|
classSelfMismatch,
|
|
8706
8876
|
duplicatePackage,
|
|
@@ -9816,6 +9986,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9816
9986
|
const ts = yield* service(TypeScriptApi);
|
|
9817
9987
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
9818
9988
|
const typeParser = yield* service(TypeParser);
|
|
9989
|
+
const tsUtils = yield* service(TypeScriptUtils);
|
|
9819
9990
|
const options = yield* service(LanguageServicePluginOptions);
|
|
9820
9991
|
if (options.quickinfoEffectParameters === "never") return quickInfo2;
|
|
9821
9992
|
function formatTypeForQuickInfo(channelType, channelName) {
|
|
@@ -9843,6 +10014,73 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9843
10014
|
text: "```ts\n/* " + title + " */\n" + formatTypeForQuickInfo(A, "Success") + "\n" + formatTypeForQuickInfo(E, "Failure") + "\n" + formatTypeForQuickInfo(R, "Requirements") + "\n```\n"
|
|
9844
10015
|
}];
|
|
9845
10016
|
}
|
|
10017
|
+
function isRightSideOfPropertyAccess(node2) {
|
|
10018
|
+
return node2.parent && ts.isPropertyAccessExpression(node2.parent) && node2.parent.name === node2;
|
|
10019
|
+
}
|
|
10020
|
+
function isArgumentExpressionOfElementAccess(node2) {
|
|
10021
|
+
return node2.parent && ts.isElementAccessExpression(node2.parent) && node2.parent.argumentExpression === node2;
|
|
10022
|
+
}
|
|
10023
|
+
function isCalleeWorker(node2, pred, calleeSelector, includeElementAccess, skipPastOuterExpressions) {
|
|
10024
|
+
let target = includeElementAccess ? climbPastPropertyOrElementAccess(node2) : climbPastPropertyAccess(node2);
|
|
10025
|
+
if (skipPastOuterExpressions) {
|
|
10026
|
+
target = tsUtils.skipOuterExpressions(target);
|
|
10027
|
+
}
|
|
10028
|
+
return !!target && !!target.parent && pred(target.parent) && calleeSelector(target.parent) === target;
|
|
10029
|
+
}
|
|
10030
|
+
function climbPastPropertyAccess(node2) {
|
|
10031
|
+
return isRightSideOfPropertyAccess(node2) ? node2.parent : node2;
|
|
10032
|
+
}
|
|
10033
|
+
function climbPastPropertyOrElementAccess(node2) {
|
|
10034
|
+
return isRightSideOfPropertyAccess(node2) || isArgumentExpressionOfElementAccess(node2) ? node2.parent : node2;
|
|
10035
|
+
}
|
|
10036
|
+
function selectExpressionOfCallOrNewExpressionOrDecorator(node2) {
|
|
10037
|
+
return node2.expression;
|
|
10038
|
+
}
|
|
10039
|
+
function isCallExpressionTarget(node2, includeElementAccess = false, skipPastOuterExpressions = false) {
|
|
10040
|
+
return isCalleeWorker(
|
|
10041
|
+
node2,
|
|
10042
|
+
ts.isCallExpression,
|
|
10043
|
+
selectExpressionOfCallOrNewExpressionOrDecorator,
|
|
10044
|
+
includeElementAccess,
|
|
10045
|
+
skipPastOuterExpressions
|
|
10046
|
+
);
|
|
10047
|
+
}
|
|
10048
|
+
function isNewExpressionTarget(node2, includeElementAccess = false, skipPastOuterExpressions = false) {
|
|
10049
|
+
return isCalleeWorker(
|
|
10050
|
+
node2,
|
|
10051
|
+
ts.isNewExpression,
|
|
10052
|
+
selectExpressionOfCallOrNewExpressionOrDecorator,
|
|
10053
|
+
includeElementAccess,
|
|
10054
|
+
skipPastOuterExpressions
|
|
10055
|
+
);
|
|
10056
|
+
}
|
|
10057
|
+
function getSignatureForQuickInfo(location) {
|
|
10058
|
+
if (location.parent && location.parent.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
|
10059
|
+
const right3 = location.parent.name;
|
|
10060
|
+
if (right3 === location || right3 && right3.getFullWidth() === 0) {
|
|
10061
|
+
location = location.parent;
|
|
10062
|
+
}
|
|
10063
|
+
}
|
|
10064
|
+
let callExpressionLike;
|
|
10065
|
+
if (ts.isCallOrNewExpression(location)) {
|
|
10066
|
+
callExpressionLike = location;
|
|
10067
|
+
} else if (isCallExpressionTarget(location) || isNewExpressionTarget(location)) {
|
|
10068
|
+
callExpressionLike = location.parent;
|
|
10069
|
+
}
|
|
10070
|
+
if (callExpressionLike) {
|
|
10071
|
+
const signature = typeChecker.getResolvedSignature(callExpressionLike);
|
|
10072
|
+
if (signature) {
|
|
10073
|
+
const returnType = typeChecker.getReturnTypeOfSignature(signature);
|
|
10074
|
+
if (returnType) {
|
|
10075
|
+
return {
|
|
10076
|
+
callExpressionLike,
|
|
10077
|
+
location,
|
|
10078
|
+
returnType
|
|
10079
|
+
};
|
|
10080
|
+
}
|
|
10081
|
+
}
|
|
10082
|
+
}
|
|
10083
|
+
}
|
|
9846
10084
|
function getNodeForQuickInfo(node2) {
|
|
9847
10085
|
if (ts.isNewExpression(node2.parent) && node2.pos === node2.parent.pos) {
|
|
9848
10086
|
return node2.parent.expression;
|
|
@@ -9863,6 +10101,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9863
10101
|
if (ts.isToken(adjustedNode) && adjustedNode.kind === ts.SyntaxKind.YieldKeyword) {
|
|
9864
10102
|
if (ts.isYieldExpression(adjustedNode.parent) && adjustedNode.parent.asteriskToken && adjustedNode.parent.expression) {
|
|
9865
10103
|
return {
|
|
10104
|
+
label: "Effect Type Parameters",
|
|
9866
10105
|
type: typeChecker.getTypeAtLocation(adjustedNode.parent.expression),
|
|
9867
10106
|
atLocation: adjustedNode.parent.expression,
|
|
9868
10107
|
node: adjustedNode.parent,
|
|
@@ -9870,7 +10109,18 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9870
10109
|
};
|
|
9871
10110
|
}
|
|
9872
10111
|
}
|
|
10112
|
+
const nodeSignature = getSignatureForQuickInfo(adjustedNode);
|
|
10113
|
+
if (nodeSignature) {
|
|
10114
|
+
return {
|
|
10115
|
+
label: "Returned Effect Type Parameters",
|
|
10116
|
+
type: nodeSignature.returnType,
|
|
10117
|
+
atLocation: nodeSignature.location,
|
|
10118
|
+
node: nodeSignature.callExpressionLike,
|
|
10119
|
+
shouldTry: options.quickinfoEffectParameters === "always" && quickInfo2 ? true : quickInfo2 && ts.displayPartsToString(quickInfo2.displayParts).indexOf("...") > -1
|
|
10120
|
+
};
|
|
10121
|
+
}
|
|
9873
10122
|
return {
|
|
10123
|
+
label: "Effect Type Parameters",
|
|
9874
10124
|
type: typeChecker.getTypeAtLocation(adjustedNode),
|
|
9875
10125
|
atLocation: adjustedNode,
|
|
9876
10126
|
node: adjustedNode,
|
|
@@ -9879,25 +10129,13 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
|
|
|
9879
10129
|
}
|
|
9880
10130
|
const data = getDataForQuickInfo();
|
|
9881
10131
|
if (!(data && data.shouldTry)) return quickInfo2;
|
|
9882
|
-
const { atLocation, node, type } = data;
|
|
10132
|
+
const { atLocation, label, node, type } = data;
|
|
9883
10133
|
const effectTypeArgsDocumentation = yield* pipe(
|
|
9884
10134
|
typeParser.effectType(
|
|
9885
10135
|
type,
|
|
9886
10136
|
atLocation
|
|
9887
10137
|
),
|
|
9888
|
-
map5((_) => makeSymbolDisplayParts(
|
|
9889
|
-
orElse2(() => {
|
|
9890
|
-
const callSignatues = typeChecker.getSignaturesOfType(type, ts.SignatureKind.Call);
|
|
9891
|
-
if (callSignatues.length !== 1) return succeed([]);
|
|
9892
|
-
const returnType = typeChecker.getReturnTypeOfSignature(callSignatues[0]);
|
|
9893
|
-
return pipe(
|
|
9894
|
-
typeParser.effectType(
|
|
9895
|
-
returnType,
|
|
9896
|
-
atLocation
|
|
9897
|
-
),
|
|
9898
|
-
map5((_) => makeSymbolDisplayParts("Returned Effect Type Parameters", _.A, _.E, _.R))
|
|
9899
|
-
);
|
|
9900
|
-
})
|
|
10138
|
+
map5((_) => makeSymbolDisplayParts(label, _.A, _.E, _.R))
|
|
9901
10139
|
);
|
|
9902
10140
|
if (!quickInfo2) {
|
|
9903
10141
|
const start = ts.getTokenPosOfNode(node, sourceFile);
|