@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 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
  }
@@ -33024,6 +33061,103 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33024
33061
  };
33025
33062
  }
33026
33063
 
33064
+ // src/diagnostics/anyUnknownInErrorContext.ts
33065
+ var anyUnknownInErrorContext = createDiagnostic({
33066
+ name: "anyUnknownInErrorContext",
33067
+ code: 28,
33068
+ severity: "off",
33069
+ apply: fn2("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
33070
+ const ts = yield* service2(TypeScriptApi);
33071
+ const typeChecker = yield* service2(TypeCheckerApi);
33072
+ const typeParser = yield* service2(TypeParser);
33073
+ const isAnyOrUnknown = (type2) => (type2.flags & ts.TypeFlags.Any) > 0 || (type2.flags & ts.TypeFlags.Unknown) > 0;
33074
+ const matchingNodes = [];
33075
+ const nodeToVisit = [sourceFile];
33076
+ const appendNodeToVisit = (node) => {
33077
+ nodeToVisit.push(node);
33078
+ return void 0;
33079
+ };
33080
+ while (nodeToVisit.length > 0) {
33081
+ const node = nodeToVisit.pop();
33082
+ if (ts.isTypeNode(node)) continue;
33083
+ if (ts.isTypeAliasDeclaration(node)) continue;
33084
+ if (ts.isInterfaceDeclaration(node)) continue;
33085
+ if (ts.isAsExpression(node) && node.type && node.type.kind === ts.SyntaxKind.AnyKeyword) {
33086
+ continue;
33087
+ }
33088
+ if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
33089
+ if (node.type) {
33090
+ const type3 = typeChecker.getTypeAtLocation(node.type);
33091
+ const expectedEffect = yield* pipe(
33092
+ typeParser.strictEffectType(type3, node.type),
33093
+ orElse14(() => void_8)
33094
+ );
33095
+ if (expectedEffect) continue;
33096
+ }
33097
+ }
33098
+ ts.forEachChild(node, appendNodeToVisit);
33099
+ if (!ts.isExpression(node)) continue;
33100
+ let type2 = typeChecker.getTypeAtLocation(node);
33101
+ if (ts.isCallExpression(node)) {
33102
+ const resolvedSignature = typeChecker.getResolvedSignature(node);
33103
+ if (resolvedSignature) {
33104
+ type2 = typeChecker.getReturnTypeOfSignature(resolvedSignature);
33105
+ }
33106
+ }
33107
+ if (!type2) continue;
33108
+ yield* pipe(
33109
+ typeParser.strictEffectType(type2, node),
33110
+ map34((effect3) => {
33111
+ const { E, R } = effect3;
33112
+ const hasAnyUnknownR = isAnyOrUnknown(R);
33113
+ const hasAnyUnknownE = isAnyOrUnknown(E);
33114
+ if (hasAnyUnknownR || hasAnyUnknownE) {
33115
+ const channels = [];
33116
+ if (hasAnyUnknownR) {
33117
+ const typeName = R.flags & ts.TypeFlags.Any ? "any" : "unknown";
33118
+ channels.push(`${typeName} in the requirements channel`);
33119
+ }
33120
+ if (hasAnyUnknownE) {
33121
+ const typeName = E.flags & ts.TypeFlags.Any ? "any" : "unknown";
33122
+ channels.push(`${typeName} in the error channel`);
33123
+ }
33124
+ const nodeStart = ts.getTokenPosOfNode(node, sourceFile);
33125
+ const nodeEnd = node.end;
33126
+ for (let i = matchingNodes.length - 1; i >= 0; i--) {
33127
+ const existing = matchingNodes[i];
33128
+ const existingStart = ts.getTokenPosOfNode(existing.node, sourceFile);
33129
+ const existingEnd = existing.node.end;
33130
+ if (existingStart <= nodeStart && existingEnd >= nodeEnd) {
33131
+ matchingNodes.splice(i, 1);
33132
+ }
33133
+ }
33134
+ const suggestions = [`This Effect has ${channels.join(" and ")} which is not recommended.`];
33135
+ if (hasAnyUnknownR) {
33136
+ suggestions.push(`Only service identifiers should appear in the requirements channel.`);
33137
+ }
33138
+ if (hasAnyUnknownE) {
33139
+ suggestions.push(
33140
+ `Having an unknown or any error type is not useful. Consider instead using specific error types baked by Data.TaggedError for example.`
33141
+ );
33142
+ }
33143
+ channels.push(`If you plan to later on manually cast the type, you can safely disable this diagnostic.`);
33144
+ const messageText = suggestions.join("\n");
33145
+ matchingNodes.push({ messageText, node, type: type2 });
33146
+ }
33147
+ }),
33148
+ ignore3
33149
+ );
33150
+ }
33151
+ for (const { messageText, node } of matchingNodes) {
33152
+ report({
33153
+ location: node,
33154
+ messageText,
33155
+ fixes: []
33156
+ });
33157
+ }
33158
+ })
33159
+ });
33160
+
33027
33161
  // src/diagnostics/catchUnfailableEffect.ts
