@effect/language-service 0.51.0 → 0.52.0

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
@@ -31907,9 +31907,10 @@ var nanoLayer3 = (fa) => gen3(function* () {
31907
31907
  const tsUtils = yield* service2(TypeScriptUtils);
31908
31908
  const typeChecker = yield* service2(TypeCheckerApi);
31909
31909
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
31910
+ const program = yield* service2(TypeScriptProgram);
31910
31911
  return yield* pipe(
31911
31912
  fa,
31912
- provideService7(TypeParser, make64(ts, tsUtils, typeChecker, typeCheckerUtils))
31913
+ provideService7(TypeParser, make64(ts, tsUtils, typeChecker, typeCheckerUtils, program))
31913
31914
  );
31914
31915
  });
31915
31916
  var TypeParserIssue = class _TypeParserIssue {
@@ -31919,7 +31920,92 @@ var TypeParserIssue = class _TypeParserIssue {
31919
31920
  function typeParserIssue(_message, _type, _node) {
31920
31921
  return TypeParserIssue.issue;
31921
31922
  }
31922
- function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
31923
+ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
31924
+ const getSourceFilePackageInfo = cachedBy(
31925
+ fn2("TypeParser.getSourceFilePackageInfo")(function* (sourceFile) {
31926
+ return tsUtils.resolveModuleWithPackageInfoFromSourceFile(program, sourceFile);
31927
+ }),
31928
+ `TypeParser.getSourceFilePackageInfo`,
31929
+ (sourceFile) => sourceFile
31930
+ );
31931
+ const getSourceFilesDeclaringSymbolModule = (packageName) => cachedBy(
31932
+ fn2("TypeParser.getSourceFilesDeclaringSymbolModule")(function* (symbol3) {
31933
+ const result = [];
31934
+ if (!symbol3.declarations) return yield* typeParserIssue("Symbol has no declarations", void 0, void 0);
31935
+ for (const sourceFile of symbol3.declarations) {
31936
+ if (!ts.isSourceFile(sourceFile)) continue;
31937
+ const packageInfo = yield* getSourceFilePackageInfo(sourceFile);
31938
+ if (!packageInfo || packageInfo.name.toLowerCase() !== packageName.toLowerCase()) continue;
31939
+ result.push(sourceFile);
31940
+ }
31941
+ if (result.length > 0) {
31942
+ return result;
31943
+ }
31944
+ return yield* typeParserIssue(`Symbol has no source file declarations`, void 0, void 0);
31945
+ }),
31946
+ `TypeParser.getSourceFilesDeclaringSymbolModule(${packageName})`,
31947
+ (symbol3) => symbol3
31948
+ );
31949
+ const isSymbolReferenceToPackageModule = (givenSymbol, packageName, checkSourceFile) => {
31950
+ let symbol3 = givenSymbol;
31951
+ while (symbol3.flags & ts.SymbolFlags.Alias) {
31952
+ symbol3 = typeChecker.getAliasedSymbol(symbol3);
31953
+ }
31954
+ return pipe(
31955
+ getSourceFilesDeclaringSymbolModule(packageName)(symbol3),
31956
+ flatMap18(
31957
+ (sourceFiles) => firstSuccessOf2(
31958
+ sourceFiles.map((_) => checkSourceFile(_))
31959
+ )
31960
+ )
31961
+ );
31962
+ };
31963
+ const isNodeReferenceToPackageModule = (givenNode, packageName, isCorrectSourceFile) => {
31964
+ const symbol3 = typeChecker.getSymbolAtLocation(givenNode);
31965
+ if (!symbol3) return typeParserIssue("Node has no symbol", void 0, givenNode);
31966
+ return isSymbolReferenceToPackageModule(symbol3, packageName, isCorrectSourceFile);
31967
+ };
31968
+ const getSourceFilesDeclaringSymbolExportedUnderPackageModule = (packageName, memberName) => cachedBy(
31969
+ fn2("TypeParser.getSourceFilesDeclaringSymbolUnderPackageExportedMember")(function* (symbol3) {
31970
+ const result = [];
31971
+ if (!symbol3.declarations) return yield* typeParserIssue("Symbol has no declarations", void 0, void 0);
31972
+ for (const declaration of symbol3.declarations) {
31973
+ const sourceFile = tsUtils.getSourceFileOfNode(declaration);
31974
+ if (!sourceFile) continue;
31975
+ const packageInfo = yield* getSourceFilePackageInfo(sourceFile);
31976
+ if (!packageInfo || packageInfo.name.toLowerCase() !== packageName.toLowerCase()) continue;
31977
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
31978
+ if (!moduleSymbol) continue;
31979
+ const memberSymbol = typeChecker.tryGetMemberInModuleExports(memberName, moduleSymbol);
31980
+ if (memberSymbol && memberSymbol === symbol3) result.push({ memberSymbol, moduleSymbol, sourceFile });
31981
+ }
31982
+ if (result.length > 0) {
31983
+ return result;
31984
+ }
31985
+ return yield* typeParserIssue(`Symbol has no declarations`, void 0, void 0);
31986
+ }),
31987
+ `TypeParser.getSourceFilesDeclaringSymbolUnderPackageExportedMember(${packageName}, ${memberName})`,
31988
+ (sym) => sym
31989
+ );
31990
+ const isSymbolExportOfPackageModule = (givenSymbol, packageName, memberName, checkSourceFile) => {
31991
+ let symbol3 = givenSymbol;
31992
+ while (symbol3.flags & ts.SymbolFlags.Alias) {
31993
+ symbol3 = typeChecker.getAliasedSymbol(symbol3);
31994
+ }
31995
+ return pipe(
31996
+ getSourceFilesDeclaringSymbolExportedUnderPackageModule(packageName, memberName)(symbol3),
31997
+ flatMap18(
31998
+ (sourceFiles) => firstSuccessOf2(
31999
+ sourceFiles.map((_) => checkSourceFile(_.sourceFile, _.moduleSymbol, _.memberSymbol))
32000
+ )
32001
+ )
32002
+ );
32003
+ };
32004
+ const isNodeReferenceToExportOfPackageModule = (givenNode, packageName, isCorrectSourceFile, memberName) => {
32005
+ const symbol3 = typeChecker.getSymbolAtLocation(givenNode);
32006
+ if (!symbol3) return typeParserIssue("Node has no symbol", void 0, givenNode);
32007
+ return isSymbolExportOfPackageModule(symbol3, packageName, memberName, isCorrectSourceFile);
32008
+ };
31923
32009
  function covariantTypeArgument(type2) {
31924
32010
  const signatures = typeChecker.getSignaturesOfType(type2, ts.SignatureKind.Call);
31925
32011
  if (signatures.length !== 1) {
@@ -32025,6 +32111,26 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32025
32111
  "TypeParser.strictEffectType",
32026
32112
  (type2) => type2
32027
32113
  );
32114
+ const isEffectTypeSourceFile = cachedBy(
32115
+ fn2("TypeParser.isEffectTypeSourceFile")(function* (sourceFile) {
32116
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
32117
+ if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
32118
+ const effectTypeSymbol = typeChecker.tryGetMemberInModuleExports("Effect", moduleSymbol);
32119
+ if (!effectTypeSymbol) return yield* typeParserIssue("Effect type not found", void 0, sourceFile);
32120
+ const type2 = typeChecker.getDeclaredTypeOfSymbol(effectTypeSymbol);
32121
+ yield* effectType(type2, sourceFile);
32122
+ return sourceFile;
32123
+ }),
32124
+ "TypeParser.isEffectTypeSourceFile",
32125
+ (sourceFile) => sourceFile
32126
+ );
32127
+ const isNodeReferenceToEffectModuleApi = (memberName) => cachedBy(
32128
+ fn2("TypeParser.isNodeReferenceToEffectModuleApi")(function* (node) {
32129
+ return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectTypeSourceFile, memberName);
32130
+ }),
32131
+ `TypeParser.isNodeReferenceToEffectModuleApi(${memberName})`,
32132
+ (node) => node
32133
+ );
32028
32134
  const layerType = cachedBy(
32029
32135
  fn2("TypeParser.layerType")(function* (type2, atLocation) {
32030
32136
  yield* pipeableType(type2, atLocation);
@@ -32081,36 +32187,6 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32081
32187
  "TypeParser.effectSubtype",
32082
32188
  (type2) => type2
32083
32189
  );
32084
- const importedSchemaModule = cachedBy(
32085
- fn2("TypeParser.importedSchemaModule")(function* (node) {
32086
- if (!ts.isIdentifier(node)) {
32087
- return yield* typeParserIssue("Node is not an expression", void 0, node);
32088
- }
32089
- const type2 = typeChecker.getTypeAtLocation(node);
32090
- const propertySymbol = typeChecker.getPropertyOfType(type2, "Class");
32091
- if (!propertySymbol) {
32092
- return yield* typeParserIssue("Type has no 'Class' property", type2, node);
32093
- }
32094
- const sourceFile = tsUtils.getSourceFileOfNode(node);
32095
- if (!sourceFile) {
32096
- return yield* typeParserIssue("Node is not in a source file", void 0, node);
32097
- }
32098
- const schemaIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
32099
- sourceFile,
32100
- "effect",
32101
- "Schema"
32102
- );
32103
- if (!schemaIdentifier) {
32104
- return yield* typeParserIssue("Schema module not found", void 0, node);
32105
- }
32106
- if (ts.idText(node) !== schemaIdentifier) {
32107
- return yield* typeParserIssue("Node is not a schema module reference", void 0, node);
32108
- }
32109
- return node;
32110
- }),
32111
- "TypeParser.importedSchemaModule",
32112
- (node) => node
32113
- );
32114
32190
  const importedContextModule = cachedBy(
32115
32191
  fn2("TypeParser.importedContextModule")(function* (node) {
32116
32192
  const type2 = typeChecker.getTypeAtLocation(node);
@@ -32141,22 +32217,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32141
32217
  "TypeParser.importedContextModule",
32142
32218
  (node) => node
32143
32219
  );
32144
- const importedEffectModule = cachedBy(
32145
- fn2("TypeParser.importedEffectModule")(function* (node) {
32146
- const type2 = typeChecker.getTypeAtLocation(node);
32147
- const propertySymbol = typeChecker.getPropertyOfType(type2, "never");
32148
- if (!propertySymbol) {
32149
- return yield* typeParserIssue("Type has no 'never' property", type2, node);
32150
- }
32151
- if (!ts.isExpression(node)) {
32152
- return yield* typeParserIssue("Node is not an expression", type2, node);
32153
- }
32154
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, node);
32155
- yield* effectType(propertyType, node);
32156
- return node;
32157
- }),
32158
- "TypeParser.importedEffectModule",
32159
- (node) => node
32220
+ const importedEffectModule = (node) => pipe(
32221
+ isNodeReferenceToPackageModule(node, "effect", isEffectTypeSourceFile),
32222
+ map34(() => node)
32160
32223
  );
32161
32224
  const importedDataModule = cachedBy(
32162
32225
  fn2("TypeParser.importedDataModule")(function* (node) {
@@ -32207,14 +32270,11 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32207
32270
  return typeParserIssue("Node is not a property access expression", void 0, node);
32208
32271
  }
32209
32272
  const propertyAccess = node.expression;
32210
- if (!(ts.isIdentifier(propertyAccess.name) && ts.idText(propertyAccess.name) === "gen")) {
32211
- return typeParserIssue("Call expression name is not 'gen'", void 0, node);
32212
- }
32213
32273
  return pipe(
32214
- importedEffectModule(propertyAccess.expression),
32215
- map34((effectModule) => ({
32274
+ isNodeReferenceToEffectModuleApi("gen")(propertyAccess),
32275
+ map34(() => ({
32216
32276
  node,
32217
- effectModule,
32277
+ effectModule: propertyAccess.expression,
32218
32278
  generatorFunction,
32219
32279
  body: generatorFunction.body
32220
32280
  }))
@@ -32250,18 +32310,11 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32250
32310
  );
32251
32311
  }
32252
32312
  const propertyAccess = node.expression;
32253
- if (!(ts.isIdentifier(propertyAccess.name) && ts.idText(propertyAccess.name) === "fnUntraced")) {
32254
- return typeParserIssue(
32255
- "Call expression name is not 'fnUntraced'",
32256
- void 0,
32257
- node
32258
- );
32259
- }
32260
32313
  return pipe(
32261
- importedEffectModule(propertyAccess.expression),
32262
- map34((effectModule) => ({
32314
+ isNodeReferenceToEffectModuleApi("fnUntraced")(propertyAccess),
32315
+ map34(() => ({
32263
32316
  node,
32264
- effectModule,
32317
+ effectModule: propertyAccess.expression,
32265
32318
  generatorFunction,
32266
32319
  body: generatorFunction.body
32267
32320
  }))
@@ -32302,19 +32355,12 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32302
32355
  );
32303
32356
  }
32304
32357
  const propertyAccess = expressionToTest;
32305
- if (!(ts.isIdentifier(propertyAccess.name) && ts.idText(propertyAccess.name) === "fn")) {
32306
- return typeParserIssue(
32307
- "Call expression name is not 'fn'",
32308
- void 0,
32309
- node
32310
- );
32311
- }
32312
32358
  return pipe(
32313
- importedEffectModule(propertyAccess.expression),
32314
- map34((effectModule) => ({
32359
+ isNodeReferenceToEffectModuleApi("fn")(propertyAccess),
32360
+ map34(() => ({
32315
32361
  node,
32316
32362
  generatorFunction,
32317
- effectModule,
32363
+ effectModule: propertyAccess.expression,
32318
32364
  body: generatorFunction.body
32319
32365
  }))
32320
32366
  );
@@ -32416,6 +32462,26 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32416
32462
  "TypeParser.effectSchemaType",
32417
32463
  (type2) => type2
32418
32464
  );
32465
+ const isEffectSchemaTypeSourceFile = cachedBy(
32466
+ fn2("TypeParser.isEffectSchemaTypeSourceFile")(function* (sourceFile) {
32467
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
32468
+ if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
32469
+ const typeSymbol = typeChecker.tryGetMemberInModuleExports("Schema", moduleSymbol);
32470
+ if (!typeSymbol) return yield* typeParserIssue("Schema type not found", void 0, sourceFile);
32471
+ const type2 = typeChecker.getDeclaredTypeOfSymbol(typeSymbol);
32472
+ yield* effectSchemaType(type2, sourceFile);
32473
+ return sourceFile;
32474
+ }),
32475
+ "TypeParser.isEffectSchemaTypeSourceFile",
32476
+ (sourceFile) => sourceFile
32477
+ );
32478
+ const isNodeReferenceToEffectSchemaModuleApi = (memberName) => cachedBy(
32479
+ fn2("TypeParser.isNodeReferenceToEffectSchemaModuleApi")(function* (node) {
32480
+ return yield* isNodeReferenceToExportOfPackageModule(node, "effect", isEffectSchemaTypeSourceFile, memberName);
32481
+ }),
32482
+ `TypeParser.isNodeReferenceToEffectSchemaModuleApi(${memberName})`,
32483
+ (node) => node
32484
+ );
32419
32485
  const contextTagVarianceStruct = (type2, atLocation) => map34(
32420
32486
  all9(
32421
32487
  varianceStructInvariantType(type2, atLocation, "_Identifier"),
@@ -32542,22 +32608,15 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32542
32608
  if (ts.isCallExpression(expression)) {
32543
32609
  const schemaCall = expression.expression;
32544
32610
  if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
32545
- const selfTypeNode = schemaCall.typeArguments[0];
32546
- const schemaIdentifier = schemaCall.expression;
32547
- if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "Class") {
32548
- const expressionType = typeChecker.getTypeAtLocation(expression);
32549
- const parsedSchemaModule = yield* pipe(
32550
- effectSchemaType(expressionType, expression),
32551
- flatMap18(() => importedSchemaModule(schemaIdentifier.expression)),
32552
- option4
32553
- );
32554
- if (isSome2(parsedSchemaModule)) {
32555
- return {
32556
- className: atLocation.name,
32557
- selfTypeNode,
32558
- Schema: parsedSchemaModule.value
32559
- };
32560
- }
32611
+ const isEffectSchemaModuleApi = yield* pipe(
32612
+ isNodeReferenceToEffectSchemaModuleApi("Class")(schemaCall.expression),
32613
+ option4
32614
+ );
32615
+ if (isSome2(isEffectSchemaModuleApi)) {
32616
+ return {
32617
+ className: atLocation.name,
32618
+ selfTypeNode: schemaCall.typeArguments[0]
32619
+ };
32561
32620
  }
32562
32621
  }
32563
32622
  }
@@ -32586,23 +32645,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32586
32645
  const schemaTaggedClassTCall = expression.expression;
32587
32646
  if (ts.isCallExpression(schemaTaggedClassTCall) && schemaTaggedClassTCall.typeArguments && schemaTaggedClassTCall.typeArguments.length > 0) {
32588
32647
  const selfTypeNode = schemaTaggedClassTCall.typeArguments[0];
32589
- const schemaIdentifier = schemaTaggedClassTCall.expression;
32590
- if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "TaggedClass") {
32591
- const expressionType = typeChecker.getTypeAtLocation(expression);
32592
- const parsedSchemaModule = yield* pipe(
32593
- effectSchemaType(expressionType, expression),
32594
- flatMap18(() => importedSchemaModule(schemaIdentifier.expression)),
32595
- option4
32596
- );
32597
- if (isSome2(parsedSchemaModule)) {
32598
- return {
32599
- className: atLocation.name,
32600
- selfTypeNode,
32601
- keyStringLiteral: schemaTaggedClassTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedClassTCall.arguments[0]) ? schemaTaggedClassTCall.arguments[0] : void 0,
32602
- tagStringLiteral: expression.arguments.length > 0 && ts.isStringLiteral(expression.arguments[0]) ? expression.arguments[0] : void 0,
32603
- Schema: parsedSchemaModule.value
32604
- };
32605
- }
32648
+ const isEffectSchemaModuleApi = yield* pipe(
32649
+ isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(schemaTaggedClassTCall.expression),
32650
+ option4
32651
+ );
32652
+ if (isSome2(isEffectSchemaModuleApi)) {
32653
+ return {
32654
+ className: atLocation.name,
32655
+ selfTypeNode,
32656
+ keyStringLiteral: schemaTaggedClassTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedClassTCall.arguments[0]) ? schemaTaggedClassTCall.arguments[0] : void 0,
32657
+ tagStringLiteral: expression.arguments.length > 0 && ts.isStringLiteral(expression.arguments[0]) ? expression.arguments[0] : void 0
32658
+ };
32606
32659
  }
32607
32660
  }
32608
32661
  }
@@ -32631,23 +32684,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32631
32684
  const schemaTaggedErrorTCall = expression.expression;
32632
32685
  if (ts.isCallExpression(schemaTaggedErrorTCall) && schemaTaggedErrorTCall.typeArguments && schemaTaggedErrorTCall.typeArguments.length > 0) {
32633
32686
  const selfTypeNode = schemaTaggedErrorTCall.typeArguments[0];
32634
- const schemaIdentifier = schemaTaggedErrorTCall.expression;
32635
- if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "TaggedError") {
32636
- const expressionType = typeChecker.getTypeAtLocation(expression);
32637
- const parsedSchemaModule = yield* pipe(
32638
- effectSchemaType(expressionType, expression),
32639
- flatMap18(() => importedSchemaModule(schemaIdentifier.expression)),
32640
- option4
32641
- );
32642
- if (isSome2(parsedSchemaModule)) {
32643
- return {
32644
- className: atLocation.name,
32645
- selfTypeNode,
32646
- keyStringLiteral: schemaTaggedErrorTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedErrorTCall.arguments[0]) ? schemaTaggedErrorTCall.arguments[0] : void 0,
32647
- tagStringLiteral: expression.arguments.length > 0 && ts.isStringLiteral(expression.arguments[0]) ? expression.arguments[0] : void 0,
32648
- Schema: parsedSchemaModule.value
32649
- };
32650
- }
32687
+ const isEffectSchemaModuleApi = yield* pipe(
32688
+ isNodeReferenceToEffectSchemaModuleApi("TaggedError")(schemaTaggedErrorTCall.expression),
32689
+ option4
32690
+ );
32691
+ if (isSome2(isEffectSchemaModuleApi)) {
32692
+ return {
32693
+ className: atLocation.name,
32694
+ selfTypeNode,
32695
+ keyStringLiteral: schemaTaggedErrorTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedErrorTCall.arguments[0]) ? schemaTaggedErrorTCall.arguments[0] : void 0,
32696
+ tagStringLiteral: expression.arguments.length > 0 && ts.isStringLiteral(expression.arguments[0]) ? expression.arguments[0] : void 0
32697
+ };
32651
32698
  }
32652
32699
  }
32653
32700
  }
@@ -32659,8 +32706,8 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32659
32706
  "TypeParser.extendsSchemaTaggedError",
32660
32707
  (atLocation) => atLocation
32661
32708
  );
32662
- const extendsDataTaggedError = cachedBy(
32663
- fn2("TypeParser.extendsDataTaggedError")(function* (atLocation) {
32709
+ const extendsSchemaTaggedRequest = cachedBy(
32710
+ fn2("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
32664
32711
  if (!atLocation.name) {
32665
32712
  return yield* typeParserIssue("Class has no name", void 0, atLocation);
32666
32713
  }
@@ -32673,18 +32720,19 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32673
32720
  if (ts.isExpressionWithTypeArguments(typeX)) {
32674
32721
  const expression = typeX.expression;
32675
32722
  if (ts.isCallExpression(expression)) {
32676
- const dataTaggedErrorCall = expression;
32677
- const dataIdentifier = dataTaggedErrorCall.expression;
32678
- if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedError") {
32679
- const parsedDataModule = yield* pipe(
32680
- importedDataModule(dataIdentifier.expression),
32723
+ const schemaTaggedRequestTCall = expression.expression;
32724
+ if (ts.isCallExpression(schemaTaggedRequestTCall) && schemaTaggedRequestTCall.typeArguments && schemaTaggedRequestTCall.typeArguments.length > 0) {
32725
+ const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
32726
+ const isEffectSchemaModuleApi = yield* pipe(
32727
+ isNodeReferenceToEffectSchemaModuleApi("TaggedRequest")(schemaTaggedRequestTCall.expression),
32681
32728
  option4
32682
32729
  );
32683
- if (isSome2(parsedDataModule)) {
32730
+ if (isSome2(isEffectSchemaModuleApi)) {
32684
32731
  return {
32685
32732
  className: atLocation.name,
32686
- keyStringLiteral: dataTaggedErrorCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedErrorCall.arguments[0]) ? dataTaggedErrorCall.arguments[0] : void 0,
32687
- Data: parsedDataModule.value
32733
+ selfTypeNode,
32734
+ tagStringLiteral: expression.arguments.length > 0 && ts.isStringLiteral(expression.arguments[0]) ? expression.arguments[0] : void 0,
32735
+ keyStringLiteral: schemaTaggedRequestTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedRequestTCall.arguments[0]) ? schemaTaggedRequestTCall.arguments[0] : void 0
32688
32736
  };
32689
32737
  }
32690
32738
  }
@@ -32692,13 +32740,13 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32692
32740
  }
32693
32741
  }
32694
32742
  }
32695
- return yield* typeParserIssue("Class does not extend Data.TaggedError", void 0, atLocation);
32743
+ return yield* typeParserIssue("Class does not extend Schema.TaggedRequest", void 0, atLocation);
32696
32744
  }),
32697
- "TypeParser.extendsDataTaggedError",
32745
+ "TypeParser.extendsSchemaTaggedRequest",
32698
32746
  (atLocation) => atLocation
32699
32747
  );
32700
- const extendsDataTaggedClass = cachedBy(
32701
- fn2("TypeParser.extendsDataTaggedClass")(function* (atLocation) {
32748
+ const extendsDataTaggedError = cachedBy(
32749
+ fn2("TypeParser.extendsDataTaggedError")(function* (atLocation) {
32702
32750
  if (!atLocation.name) {
32703
32751
  return yield* typeParserIssue("Class has no name", void 0, atLocation);
32704
32752
  }
@@ -32711,9 +32759,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32711
32759
  if (ts.isExpressionWithTypeArguments(typeX)) {
32712
32760
  const expression = typeX.expression;
32713
32761
  if (ts.isCallExpression(expression)) {
32714
- const dataTaggedClassCall = expression;
32715
- const dataIdentifier = dataTaggedClassCall.expression;
32716
- if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedClass") {
32762
+ const dataTaggedErrorCall = expression;
32763
+ const dataIdentifier = dataTaggedErrorCall.expression;
32764
+ if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedError") {
32717
32765
  const parsedDataModule = yield* pipe(
32718
32766
  importedDataModule(dataIdentifier.expression),
32719
32767
  option4
@@ -32721,7 +32769,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32721
32769
  if (isSome2(parsedDataModule)) {
32722
32770
  return {
32723
32771
  className: atLocation.name,
32724
- keyStringLiteral: dataTaggedClassCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedClassCall.arguments[0]) ? dataTaggedClassCall.arguments[0] : void 0,
32772
+ keyStringLiteral: dataTaggedErrorCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedErrorCall.arguments[0]) ? dataTaggedErrorCall.arguments[0] : void 0,
32725
32773
  Data: parsedDataModule.value
32726
32774
  };
32727
32775
  }
@@ -32730,13 +32778,13 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32730
32778
  }
32731
32779
  }
32732
32780
  }
32733
- return yield* typeParserIssue("Class does not extend Data.TaggedClass", void 0, atLocation);
32781
+ return yield* typeParserIssue("Class does not extend Data.TaggedError", void 0, atLocation);
32734
32782
  }),
32735
- "TypeParser.extendsDataTaggedClass",
32783
+ "TypeParser.extendsDataTaggedError",
32736
32784
  (atLocation) => atLocation
32737
32785
  );
32738
- const extendsSchemaTaggedRequest = cachedBy(
32739
- fn2("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
32786
+ const extendsDataTaggedClass = cachedBy(
32787
+ fn2("TypeParser.extendsDataTaggedClass")(function* (atLocation) {
32740
32788
  if (!atLocation.name) {
32741
32789
  return yield* typeParserIssue("Class has no name", void 0, atLocation);
32742
32790
  }
@@ -32749,35 +32797,28 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32749
32797
  if (ts.isExpressionWithTypeArguments(typeX)) {
32750
32798
  const expression = typeX.expression;
32751
32799
  if (ts.isCallExpression(expression)) {
32752
- const schemaTaggedRequestTCall = expression.expression;
32753
- if (ts.isCallExpression(schemaTaggedRequestTCall) && schemaTaggedRequestTCall.typeArguments && schemaTaggedRequestTCall.typeArguments.length > 0) {
32754
- const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
32755
- const schemaIdentifier = schemaTaggedRequestTCall.expression;
32756
- if (ts.isPropertyAccessExpression(schemaIdentifier) && ts.isIdentifier(schemaIdentifier.name) && ts.idText(schemaIdentifier.name) === "TaggedRequest") {
32757
- const expressionType = typeChecker.getTypeAtLocation(expression);
32758
- const parsedSchemaModule = yield* pipe(
32759
- effectSchemaType(expressionType, expression),
32760
- flatMap18(() => importedSchemaModule(schemaIdentifier.expression)),
32761
- option4
32762
- );
32763
- if (isSome2(parsedSchemaModule)) {
32764
- return {
32765
- className: atLocation.name,
32766
- selfTypeNode,
32767
- tagStringLiteral: expression.arguments.length > 0 && ts.isStringLiteral(expression.arguments[0]) ? expression.arguments[0] : void 0,
32768
- keyStringLiteral: schemaTaggedRequestTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedRequestTCall.arguments[0]) ? schemaTaggedRequestTCall.arguments[0] : void 0,
32769
- Schema: parsedSchemaModule.value
32770
- };
32771
- }
32800
+ const dataTaggedClassCall = expression;
32801
+ const dataIdentifier = dataTaggedClassCall.expression;
32802
+ if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedClass") {
32803
+ const parsedDataModule = yield* pipe(
32804
+ importedDataModule(dataIdentifier.expression),
32805
+ option4
32806
+ );
32807
+ if (isSome2(parsedDataModule)) {
32808
+ return {
32809
+ className: atLocation.name,
32810
+ keyStringLiteral: dataTaggedClassCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedClassCall.arguments[0]) ? dataTaggedClassCall.arguments[0] : void 0,
32811
+ Data: parsedDataModule.value
32812
+ };
32772
32813
  }
32773
32814
  }
32774
32815
  }
32775
32816
  }
32776
32817
  }
32777
32818
  }
32778
- return yield* typeParserIssue("Class does not extend Schema.TaggedRequest", void 0, atLocation);
32819
+ return yield* typeParserIssue("Class does not extend Data.TaggedClass", void 0, atLocation);
32779
32820
  }),
32780
- "TypeParser.extendsSchemaTaggedRequest",
32821
+ "TypeParser.extendsDataTaggedClass",
32781
32822
  (atLocation) => atLocation
32782
32823
  );
32783
32824
  const extendsContextTag = cachedBy(
@@ -32837,6 +32878,10 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32837
32878
  if (!heritageClauses) {
32838
32879
  return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
32839
32880
  }
32881
+ const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
32882
+ if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
32883
+ const type2 = typeChecker.getTypeOfSymbol(classSym);
32884
+ const tagType = yield* contextTag(type2, atLocation);
32840
32885
  for (const heritageClause of heritageClauses) {
32841
32886
  for (const typeX of heritageClause.types) {
32842
32887
  if (ts.isExpressionWithTypeArguments(typeX)) {
@@ -32846,26 +32891,19 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32846
32891
  if (ts.isCallExpression(effectTagCall) && wholeCall.typeArguments && wholeCall.typeArguments.length > 0) {
32847
32892
  const effectTagIdentifier = effectTagCall.expression;
32848
32893
  const selfTypeNode = wholeCall.typeArguments[0];
32849
- if (ts.isPropertyAccessExpression(effectTagIdentifier) && ts.isIdentifier(effectTagIdentifier.name) && ts.idText(effectTagIdentifier.name) === "Tag") {
32850
- const parsedEffectModule = yield* pipe(
32851
- importedEffectModule(effectTagIdentifier.expression),
32852
- option4
32853
- );
32854
- if (isSome2(parsedEffectModule)) {
32855
- const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
32856
- if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
32857
- const type2 = typeChecker.getTypeOfSymbol(classSym);
32858
- const tagType = yield* contextTag(type2, atLocation);
32859
- return {
32860
- className: atLocation.name,
32861
- selfTypeNode,
32862
- keyStringLiteral: ts.isStringLiteral(effectTagCall.arguments[0]) ? effectTagCall.arguments[0] : void 0,
32863
- args: effectTagCall.arguments,
32864
- Identifier: tagType.Identifier,
32865
- Service: tagType.Service,
32866
- Tag: parsedEffectModule.value
32867
- };
32868
- }
32894
+ const isEffectTag = yield* pipe(
32895
+ isNodeReferenceToEffectModuleApi("Tag")(effectTagIdentifier),
32896
+ option4
32897
+ );
32898
+ if (isSome2(isEffectTag)) {
32899
+ return {
32900
+ className: atLocation.name,
32901
+ selfTypeNode,
32902
+ keyStringLiteral: ts.isStringLiteral(effectTagCall.arguments[0]) ? effectTagCall.arguments[0] : void 0,
32903
+ args: effectTagCall.arguments,
32904
+ Identifier: tagType.Identifier,
32905
+ Service: tagType.Service
32906
+ };
32869
32907
  }
32870
32908
  }
32871
32909
  }
@@ -32895,13 +32933,16 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32895
32933
  if (ts.isCallExpression(effectServiceCall) && effectServiceCall.typeArguments && effectServiceCall.typeArguments.length > 0) {
32896
32934
  const effectServiceIdentifier = effectServiceCall.expression;
32897
32935
  const selfTypeNode = effectServiceCall.typeArguments[0];
32898
- if (ts.isPropertyAccessExpression(effectServiceIdentifier) && ts.isIdentifier(effectServiceIdentifier.name) && ts.idText(effectServiceIdentifier.name) === "Service") {
32936
+ const isEffectService = yield* pipe(
32937
+ isNodeReferenceToEffectModuleApi("Service")(effectServiceIdentifier),
32938
+ option4
32939
+ );
32940
+ if (isSome2(isEffectService)) {
32899
32941
  const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
32900
32942
  if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
32901
32943
  const type2 = typeChecker.getTypeOfSymbol(classSym);
32902
32944
  const parsedContextTag = yield* pipe(
32903
- importedEffectModule(effectServiceIdentifier.expression),
32904
- flatMap18(() => contextTag(type2, atLocation)),
32945
+ contextTag(type2, atLocation),
32905
32946
  option4
32906
32947
  );
32907
32948
  if (isSome2(parsedContextTag)) {
@@ -32943,6 +32984,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32943
32984
  (atLocation) => atLocation
32944
32985
  );
32945
32986
  return {
32987
+ isNodeReferenceToEffectModuleApi,
32946
32988
  effectType,
32947
32989
  strictEffectType,
32948
32990
  layerType,
@@ -32971,6 +33013,80 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils) {
32971
33013
  };
32972
33014
  }
32973
33015
 
33016
+ // src/diagnostics/catchUnfailableEffect.ts
33017
+ var catchUnfailableEffect = createDiagnostic({
33018
+ name: "catchUnfailableEffect",
33019
+ code: 2,
33020
+ severity: "suggestion",
33021
+ apply: fn2("catchUnfailableEffect.apply")(function* (sourceFile, report) {
33022
+ const ts = yield* service2(TypeScriptApi);
33023
+ const typeParser = yield* service2(TypeParser);
33024
+ const typeChecker = yield* service2(TypeCheckerApi);
33025
+ const nodeToVisit = [];
33026
+ const appendNodeToVisit = (node) => {
33027
+ nodeToVisit.push(node);
33028
+ return void 0;
33029
+ };
33030
+ ts.forEachChild(sourceFile, appendNodeToVisit);
33031
+ while (nodeToVisit.length > 0) {
33032
+ const node = nodeToVisit.shift();
33033
+ ts.forEachChild(node, appendNodeToVisit);
33034
+ if (ts.isCallExpression(node)) {
33035
+ const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
33036
+ const isCatchCall = yield* pipe(
33037
+ firstSuccessOf2(
33038
+ catchFunctions.map((catchFn) => typeParser.isNodeReferenceToEffectModuleApi(catchFn)(node.expression))
33039
+ ),
33040
+ option4
33041
+ );
33042
+ if (isSome2(isCatchCall)) {
33043
+ const parent = node.parent;
33044
+ if (parent && ts.isCallExpression(parent)) {
33045
+ const pipeCallResult = yield* pipe(
33046
+ typeParser.pipeCall(parent),
33047
+ option4
33048
+ );
33049
+ if (isSome2(pipeCallResult)) {
33050
+ const { args: args3, node: pipeCallNode, subject } = pipeCallResult.value;
33051
+ const argIndex = args3.findIndex((arg) => arg === node);
33052
+ if (argIndex !== -1) {
33053
+ let effectTypeToCheck;
33054
+ if (argIndex === 0) {
33055
+ effectTypeToCheck = typeChecker.getTypeAtLocation(subject);
33056
+ } else {
33057
+ const signature = typeChecker.getResolvedSignature(pipeCallNode);
33058
+ if (signature) {
33059
+ const typeArguments = typeChecker.getTypeArgumentsForResolvedSignature(signature);
33060
+ if (typeArguments && typeArguments.length > argIndex) {
33061
+ effectTypeToCheck = typeArguments[argIndex];
33062
+ }
33063
+ }
33064
+ }
33065
+ if (effectTypeToCheck) {
33066
+ const effectType = yield* pipe(
33067
+ typeParser.effectType(effectTypeToCheck, node),
33068
+ option4
33069
+ );
33070
+ if (isSome2(effectType)) {
33071
+ const { E } = effectType.value;
33072
+ if (E.flags & ts.TypeFlags.Never) {
33073
+ report({
33074
+ location: node.expression,
33075
+ messageText: `Looks like the previous effect never fails, so probably this error handling will never be triggered.`,
33076
+ fixes: []
33077
+ });
33078
+ }
33079
+ }
33080
+ }
33081
+ }
33082
+ }
33083
+ }
33084
+ }
33085
+ }
33086
+ }
33087
+ })
33088
+ });
33089
+
32974
33090
  // src/diagnostics/classSelfMismatch.ts
32975
33091
  var classSelfMismatch = createDiagnostic({
32976
33092
  name: "classSelfMismatch",
@@ -34230,11 +34346,11 @@ var multipleEffectProvide = createDiagnostic({
34230
34346
  "Layer"
34231
34347
  ) || "Layer";
34232
34348
  const parseEffectProvideLayer = (node) => {
34233
- if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "provide" && node.arguments.length > 0) {
34349
+ if (ts.isCallExpression(node) && node.arguments.length > 0) {
34234
34350
  const layer12 = node.arguments[0];
34235
34351
  const type2 = typeChecker.getTypeAtLocation(layer12);
34236
34352
  return pipe(
34237
- typeParser.importedEffectModule(node.expression.expression),
34353
+ typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression),
34238
34354
  flatMap18(() => typeParser.layerType(type2, layer12)),
34239
34355
  map34(() => ({ layer: layer12, node })),
34240
34356
  orElse14(() => void_8)
@@ -35083,10 +35199,10 @@ var strictEffectProvide = createDiagnostic({
35083
35199
  const typeChecker = yield* service2(TypeCheckerApi);
35084
35200
  const typeParser = yield* service2(TypeParser);
35085
35201
  const parseEffectProvideWithLayer = (node) => gen3(function* () {
35086
- if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression) || !ts.isIdentifier(node.expression.name) || ts.idText(node.expression.name) !== "provide" || node.arguments.length === 0) {
35202
+ if (!ts.isCallExpression(node) || node.arguments.length === 0) {
35087
35203
  return yield* typeParserIssue("Not an Effect.provide call");
35088
35204
  }
35089
- yield* typeParser.importedEffectModule(node.expression.expression);
35205
+ yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
35090
35206
  return yield* firstSuccessOf2(
35091
35207
  node.arguments.map((arg) => {
35092
35208
  const argType = typeChecker.getTypeAtLocation(arg);
@@ -35381,6 +35497,7 @@ var unsupportedServiceAccessors = createDiagnostic({
35381
35497
 
35382
35498
  // src/diagnostics.ts
35383
35499
  var diagnostics = [
35500
+ catchUnfailableEffect,
35384
35501
  classSelfMismatch,
35385
35502
  duplicatePackage,
35386
35503
  effectGenUsesAdapter,