@effect/language-service 0.78.0 → 0.79.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
@@ -25719,7 +25719,7 @@ var runWith2 = (command, config) => {
25719
25719
  // package.json
25720
25720
  var package_default = {
25721
25721
  name: "@effect/language-service",
25722
- version: "0.78.0",
25722
+ version: "0.79.0",
25723
25723
  publishConfig: {
25724
25724
  access: "public",
25725
25725
  directory: "dist"
@@ -25747,15 +25747,17 @@ var package_default = {
25747
25747
  ],
25748
25748
  scripts: {
25749
25749
  build: "tsup",
25750
+ codegen: "node --import tsx ./scripts/generate-diagnostics-readme-table.ts",
25750
25751
  dev: "tsup --watch",
25751
25752
  clean: "rimraf dist build .tsbuildinfo",
25752
25753
  lint: "eslint src test",
25753
25754
  "lint-fix": "eslint src test --fix",
25754
25755
  check: "tsc -b tsconfig.json",
25756
+ "check:codegen": "node --import tsx ./scripts/generate-diagnostics-readme-table.ts --check",
25755
25757
  circular: "madge --extensions ts --circular --no-color --no-spinner --warning src",
25756
25758
  test: "vitest",
25757
25759
  "test-update": "vitest --update",
25758
- "test-patch": "pnpm clean && pnpm build && pnpm effect-language-service unpatch && pnpm effect-language-service patch && pnpm check",
25760
+ "test-patch": "pnpm clean && pnpm build && node dist/cli.js unpatch && node dist/cli.js patch && pnpm check",
25759
25761
  coverage: "vitest run --coverage",
25760
25762
  perf: "tsx test/perf.ts"
25761
25763
  },
@@ -27527,10 +27529,12 @@ var defaults = {
27527
27529
  extendedKeyDetection: false,
27528
27530
  ignoreEffectWarningsInTscExitCode: false,
27529
27531
  ignoreEffectSuggestionsInTscExitCode: true,
27532
+ ignoreEffectErrorsInTscExitCode: false,
27530
27533
  pipeableMinArgCount: 2,
27531
27534
  effectFn: ["span"],
27532
27535
  layerGraphFollowDepth: 0,
27533
- mermaidProvider: "mermaid.live"
27536
+ mermaidProvider: "mermaid.live",
27537
+ skipDisabledOptimization: false
27534
27538
  };
27535
27539
  function parseKeyPatterns(patterns) {
27536
27540
  const result3 = [];
@@ -27554,6 +27558,7 @@ function parse4(config) {
27554
27558
  includeSuggestionsInTsc: isObject(config) && hasProperty(config, "includeSuggestionsInTsc") && isBoolean(config.includeSuggestionsInTsc) ? config.includeSuggestionsInTsc : defaults.includeSuggestionsInTsc,
27555
27559
  ignoreEffectWarningsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectWarningsInTscExitCode") && isBoolean(config.ignoreEffectWarningsInTscExitCode) ? config.ignoreEffectWarningsInTscExitCode : defaults.ignoreEffectWarningsInTscExitCode,
27556
27560
  ignoreEffectSuggestionsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectSuggestionsInTscExitCode") && isBoolean(config.ignoreEffectSuggestionsInTscExitCode) ? config.ignoreEffectSuggestionsInTscExitCode : defaults.ignoreEffectSuggestionsInTscExitCode,
27561
+ ignoreEffectErrorsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectErrorsInTscExitCode") && isBoolean(config.ignoreEffectErrorsInTscExitCode) ? config.ignoreEffectErrorsInTscExitCode : defaults.ignoreEffectErrorsInTscExitCode,
27557
27562
  quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : defaults.quickinfo,
27558
27563
  quickinfoEffectParameters: isObject(config) && hasProperty(config, "quickinfoEffectParameters") && isString(config.quickinfoEffectParameters) && ["always", "never", "whentruncated"].includes(config.quickinfoEffectParameters.toLowerCase()) ? config.quickinfoEffectParameters.toLowerCase() : defaults.quickinfoEffectParameters,
27559
27564
  quickinfoMaximumLength: isObject(config) && hasProperty(config, "quickinfoMaximumLength") && isNumber(config.quickinfoMaximumLength) ? config.quickinfoMaximumLength : defaults.quickinfoMaximumLength,
@@ -27574,7 +27579,8 @@ function parse4(config) {
27574
27579
  (_) => _.toLowerCase()
27575
27580
  ) : defaults.effectFn,
27576
27581
  layerGraphFollowDepth: isObject(config) && hasProperty(config, "layerGraphFollowDepth") && isNumber(config.layerGraphFollowDepth) ? config.layerGraphFollowDepth : defaults.layerGraphFollowDepth,
27577
- mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider
27582
+ mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider,
27583
+ skipDisabledOptimization: isObject(config) && hasProperty(config, "skipDisabledOptimization") && isBoolean(config.skipDisabledOptimization) ? config.skipDisabledOptimization : defaults.skipDisabledOptimization
27578
27584
  };
27579
27585
  }
27580
27586
 
@@ -27758,7 +27764,7 @@ var createDiagnosticExecutor = fn3("LSP.createCommentDirectivesProcessor")(
27758
27764
  if (skippedRules.indexOf(ruleNameLowered) > -1 || skippedRules.indexOf("*") > -1) {
27759
27765
  return { diagnostics: diagnostics3, codeFixes };
27760
27766
  }
27761
- if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
27767
+ if (!pluginOptions.skipDisabledOptimization && defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
27762
27768
  return { diagnostics: diagnostics3, codeFixes };
27763
27769
  }
27764
27770
  const fixByDisableNextLine = (node) => ({
@@ -31656,6 +31662,8 @@ var anyUnknownInErrorContext = createDiagnostic({
31656
31662
  code: 28,
31657
31663
  description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
31658
31664
  severity: "off",
31665
+ fixable: false,
31666
+ supportedEffect: ["v3", "v4"],
31659
31667
  apply: fn3("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
31660
31668
  const ts = yield* service2(TypeScriptApi);
31661
31669
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -31759,6 +31767,8 @@ var catchAllToMapError = createDiagnostic({
31759
31767
  code: 39,
31760
31768
  description: "Suggests using Effect.mapError instead of Effect.catchAll when the callback only wraps the error with Effect.fail",
31761
31769
  severity: "suggestion",
31770
+ fixable: true,
31771
+ supportedEffect: ["v3", "v4"],
31762
31772
  apply: fn3("catchAllToMapError.apply")(function* (sourceFile, report) {
31763
31773
  const ts = yield* service2(TypeScriptApi);
31764
31774
  const typeParser = yield* service2(TypeParser);
@@ -31856,6 +31866,8 @@ var catchUnfailableEffect = createDiagnostic({
31856
31866
  code: 2,
31857
31867
  description: "Warns when using error handling on Effects that never fail (error type is 'never')",
31858
31868
  severity: "suggestion",
31869
+ fixable: false,
31870
+ supportedEffect: ["v3", "v4"],
31859
31871
  apply: fn3("catchUnfailableEffect.apply")(function* (sourceFile, report) {
31860
31872
  const ts = yield* service2(TypeScriptApi);
31861
31873
  const typeParser = yield* service2(TypeParser);
@@ -31905,6 +31917,8 @@ var classSelfMismatch = createDiagnostic({
31905
31917
  code: 20,
31906
31918
  description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
31907
31919
  severity: "error",
31920
+ fixable: true,
31921
+ supportedEffect: ["v3", "v4"],
31908
31922
  apply: fn3("classSelfMismatch.apply")(function* (sourceFile, report) {
31909
31923
  const ts = yield* service2(TypeScriptApi);
31910
31924
  const typeParser = yield* service2(TypeParser);
@@ -32043,6 +32057,8 @@ var deterministicKeys = createDiagnostic({
32043
32057
  code: 25,
32044
32058
  description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
32045
32059
  severity: "off",
32060
+ fixable: true,
32061
+ supportedEffect: ["v3", "v4"],
32046
32062
  apply: fn3("deterministicKeys.apply")(function* (sourceFile, report) {
32047
32063
  const ts = yield* service2(TypeScriptApi);
32048
32064
  const typeParser = yield* service2(TypeParser);
@@ -32160,6 +32176,8 @@ var duplicatePackage = createDiagnostic({
32160
32176
  code: 6,
32161
32177
  description: "Detects when multiple versions of the same Effect package are loaded",
32162
32178
  severity: "warning",
32179
+ fixable: false,
32180
+ supportedEffect: ["v3", "v4"],
32163
32181
  apply: fn3("duplicatePackage.apply")(function* (sourceFile, report) {
32164
32182
  const typeParser = yield* service2(TypeParser);
32165
32183
  const options = yield* service2(LanguageServicePluginOptions);
@@ -32189,6 +32207,8 @@ var effectFnIife = createDiagnostic({
32189
32207
  code: 46,
32190
32208
  description: "Effect.fn or Effect.fnUntraced is called as an IIFE (Immediately Invoked Function Expression). Use Effect.gen instead.",
32191
32209
  severity: "warning",
32210
+ fixable: true,
32211
+ supportedEffect: ["v3", "v4"],
32192
32212
  apply: fn3("effectFnIife.apply")(function* (sourceFile, report) {
32193
32213
  const ts = yield* service2(TypeScriptApi);
32194
32214
  const typeParser = yield* service2(TypeParser);
@@ -32291,6 +32311,8 @@ var effectFnOpportunity = createDiagnostic({
32291
32311
  code: 41,
32292
32312
  description: "Suggests using Effect.fn for functions that returns an Effect",
32293
32313
  severity: "suggestion",
32314
+ fixable: true,
32315
+ supportedEffect: ["v3", "v4"],
32294
32316
  apply: fn3("effectFnOpportunity.apply")(function* (sourceFile, report) {
32295
32317
  const ts = yield* service2(TypeScriptApi);
32296
32318
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -32883,6 +32905,8 @@ var effectGenUsesAdapter = createDiagnostic({
32883
32905
  code: 23,
32884
32906
  description: "Warns when using the deprecated adapter parameter in Effect.gen",
32885
32907
  severity: "warning",
32908
+ fixable: false,
32909
+ supportedEffect: ["v3", "v4"],
32886
32910
  apply: fn3("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
32887
32911
  const ts = yield* service2(TypeScriptApi);
32888
32912
  const typeParser = yield* service2(TypeParser);
@@ -32921,6 +32945,8 @@ var effectInFailure = createDiagnostic({
32921
32945
  code: 49,
32922
32946
  description: "Warns when an Effect is used inside an Effect failure channel",
32923
32947
  severity: "warning",
32948
+ fixable: false,
32949
+ supportedEffect: ["v3", "v4"],
32924
32950
  apply: fn3("effectInFailure.apply")(function* (sourceFile, report) {
32925
32951
  const ts = yield* service2(TypeScriptApi);
32926
32952
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -32985,6 +33011,8 @@ var effectInVoidSuccess = createDiagnostic({
32985
33011
  code: 14,
32986
33012
  description: "Detects nested Effects in void success channels that may cause unexecuted effects",
32987
33013
  severity: "warning",
33014
+ fixable: false,
33015
+ supportedEffect: ["v3", "v4"],
32988
33016
  apply: fn3("effectInVoidSuccess.apply")(function* (sourceFile, report) {
32989
33017
  const ts = yield* service2(TypeScriptApi);
32990
33018
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -33034,6 +33062,8 @@ var effectMapVoid = createDiagnostic({
33034
33062
  code: 40,
33035
33063
  description: "Suggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {})",
33036
33064
  severity: "suggestion",
33065
+ fixable: true,
33066
+ supportedEffect: ["v3", "v4"],
33037
33067
  apply: fn3("effectMapVoid.apply")(function* (sourceFile, report) {
33038
33068
  const ts = yield* service2(TypeScriptApi);
33039
33069
  const typeParser = yield* service2(TypeParser);
@@ -33098,6 +33128,8 @@ var effectSucceedWithVoid = createDiagnostic({
33098
33128
  code: 47,
33099
33129
  description: "Suggests using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0)",
33100
33130
  severity: "suggestion",
33131
+ fixable: true,
33132
+ supportedEffect: ["v3", "v4"],
33101
33133
  apply: fn3("effectSucceedWithVoid.apply")(function* (sourceFile, report) {
33102
33134
  const ts = yield* service2(TypeScriptApi);
33103
33135
  const typeParser = yield* service2(TypeParser);
@@ -33143,12 +33175,66 @@ var effectSucceedWithVoid = createDiagnostic({
33143
33175
  })
33144
33176
  });
33145
33177
 
33178
+ // src/diagnostics/extendsNativeError.ts
33179
+ var extendsNativeError = createDiagnostic({
33180
+ name: "extendsNativeError",
33181
+ code: 50,
33182
+ description: "Warns when a class directly extends the native Error class",
33183
+ severity: "off",
33184
+ fixable: false,
33185
+ supportedEffect: ["v3", "v4"],
33186
+ apply: fn3("extendsNativeError.apply")(function* (sourceFile, report) {
33187
+ const ts = yield* service2(TypeScriptApi);
33188
+ const typeChecker = yield* service2(TypeCheckerApi);
33189
+ const errorSymbol = typeChecker.resolveName("Error", void 0, ts.SymbolFlags.Type, false);
33190
+ if (!errorSymbol) return;
33191
+ const nodeToVisit = [];
33192
+ const appendNodeToVisit = (node) => {
33193
+ nodeToVisit.push(node);
33194
+ return void 0;
33195
+ };
33196
+ ts.forEachChild(sourceFile, appendNodeToVisit);
33197
+ while (nodeToVisit.length > 0) {
33198
+ const node = nodeToVisit.shift();
33199
+ if (ts.isClassDeclaration(node) && node.heritageClauses) {
33200
+ for (const clause of node.heritageClauses) {
33201
+ if (clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.length > 0) {
33202
+ const typeExpression = clause.types[0].expression;
33203
+ const exprSymbol = typeChecker.getSymbolAtLocation(typeExpression);
33204
+ const resolvedSymbol = exprSymbol && exprSymbol.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(exprSymbol) : exprSymbol;
33205
+ const isNativeError = resolvedSymbol === errorSymbol || (() => {
33206
+ if (!resolvedSymbol || resolvedSymbol === errorSymbol) return false;
33207
+ const exprType = typeChecker.getTypeAtLocation(typeExpression);
33208
+ const constructSignatures = typeChecker.getSignaturesOfType(exprType, ts.SignatureKind.Construct);
33209
+ if (constructSignatures.length > 0) {
33210
+ const instanceType = typeChecker.getReturnTypeOfSignature(constructSignatures[0]);
33211
+ return instanceType.symbol === errorSymbol;
33212
+ }
33213
+ return false;
33214
+ })();
33215
+ if (isNativeError) {
33216
+ report({
33217
+ location: node.name ?? typeExpression,
33218
+ messageText: "Avoid extending the native 'Error' class directly. Consider using a tagged error (e.g. Data.TaggedError) to maintain type safety in the Effect failure channel.",
33219
+ fixes: []
33220
+ });
33221
+ }
33222
+ }
33223
+ }
33224
+ }
33225
+ ts.forEachChild(node, appendNodeToVisit);
33226
+ }
33227
+ })
33228
+ });
33229
+
33146
33230
  // src/diagnostics/floatingEffect.ts
33147
33231
  var floatingEffect = createDiagnostic({
33148
33232
  name: "floatingEffect",
33149
33233
  code: 3,
33150
33234
  description: "Ensures Effects are yielded or assigned to variables, not left floating",
33151
33235
  severity: "error",
33236
+ fixable: false,
33237
+ supportedEffect: ["v3", "v4"],
33152
33238
  apply: fn3("floatingEffect.apply")(function* (sourceFile, report) {
33153
33239
  const ts = yield* service2(TypeScriptApi);
33154
33240
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -33200,6 +33286,8 @@ var genericEffectServices = createDiagnostic({
33200
33286
  code: 10,
33201
33287
  description: "Prevents services with type parameters that cannot be discriminated at runtime",
33202
33288
  severity: "warning",
33289
+ fixable: false,
33290
+ supportedEffect: ["v3", "v4"],
33203
33291
  apply: fn3("genericEffectServices.apply")(function* (sourceFile, report) {
33204
33292
  const ts = yield* service2(TypeScriptApi);
33205
33293
  const typeParser = yield* service2(TypeParser);
@@ -33247,6 +33335,8 @@ var globalErrorInEffectCatch = createDiagnostic({
33247
33335
  code: 36,
33248
33336
  description: "Warns when catch callbacks return global Error type instead of typed errors",
33249
33337
  severity: "warning",
33338
+ fixable: false,
33339
+ supportedEffect: ["v3", "v4"],
33250
33340
  apply: fn3("globalErrorInEffectCatch.apply")(function* (sourceFile, report) {
33251
33341
  const ts = yield* service2(TypeScriptApi);
33252
33342
  const typeParser = yield* service2(TypeParser);
@@ -33307,6 +33397,8 @@ var globalErrorInEffectFailure = createDiagnostic({
33307
33397
  code: 35,
33308
33398
  description: "Warns when the global Error type is used in an Effect failure channel",
33309
33399
  severity: "warning",
33400
+ fixable: false,
33401
+ supportedEffect: ["v3", "v4"],
33310
33402
  apply: fn3("globalErrorInEffectFailure.apply")(function* (sourceFile, report) {
33311
33403
  const ts = yield* service2(TypeScriptApi);
33312
33404
  const typeParser = yield* service2(TypeParser);
@@ -33360,6 +33452,8 @@ var importFromBarrel = createDiagnostic({
33360
33452
  code: 12,
33361
33453
  description: "Suggests importing from specific module paths instead of barrel exports",
33362
33454
  severity: "off",
33455
+ fixable: true,
33456
+ supportedEffect: ["v3", "v4"],
33363
33457
  apply: fn3("importFromBarrel.apply")(function* (sourceFile, report) {
33364
33458
  const languageServicePluginOptions = yield* service2(LanguageServicePluginOptions);
33365
33459
  if (languageServicePluginOptions.namespaceImportPackages.length === 0) return;
@@ -33500,6 +33594,8 @@ var instanceOfSchema = createDiagnostic({
33500
33594
  code: 45,
33501
33595
  description: "Suggests using Schema.is instead of instanceof for Effect Schema types",
33502
33596
  severity: "off",
33597
+ fixable: true,
33598
+ supportedEffect: ["v3", "v4"],
33503
33599
  apply: fn3("instanceOfSchema.apply")(function* (sourceFile, report) {
33504
33600
  const ts = yield* service2(TypeScriptApi);
33505
33601
  const typeParser = yield* service2(TypeParser);
@@ -33563,6 +33659,8 @@ var layerMergeAllWithDependencies = createDiagnostic({
33563
33659
  code: 37,
33564
33660
  description: "Detects interdependencies in Layer.mergeAll calls where one layer provides a service that another layer requires",
33565
33661
  severity: "warning",
33662
+ fixable: true,
33663
+ supportedEffect: ["v3", "v4"],
33566
33664
  apply: fn3("layerMergeAllWithDependencies.apply")(function* (sourceFile, report) {
33567
33665
  const ts = yield* service2(TypeScriptApi);
33568
33666
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -33676,6 +33774,8 @@ var leakingRequirements = createDiagnostic({
33676
33774
  code: 8,
33677
33775
  description: "Detects implementation services leaked in service methods",
33678
33776
  severity: "suggestion",
33777
+ fixable: false,
33778
+ supportedEffect: ["v3", "v4"],
33679
33779
  apply: fn3("leakingRequirements.apply")(function* (sourceFile, report) {
33680
33780
  const ts = yield* service2(TypeScriptApi);
33681
33781
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -33830,6 +33930,8 @@ var missedPipeableOpportunity = createDiagnostic({
33830
33930
  code: 26,
33831
33931
  description: "Enforces the use of pipeable style for nested function calls",
33832
33932
  severity: "off",
33933
+ fixable: true,
33934
+ supportedEffect: ["v3", "v4"],
33833
33935
  apply: fn3("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
33834
33936
  const ts = yield* service2(TypeScriptApi);
33835
33937
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -34010,6 +34112,8 @@ var missingEffectContext = createDiagnostic({
34010
34112
  code: 1,
34011
34113
  description: "Reports missing service requirements in Effect context channel",
34012
34114
  severity: "error",
34115
+ fixable: false,
34116
+ supportedEffect: ["v3", "v4"],
34013
34117
  apply: fn3("missingEffectContext.apply")(function* (sourceFile, report) {
34014
34118
  const typeChecker = yield* service2(TypeCheckerApi);
34015
34119
  const typeParser = yield* service2(TypeParser);
@@ -34059,6 +34163,8 @@ var missingEffectError = createDiagnostic({
34059
34163
  code: 1,
34060
34164
  description: "Reports missing error types in Effect error channel",
34061
34165
  severity: "error",
34166
+ fixable: true,
34167
+ supportedEffect: ["v3", "v4"],
34062
34168
  apply: fn3("missingEffectError.apply")(function* (sourceFile, report) {
34063
34169
  const ts = yield* service2(TypeScriptApi);
34064
34170
  const tsUtils = yield* service2(TypeScriptUtils);
@@ -34200,6 +34306,8 @@ var missingEffectServiceDependency = createDiagnostic({
34200
34306
  code: 22,
34201
34307
  description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
34202
34308
  severity: "off",
34309
+ fixable: false,
34310
+ supportedEffect: ["v3"],
34203
34311
  apply: fn3("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
34204
34312
  const ts = yield* service2(TypeScriptApi);
34205
34313
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -34294,6 +34402,8 @@ var missingLayerContext = createDiagnostic({
34294
34402
  code: 38,
34295
34403
  description: "Reports missing service requirements in Layer context channel",
34296
34404
  severity: "error",
34405
+ fixable: false,
34406
+ supportedEffect: ["v3", "v4"],
34297
34407
  apply: fn3("missingLayerContext.apply")(function* (sourceFile, report) {
34298
34408
  const typeChecker = yield* service2(TypeCheckerApi);
34299
34409
  const typeParser = yield* service2(TypeParser);
@@ -34343,6 +34453,8 @@ var missingReturnYieldStar = createDiagnostic({
34343
34453
  code: 7,
34344
34454
  description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
34345
34455
  severity: "error",
34456
+ fixable: true,
34457
+ supportedEffect: ["v3", "v4"],
34346
34458
  apply: fn3("missingReturnYieldStar.apply")(function* (sourceFile, report) {
34347
34459
  const ts = yield* service2(TypeScriptApi);
34348
34460
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
@@ -34393,6 +34505,8 @@ var missingStarInYieldEffectGen = createDiagnostic({
34393
34505
  code: 4,
34394
34506
  description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
34395
34507
  severity: "error",
34508
+ fixable: true,
34509
+ supportedEffect: ["v3", "v4"],
34396
34510
  apply: fn3("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
34397
34511
  const ts = yield* service2(TypeScriptApi);
34398
34512
  const typeParser = yield* service2(TypeParser);
@@ -34468,6 +34582,8 @@ var multipleEffectProvide = createDiagnostic({
34468
34582
  code: 18,
34469
34583
  description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
34470
34584
  severity: "warning",
34585
+ fixable: true,
34586
+ supportedEffect: ["v3", "v4"],
34471
34587
  apply: fn3("multipleEffectProvide.apply")(function* (sourceFile, report) {
34472
34588
  const ts = yield* service2(TypeScriptApi);
34473
34589
  const tsUtils = yield* service2(TypeScriptUtils);
@@ -34554,12 +34670,85 @@ var multipleEffectProvide = createDiagnostic({
34554
34670
  })
34555
34671
  });
34556
34672
 
34673
+ // src/diagnostics/nodeBuiltinImport.ts
34674
+ var moduleAlternativesV3 = /* @__PURE__ */ new Map([
34675
+ ["fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
34676
+ ["node:fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
34677
+ ["fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
34678
+ ["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
34679
+ ["path", { alternative: "Path", module: "path", package: "@effect/platform" }],
34680
+ ["node:path", { alternative: "Path", module: "path", package: "@effect/platform" }],
34681
+ ["path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
34682
+ ["node:path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
34683
+ ["path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
34684
+ ["node:path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
34685
+ ["child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }],
34686
+ ["node:child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }]
34687
+ ]);
34688
+ var moduleAlternativesV4 = /* @__PURE__ */ new Map([
34689
+ ["fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
34690
+ ["node:fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
34691
+ ["fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
34692
+ ["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
34693
+ ["path", { alternative: "Path", module: "path", package: "effect" }],
34694
+ ["node:path", { alternative: "Path", module: "path", package: "effect" }],
34695
+ ["path/posix", { alternative: "Path", module: "path", package: "effect" }],
34696
+ ["node:path/posix", { alternative: "Path", module: "path", package: "effect" }],
34697
+ ["path/win32", { alternative: "Path", module: "path", package: "effect" }],
34698
+ ["node:path/win32", { alternative: "Path", module: "path", package: "effect" }],
34699
+ ["child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }],
34700
+ ["node:child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }]
34701
+ ]);
34702
+ var nodeBuiltinImport = createDiagnostic({
34703
+ name: "nodeBuiltinImport",
34704
+ code: 52,
34705
+ description: "Warns when importing Node.js built-in modules that have Effect-native counterparts",
34706
+ severity: "off",
34707
+ fixable: false,
34708
+ supportedEffect: ["v3", "v4"],
34709
+ apply: fn3("nodeBuiltinImport.apply")(function* (sourceFile, report) {
34710
+ const ts = yield* service2(TypeScriptApi);
34711
+ const typeParser = yield* service2(TypeParser);
34712
+ const moduleAlternatives = typeParser.supportedEffect() === "v3" ? moduleAlternativesV3 : moduleAlternativesV4;
34713
+ for (const statement of sourceFile.statements) {
34714
+ if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
34715
+ const specifier = statement.moduleSpecifier.text;
34716
+ const match9 = moduleAlternatives.get(specifier);
34717
+ if (match9) {
34718
+ report({
34719
+ location: statement.moduleSpecifier,
34720
+ messageText: `Prefer using ${match9.alternative} from ${match9.package} instead of the Node.js '${match9.module}' module.`,
34721
+ fixes: []
34722
+ });
34723
+ }
34724
+ } else if (ts.isVariableStatement(statement)) {
34725
+ for (const decl of statement.declarationList.declarations) {
34726
+ if (decl.initializer && ts.isCallExpression(decl.initializer) && ts.isIdentifier(decl.initializer.expression) && ts.idText(decl.initializer.expression) === "require" && decl.initializer.arguments.length === 1 && ts.isStringLiteral(decl.initializer.arguments[0])) {
34727
+ const arg = decl.initializer.arguments[0];
34728
+ const specifier = arg.text;
34729
+ const match9 = moduleAlternatives.get(specifier);
34730
+ if (match9) {
34731
+ report({
34732
+ location: arg,
34733
+ messageText: `Prefer using ${match9.alternative} from ${match9.package} instead of the Node.js '${match9.module}' module.`,
34734
+ fixes: []
34735
+ });
34736
+ }
34737
+ }
34738
+ }
34739
+ }
34740
+ }
34741
+ })
34742
+ });
34743
+
34557
34744
  // src/diagnostics/nonObjectEffectServiceType.ts
34558
34745
  var nonObjectEffectServiceType = createDiagnostic({
34559
34746
  name: "nonObjectEffectServiceType",
34560
34747
  code: 24,
34561
34748
  description: "Ensures Effect.Service types are objects, not primitives",
34562
34749
  severity: "error",
34750
+ fixable: false,
34751
+ supportedEffect: ["v3"],
34563
34752
  apply: fn3("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
34564
34753
  const ts = yield* service2(TypeScriptApi);
34565
34754
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -35342,6 +35531,8 @@ var outdatedApi = createDiagnostic({
35342
35531
  code: 48,
35343
35532
  description: "Detects usage of APIs that have been removed or renamed in Effect v4",
35344
35533
  severity: "warning",
35534
+ fixable: false,
35535
+ supportedEffect: ["v4"],
35345
35536
  apply: fn3("outdatedApi.apply")(function* (sourceFile, report) {
35346
35537
  const typeParser = yield* service2(TypeParser);
35347
35538
  const ts = yield* service2(TypeScriptApi);
@@ -35409,6 +35600,8 @@ var outdatedEffectCodegen = createDiagnostic({
35409
35600
  code: 19,
35410
35601
  description: "Detects when generated code is outdated and needs to be regenerated",
35411
35602
  severity: "warning",
35603
+ fixable: true,
35604
+ supportedEffect: ["v3", "v4"],
35412
35605
  apply: fn3("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
35413
35606
  const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
35414
35607
  for (const { codegen: codegen2, hash: hash2, range: range2 } of codegensWithRanges) {
@@ -35455,6 +35648,8 @@ var overriddenSchemaConstructor = createDiagnostic({
35455
35648
  code: 30,
35456
35649
  description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
35457
35650
  severity: "error",
35651
+ fixable: true,
35652
+ supportedEffect: ["v3", "v4"],
35458
35653
  apply: fn3("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
35459
35654
  const ts = yield* service2(TypeScriptApi);
35460
35655
  const typeParser = yield* service2(TypeParser);
@@ -35592,6 +35787,8 @@ var preferSchemaOverJson = createDiagnostic({
35592
35787
  code: 44,
35593
35788
  description: "Suggests using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify which may throw",
35594
35789
  severity: "suggestion",
35790
+ fixable: false,
35791
+ supportedEffect: ["v3", "v4"],
35595
35792
  apply: fn3("preferSchemaOverJson.apply")(function* (sourceFile, report) {
35596
35793
  const ts = yield* service2(TypeScriptApi);
35597
35794
  const typeParser = yield* service2(TypeParser);
@@ -35702,6 +35899,8 @@ var redundantSchemaTagIdentifier = createDiagnostic({
35702
35899
  code: 42,
35703
35900
  description: "Suggests removing redundant identifier argument when it equals the tag value in Schema.TaggedClass/TaggedError/TaggedRequest",
35704
35901
  severity: "suggestion",
35902
+ fixable: true,
35903
+ supportedEffect: ["v3", "v4"],
35705
35904
  apply: fn3("redundantSchemaTagIdentifier.apply")(function* (sourceFile, report) {
35706
35905
  const ts = yield* service2(TypeScriptApi);
35707
35906
  const typeParser = yield* service2(TypeParser);
@@ -35752,6 +35951,8 @@ var returnEffectInGen = createDiagnostic({
35752
35951
  code: 11,
35753
35952
  description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
35754
35953
  severity: "suggestion",
35954
+ fixable: true,
35955
+ supportedEffect: ["v3", "v4"],
35755
35956
  apply: fn3("returnEffectInGen.apply")(function* (sourceFile, report) {
35756
35957
  const ts = yield* service2(TypeScriptApi);
35757
35958
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
@@ -35821,6 +36022,8 @@ var runEffectInsideEffect = createDiagnostic({
35821
36022
  code: 32,
35822
36023
  description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
35823
36024
  severity: "suggestion",
36025
+ fixable: true,
36026
+ supportedEffect: ["v3"],
35824
36027
  apply: fn3("runEffectInsideEffect.apply")(function* (sourceFile, report) {
35825
36028
  const ts = yield* service2(TypeScriptApi);
35826
36029
  const typeParser = yield* service2(TypeParser);
@@ -35945,6 +36148,8 @@ var schemaStructWithTag = createDiagnostic({
35945
36148
  code: 34,
35946
36149
  description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
35947
36150
  severity: "suggestion",
36151
+ fixable: true,
36152
+ supportedEffect: ["v3", "v4"],
35948
36153
  apply: fn3("schemaStructWithTag.apply")(function* (sourceFile, report) {
35949
36154
  const ts = yield* service2(TypeScriptApi);
35950
36155
  const typeParser = yield* service2(TypeParser);
@@ -36037,6 +36242,8 @@ var schemaSyncInEffect = createDiagnostic({
36037
36242
  code: 43,
36038
36243
  description: "Suggests using Effect-based Schema methods instead of sync methods inside Effect generators",
36039
36244
  severity: "suggestion",
36245
+ fixable: false,
36246
+ supportedEffect: ["v3", "v4"],
36040
36247
  apply: fn3("schemaSyncInEffect.apply")(function* (sourceFile, report) {
36041
36248
  const ts = yield* service2(TypeScriptApi);
36042
36249
  const typeParser = yield* service2(TypeParser);
@@ -36086,6 +36293,8 @@ var schemaUnionOfLiterals = createDiagnostic({
36086
36293
  code: 33,
36087
36294
  description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
36088
36295
  severity: "off",
36296
+ fixable: true,
36297
+ supportedEffect: ["v3"],
36089
36298
  apply: fn3("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
36090
36299
  const ts = yield* service2(TypeScriptApi);
36091
36300
  const typeParser = yield* service2(TypeParser);
@@ -36161,6 +36370,8 @@ var scopeInLayerEffect = createDiagnostic({
36161
36370
  code: 13,
36162
36371
  description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
36163
36372
  severity: "warning",
36373
+ fixable: true,
36374
+ supportedEffect: ["v3"],
36164
36375
  apply: fn3("scopeInLayerEffect.apply")(function* (sourceFile, report) {
36165
36376
  const ts = yield* service2(TypeScriptApi);
36166
36377
  const tsUtils = yield* service2(TypeScriptUtils);
@@ -36250,12 +36461,91 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
36250
36461
  })
36251
36462
  });
36252
36463
 
36464
+ // src/diagnostics/serviceNotAsClass.ts
36465
+ var serviceNotAsClass = createDiagnostic({
36466
+ name: "serviceNotAsClass",
36467
+ code: 51,
36468
+ description: "Warns when ServiceMap.Service is used as a variable instead of a class declaration",
36469
+ severity: "off",
36470
+ fixable: true,
36471
+ supportedEffect: ["v4"],
36472
+ apply: fn3("serviceNotAsClass.apply")(function* (sourceFile, report) {
36473
+ const ts = yield* service2(TypeScriptApi);
36474
+ const typeParser = yield* service2(TypeParser);
36475
+ if (typeParser.supportedEffect() === "v3") return;
36476
+ const nodeToVisit = [];
36477
+ const appendNodeToVisit = (node) => {
36478
+ nodeToVisit.push(node);
36479
+ return void 0;
36480
+ };
36481
+ ts.forEachChild(sourceFile, appendNodeToVisit);
36482
+ while (nodeToVisit.length > 0) {
36483
+ const node = nodeToVisit.shift();
36484
+ ts.forEachChild(node, appendNodeToVisit);
36485
+ if (!ts.isVariableDeclaration(node)) continue;
36486
+ if (!node.initializer || !ts.isCallExpression(node.initializer)) continue;
36487
+ const callExpr = node.initializer;
36488
+ if (!callExpr.typeArguments || callExpr.typeArguments.length === 0) continue;
36489
+ const typeArgs = callExpr.typeArguments;
36490
+ const declList = node.parent;
36491
+ if (!ts.isVariableDeclarationList(declList)) continue;
36492
+ if (!(declList.flags & ts.NodeFlags.Const)) continue;
36493
+ const isServiceMapService = yield* pipe(
36494
+ typeParser.isNodeReferenceToServiceMapModuleApi("Service")(callExpr.expression),
36495
+ orUndefined
36496
+ );
36497
+ if (!isServiceMapService) continue;
36498
+ const variableName = ts.isIdentifier(node.name) ? ts.idText(node.name) : sourceFile.text.substring(ts.getTokenPosOfNode(node.name, sourceFile), node.name.end);
36499
+ const variableStatement = declList.parent;
36500
+ const argsText = callExpr.arguments.length > 0 ? callExpr.arguments.map((a) => sourceFile.text.substring(ts.getTokenPosOfNode(a, sourceFile), a.end)).join(", ") : "";
36501
+ const shapeText = typeArgs.length > 0 ? typeArgs.map((t) => sourceFile.text.substring(ts.getTokenPosOfNode(t, sourceFile), t.end)).join(", ") : "Shape";
36502
+ report({
36503
+ location: callExpr,
36504
+ messageText: `ServiceMap.Service should be used in a class declaration instead of as a variable. Use: class ${variableName} extends ServiceMap.Service<${variableName}, ${shapeText}>()("${argsText.replace(/['"]/g, "")}") {}`,
36505
+ fixes: [{
36506
+ fixName: "serviceNotAsClass",
36507
+ description: `Convert to class declaration`,
36508
+ apply: gen3(function* () {
36509
+ const changeTracker = yield* service2(ChangeTracker);
36510
+ const targetNode = ts.isVariableStatement(variableStatement) ? variableStatement : declList;
36511
+ const innerCall = ts.factory.createCallExpression(
36512
+ callExpr.expression,
36513
+ [ts.factory.createTypeReferenceNode(variableName), ...typeArgs],
36514
+ []
36515
+ );
36516
+ const outerCall = ts.factory.createCallExpression(
36517
+ innerCall,
36518
+ void 0,
36519
+ [...callExpr.arguments]
36520
+ );
36521
+ const heritageClause = ts.factory.createHeritageClause(
36522
+ ts.SyntaxKind.ExtendsKeyword,
36523
+ [ts.factory.createExpressionWithTypeArguments(outerCall, void 0)]
36524
+ );
36525
+ const modifiers = ts.isVariableStatement(variableStatement) ? variableStatement.modifiers : void 0;
36526
+ const classDeclaration = ts.factory.createClassDeclaration(
36527
+ modifiers,
36528
+ ts.isIdentifier(node.name) ? node.name : ts.factory.createIdentifier(variableName),
36529
+ void 0,
36530
+ [heritageClause],
36531
+ []
36532
+ );
36533
+ changeTracker.replaceNode(sourceFile, targetNode, classDeclaration);
36534
+ })
36535
+ }]
36536
+ });
36537
+ }
36538
+ })
36539
+ });
36540
+
36253
36541
  // src/diagnostics/strictBooleanExpressions.ts
36254
36542
  var strictBooleanExpressions = createDiagnostic({
36255
36543
  name: "strictBooleanExpressions",
36256
36544
  code: 17,
36257
36545
  description: "Enforces boolean types in conditional expressions for type safety",
36258
36546
  severity: "off",
36547
+ fixable: false,
36548
+ supportedEffect: ["v3", "v4"],
36259
36549
  apply: fn3("strictBooleanExpressions.apply")(function* (sourceFile, report) {
36260
36550
  const ts = yield* service2(TypeScriptApi);
36261
36551
  const typeChecker = yield* service2(TypeCheckerApi);
@@ -36327,6 +36617,8 @@ var strictEffectProvide = createDiagnostic({
36327
36617
  code: 27,
36328
36618
  description: "Warns when using Effect.provide with layers outside of application entry points",
36329
36619
  severity: "off",
36620
+ fixable: false,
36621
+ supportedEffect: ["v3", "v4"],
36330
36622
  apply: fn3("strictEffectProvide.apply")(function* (sourceFile, report) {
36331
36623
  const ts = yield* service2(TypeScriptApi);
36332
36624
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
@@ -36378,6 +36670,8 @@ var tryCatchInEffectGen = createDiagnostic({
36378
36670
  code: 15,
36379
36671
  description: "Discourages try/catch in Effect generators in favor of Effect error handling",
36380
36672
  severity: "suggestion",
36673
+ fixable: false,
36674
+ supportedEffect: ["v3", "v4"],
36381
36675
  apply: fn3("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
36382
36676
  const ts = yield* service2(TypeScriptApi);
36383
36677
  const typeParser = yield* service2(TypeParser);
@@ -36435,6 +36729,8 @@ var unknownInEffectCatch = createDiagnostic({
36435
36729
  code: 31,
36436
36730
  description: "Warns when catch callbacks return unknown instead of typed errors",
36437
36731
  severity: "warning",
36732
+ fixable: false,
36733
+ supportedEffect: ["v3", "v4"],
36438
36734
  apply: fn3("unknownInEffectCatch.apply")(function* (sourceFile, report) {
36439
36735
  const ts = yield* service2(TypeScriptApi);
36440
36736
  const typeParser = yield* service2(TypeParser);
@@ -36496,6 +36792,8 @@ var unnecessaryEffectGen = createDiagnostic({
36496
36792
  code: 5,
36497
36793
  description: "Suggests removing Effect.gen when it contains only a single return statement",
36498
36794
  severity: "suggestion",
36795
+ fixable: true,
36796
+ supportedEffect: ["v3", "v4"],
36499
36797
  apply: fn3("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
36500
36798
  const ts = yield* service2(TypeScriptApi);
36501
36799
  const typeParser = yield* service2(TypeParser);
@@ -36540,6 +36838,8 @@ var unnecessaryFailYieldableError = createDiagnostic({
36540
36838
  code: 29,
36541
36839
  description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
36542
36840
  severity: "suggestion",
36841
+ fixable: true,
36842
+ supportedEffect: ["v3", "v4"],
36543
36843
  apply: fn3("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
36544
36844
  const ts = yield* service2(TypeScriptApi);
36545
36845
  const typeParser = yield* service2(TypeParser);
@@ -36599,6 +36899,8 @@ var unnecessaryPipe = createDiagnostic({
36599
36899
  code: 9,
36600
36900
  description: "Removes pipe calls with no arguments",
36601
36901
  severity: "suggestion",
36902
+ fixable: true,
36903
+ supportedEffect: ["v3", "v4"],
36602
36904
  apply: fn3("unnecessaryPipe.apply")(function* (sourceFile, report) {
36603
36905
  const ts = yield* service2(TypeScriptApi);
36604
36906
  const typeParser = yield* service2(TypeParser);
@@ -36645,6 +36947,8 @@ var unnecessaryPipeChain = createDiagnostic({
36645
36947
  code: 16,
36646
36948
  description: "Simplifies chained pipe calls into a single pipe call",
36647
36949
  severity: "suggestion",
36950
+ fixable: true,
36951
+ supportedEffect: ["v3", "v4"],
36648
36952
  apply: fn3("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
36649
36953
  const ts = yield* service2(TypeScriptApi);
36650
36954
  const typeParser = yield* service2(TypeParser);
@@ -36720,6 +37024,8 @@ var unsupportedServiceAccessors = createDiagnostic({
36720
37024
  code: 21,
36721
37025
  description: "Warns about service accessors that need codegen due to generic/complex signatures",
36722
37026
  severity: "warning",
37027
+ fixable: true,
37028
+ supportedEffect: ["v3", "v4"],
36723
37029
  apply: fn3("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
36724
37030
  const ts = yield* service2(TypeScriptApi);
36725
37031
  const nodeToVisit = [];
@@ -36822,7 +37128,10 @@ var diagnostics = [
36822
37128
  effectFnOpportunity,
36823
37129
  redundantSchemaTagIdentifier,
36824
37130
  schemaSyncInEffect,
36825
- preferSchemaOverJson
37131
+ preferSchemaOverJson,
37132
+ extendsNativeError,
37133
+ serviceNotAsClass,
37134
+ nodeBuiltinImport
36826
37135
  ];
36827
37136
 
36828
37137
  // src/cli/diagnostics.ts
@@ -37757,7 +38066,10 @@ var import_project_service3 = __toESM(require_dist3());
37757
38066
  var getLocationFromDeclaration = (declaration, tsInstance) => {
37758
38067
  const sourceFile = declaration.getSourceFile();
37759
38068
  if (!sourceFile) return void 0;
37760
- const { character, line } = tsInstance.getLineAndCharacterOfPosition(sourceFile, declaration.getStart());
38069
+ const { character, line } = tsInstance.getLineAndCharacterOfPosition(
38070
+ sourceFile,
38071
+ tsInstance.getTokenPosOfNode(declaration, sourceFile)
38072
+ );
37761
38073
  return {
37762
38074
  filePath: sourceFile.fileName,
37763
38075
  line: line + 1,
@@ -38359,7 +38671,8 @@ function getExpressionName(tsApi, expr) {
38359
38671
  if (tsApi.isCallExpression(expr)) {
38360
38672
  return getExpressionName(tsApi, expr.expression);
38361
38673
  }
38362
- const text2 = expr.getText().replace(/\s+/g, " ");
38674
+ const sourceFile = expr.getSourceFile();
38675
+ const text2 = sourceFile.text.substring(tsApi.getTokenPosOfNode(expr, sourceFile), expr.end).replace(/\s+/g, " ");
38363
38676
  return text2.length > 30 ? text2.slice(0, 27) + "..." : text2;
38364
38677
  }
38365
38678
  var collectLayerInfoByName = (sourceFile, layerName, selectedOutputIndices) => gen3(function* () {