33028
33162
  var catchUnfailableEffect = createDiagnostic({
33029
33163
  name: "catchUnfailableEffect",
@@ -33872,8 +34006,20 @@ var missedPipeableOpportunity = createDiagnostic({
33872
34006
  while (nodeToVisit.length > 0) {
33873
34007
  const node = nodeToVisit.shift();
33874
34008
  if (ts.isCallExpression(node) && node.arguments.length === 1) {
33875
- const parentChain = callChainNodes.get(node) || [];
33876
- callChainNodes.set(node.arguments[0], parentChain.concat(node));
34009
+ const isPipeCall = yield* pipe(typeParser.pipeCall(node), orElse14(() => void_8));
34010
+ if (!isPipeCall) {
34011
+ const resolvedSignature = typeChecker.getResolvedSignature(node);
34012
+ if (resolvedSignature) {
34013
+ const returnType = typeChecker.getReturnTypeOfSignature(resolvedSignature);
34014
+ if (returnType) {
34015
+ const callSignatures = typeChecker.getSignaturesOfType(returnType, ts.SignatureKind.Call);
34016
+ if (callSignatures.length === 0) {
34017
+ const parentChain = callChainNodes.get(node) || [];
34018
+ callChainNodes.set(node.arguments[0], parentChain.concat(node));
34019
+ }
34020
+ }
34021
+ }
34022
+ }
33877
34023
  } else if (callChainNodes.has(node) && ts.isExpression(node)) {
33878
34024
  const parentChain = (callChainNodes.get(node) || []).slice();
33879
34025
  const originalParentChain = parentChain.slice();
@@ -34870,6 +35016,26 @@ var overriddenSchemaConstructor = createDiagnostic({
34870
35016
  const ts = yield* service2(TypeScriptApi);
34871
35017
  const typeParser = yield* service2(TypeParser);
34872
35018
  const typeChecker = yield* service2(TypeCheckerApi);
35019
+ function isAllowedConstructor(node) {
35020
+ if (node.body && node.body.statements.length === 1) {
35021
+ const expressionStatement = node.body.statements[0];
35022
+ if (ts.isExpressionStatement(expressionStatement)) {
35023
+ const maybeCallSuper = expressionStatement.expression;
35024
+ if (ts.isCallExpression(maybeCallSuper)) {
35025
+ if (maybeCallSuper.expression.kind === ts.SyntaxKind.SuperKeyword) {
35026
+ const expectedNames = node.parameters.map((_) => _.name).filter(ts.isIdentifier).map((_) => ts.idText(_));
35027
+ if (expectedNames.length === 2 && expectedNames.length === node.parameters.length) {
35028
+ const givenNames = maybeCallSuper.arguments.filter(ts.isIdentifier).map((_) => ts.idText(_));
35029
+ if (givenNames.length === expectedNames.length && givenNames.every((name, index) => name === expectedNames[index])) {
35030
+ return true;
35031
+ }
35032
+ }
35033
+ }
35034
+ }
35035
+ }
35036
+ }
35037
+ return false;
35038
+ }
34873
35039
  const nodeToVisit = [];
34874
35040
  const appendNodeToVisit = (node) => {
34875
35041
  nodeToVisit.push(node);
@@ -34901,6 +35067,9 @@ var overriddenSchemaConstructor = createDiagnostic({
34901
35067
  const members = node.members;
34902
35068
  for (const member of members) {
34903
35069
  if (ts.isConstructorDeclaration(member)) {
35070
+ if (isAllowedConstructor(member)) {
35071
+ continue;
35072
+ }
34904
35073
  const fixAsStaticNew = {
34905
35074
  fixName: "overriddenSchemaConstructor_static",
34906
35075
  description: "Rewrite using the static 'new' pattern",
@@ -35698,6 +35867,7 @@ var unsupportedServiceAccessors = createDiagnostic({
35698
35867
 
35699
35868
  // src/diagnostics.ts
35700
35869
  var diagnostics = [
35870
+ anyUnknownInErrorContext,
35701
35871
  catchUnfailableEffect,
35702
35872
  classSelfMismatch,
35703
35873
  duplicatePackage,