Skip to content

Commit

Permalink
change STM type parameters order from STM<R, E, A> to `STM<A, E =…
Browse files Browse the repository at this point in the history
… never, R = never>` (#2043)
  • Loading branch information
gcanti authored and tim-smart committed Feb 9, 2024
1 parent 86f665d commit 7356e5c
Show file tree
Hide file tree
Showing 48 changed files with 2,248 additions and 1,652 deletions.
5 changes: 5 additions & 0 deletions .changeset/rotten-ties-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": minor
---

change `STM` type parameters order from `STM<R, E, A>` to `STM<A, E = never, R = never>`
24 changes: 12 additions & 12 deletions packages/effect/dtslint/TMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,42 @@ declare const stringNumber: TMap.TMap<string, number>
// removeIf
// -----------------------------------------------------------------------------

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
TMap.removeIf(stringNumber, (key) => key === "aa")

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
TMap.removeIf(stringNumber, (key) => key === "aa", { discard: false })

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
pipe(stringNumber, TMap.removeIf((key) => key === "aa"))

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
pipe(stringNumber, TMap.removeIf((key) => key === "aa", { discard: false }))

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
TMap.removeIf(stringNumber, (key) => key === "aa", { discard: true })

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
pipe(stringNumber, TMap.removeIf((key) => key === "aa", { discard: true }))

// -----------------------------------------------------------------------------
// retainIf
// -----------------------------------------------------------------------------

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
TMap.retainIf(stringNumber, (key) => key === "aa")

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
TMap.retainIf(stringNumber, (key) => key === "aa", { discard: false })

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
pipe(stringNumber, TMap.retainIf((key) => key === "aa"))

// $ExpectType STM<never, never, [string, number][]>
// $ExpectType STM<[string, number][], never, never>
pipe(stringNumber, TMap.retainIf((key) => key === "aa", { discard: false }))

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
TMap.retainIf(stringNumber, (key) => key === "aa", { discard: true })

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
pipe(stringNumber, TMap.retainIf((key) => key === "aa", { discard: true }))
24 changes: 12 additions & 12 deletions packages/effect/dtslint/TSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,42 @@ declare const string: TSet.TSet<string>
// removeIf
// -----------------------------------------------------------------------------

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
TSet.removeIf(string, (key) => key === "aa")

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
TSet.removeIf(string, (key) => key === "aa", { discard: false })

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
pipe(string, TSet.removeIf((key) => key === "aa"))

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
pipe(string, TSet.removeIf((key) => key === "aa", { discard: false }))

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
TSet.removeIf(string, (key) => key === "aa", { discard: true })

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
pipe(string, TSet.removeIf((key) => key === "aa", { discard: true }))

// -----------------------------------------------------------------------------
// retainIf
// -----------------------------------------------------------------------------

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
TSet.retainIf(string, (key) => key === "aa")

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
TSet.retainIf(string, (key) => key === "aa", { discard: false })

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
pipe(string, TSet.retainIf((key) => key === "aa"))

// $ExpectType STM<never, never, string[]>
// $ExpectType STM<string[], never, never>
pipe(string, TSet.retainIf((key) => key === "aa", { discard: false }))

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
TSet.retainIf(string, (key) => key === "aa", { discard: true })

// $ExpectType STM<never, never, void>
// $ExpectType STM<void, never, never>
pipe(string, TSet.retainIf((key) => key === "aa", { discard: true }))
13 changes: 13 additions & 0 deletions packages/effect/mod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
dirs=(./src)
for dir in ${dirs[@]};
do
echo Refactoring $dir
files=$(find $dir -type f \( -name "*.ts" -o -name "*.tsx" \) | xargs ls)
npx jscodeshift \
-t \
./mod.ts \
--extensions=ts,tsx \
--parser=ts \
$files
done
134 changes: 134 additions & 0 deletions packages/effect/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import type k from "ast-types/gen/kinds.js"
import type cs from "jscodeshift"

const enabled = {
swapSTMParams: false,
swapSTMGenParams: false,
cleanupSTM: false,
cleanupEffect: false,
cleanupStream: false,
cleanupExit: false
}

const cleanup = (nodeName: string) => (ast: cs.ASTPath<cs.TSTypeReference>) => {
const name = ast.value.typeName
const is = (node: typeof name): boolean => {
switch (node.type) {
case "Identifier": {
if (node.name === nodeName) {
return true
}
return false
}
case "JSXIdentifier": {
return false
}
case "TSQualifiedName": {
return is(node.right)
}
case "TSTypeParameter": {
return false
}
}
}
if (
is(name) &&
ast.value.typeParameters
) {
const params = ast.value.typeParameters.params
const len = params.length
for (let i = 1; i < len; i++) {
popNever(params)
}
}
}

const cleanupEffect = cleanup("Effect")
const cleanupStream = cleanup("Stream")
const cleanupExit = cleanup("Exit")
const cleanupSTM = cleanup("STM")

const swapParams = (nodeName: string) => (ast: cs.ASTPath<cs.TSTypeReference>) => {
const name = ast.value.typeName
const is = (node: typeof name): boolean => {
switch (node.type) {
case "Identifier": {
if (node.name === nodeName) {
return true
}
return false
}
case "JSXIdentifier": {
return false
}
case "TSQualifiedName": {
return is(node.right)
}
case "TSTypeParameter": {
return false
}
}
}
if (
is(name) &&
ast.value.typeParameters &&
ast.value.typeParameters.params.length === 3
) {
const params = ast.value.typeParameters.params
const newParams = [params[2], params[1], params[0]]
popNever(newParams)
popNever(newParams)
ast.value.typeParameters.params = newParams
}
}

const swapSTMParams = swapParams("STM")
const swapSTMGenParams = swapParams("STMGen")

const popNever = (params: Array<k.TSTypeKind>) => {
if (params.length > 0 && params[params.length - 1].type === "TSNeverKeyword") {
params.pop()
}
}

export default function transformer(file: cs.FileInfo, api: cs.API) {
const j = api.jscodeshift
const root = j(file.source)

const forEveryTypeReference = (node: typeof root, f: (ast: cs.ASTPath<cs.TSTypeReference>) => void) => {
node.find(j.TSTypeReference).forEach((ast) => {
f(ast)
})
node.find(j.CallExpression).forEach((path) => {
const typeParams = (path.value as any).typeParameters as cs.TSTypeParameterInstantiation
if (typeParams) {
j(typeParams).find(j.TSTypeReference).forEach((tref) => {
f(tref)
})
}
})
}

forEveryTypeReference(root, (ast) => {
if (enabled.swapSTMParams) {
swapSTMParams(ast)
}
if (enabled.swapSTMGenParams) {
swapSTMGenParams(ast)
}
if (enabled.cleanupEffect) {
cleanupEffect(ast)
}
if (enabled.cleanupStream) {
cleanupStream(ast)
}
if (enabled.cleanupExit) {
cleanupExit(ast)
}
if (enabled.cleanupSTM) {
cleanupSTM(ast)
}
})

return root.toSource()
}
5 changes: 4 additions & 1 deletion packages/effect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
"coverage": "vitest --coverage"
},
"devDependencies": {
"@types/node": "^20.10.5"
"@types/jscodeshift": "^0.11.11",
"@types/node": "^20.10.5",
"ast-types": "^0.14.2",
"jscodeshift": "^0.15.1"
}
}
4 changes: 2 additions & 2 deletions packages/effect/src/Deferred.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ export const completeWith: {
* @category utils
*/
export const done: {
<A, E>(exit: Exit.Exit<A, E>): (self: Deferred<E, A>) => Effect.Effect<boolean, never, never>
<E, A>(self: Deferred<E, A>, exit: Exit.Exit<A, E>): Effect.Effect<boolean, never, never>
<A, E>(exit: Exit.Exit<A, E>): (self: Deferred<E, A>) => Effect.Effect<boolean>
<E, A>(self: Deferred<E, A>, exit: Exit.Exit<A, E>): Effect.Effect<boolean>
} = core.deferredDone

/**
Expand Down
14 changes: 6 additions & 8 deletions packages/effect/src/Effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ export const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
export const cachedFunction: <A, B, E, R>(
f: (a: A) => Effect<B, E, R>,
eq?: Equivalence<A>
) => Effect<(a: A) => Effect<B, E, R>, never, never> = circular.cachedFunction
) => Effect<(a: A) => Effect<B, E, R>> = circular.cachedFunction

/**
* Returns an effect that will be executed at most once, even if it is
Expand Down Expand Up @@ -1900,8 +1900,8 @@ export const tryMapPromise: {
export const tryPromise: {
<A, E>(
options: { readonly try: (signal: AbortSignal) => Promise<A>; readonly catch: (error: unknown) => E }
): Effect<A, E, never>
<A>(try_: (signal: AbortSignal) => Promise<A>): Effect<A, Cause.UnknownException, never>
): Effect<A, E>
<A>(try_: (signal: AbortSignal) => Promise<A>): Effect<A, Cause.UnknownException>
} = effect.tryPromise

/**
Expand Down Expand Up @@ -2473,7 +2473,7 @@ export const using: {
*/
export const withEarlyRelease: <A, E, R>(
self: Effect<A, E, R>
) => Effect<[Effect<void, never, never>, A], E, R | Scope.Scope> = fiberRuntime.withEarlyRelease
) => Effect<[Effect<void>, A], E, R | Scope.Scope> = fiberRuntime.withEarlyRelease

