@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/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
- return unsafeRun(nano);
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
- return !(symbol3.declarations || []).some((declaration) => {
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("Effect Type Parameters", _.A, _.E, _.R)),
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]);