Skip to content

Commit 72827c0

Browse files
Allow suppressing leaked service diagnostics (#687)
1 parent 6d23a96 commit 72827c0

File tree

12 files changed

+114
-13
lines changed

12 files changed

+114
-13
lines changed

.changeset/green-buses-joke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@effect/language-service": patch
3+
---
4+
5+
Allow the leaking requirements diagnostic to suppress specific leaked services with `@effect-expect-leaking` comments on the enclosing declaration.

packages/harness-effect-v3/__snapshots__/diagnostics/leakingRequirements.ts.output

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This leaks implementation details into the service's public type — callers sho
55

66
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
77

8-
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), not to this service.
8+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.
99

1010
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)
1111

@@ -16,6 +16,6 @@ This leaks implementation details into the service's public type — callers sho
1616

1717
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
1818

19-
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), not to this service.
19+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.
2020

2121
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)

packages/harness-effect-v3/__snapshots__/diagnostics/leakingRequirements_genericTag.ts.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ This leaks implementation details into the service's public type — callers sho
55

66
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
77

8-
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), not to this service.
8+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.
99

1010
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)

packages/harness-effect-v4/__snapshots__/diagnostics/leakingRequirements.ts.output

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This leaks implementation details into the service's public type — callers sho
55

66
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
77

8-
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), not to this service.
8+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.
99

1010
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)
1111

@@ -16,6 +16,6 @@ This leaks implementation details into the service's public type — callers sho
1616

1717
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
1818

19-
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), not to this service.
19+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.
2020

2121
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
leakingRequirements_skipNextLine from 495 to 506
2+
leakingRequirements_skipFile from 495 to 506
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
LeakingDeps
2+
15:13 - 15:24 | 2 | Methods of this Service require `Cache` from every caller.
3+
4+
This leaks implementation details into the service's public type — callers shouldn't need to know *how* the service works internally, only *what* it provides.
5+
6+
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
7+
8+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `Cache` interface), or to this service by adding a `@effect-expect-leaking Cache` JSDoc.
9+
10+
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)

packages/harness-effect-v4/__snapshots__/diagnostics/leakingRequirements_genericTag.ts.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ This leaks implementation details into the service's public type — callers sho
55

66
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
77

8-
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), not to this service.
8+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.
99

1010
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)

packages/harness-effect-v4/__snapshots__/diagnostics/leakingRequirements_preview.ts.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ This leaks implementation details into the service's public type — callers sho
55

66
Resolve these dependencies at Layer creation and provide them to each method, so the service's type reflects its purpose, not its implementation.
77

8-
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), not to this service.
8+
To suppress this diagnostic for specific dependency types that are intentionally passed through (e.g., HttpServerRequest), add `@effect-leakable-service` JSDoc to their interface declarations (e.g., the `FileSystem` interface), or to this service by adding a `@effect-expect-leaking FileSystem` JSDoc.
99

1010
More info and examples at https://effect.website/docs/requirements-management/layers/#avoiding-requirement-leakage effect(leakingRequirements)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import type { Effect } from "effect"
2+
import { ServiceMap } from "effect"
3+
4+
export class FileSystem extends ServiceMap.Service<FileSystem, {
5+
writeFile: (content: string) => Effect.Effect<void>
6+
}>()("FileSystem") {}
7+
8+
export class Cache extends ServiceMap.Service<Cache, {
9+
writeFile: (content: string) => Effect.Effect<void>
10+
}>()("Cache") {}
11+
12+
// LeakingDeps is leaking FileSystem and Cache, but only Cache should be considered to be leaked
13+
14+
// @effect-expect-leaking FileSystem
15+
export class LeakingDeps extends ServiceMap.Service<LeakingDeps, {
16+
writeCache: () => Effect.Effect<void, never, FileSystem | Cache>
17+
readCache: Effect.Effect<void, never, FileSystem | Cache>
18+
}>()("LeakingDeps") {}
19+
20+
// LeakingDeps2 is leaking FileSystem and Cache, but both are expected to be leaked
21+
22+
// @effect-expect-leaking FileSystem Cache
23+
export class LeakingDeps2 extends ServiceMap.Service<LeakingDeps2, {
24+
writeCache: () => Effect.Effect<void, never, FileSystem | Cache>
25+
readCache: Effect.Effect<void, never, FileSystem | Cache>
26+
}>()("LeakingDeps2") {}
27+
28+
// LeakingDeps3 is leaking FileSystem and Cache, but both are expected to be leaked
29+
30+
/**
31+
* Example inside of a class with multiple JSDoc
32+
* @effect-leakable-service
33+
* @effect-expect-leaking FileSystem Cache
34+
*/
35+
export class LeakingDeps3 extends ServiceMap.Service<LeakingDeps3, {
36+
writeCache: () => Effect.Effect<void, never, FileSystem | Cache>
37+
readCache: Effect.Effect<void, never, FileSystem | Cache>
38+
}>()("LeakingDeps3") {}
39+
40+
// LeakingDeps4 is leaking FileSystem and Cache, but both are expected to be leaked
41+
42+
// @effect-expect-leaking FileSystem Cache
43+
export const LeakingDeps4 = ServiceMap.Service<{
44+
writeCache: () => Effect.Effect<void, never, FileSystem | Cache>
45+
readCache: Effect.Effect<void, never, FileSystem | Cache>
46+
}>("LeakingDeps4")

packages/language-service/src/core/TypeScriptApi.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ declare module "typescript" {
187187
export interface Node {
188188
/** @deprecated Use ts.getTokenPosOfNode(node, sourceFile) instead */
189189
getStart(sourceFile?: ts.SourceFile, includeJsDocComment?: boolean): number
190+
/** @deprecated Use node.pos instead */
191+
getFullStart(): number
190192
/** @deprecated Use sourceFile.text.substring(node.pos, node.end) instead */
191193
getText(sourceFile?: ts.SourceFile): string
192194
}

0 commit comments

Comments
 (0)