// -------------------------------------------------------------------------------------
// supervision & fibers
Expand Down Expand Up @@ -4902,8 +4902,7 @@ export const ap: {
* @category requests & batching
* @since 2.0.0
*/
export const blocked: <E, A>(blockedRequests: RequestBlock, _continue: Effect<A, E, never>) => Blocked<E, A> =
core.blocked
export const blocked: <E, A>(blockedRequests: RequestBlock, _continue: Effect<A, E>) => Blocked<E, A> = core.blocked

/**
* @category requests & batching
Expand Down Expand Up @@ -5226,8 +5225,7 @@ export const withParentSpan: {
* @since 2.0.0
* @category optionality
*/
export const fromNullable: <A>(value: A) => Effect<NonNullable<A>, Cause.NoSuchElementException, never> =
effect.fromNullable
export const fromNullable: <A>(value: A) => Effect<NonNullable<A>, Cause.NoSuchElementException> = effect.fromNullable

/**
* Wraps the success value of this effect with `Option.some`, and maps
Expand Down
8 changes: 4 additions & 4 deletions packages/effect/src/Exit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export const all: <A, E>(
* @since 2.0.0
* @category constructors
*/
export const die: (defect: unknown) => Exit<never, never> = core.exitDie
export const die: (defect: unknown) => Exit<never> = core.exitDie

/**
* Executes the predicate on the value of the specified exit if it is a
Expand All @@ -167,9 +167,9 @@ export const die: (defect: unknown) => Exit<never, never> = core.exitDie
* @category elements
*/
export const exists: {
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>): <E>(self: Exit<A, E>) => self is Exit<B, never>
<A, B extends A>(refinement: Refinement<NoInfer<A>, B>): <E>(self: Exit<A, E>) => self is Exit<B>
<A>(predicate: Predicate<NoInfer<A>>): <E>(self: Exit<A, E>) => boolean
<A, E, B extends A>(self: Exit<A, E>, refinement: Refinement<A, B>): self is Exit<B, never>
<A, E, B extends A>(self: Exit<A, E>, refinement: Refinement<A, B>): self is Exit<B>
<A, E>(self: Exit<A, E>, predicate: Predicate<A>): boolean
} = core.exitExists

