@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 CHANGED
@@ -30069,8 +30069,9 @@ var contAll = Symbol.for("Nano.contAll");
30069
30069
  var NanoYield = Symbol.for("Nano.yield");
30070
30070
  var args2 = Symbol.for("Nano.args");
30071
30071
  var NanoDefectException = class {
30072
- constructor(message) {
30072
+ constructor(message, lastSpan) {
30073
30073
  this.message = message;
30074
+ this.lastSpan = lastSpan;
30074
30075
  }
30075
30076
  _tag = "@effect/language-service/NanoDefectException";
30076
30077
  };
@@ -30128,6 +30129,7 @@ var NanoFiber = class {
30128
30129
  _services = {};
30129
30130
  _cache = {};
30130
30131
  _perf = false;
30132
+ _lastSpan = "";
30131
30133
  runLoop(nano) {
30132
30134
  let current = nano;
30133
30135
  while (true) {
@@ -30158,17 +30160,21 @@ var WithSpanProto = {
30158
30160
  [evaluate2](fiber) {
30159
30161
  const [fa, name] = this[args2];
30160
30162
  if (!fiber._perf) return fa;
30163
+ const previousSpan = fiber._lastSpan;
30164
+ fiber._lastSpan = name;
30161
30165
  const start4 = performance.now();
30162
30166
  timingsCount[name] = (timingsCount[name] || 0) + 1;
30163
30167
  return match17(fa, {
30164
30168
  onSuccess: (_) => {
30165
30169
  const end5 = performance.now();
30166
30170
  timings[name] = (timings[name] || 0) + (end5 - start4);
30171
+ fiber._lastSpan = previousSpan;
30167
30172
  return succeed17(_);
30168
30173
  },
30169
30174
  onFailure: (_) => {
30170
30175
  const end5 = performance.now();
30171
30176
  timings[name] = (timings[name] || 0) + (end5 - start4);
30177
+ fiber._lastSpan = previousSpan;
30172
30178
  return fail18(_);
30173
30179
  }
30174
30180
  });
@@ -30179,19 +30185,16 @@ var withSpan6 = (name) => (fa) => {
30179
30185
  nano[args2] = [fa, name];
30180
30186
  return nano;
30181
30187
  };
30182
- var unsafeRun = (nano) => {
30183
- const fiber = new NanoFiber();
30184
- const result = fiber.runLoop(nano);
30185
- if (result._tag === "Success") {
30186
- return right2(result.value);
30187
- }
30188
- return left2(result.value);
30189
- };
30190
30188
  var run9 = (nano) => {
30189
+ const fiber = new NanoFiber();
30191
30190
  try {
30192
- return unsafeRun(nano);
30191
+ const result = fiber.runLoop(nano);
30192
+ if (result._tag === "Success") {
30193
+ return right2(result.value);
30194
+ }
30195
+ return left2(result.value);
30193
30196
  } catch (e) {
30194
- return left2(new NanoDefectException(e));
30197
+ return left2(new NanoDefectException(e, fiber._lastSpan));
30195
30198
  }
30196
30199
  };
30197
30200
  var OnSuccessProto2 = {
@@ -30298,7 +30301,7 @@ var ServiceProto = {
30298
30301
  return cont2 ? cont2[contA](value5, fiber) : fiber.yieldWith(succeed17(value5));
30299
30302
  }
30300
30303
  const cont = fiber.getCont(contE);
30301
- return cont ? cont[contE](tag4, fiber) : fiber.yieldWith(fail18(new NanoDefectException(`Service ${tag4.key} not found`)));
30304
+ return cont ? cont[contE](tag4, fiber) : fiber.yieldWith(fail18(new NanoDefectException(`Service ${tag4.key} not found`, fiber._lastSpan)));
30302
30305
  }
30303
30306
  };
30304
30307
  var service2 = (tag4) => {
@@ -30877,6 +30880,30 @@ function makeTypeScriptUtils(ts) {
30877
30880
  }
30878
30881
  return node;
30879
30882
  }
30883
+ function isOuterExpression(node, kinds = ts.OuterExpressionKinds.All) {
30884
+ switch (node.kind) {
30885
+ case ts.SyntaxKind.ParenthesizedExpression:
30886
+ return (kinds & ts.OuterExpressionKinds.Parentheses) !== 0;
30887
+ case ts.SyntaxKind.TypeAssertionExpression:
30888
+ case ts.SyntaxKind.AsExpression:
30889
+ return (kinds & ts.OuterExpressionKinds.TypeAssertions) !== 0;
30890
+ case ts.SyntaxKind.SatisfiesExpression:
30891
+ return (kinds & (ts.OuterExpressionKinds.TypeAssertions | ts.OuterExpressionKinds.Satisfies)) !== 0;
30892
+ case ts.SyntaxKind.ExpressionWithTypeArguments:
30893
+ return (kinds & ts.OuterExpressionKinds.ExpressionsWithTypeArguments) !== 0;
30894
+ case ts.SyntaxKind.NonNullExpression:
30895
+ return (kinds & ts.OuterExpressionKinds.NonNullAssertions) !== 0;
30896
+ case ts.SyntaxKind.PartiallyEmittedExpression:
30897
+ return (kinds & ts.OuterExpressionKinds.PartiallyEmittedExpressions) !== 0;
30898
+ }
30899
+ return false;
30900
+ }
30901
+ function skipOuterExpressions(node, kinds = ts.OuterExpressionKinds.All) {
30902
+ while (isOuterExpression(node, kinds)) {
30903
+ node = node.expression;
30904
+ }
30905
+ return node;
30906
+ }
30880
30907
  return {
30881
30908
  findNodeAtPositionIncludingTrivia,
30882
30909
  parsePackageContentNameAndVersionFromScope,
@@ -30897,7 +30924,9 @@ function makeTypeScriptUtils(ts) {
30897
30924
  createEffectGenCallExpressionWithBlock,
30898
30925
  createReturnYieldStarStatement,
30899
30926
  parseAccessedExpressionForCompletion,
30900
- getSourceFileOfNode
30927
+ getSourceFileOfNode,
30928
+ isOuterExpression,
30929
+ skipOuterExpressions
30901
30930
  };
30902
30931
  }
30903
30932
 
@@ -31330,6 +31359,14 @@ var createDiagnosticExecutor = fn2("LSP.createCommentDirectivesProcessor")(
31330
31359
  result = node2;
31331
31360
  return;
31332
31361
  }
31362
+ if (ts.isPropertyAssignment(node2)) {
31363
+ const realStart = ts.getTokenPosOfNode(node2, sourceFile);
31364
+ const starts = sourceFile.getLineStarts().filter((start4) => start4 >= node2.pos && start4 <= realStart);
31365
+ if (starts.length > 0) {
31366
+ result = node2;
31367
+ return;
31368
+ }
31369
+ }
31333
31370
  if (result) return;
31334
31371
  if (node2.parent) find3(node2.parent);
31335
31372
  }
@@ -31941,6 +31978,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
31941
31978
  const getSourceFilesDeclaringSymbolModule = (packageName) => cachedBy(
31942
31979
  fn2("TypeParser.getSourceFilesDeclaringSymbolModule")(function* (symbol3) {
31943
31980
  const result = [];
31981
+ if (!symbol3) return result;
31944
31982
  if (!symbol3.declarations) return yield* typeParserIssue("Symbol has no declarations", void 0, void 0);
31945
31983
  for (const sourceFile of symbol3.declarations) {
31946
31984
  if (!ts.isSourceFile(sourceFile)) continue;
@@ -31978,6 +32016,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
31978
32016
  const getSourceFilesDeclaringSymbolExportedUnderPackageModule = (packageName, memberName) => cachedBy(
31979
32017
  fn2("TypeParser.getSourceFilesDeclaringSymbolUnderPackageExportedMember")(function* (symbol3) {
31980
32018
  const result = [];
32019
+ if (!symbol3) return result;
31981
32020
  if (!symbol3.declarations) return yield* typeParserIssue("Symbol has no declarations", void 0, void 0);
31982
32021
  for (const declaration of symbol3.declarations) {
31983
32022
  const sourceFile = tsUtils.getSourceFileOfNode(declaration);
@@ -32199,14 +32238,14 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
32199
32238
  );
32200
32239
  const importedContextModule = cachedBy(
32201
32240
  fn2("TypeParser.importedContextModule")(function* (node) {
32241
+ if (!ts.isIdentifier(node)) {
32242
+ return yield* typeParserIssue("Node is not an identifier", void 0, node);
32243
+ }
32202
32244
  const type2 = typeChecker.getTypeAtLocation(node);
32203
32245
  const propertySymbol = typeChecker.getPropertyOfType(type2, "Tag");
32204
32246
  if (!propertySymbol) {
32205
32247
  return yield* typeParserIssue("Type has no 'Tag' property", type2, node);
32206
32248
  }
32207
- if (!ts.isIdentifier(node)) {
32208
- return yield* typeParserIssue("Node is not an identifier", type2, node);
32209
- }
32210
32249
  const sourceFile = tsUtils.getSourceFileOfNode(node);
32211
32250
  if (!sourceFile) {
32212
32251
  return yield* typeParserIssue("Node is not in a source file", void 0, node);
@@ -32233,14 +32272,14 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
32233
32272
  );
32234
32273
  const importedDataModule = cachedBy(
32235
32274
  fn2("TypeParser.importedDataModule")(function* (node) {
32275
+ if (!ts.isIdentifier(node)) {
32276
+ return yield* typeParserIssue("Node is not an expression", void 0, node);
32277
+ }
32236
32278
  const type2 = typeChecker.getTypeAtLocation(node);
32237
32279
  const propertySymbol = typeChecker.getPropertyOfType(type2, "TaggedError");
32238
32280
  if (!propertySymbol) {
32239
32281
  return yield* typeParserIssue("Type has no 'TaggedError' property", type2, node);
32240
32282
  }
32241
- if (!ts.isIdentifier(node)) {
32242
- return yield* typeParserIssue("Node is not an expression", type2, node);
32243
- }
32244
32283
  const sourceFile = tsUtils.getSourceFileOfNode(node);
32245
32284
  if (!sourceFile) {
32246
32285
  return yield* typeParserIssue("Node is not in a source file", void 0, node);
@@ -33024,6 +33063,103 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33024
33063
  };
33025
33064
  }
33026
33065
 
33066
+ // src/diagnostics/anyUnknownInErrorContext.ts
33067
+ var anyUnknownInErrorContext = createDiagnostic({
33068
+ name: "anyUnknownInErrorContext",
33069
+ code: 28,
33070
+ severity: "off",
33071
+ apply: fn2("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
33072
+ const ts = yield* service2(TypeScriptApi);
33073
+ const typeChecker = yield* service2(TypeCheckerApi);
33074
+ const typeParser = yield* service2(TypeParser);
33075
+ const isAnyOrUnknown = (type2) => (type2.flags & ts.TypeFlags.Any) > 0 || (type2.flags & ts.TypeFlags.Unknown) > 0;
33076
+ const matchingNodes = [];
33077
+ const nodeToVisit = [sourceFile];
33078
+ const appendNodeToVisit = (node) => {
33079
+ nodeToVisit.push(node);
33080
+ return void 0;
33081
+ };
33082
+ while (nodeToVisit.length > 0) {
33083
+ const node = nodeToVisit.pop();
33084
+ if (ts.isTypeNode(node)) continue;
33085
+ if (ts.isTypeAliasDeclaration(node)) continue;
33086
+ if (ts.isInterfaceDeclaration(node)) continue;
33087
+ if (ts.isAsExpression(node) && node.type && node.type.kind === ts.SyntaxKind.AnyKeyword) {
33088
+ continue;
33089
+ }
33090
+ if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
33091
+ if (node.type) {
33092
+ const type3 = typeChecker.getTypeAtLocation(node.type);
33093
+ const expectedEffect = yield* pipe(
33094
+ typeParser.strictEffectType(type3, node.type),
33095
+ orElse14(() => void_8)
33096
+ );
33097
+ if (expectedEffect) continue;
33098
+ }
33099
+ }
33100
+ ts.forEachChild(node, appendNodeToVisit);
33101
+ if (!ts.isExpression(node)) continue;
33102
+ let type2 = typeChecker.getTypeAtLocation(node);
33103
+ if (ts.isCallExpression(node)) {
33104
+ const resolvedSignature = typeChecker.getResolvedSignature(node);
33105
+ if (resolvedSignature) {
33106
+ type2 = typeChecker.getReturnTypeOfSignature(resolvedSignature);
33107
+ }
33108
+ }
33109
+ if (!type2) continue;
33110
+ yield* pipe(
33111
+ typeParser.strictEffectType(type2, node),
33112
+ map34((effect3) => {
33113
+ const { E, R } = effect3;
33114
+ const hasAnyUnknownR = isAnyOrUnknown(R);
33115
+ const hasAnyUnknownE = isAnyOrUnknown(E);
33116
+ if (hasAnyUnknownR || hasAnyUnknownE) {
33117
+ const channels = [];
33118
+ if (hasAnyUnknownR) {
33119
+ const typeName = R.flags & ts.TypeFlags.Any ? "any" : "unknown";
33120
+ channels.push(`${typeName} in the requirements channel`);
33121
+ }
33122
+ if (hasAnyUnknownE) {
33123
+ const typeName = E.flags & ts.TypeFlags.Any ? "any" : "unknown";
33124
+ channels.push(`${typeName} in the error channel`);
33125
+ }
33126
+ const nodeStart = ts.getTokenPosOfNode(node, sourceFile);
33127
+ const nodeEnd = node.end;
33128
+ for (let i = matchingNodes.length - 1; i >= 0; i--) {
33129
+ const existing = matchingNodes[i];
33130
+ const existingStart = ts.getTokenPosOfNode(existing.node, sourceFile);
33131
+ const existingEnd = existing.node.end;
33132
+ if (existingStart <= nodeStart && existingEnd >= nodeEnd) {
33133
+ matchingNodes.splice(i, 1);
33134
+ }
33135
+ }
33136
+ const suggestions = [`This Effect has ${channels.join(" and ")} which is not recommended.`];
33137
+ if (hasAnyUnknownR) {
33138
+ suggestions.push(`Only service identifiers should appear in the requirements channel.`);
33139
+ }
33140
+ if (hasAnyUnknownE) {
33141
+ suggestions.push(
33142
+ `Having an unknown or any error type is not useful. Consider instead using specific error types baked by Data.TaggedError for example.`
33143
+ );
33144
+ }
33145
+ channels.push(`If you plan to later on manually cast the type, you can safely disable this diagnostic.`);
33146
+ const messageText = suggestions.join("\n");
33147
+ matchingNodes.push({ messageText, node, type: type2 });
33148
+ }
33149
+ }),
33150
+ ignore3
33151
+ );
33152
+ }
33153
+ for (const { messageText, node } of matchingNodes) {
33154
+ report({
33155
+ location: node,
33156
+ messageText,
33157
+ fixes: []
33158
+ });
33159
+ }
33160
+ })
33161
+ });
33162
+
33027
33163
  // src/diagnostics/catchUnfailableEffect.ts
33028
33164
  var catchUnfailableEffect = createDiagnostic({
33029
33165
  name: "catchUnfailableEffect",
@@ -33785,9 +33921,10 @@ var leakingRequirements = createDiagnostic({
33785
33921
  (type2) => {
33786
33922
  let symbol3 = type2.symbol;
33787
33923
  if (symbol3 && symbol3.flags & ts.SymbolFlags.Alias) {
33788
- symbol3 = typeChecker.getAliasedSymbol(symbol3);
33924
+ symbol3 = typeChecker.getAliasedSymbol(symbol3) || symbol3;
33789
33925
  }
33790
- return !(symbol3.declarations || []).some((declaration) => {
33926
+ if (!symbol3) return false;
33927
+ return !(symbol3?.declarations || []).some((declaration) => {
33791
33928
  const declarationSource = tsUtils.getSourceFileOfNode(declaration);
33792
33929
  if (!declarationSource) return false;
33793
33930
  return declarationSource.text.substring(declaration.pos, declaration.end).toLowerCase().indexOf(
@@ -34882,6 +35019,26 @@ var overriddenSchemaConstructor = createDiagnostic({
34882
35019
  const ts = yield* service2(TypeScriptApi);
34883
35020
  const typeParser = yield* service2(TypeParser);
34884
35021
  const typeChecker = yield* service2(TypeCheckerApi);
35022
+ function isAllowedConstructor(node) {
35023
+ if (node.body && node.body.statements.length === 1) {
35024
+ const expressionStatement = node.body.statements[0];
35025
+ if (ts.isExpressionStatement(expressionStatement)) {
35026
+ const maybeCallSuper = expressionStatement.expression;
35027
+ if (ts.isCallExpression(maybeCallSuper)) {
35028
+ if (maybeCallSuper.expression.kind === ts.SyntaxKind.SuperKeyword) {
35029
+ const expectedNames = node.parameters.map((_) => _.name).filter(ts.isIdentifier).map((_) => ts.idText(_));
35030
+ if (expectedNames.length === 2 && expectedNames.length === node.parameters.length) {
35031
+ const givenNames = maybeCallSuper.arguments.filter(ts.isIdentifier).map((_) => ts.idText(_));
35032
+ if (givenNames.length === expectedNames.length && givenNames.every((name, index) => name === expectedNames[index])) {
35033
+ return true;
35034
+ }
35035
+ }
35036
+ }
35037
+ }
35038
+ }
35039
+ }
35040
+ return false;
35041
+ }
34885
35042
  const nodeToVisit = [];
34886
35043
  const appendNodeToVisit = (node) => {
34887
35044
  nodeToVisit.push(node);
@@ -34913,6 +35070,9 @@ var overriddenSchemaConstructor = createDiagnostic({
34913
35070
  const members = node.members;
34914
35071
  for (const member of members) {
34915
35072
  if (ts.isConstructorDeclaration(member)) {
35073
+ if (isAllowedConstructor(member)) {
35074
+ continue;
35075
+ }
34916
35076
  const fixAsStaticNew = {
34917
35077
  fixName: "overriddenSchemaConstructor_static",
34918
35078
  description: "Rewrite using the static 'new' pattern",
@@ -35321,6 +35481,7 @@ var strictBooleanExpressions = createDiagnostic({
35321
35481
  for (const nodeToCheck of nodes) {
35322
35482
  if (!nodeToCheck) continue;
35323
35483
  if (!conditionChecks.has(nodeToCheck.parent)) continue;
35484
+ if (!ts.isExpression(nodeToCheck)) continue;
35324
35485
  const nodeType = typeChecker.getTypeAtLocation(nodeToCheck);
35325
35486
  const constrainedType = typeChecker.getBaseConstraintOfType(nodeType);
35326
35487
  let typesToCheck = [constrainedType || nodeType];
@@ -35710,6 +35871,7 @@ var unsupportedServiceAccessors = createDiagnostic({
35710
35871
 
35711
35872
  // src/diagnostics.ts
35712
35873
  var diagnostics = [
35874
+ anyUnknownInErrorContext,
35713
35875
  catchUnfailableEffect,
35714
35876
  classSelfMismatch,
35715
35877
  duplicatePackage,