Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/tall-maps-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@effect/language-service": patch
---

Refactor Effect context tracking to use cached node context flags and direct generator lookups.

This aligns the TypeScript implementation more closely with the TSGo version and simplifies diagnostics that need to detect whether code is inside an Effect generator.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
globalConsoleInEffect_skipNextLine from 207 to 226
globalConsoleInEffect_skipFile from 207 to 226
globalConsoleInEffect_skipNextLine from 413 to 439
globalConsoleInEffect_skipFile from 413 to 439
globalConsoleInEffect_skipNextLine from 289 to 308
globalConsoleInEffect_skipFile from 289 to 308
globalConsoleInEffect_skipNextLine from 522 to 556
globalConsoleInEffect_skipFile from 522 to 556
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
console.log("sync")
6:47 - 6:66 | 0 | This Effect code uses `console.log`, logging in Effect code is represented through `Effect.log or Logger`. effect(globalConsoleInEffect)

console.warn("try")
9:13 - 9:32 | 0 | This Effect code uses `console.warn`, logging in Effect code is represented through `Effect.logWarning or Logger`. effect(globalConsoleInEffect)

console.log("try-promise")
13:65 - 13:91 | 0 | This Effect code uses `console.log`, logging in Effect code is represented through `Effect.log or Logger`. effect(globalConsoleInEffect)