Expand Down Expand Up @@ -261,7 +261,7 @@ export const getOrElse: {
* @since 2.0.0
* @category constructors
*/
export const interrupt: (fiberId: FiberId.FiberId) => Exit<never, never> = core.exitInterrupt
export const interrupt: (fiberId: FiberId.FiberId) => Exit<never> = core.exitInterrupt

/**
* Maps over the `Success` value of the specified exit using the provided
Expand Down
9 changes: 4 additions & 5 deletions packages/effect/src/Fiber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,7 @@ export const failCause: <E>(cause: Cause.Cause<E>) => Fiber<E, never> = internal
* @since 2.0.0
* @category conversions
*/
export const fromEffect: <E, A>(effect: Effect.Effect<A, E, never>) => Effect.Effect<Fiber<E, A>, never, never> =
internal.fromEffect
export const fromEffect: <E, A>(effect: Effect.Effect<A, E>) => Effect.Effect<Fiber<E, A>> = internal.fromEffect

/**
* Gets the current fiber if one is running.
Expand Down Expand Up @@ -452,7 +451,7 @@ export const join: <E, A>(self: Fiber<E, A>) => Effect.Effect<A, E> = internal.j
* @since 2.0.0
* @category destructors
*/
export const joinAll: <E, A>(fibers: Iterable<Fiber<E, A>>) => Effect.Effect<void, E, never> = fiberRuntime.fiberJoinAll
export const joinAll: <E, A>(fibers: Iterable<Fiber<E, A>>) => Effect.Effect<void, E> = fiberRuntime.fiberJoinAll

/**
* Maps over the value the Fiber computes.
Expand All @@ -472,8 +471,8 @@ export const map: {
* @category mapping
*/
export const mapEffect: {
<A, A2, E2>(f: (a: A) => Effect.Effect<A2, E2, never>): <E>(self: Fiber<E, A>) => Fiber<E2 | E, A2>
<E, A, A2, E2>(self: Fiber<E, A>, f: (a: A) => Effect.Effect<A2, E2, never>): Fiber<E | E2, A2>
<A, A2, E2>(f: (a: A) => Effect.Effect<A2, E2>): <E>(self: Fiber<E, A>) => Fiber<E2 | E, A2>
<E, A, A2, E2>(self: Fiber<E, A>, f: (a: A) => Effect.Effect<A2, E2>): Fiber<E | E2, A2>
} = internal.mapEffect

/**
Expand Down
Loading

0 comments on commit 7356e5c

Please sign in to comment.