console.warn("try-promise-object")
16:19 - 16:53 | 0 | This Effect code uses `console.warn`, logging in Effect code is represented through `Effect.logWarning or Logger`. effect(globalConsoleInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
globalDateInEffect_skipNextLine from 201 to 211
globalDateInEffect_skipFile from 201 to 211
globalDateInEffect_skipNextLine from 386 to 396
globalDateInEffect_skipFile from 386 to 396
globalDateInEffect_skipNextLine from 274 to 284
globalDateInEffect_skipFile from 274 to 284
globalDateInEffect_skipNextLine from 476 to 486
globalDateInEffect_skipFile from 476 to 486
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Date.now()
6:44 - 6:54 | 0 | This Effect code uses `Date.now()`, time access in Effect code is represented through `Clock` from Effect. effect(globalDateInEffect)

new Date()
9:13 - 9:23 | 0 | This Effect code constructs `new Date()`, date values in Effect code are represented through `DateTime` from Effect. effect(globalDateInEffect)

Date.now()
13:62 - 13:72 | 0 | This Effect code uses `Date.now()`, time access in Effect code is represented through `Clock` from Effect. effect(globalDateInEffect)

new Date()
16:19 - 16:29 | 0 | This Effect code constructs `new Date()`, date values in Effect code are represented through `DateTime` from Effect. effect(globalDateInEffect)
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
no codefixes
globalFetchInEffect_skipNextLine from 198 to 203
globalFetchInEffect_skipFile from 198 to 203
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
// no diagnostics
fetch
6:37 - 6:42 | 0 | This Effect code calls the global `fetch` function, HTTP requests in Effect code are represented through `HttpClient` from `@effect/platform`. effect(globalFetchInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
globalFetchInEffect_skipNextLine from 203 to 208
globalFetchInEffect_skipFile from 203 to 208
globalFetchInEffect_skipNextLine from 432 to 437
globalFetchInEffect_skipFile from 432 to 437
globalFetchInEffect_skipNextLine from 297 to 302
globalFetchInEffect_skipFile from 297 to 302
globalFetchInEffect_skipNextLine from 553 to 558
globalFetchInEffect_skipFile from 553 to 558
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fetch
6:45 - 6:50 | 0 | This Effect code calls the global `fetch` function, HTTP requests in Effect code are represented through `HttpClient` from `@effect/platform`. effect(globalFetchInEffect)

fetch
9:13 - 9:18 | 0 | This Effect code calls the global `fetch` function, HTTP requests in Effect code are represented through `HttpClient` from `@effect/platform`. effect(globalFetchInEffect)

fetch
13:63 - 13:68 | 0 | This Effect code calls the global `fetch` function, HTTP requests in Effect code are represented through `HttpClient` from `@effect/platform`. effect(globalFetchInEffect)

fetch
16:19 - 16:24 | 0 | This Effect code calls the global `fetch` function, HTTP requests in Effect code are represented through `HttpClient` from `@effect/platform`. effect(globalFetchInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
globalRandomInEffect_skipNextLine from 205 to 218
globalRandomInEffect_skipFile from 205 to 218
globalRandomInEffect_skipNextLine from 397 to 410
globalRandomInEffect_skipFile from 397 to 410
globalRandomInEffect_skipNextLine from 280 to 293
globalRandomInEffect_skipFile from 280 to 293
globalRandomInEffect_skipNextLine from 492 to 505
globalRandomInEffect_skipFile from 492 to 505
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Math.random()
6:46 - 6:59 | 0 | This Effect code uses `Math.random()`, randomness is represented through the Effect `Random` service. effect(globalRandomInEffect)

Math.random()
9:13 - 9:26 | 0 | This Effect code uses `Math.random()`, randomness is represented through the Effect `Random` service. effect(globalRandomInEffect)

Math.random()
13:64 - 13:77 | 0 | This Effect code uses `Math.random()`, randomness is represented through the Effect `Random` service. effect(globalRandomInEffect)

Math.random()
16:19 - 16:32 | 0 | This Effect code uses `Math.random()`, randomness is represented through the Effect `Random` service. effect(globalRandomInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
globalTimersInEffect_skipNextLine from 205 to 229
globalTimersInEffect_skipFile from 205 to 229
globalTimersInEffect_skipNextLine from 420 to 444
globalTimersInEffect_skipFile from 420 to 444
globalTimersInEffect_skipNextLine from 291 to 316
globalTimersInEffect_skipFile from 291 to 316
globalTimersInEffect_skipNextLine from 526 to 550
globalTimersInEffect_skipFile from 526 to 550
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
setTimeout(() => {}, 10)
6:46 - 6:70 | 0 | This Effect code uses `setTimeout`, the corresponding timer API in this context is `Effect.sleep or Schedule` from Effect. effect(globalTimersInEffect)

setInterval(() => {}, 10)
9:13 - 9:38 | 0 | This Effect code uses `setInterval`, the corresponding timer API in this context is `Schedule or Effect.repeat` from Effect. effect(globalTimersInEffect)

setTimeout(() => {}, 10)
13:64 - 13:88 | 0 | This Effect code uses `setTimeout`, the corresponding timer API in this context is `Effect.sleep or Schedule` from Effect. effect(globalTimersInEffect)

setTimeout(() => {}, 10)
16:19 - 16:43 | 0 | This Effect code uses `setTimeout`, the corresponding timer API in this context is `Effect.sleep or Schedule` from Effect. effect(globalTimersInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
processEnvInEffect_skipNextLine from 231 to 254
processEnvInEffect_skipFile from 231 to 254
processEnvInEffect_skipNextLine from 436 to 466
processEnvInEffect_skipFile from 436 to 466
processEnvInEffect_skipNextLine from 313 to 335
processEnvInEffect_skipFile from 313 to 335
processEnvInEffect_skipNextLine from 545 to 582
processEnvInEffect_skipFile from 545 to 582
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
process.env.SYNC_SECRET
7:43 - 7:66 | 0 | This Effect code reads from `process.env`, environment configuration in Effect code is represented through `Config` from Effect. effect(processEnvInEffect)

process.env.TRY_SECRET
10:13 - 10:35 | 0 | This Effect code reads from `process.env`, environment configuration in Effect code is represented through `Config` from Effect. effect(processEnvInEffect)

process.env.TRY_PROMISE_SECRET
14:61 - 14:91 | 0 | This Effect code reads from `process.env`, environment configuration in Effect code is represented through `Config` from Effect. effect(processEnvInEffect)

process.env.TRY_PROMISE_OBJECT_SECRET
17:19 - 17:56 | 0 | This Effect code reads from `process.env`, environment configuration in Effect code is represented through `Config` from Effect. effect(processEnvInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
schemaSyncInEffect_skipNextLine from 240 to 257
schemaSyncInEffect_skipFile from 240 to 257
schemaSyncInEffect_skipNextLine from 510 to 527
schemaSyncInEffect_skipFile from 510 to 527
schemaSyncInEffect_skipNextLine from 354 to 371
schemaSyncInEffect_skipFile from 354 to 371
schemaSyncInEffect_skipNextLine from 643 to 667
schemaSyncInEffect_skipFile from 643 to 667
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Schema.decodeSync
10:46 - 10:63 | 2 | `Schema.decodeSync` is used inside an Effect generator. `Schema.decode` preserves the typed Effect error channel for this operation without throwing. effect(schemaSyncInEffect)

Schema.decodeSync
13:13 - 13:30 | 2 | `Schema.decodeSync` is used inside an Effect generator. `Schema.decode` preserves the typed Effect error channel for this operation without throwing. effect(schemaSyncInEffect)

Schema.encodeSync
17:64 - 17:81 | 2 | `Schema.encodeSync` is used inside an Effect generator. `Schema.encode` preserves the typed Effect error channel for this operation without throwing. effect(schemaSyncInEffect)

Schema.encodeUnknownSync
20:19 - 20:43 | 2 | `Schema.encodeUnknownSync` is used inside an Effect generator. `Schema.encodeUnknown` preserves the typed Effect error channel for this operation without throwing. effect(schemaSyncInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @effect-diagnostics globalConsoleInEffect:warning
import { Data, Effect } from "effect"

class ExampleError extends Data.TaggedError("ExampleError")<{}> {}

export const consoleInSync = Effect.sync(() => console.log("sync"))

export const consoleInTryObject = Effect.try({
try: () => console.warn("try"),
catch: () => new ExampleError()
})

export const consoleInTryPromise = Effect.tryPromise(async () => console.log("try-promise"))

export const consoleInTryPromiseObject = Effect.tryPromise({
try: async () => console.warn("try-promise-object"),
catch: () => new ExampleError()
})

export const shouldNotTriggerReturnedFunction = Effect.sync(() => () => console.log("nested"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @effect-diagnostics globalDateInEffect:warning
import { Data, Effect } from "effect"

class ExampleError extends Data.TaggedError("ExampleError")<{}> {}

export const dateInSync = Effect.sync(() => Date.now())

export const newDateInTryObject = Effect.try({
try: () => new Date(),
catch: () => new ExampleError()
})

export const dateInTryPromise = Effect.tryPromise(async () => Date.now())

export const dateInTryPromiseObject = Effect.tryPromise({
try: async () => new Date(),
catch: () => new ExampleError()
})

export const shouldNotTriggerReturnedFunction = Effect.sync(() => () => new Date())
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @effect-diagnostics globalFetchInEffect:warning
import { Data, Effect } from "effect"

class ExampleError extends Data.TaggedError("ExampleError")<{}> {}

export const fetchInSync = Effect.sync(() => fetch("https://example.com/sync"))

export const fetchInTryObject = Effect.try({
try: () => fetch("https://example.com/try"),
catch: () => new ExampleError()
})

export const fetchInTryPromise = Effect.tryPromise(async () => fetch("https://example.com/try-promise"))

export const fetchInTryPromiseObject = Effect.tryPromise({
try: async () => fetch("https://example.com/try-promise-object"),
catch: () => new ExampleError()
})

export const shouldNotTriggerReturnedFunction = Effect.sync(() => () => fetch("https://example.com/nested"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @effect-diagnostics globalRandomInEffect:warning
import { Data, Effect } from "effect"

class ExampleError extends Data.TaggedError("ExampleError")<{}> {}

export const randomInSync = Effect.sync(() => Math.random())

export const randomInTryObject = Effect.try({
try: () => Math.random(),
catch: () => new ExampleError()
})

export const randomInTryPromise = Effect.tryPromise(async () => Math.random())

export const randomInTryPromiseObject = Effect.tryPromise({
try: async () => Math.random(),
catch: () => new ExampleError()
})

export const shouldNotTriggerReturnedFunction = Effect.sync(() => () => Math.random())
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// @effect-diagnostics globalTimersInEffect:warning
import { Data, Effect } from "effect"

class ExampleError extends Data.TaggedError("ExampleError")<{}> {}

export const timersInSync = Effect.sync(() => setTimeout(() => {}, 10))

export const timersInTryObject = Effect.try({
try: () => setInterval(() => {}, 10),
catch: () => new ExampleError()
})

export const timersInTryPromise = Effect.tryPromise(async () => setTimeout(() => {}, 10))

export const timersInTryPromiseObject = Effect.tryPromise({
try: async () => setTimeout(() => {}, 10),
catch: () => new ExampleError()
})

export const shouldNotTriggerReturnedFunction = Effect.sync(() => () => setTimeout(() => {}, 10))
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export const nestedFunctionInGen = Effect.gen(function*() {

// Should NOT trigger - JSON.parse not as direct expression in Effect.try
export const notDirectExpression = Effect.try(() => {
const parsed = JSON.parse("{\"indirect\":true}")
return parsed.indirect
return () => {
const parsed = JSON.parse("{\"indirect\":true}")
return parsed.indirect
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @effect-diagnostics processEnvInEffect:warning
/// <reference types="node" />
import { Data, Effect } from "effect"

class ExampleError extends Data.TaggedError("ExampleError")<{}> {}

export const envInSync = Effect.sync(() => process.env.SYNC_SECRET)

export const envInTryObject = Effect.try({
try: () => process.env.TRY_SECRET,
catch: () => new ExampleError()
})

export const envInTryPromise = Effect.tryPromise(async () => process.env.TRY_PROMISE_SECRET)

export const envInTryPromiseObject = Effect.tryPromise({
try: async () => process.env.TRY_PROMISE_OBJECT_SECRET,
catch: () => new ExampleError()
})

export const shouldNotTriggerReturnedFunction = Effect.sync(() => () => process.env.NESTED_SECRET)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Data, Effect, Schema } from "effect"

class ExampleError extends Data.TaggedError("ExampleError")<{}> {}

const Person = Schema.Struct({
name: Schema.String,
age: Schema.Number
})

export const decodeInSync = Effect.sync(() => Schema.decodeSync(Person)({ name: "John", age: 30 }))

export const decodeInTryObject = Effect.try({
try: () => Schema.decodeSync(Person)({ name: "Jane", age: 25 }),
catch: () => new ExampleError()
})

export const encodeInTryPromise = Effect.tryPromise(async () => Schema.encodeSync(Person)({ name: "Bob", age: 40 }))

export const encodeInTryPromiseObject = Effect.tryPromise({
try: async () => Schema.encodeUnknownSync(Person)({ name: "Carol", age: 50 }),
catch: () => new ExampleError()
})

export const shouldNotTriggerReturnedFunction = Effect.sync(
() => () => Schema.decodeSync(Person)({ name: "Nested", age: 10 })
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cryptoRandomUUIDInEffect_skipNextLine from 207 to 226
cryptoRandomUUIDInEffect_skipFile from 207 to 226
cryptoRandomUUIDInEffect_skipNextLine from 407 to 426
cryptoRandomUUIDInEffect_skipFile from 407 to 426
cryptoRandomUUIDInEffect_skipNextLine from 286 to 305
cryptoRandomUUIDInEffect_skipFile from 286 to 305
cryptoRandomUUIDInEffect_skipNextLine from 506 to 525
cryptoRandomUUIDInEffect_skipFile from 506 to 525
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
crypto.randomUUID()
6:44 - 6:63 | 0 | This Effect code uses `crypto.randomUUID()`, prefer the Effect `Random` module instead because it uses Effect-injected randomness rather than the `crypto` module behind the scenes. effect(cryptoRandomUUIDInEffect)

crypto.randomUUID()
9:13 - 9:32 | 0 | This Effect code uses `crypto.randomUUID()`, prefer the Effect `Random` module instead because it uses Effect-injected randomness rather than the `crypto` module behind the scenes. effect(cryptoRandomUUIDInEffect)

crypto.randomUUID()
13:62 - 13:81 | 0 | This Effect code uses `crypto.randomUUID()`, prefer the Effect `Random` module instead because it uses Effect-injected randomness rather than the `crypto` module behind the scenes. effect(cryptoRandomUUIDInEffect)

crypto.randomUUID()
16:19 - 16:38 | 0 | This Effect code uses `crypto.randomUUID()`, prefer the Effect `Random` module instead because it uses Effect-injected randomness rather than the `crypto` module behind the scenes. effect(cryptoRandomUUIDInEffect)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
globalConsoleInEffect_skipNextLine from 207 to 226
globalConsoleInEffect_skipFile from 207 to 226
globalConsoleInEffect_skipNextLine from 413 to 439
globalConsoleInEffect_skipFile from 413 to 439
globalConsoleInEffect_skipNextLine from 289 to 308
globalConsoleInEffect_skipFile from 289 to 308
globalConsoleInEffect_skipNextLine from 522 to 556
globalConsoleInEffect_skipFile from 522 to 556
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
console.log("sync")
6:47 - 6:66 | 0 | This Effect code uses `console.log`, logging in Effect code is represented through `Effect.log or Logger`. effect(globalConsoleInEffect)

console.warn("try")
9:13 - 9:32 | 0 | This Effect code uses `console.warn`, logging in Effect code is represented through `Effect.logWarning or Logger`. effect(globalConsoleInEffect)

console.log("try-promise")
13:65 - 13:91 | 0 | This Effect code uses `console.log`, logging in Effect code is represented through `Effect.log or Logger`. effect(globalConsoleInEffect)

console.warn("try-promise-object")
16:19 - 16:53 | 0 | This Effect code uses `console.warn`, logging in Effect code is represented through `Effect.logWarning or Logger`. effect(globalConsoleInEffect)
Loading
Loading