@soundscript/soundscript 0.1.15 → 0.1.17

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.
Files changed (47) hide show
  1. package/decode.d.ts +2 -2
  2. package/decode.js.map +1 -1
  3. package/json.js +1 -1
  4. package/numerics.js +4 -4
  5. package/package.json +6 -6
  6. package/project-transform/src/checker/rules/flow.js +16 -3
  7. package/project-transform/src/checker/rules/flow.ts +20 -3
  8. package/project-transform/src/checker/rules/flow_invalidation.js +18 -21
  9. package/project-transform/src/checker/rules/flow_invalidation.ts +25 -20
  10. package/project-transform/src/checker/rules/relations.js +157 -3
  11. package/project-transform/src/checker/rules/relations.ts +207 -1
  12. package/project-transform/src/checker/rules/unsound_syntax.js +0 -3
  13. package/project-transform/src/checker/rules/unsound_syntax.ts +0 -4
  14. package/project-transform/src/cli.js +1 -1
  15. package/project-transform/src/cli.ts +1 -1
  16. package/project-transform/src/compiler/compile_project.js +75 -9
  17. package/project-transform/src/compiler/compile_project.ts +121 -7
  18. package/project-transform/src/compiler/ir.ts +19 -1
  19. package/project-transform/src/compiler/lower.js +10335 -1477
  20. package/project-transform/src/compiler/lower.ts +16826 -4074
  21. package/project-transform/src/compiler/toolchain.js +36 -4
  22. package/project-transform/src/compiler/toolchain.ts +36 -4
  23. package/project-transform/src/compiler/wasm_js_host_runtime.js +134 -0
  24. package/project-transform/src/compiler/wasm_js_host_runtime.ts +146 -0
  25. package/project-transform/src/compiler/wat_arrays.js +4 -1
  26. package/project-transform/src/compiler/wat_arrays.ts +5 -1
  27. package/project-transform/src/compiler/wat_emitter.js +1497 -311
  28. package/project-transform/src/compiler/wat_emitter.ts +2971 -1017
  29. package/project-transform/src/compiler/wat_tagged.js +5 -0
  30. package/project-transform/src/compiler/wat_tagged.ts +5 -0
  31. package/project-transform/src/compiler_generator_runner.js +2139 -19
  32. package/project-transform/src/compiler_generator_runner.ts +2143 -20
  33. package/project-transform/src/compiler_promise_runner.js +4615 -636
  34. package/project-transform/src/compiler_promise_runner.ts +4703 -659
  35. package/project-transform/src/compiler_test_helpers.js +0 -579
  36. package/project-transform/src/compiler_test_helpers.ts +0 -648
  37. package/project-transform/src/frontend/macro_expander.js +4 -6
  38. package/project-transform/src/frontend/macro_expander.ts +4 -6
  39. package/project-transform/src/frontend/macro_operand_semantics.js +124 -1
  40. package/project-transform/src/frontend/macro_operand_semantics.ts +230 -6
  41. package/project-transform/src/frontend/macro_resolver.js +2 -2
  42. package/project-transform/src/frontend/macro_resolver.ts +2 -1
  43. package/project-transform/src/frontend/project_macro_support.js +29 -5
  44. package/project-transform/src/frontend/project_macro_support.ts +46 -10
  45. package/project-transform/src/stdlib/decode.d.ts +2 -2
  46. package/project-transform/src/stdlib/decode.ts +2 -2
  47. package/soundscript/decode.sts +2 -2
package/decode.d.ts CHANGED
@@ -8,11 +8,11 @@ export class DecodeFailure extends Failure {
8
8
  readonly path: DecodePath;
9
9
  constructor(
10
10
  message?: string,
11
- options?: {
11
+ options?: Readonly<{
12
12
  cause?: unknown;
13
13
  path?: DecodePath;
14
14
  trace?: readonly ErrorFrame[];
15
- },
15
+ }>,
16
16
  );
17
17
  at(segment: DecodePathSegment): this;
18
18
  }
package/decode.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"decode.js","sourceRoot":"","sources":["./soundscript/decode.sts"],"names":[],"mappings":"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","sourcesContent":["import { type ErrorFrame, Failure } from '@soundscript/soundscript/failures';\nimport { err, isErr, none, ok, some, type Option, type Result } from '@soundscript/soundscript/result';\n\nexport type DecodePathSegment = string | number;\nexport type DecodePath = readonly DecodePathSegment[];\n\nexport class DecodeFailure extends Failure {\n readonly path: DecodePath;\n\n constructor(\n message = 'Failed to decode value.',\n options: {\n cause?: unknown;\n path?: DecodePath;\n trace?: readonly ErrorFrame[];\n } = {},\n ) {\n super(message, {\n ...(options.cause === undefined ? {} : { cause: options.cause }),\n ...(options.trace === undefined ? {} : { trace: options.trace }),\n });\n this.path = options.path ?? [];\n }\n\n at(segment: DecodePathSegment): this {\n const prototype = Object.getPrototypeOf(this as object);\n const clone = (prototype === null ? Object.create(null) : Object.create(prototype)) as this;\n Object.defineProperties(clone, Object.getOwnPropertyDescriptors(this));\n Object.defineProperty(clone, 'path', {\n configurable: true,\n enumerable: true,\n writable: false,\n value: [segment, ...this.path],\n });\n return clone;\n }\n}\n\n// #[variance(T: out, E: out)]\nexport type Decoder<T, E = DecodeFailure> = {\n decode(value: unknown): Result<T, E>;\n};\n\n// #[variance(T: out, E: out)]\nexport type OptionalDecoder<T, E = DecodeFailure> = Decoder<T | undefined, E> & {\n readonly __soundscriptOptional: true;\n readonly inner: Decoder<T, E>;\n};\n\ntype DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown> ? TValue : never;\ntype DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E> ? E : never;\n\ntype ObjectShape = Record<string, Decoder<unknown, unknown>>;\ntype TupleShape = readonly Decoder<unknown, unknown>[];\n\nexport const string: Decoder<string> = {\n decode(value): Result<string, DecodeFailure> {\n return typeof value === 'string'\n ? ok(value)\n : err(new DecodeFailure('Expected string.', { cause: value }));\n },\n};\n\nexport const number: Decoder<number> = {\n decode(value): Result<number, DecodeFailure> {\n return typeof value === 'number'\n ? ok(value)\n : err(new DecodeFailure('Expected number.', { cause: value }));\n },\n};\n\nexport const boolean: Decoder<boolean> = {\n decode(value): Result<boolean, DecodeFailure> {\n return typeof value === 'boolean'\n ? ok(value)\n : err(new DecodeFailure('Expected boolean.', { cause: value }));\n },\n};\n\nexport const bigint: Decoder<bigint> = {\n decode(value): Result<bigint, DecodeFailure> {\n if (typeof value === 'bigint') {\n return ok(value);\n }\n\n if (typeof value === 'number') {\n return Number.isInteger(value) && Number.isSafeInteger(value)\n ? ok(BigInt(value))\n : err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n\n if (typeof value === 'string') {\n try {\n return ok(BigInt(value));\n } catch {\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n }\n\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n },\n};\n\nexport function lazy<T, E>(getDecoder: () => Decoder<T, E>): Decoder<T, E> {\n return {\n decode(value) {\n return getDecoder().decode(value);\n },\n };\n}\n\nexport function optional<T, E>(decoder: Decoder<T, E>): OptionalDecoder<T, E> {\n return {\n __soundscriptOptional: true,\n inner: decoder,\n decode(value) {\n return value === undefined ? ok(undefined) : decoder.decode(value);\n },\n };\n}\n\nexport function literal<const T extends string | number | boolean | null>(value: T): Decoder<T> {\n return {\n decode(input) {\n return Object.is(input, value)\n ? ok(value)\n : err(new DecodeFailure(`Expected literal ${JSON.stringify(value)}.`, { cause: input }));\n },\n };\n}\n\nexport function array<T, E>(item: Decoder<T, E>): Decoder<readonly T[], E | DecodeFailure> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected array.', { cause: value }));\n }\n\n const decodedValues: T[] = [];\n for (let index = 0; index < value.length; index += 1) {\n const decoded = item.decode(value[index]);\n if (isErr(decoded)) {\n return err(prependPathIfPossible(decoded.error, index));\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues);\n },\n };\n}\n\nexport function tuple<const TElements extends TupleShape>(\n ...elements: TElements\n): Decoder<\n { readonly [K in keyof TElements]: DecoderValue<TElements[K]> },\n DecoderError<TElements[number]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected tuple.', { cause: value }));\n }\n\n if (value.length !== elements.length) {\n return err(\n new DecodeFailure(`Expected tuple of length ${elements.length}.`, {\n cause: value,\n }),\n );\n }\n\n const decodedValues: unknown[] = [];\n for (let index = 0; index < elements.length; index += 1) {\n const elementDecoder = elements[index];\n if (!elementDecoder) {\n continue;\n }\n const decoded = elementDecoder.decode(value[index]);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, index) as\n | DecoderError<TElements[number]>\n | DecodeFailure,\n );\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues as { readonly [K in keyof TElements]: DecoderValue<TElements[K]> });\n },\n };\n}\n\nexport function option<T, E>(item: Decoder<T, E>): Decoder<Option<T>, E | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('some'),\n value: item,\n }),\n (value) => some(value.value) as Option<T>,\n ),\n map(\n object({\n tag: literal('none'),\n }),\n () => none() as Option<T>,\n ),\n );\n}\n\nexport function result<T, EValue, EDecodeValue, EDecodeError>(\n okDecoder: Decoder<T, EDecodeValue>,\n errDecoder: Decoder<EValue, EDecodeError>,\n): Decoder<Result<T, EValue>, EDecodeValue | EDecodeError | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('ok'),\n value: okDecoder,\n }),\n (value) => ok(value.value) as Result<T, EValue>,\n ),\n map(\n object({\n tag: literal('err'),\n error: errDecoder,\n }),\n (value) => err(value.error) as Result<T, EValue>,\n ),\n );\n}\n\nexport function object<TShape extends ObjectShape>(\n shape: TShape,\n): Decoder<\n { readonly [K in keyof TShape]: DecoderValue<TShape[K]> },\n DecoderError<TShape[keyof TShape]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!isPlainObject(value)) {\n return err(new DecodeFailure('Expected object.', { cause: value }));\n }\n\n const record = value as Record<string, unknown>;\n const decodedObject: Record<string, unknown> = {};\n\n for (const key of Object.keys(shape)) {\n const decoder = shape[key];\n if (!decoder) {\n continue;\n }\n const hasKey = key in record;\n const rawValue = record[key];\n\n if (!hasKey || rawValue === undefined) {\n if (isOptionalDecoder(decoder)) {\n decodedObject[key] = undefined;\n continue;\n }\n\n return err(\n new DecodeFailure(`Missing field \"${key}\".`, {\n cause: value,\n path: [key],\n }),\n );\n }\n\n const decoded = decoder.decode(rawValue);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, key) as\n | DecoderError<TShape[keyof TShape]>\n | DecodeFailure,\n );\n }\n\n decodedObject[key] = decoded.value;\n }\n\n return ok(decodedObject as { readonly [K in keyof TShape]: DecoderValue<TShape[K]> });\n },\n };\n}\n\nexport function field<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T, E | DecodeFailure> {\n const shape = { [key]: decoder } as { readonly [P in K]: Decoder<T, E> };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function optionalField<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T | undefined, E | DecodeFailure> {\n const shape = { [key]: optional(decoder) } as {\n readonly [P in K]: OptionalDecoder<T, E>;\n };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function union<A, B, ELeft, ERight>(\n left: Decoder<A, ELeft>,\n right: Decoder<B, ERight>,\n): Decoder<A | B, ELeft | ERight | DecodeFailure> {\n return {\n decode(value) {\n const leftDecoded = left.decode(value);\n if (isErr(leftDecoded)) {\n const rightDecoded = right.decode(value);\n if (isErr(rightDecoded)) {\n return err(\n new DecodeFailure('Expected one of the union members.', {\n cause: value,\n }),\n );\n }\n return rightDecoded;\n }\n return leftDecoded;\n },\n };\n}\n\nexport function map<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => B,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : ok(project(decoded.value));\n },\n };\n}\n\nexport function andThen<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => Decoder<B, E>,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : project(decoded.value).decode(valueOf(decoded));\n },\n };\n}\n\nexport function refine<A, B extends A, E>(\n decoder: Decoder<A, E>,\n predicate: (value: A) => value is B,\n message: string,\n): Decoder<B, E | DecodeFailure> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n if (isErr(decoded)) {\n return decoded;\n }\n\n return predicate(decoded.value)\n ? ok(decoded.value)\n : err(new DecodeFailure(message, { cause: value }));\n },\n };\n}\n\nfunction prependPathIfPossible<E>(error: E, segment: DecodePathSegment): E | DecodeFailure {\n return error instanceof DecodeFailure ? error.at(segment) : error;\n}\n\nfunction isOptionalDecoder(\n value: Decoder<unknown, unknown>,\n): value is OptionalDecoder<unknown, unknown> {\n return '__soundscriptOptional' in value &&\n value.__soundscriptOptional === true;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction valueOf<T>(decoded: { readonly value: T }): T {\n return decoded.value;\n}\n"]}
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["./soundscript/decode.sts"],"names":[],"mappings":"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","sourcesContent":["import { type ErrorFrame, Failure } from '@soundscript/soundscript/failures';\nimport { err, isErr, none, ok, some, type Option, type Result } from '@soundscript/soundscript/result';\n\nexport type DecodePathSegment = string | number;\nexport type DecodePath = readonly DecodePathSegment[];\n\nexport class DecodeFailure extends Failure {\n readonly path: DecodePath;\n\n constructor(\n message = 'Failed to decode value.',\n options: Readonly<{\n cause?: unknown;\n path?: DecodePath;\n trace?: readonly ErrorFrame[];\n }> = {},\n ) {\n super(message, {\n ...(options.cause === undefined ? {} : { cause: options.cause }),\n ...(options.trace === undefined ? {} : { trace: options.trace }),\n });\n this.path = options.path ?? [];\n }\n\n at(segment: DecodePathSegment): this {\n const prototype = Object.getPrototypeOf(this as object);\n const clone = (prototype === null ? Object.create(null) : Object.create(prototype)) as this;\n Object.defineProperties(clone, Object.getOwnPropertyDescriptors(this));\n Object.defineProperty(clone, 'path', {\n configurable: true,\n enumerable: true,\n writable: false,\n value: [segment, ...this.path],\n });\n return clone;\n }\n}\n\n// #[variance(T: out, E: out)]\nexport type Decoder<T, E = DecodeFailure> = {\n decode(value: unknown): Result<T, E>;\n};\n\n// #[variance(T: out, E: out)]\nexport type OptionalDecoder<T, E = DecodeFailure> = Decoder<T | undefined, E> & {\n readonly __soundscriptOptional: true;\n readonly inner: Decoder<T, E>;\n};\n\ntype DecoderValue<TDecoder> = TDecoder extends Decoder<infer TValue, unknown> ? TValue : never;\ntype DecoderError<TDecoder> = TDecoder extends Decoder<unknown, infer E> ? E : never;\n\ntype ObjectShape = Record<string, Decoder<unknown, unknown>>;\ntype TupleShape = readonly Decoder<unknown, unknown>[];\n\nexport const string: Decoder<string> = {\n decode(value): Result<string, DecodeFailure> {\n return typeof value === 'string'\n ? ok(value)\n : err(new DecodeFailure('Expected string.', { cause: value }));\n },\n};\n\nexport const number: Decoder<number> = {\n decode(value): Result<number, DecodeFailure> {\n return typeof value === 'number'\n ? ok(value)\n : err(new DecodeFailure('Expected number.', { cause: value }));\n },\n};\n\nexport const boolean: Decoder<boolean> = {\n decode(value): Result<boolean, DecodeFailure> {\n return typeof value === 'boolean'\n ? ok(value)\n : err(new DecodeFailure('Expected boolean.', { cause: value }));\n },\n};\n\nexport const bigint: Decoder<bigint> = {\n decode(value): Result<bigint, DecodeFailure> {\n if (typeof value === 'bigint') {\n return ok(value);\n }\n\n if (typeof value === 'number') {\n return Number.isInteger(value) && Number.isSafeInteger(value)\n ? ok(BigInt(value))\n : err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n\n if (typeof value === 'string') {\n try {\n return ok(BigInt(value));\n } catch {\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n }\n }\n\n return err(new DecodeFailure('Expected bigint.', { cause: value }));\n },\n};\n\nexport function lazy<T, E>(getDecoder: () => Decoder<T, E>): Decoder<T, E> {\n return {\n decode(value) {\n return getDecoder().decode(value);\n },\n };\n}\n\nexport function optional<T, E>(decoder: Decoder<T, E>): OptionalDecoder<T, E> {\n return {\n __soundscriptOptional: true,\n inner: decoder,\n decode(value) {\n return value === undefined ? ok(undefined) : decoder.decode(value);\n },\n };\n}\n\nexport function literal<const T extends string | number | boolean | null>(value: T): Decoder<T> {\n return {\n decode(input) {\n return Object.is(input, value)\n ? ok(value)\n : err(new DecodeFailure(`Expected literal ${JSON.stringify(value)}.`, { cause: input }));\n },\n };\n}\n\nexport function array<T, E>(item: Decoder<T, E>): Decoder<readonly T[], E | DecodeFailure> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected array.', { cause: value }));\n }\n\n const decodedValues: T[] = [];\n for (let index = 0; index < value.length; index += 1) {\n const decoded = item.decode(value[index]);\n if (isErr(decoded)) {\n return err(prependPathIfPossible(decoded.error, index));\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues);\n },\n };\n}\n\nexport function tuple<const TElements extends TupleShape>(\n ...elements: TElements\n): Decoder<\n { readonly [K in keyof TElements]: DecoderValue<TElements[K]> },\n DecoderError<TElements[number]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!Array.isArray(value)) {\n return err(new DecodeFailure('Expected tuple.', { cause: value }));\n }\n\n if (value.length !== elements.length) {\n return err(\n new DecodeFailure(`Expected tuple of length ${elements.length}.`, {\n cause: value,\n }),\n );\n }\n\n const decodedValues: unknown[] = [];\n for (let index = 0; index < elements.length; index += 1) {\n const elementDecoder = elements[index];\n if (!elementDecoder) {\n continue;\n }\n const decoded = elementDecoder.decode(value[index]);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, index) as\n | DecoderError<TElements[number]>\n | DecodeFailure,\n );\n }\n decodedValues.push(decoded.value);\n }\n\n return ok(decodedValues as { readonly [K in keyof TElements]: DecoderValue<TElements[K]> });\n },\n };\n}\n\nexport function option<T, E>(item: Decoder<T, E>): Decoder<Option<T>, E | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('some'),\n value: item,\n }),\n (value) => some(value.value) as Option<T>,\n ),\n map(\n object({\n tag: literal('none'),\n }),\n () => none() as Option<T>,\n ),\n );\n}\n\nexport function result<T, EValue, EDecodeValue, EDecodeError>(\n okDecoder: Decoder<T, EDecodeValue>,\n errDecoder: Decoder<EValue, EDecodeError>,\n): Decoder<Result<T, EValue>, EDecodeValue | EDecodeError | DecodeFailure> {\n return union(\n map(\n object({\n tag: literal('ok'),\n value: okDecoder,\n }),\n (value) => ok(value.value) as Result<T, EValue>,\n ),\n map(\n object({\n tag: literal('err'),\n error: errDecoder,\n }),\n (value) => err(value.error) as Result<T, EValue>,\n ),\n );\n}\n\nexport function object<TShape extends ObjectShape>(\n shape: TShape,\n): Decoder<\n { readonly [K in keyof TShape]: DecoderValue<TShape[K]> },\n DecoderError<TShape[keyof TShape]> | DecodeFailure\n> {\n return {\n decode(value) {\n if (!isPlainObject(value)) {\n return err(new DecodeFailure('Expected object.', { cause: value }));\n }\n\n const record = value as Record<string, unknown>;\n const decodedObject: Record<string, unknown> = {};\n\n for (const key of Object.keys(shape)) {\n const decoder = shape[key];\n if (!decoder) {\n continue;\n }\n const hasKey = key in record;\n const rawValue = record[key];\n\n if (!hasKey || rawValue === undefined) {\n if (isOptionalDecoder(decoder)) {\n decodedObject[key] = undefined;\n continue;\n }\n\n return err(\n new DecodeFailure(`Missing field \"${key}\".`, {\n cause: value,\n path: [key],\n }),\n );\n }\n\n const decoded = decoder.decode(rawValue);\n if (isErr(decoded)) {\n return err(\n prependPathIfPossible(decoded.error, key) as\n | DecoderError<TShape[keyof TShape]>\n | DecodeFailure,\n );\n }\n\n decodedObject[key] = decoded.value;\n }\n\n return ok(decodedObject as { readonly [K in keyof TShape]: DecoderValue<TShape[K]> });\n },\n };\n}\n\nexport function field<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T, E | DecodeFailure> {\n const shape = { [key]: decoder } as { readonly [P in K]: Decoder<T, E> };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function optionalField<K extends string, T, E>(\n key: K,\n decoder: Decoder<T, E>,\n): Decoder<T | undefined, E | DecodeFailure> {\n const shape = { [key]: optional(decoder) } as {\n readonly [P in K]: OptionalDecoder<T, E>;\n };\n return map(object(shape), (value) => value[key]);\n}\n\nexport function union<A, B, ELeft, ERight>(\n left: Decoder<A, ELeft>,\n right: Decoder<B, ERight>,\n): Decoder<A | B, ELeft | ERight | DecodeFailure> {\n return {\n decode(value) {\n const leftDecoded = left.decode(value);\n if (isErr(leftDecoded)) {\n const rightDecoded = right.decode(value);\n if (isErr(rightDecoded)) {\n return err(\n new DecodeFailure('Expected one of the union members.', {\n cause: value,\n }),\n );\n }\n return rightDecoded;\n }\n return leftDecoded;\n },\n };\n}\n\nexport function map<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => B,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : ok(project(decoded.value));\n },\n };\n}\n\nexport function andThen<A, B, E>(\n decoder: Decoder<A, E>,\n project: (value: A) => Decoder<B, E>,\n): Decoder<B, E> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n return isErr(decoded) ? decoded : project(decoded.value).decode(valueOf(decoded));\n },\n };\n}\n\nexport function refine<A, B extends A, E>(\n decoder: Decoder<A, E>,\n predicate: (value: A) => value is B,\n message: string,\n): Decoder<B, E | DecodeFailure> {\n return {\n decode(value) {\n const decoded = decoder.decode(value);\n if (isErr(decoded)) {\n return decoded;\n }\n\n return predicate(decoded.value)\n ? ok(decoded.value)\n : err(new DecodeFailure(message, { cause: value }));\n },\n };\n}\n\nfunction prependPathIfPossible<E>(error: E, segment: DecodePathSegment): E | DecodeFailure {\n return error instanceof DecodeFailure ? error.at(segment) : error;\n}\n\nfunction isOptionalDecoder(\n value: Decoder<unknown, unknown>,\n): value is OptionalDecoder<unknown, unknown> {\n return '__soundscriptOptional' in value &&\n value.__soundscriptOptional === true;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction valueOf<T>(decoded: { readonly value: T }): T {\n return decoded.value;\n}\n"]}
package/json.js CHANGED
@@ -12,7 +12,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  var _JsonLikeParser_instances, _JsonLikeParser_index, _JsonLikeParser_text, _JsonLikeParser_consumeKeyword, _JsonLikeParser_parseArray, _JsonLikeParser_parseNumber, _JsonLikeParser_parseObject, _JsonLikeParser_parseString, _JsonLikeParser_consumeDigits, _JsonLikeParser_skipWhitespace, _JsonLikeParser_isDigit, _JsonLikeParser_error;
13
13
  import { Failure } from '@soundscript/soundscript/failures';
14
14
  import { isErr, resultOf } from '@soundscript/soundscript/result';
15
- import { F32, F64, format as formatNumeric, I8, I16, I32, I64, isNumeric, toHostNumber, U8, U16, U32, U64, } from './numerics.sts';
15
+ import { F32, F64, format as formatNumeric, I8, I16, I32, I64, isNumeric, toHostNumber, U8, U16, U32, U64, } from './numerics.js';
16
16
  const MAX_SAFE_INTEGER_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
17
17
  const MIN_SAFE_INTEGER_BIGINT = BigInt(Number.MIN_SAFE_INTEGER);
18
18
  export class JsonParseFailure extends Failure {
package/numerics.js CHANGED
@@ -10,10 +10,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
12
  var _MachineNumericBox_key, _MachineNumericBox_payload;
13
- import { fromCompare } from './compare.sts';
14
- import { Failure } from './failures.sts';
15
- import { fromHashEq, stringHash } from './hash.sts';
16
- import { err, ok } from './result.sts';
13
+ import { fromCompare } from './compare.js';
14
+ import { Failure } from './failures.js';
15
+ import { fromHashEq, stringHash } from './hash.js';
16
+ import { err, ok } from './result.js';
17
17
  export class NumericOverflowFailure extends Failure {
18
18
  constructor(leaf, operation) {
19
19
  super(`Checked ${operation} overflowed for ${leaf}.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soundscript/soundscript",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -232,11 +232,11 @@
232
232
  "typescript": "5.9.3"
233
233
  },
234
234
  "optionalDependencies": {
235
- "@soundscript/cli-darwin-arm64": "0.1.15",
236
- "@soundscript/cli-darwin-x64": "0.1.15",
237
- "@soundscript/cli-linux-arm64": "0.1.15",
238
- "@soundscript/cli-linux-x64": "0.1.15",
239
- "@soundscript/cli-win32-x64": "0.1.15"
235
+ "@soundscript/cli-darwin-arm64": "0.1.17",
236
+ "@soundscript/cli-darwin-x64": "0.1.17",
237
+ "@soundscript/cli-linux-arm64": "0.1.17",
238
+ "@soundscript/cli-linux-x64": "0.1.17",
239
+ "@soundscript/cli-win32-x64": "0.1.17"
240
240
  },
241
241
  "repository": {
242
242
  "type": "git",
@@ -3,6 +3,7 @@ import { SOUND_DIAGNOSTIC_CODES, SOUND_DIAGNOSTIC_MESSAGES } from '../engine/dia
3
3
  import { getNodeDiagnosticRange, } from '../diagnostics.js';
4
4
  import { getFlowChildRegionStructure, getFlowRegionStructure, materializeConditionStructures, } from './flow_facts.js';
5
5
  import { cloneState, FLOW_FACT_ENVIRONMENT, isFunctionLikeWithBody, prepareChildRegionState, recordExecutedExpressionAliases, recordVariableAliases, statementAffectsNarrow, } from './flow_invalidation.js';
6
+ import { isConstLocalBindingPath } from './flow_shared.js';
6
7
  import { isInsideSyntheticErrorNormalizationHelper } from './generated_helpers.js';
7
8
  function boundaryKindLabel(kind) {
8
9
  switch (kind) {
@@ -114,6 +115,15 @@ function findInvalidation(context, statement, activeFacts, state) {
114
115
  }
115
116
  return undefined;
116
117
  }
118
+ function factRequiresBoundaryInvalidation(fact) {
119
+ if (fact.path.segments.length !== 0 || !isConstLocalBindingPath(fact.path)) {
120
+ return true;
121
+ }
122
+ return fact.kind !== 'discriminantLiteral' &&
123
+ fact.kind !== 'nonNull' &&
124
+ fact.kind !== 'truthy' &&
125
+ fact.kind !== 'typeof';
126
+ }
117
127
  function analyzeStatements(context, regionNode, statements, state, diagnostics, inheritedFacts = [], options = {}) {
118
128
  const region = regionNode ? getFlowRegionStructure(context, regionNode, statements, options) : {
119
129
  entries: statements.map((statement) => ({
@@ -134,7 +144,8 @@ function analyzeStatements(context, regionNode, statements, state, diagnostics,
134
144
  boundaryKind: classifyBoundaryKind(sequentialAnalysis.invalidatingNode),
135
145
  }));
136
146
  }
137
- const activeSequentialFacts = [...inheritedFacts, ...sequentialAnalysis.facts];
147
+ const activeSequentialFacts = [...inheritedFacts, ...sequentialAnalysis.facts]
148
+ .filter(factRequiresBoundaryInvalidation);
138
149
  const invalidatingNode = findInvalidation(context, statement, activeSequentialFacts, state);
139
150
  if (invalidatingNode) {
140
151
  diagnostics.push(createDiagnostic(context, invalidatingNode));
@@ -187,7 +198,8 @@ function analyzeRootRegion(context, regionNode, statements, diagnostics) {
187
198
  export function runFlowRules(context) {
188
199
  const diagnostics = [];
189
200
  context.forEachSourceFile((sourceFile) => {
190
- analyzeRootRegion(context, sourceFile, sourceFile.statements.filter((statement) => !context.isGeneratedNode(statement)), diagnostics);
201
+ const rootStatements = sourceFile.statements.filter((statement) => !context.isGeneratedNode(statement));
202
+ analyzeRootRegion(context, sourceFile, rootStatements, diagnostics);
191
203
  context.traverse(sourceFile, (node) => {
192
204
  if (!isFunctionLikeWithBody(node)) {
193
205
  return;
@@ -195,7 +207,8 @@ export function runFlowRules(context) {
195
207
  if (isInsideSyntheticErrorNormalizationHelper(node)) {
196
208
  return;
197
209
  }
198
- analyzeRootRegion(context, ts.isBlock(node.body) ? node.body : undefined, getRootStatements(node.body).filter((statement) => !context.isGeneratedNode(statement)), diagnostics);
210
+ const bodyStatements = getRootStatements(node.body).filter((statement) => !context.isGeneratedNode(statement));
211
+ analyzeRootRegion(context, ts.isBlock(node.body) ? node.body : undefined, bodyStatements, diagnostics);
199
212
  });
200
213
  });
201
214
  return diagnostics;
@@ -25,6 +25,7 @@ import {
25
25
  recordVariableAliases,
26
26
  statementAffectsNarrow,
27
27
  } from './flow_invalidation.ts';
28
+ import { isConstLocalBindingPath } from './flow_shared.ts';
28
29
  import { isInsideSyntheticErrorNormalizationHelper } from './generated_helpers.ts';
29
30
 
30
31
  type InvalidationBoundaryKind =
@@ -181,6 +182,19 @@ function findInvalidation(
181
182
  return undefined;
182
183
  }
183
184
 
185
+ function factRequiresBoundaryInvalidation(
186
+ fact: FlowFact<NormalizedPath>,
187
+ ): boolean {
188
+ if (fact.path.segments.length !== 0 || !isConstLocalBindingPath(fact.path)) {
189
+ return true;
190
+ }
191
+
192
+ return fact.kind !== 'discriminantLiteral' &&
193
+ fact.kind !== 'nonNull' &&
194
+ fact.kind !== 'truthy' &&
195
+ fact.kind !== 'typeof';
196
+ }
197
+
184
198
  function analyzeStatements(
185
199
  context: AnalysisContext,
186
200
  regionNode: ts.Node | undefined,
@@ -218,7 +232,8 @@ function analyzeStatements(
218
232
  }),
219
233
  );
220
234
  }
221
- const activeSequentialFacts = [...inheritedFacts, ...sequentialAnalysis.facts];
235
+ const activeSequentialFacts = [...inheritedFacts, ...sequentialAnalysis.facts]
236
+ .filter(factRequiresBoundaryInvalidation);
222
237
  const invalidatingNode = findInvalidation(context, statement, activeSequentialFacts, state);
223
238
  if (invalidatingNode) {
224
239
  diagnostics.push(createDiagnostic(context, invalidatingNode));
@@ -305,10 +320,11 @@ export function runFlowRules(context: AnalysisContext): SoundDiagnostic[] {
305
320
  const diagnostics: SoundDiagnostic[] = [];
306
321
 
307
322
  context.forEachSourceFile((sourceFile) => {
323
+ const rootStatements = sourceFile.statements.filter((statement) => !context.isGeneratedNode(statement));
308
324
  analyzeRootRegion(
309
325
  context,
310
326
  sourceFile,
311
- sourceFile.statements.filter((statement) => !context.isGeneratedNode(statement)),
327
+ rootStatements,
312
328
  diagnostics,
313
329
  );
314
330
 
@@ -320,10 +336,11 @@ export function runFlowRules(context: AnalysisContext): SoundDiagnostic[] {
320
336
  return;
321
337
  }
322
338
 
339
+ const bodyStatements = getRootStatements(node.body).filter((statement) => !context.isGeneratedNode(statement));
323
340
  analyzeRootRegion(
324
341
  context,
325
342
  ts.isBlock(node.body) ? node.body : undefined,
326
- getRootStatements(node.body).filter((statement) => !context.isGeneratedNode(statement)),
343
+ bodyStatements,
327
344
  diagnostics,
328
345
  );
329
346
  });
@@ -1,5 +1,5 @@
1
1
  import ts from 'typescript';
2
- import { bindFunctionBindingName, appendSegment, arrayMutationCallAffectsNarrow, assignmentAffectsNarrow, bindFunctionReceiverPath, cloneState, getCalledMember, getExpressionSymbol, getFunctionBindings, getFunctionBodyCalledMember, getFunctionLikeFromBoundMemberCall, getFunctionLikeFromBoundValue, getFunctionLikeFromCallExpression, getStateExpressionBoundValue, getUniformArrayElementBindingFromExpression, getUniformArrayElementBindingFromFunctionBodyExpression, getUniformMapEntryBindingsFromExpression, getUniformMapEntryBindingsFromFunctionBodyExpression, getUniformSetElementBindingFromExpression, getUniformSetElementBindingFromFunctionBodyExpression, getNestedFunctionBindings, getMutableBindingSymbol, getShorthandStateBoundValue, getSymbolId, getUpdateExpressionOperand, isConstLocalBindingPath, isFunctionLikeWithBody, isLocalBindingPath, isStableConstLocalBindingPath, MUTATING_ASSIGNMENT_OPERATORS, mutationAffectsNarrow, normalizeExpressionPath, normalizeExpressionSourcePath, normalizeFunctionBodyPath, opaqueArgumentEscapeAffectsNarrow, pathsMatch, recordForOfLoopHeaderAliases, recordFunctionBodyConstBindings, recordExecutedExpressionAliases, recordVariableAliases, typeMayAliasMutableState, typedUpdateExpressionAffectsNarrow, } from './flow_shared.js';
2
+ import { bindFunctionBindingName, appendSegment, arrayMutationCallAffectsNarrow, assignmentAffectsNarrow, bindFunctionReceiverPath, cloneState, getCalledMember, getExpressionSymbol, getFunctionBindings, getFunctionBodyCalledMember, getFunctionLikeFromExpression, getFunctionLikeFromBoundMemberCall, getFunctionLikeFromBoundValue, getFunctionLikeFromCallExpression, getStateExpressionBoundValue, getUniformArrayElementBindingFromExpression, getUniformArrayElementBindingFromFunctionBodyExpression, getUniformMapEntryBindingsFromExpression, getUniformMapEntryBindingsFromFunctionBodyExpression, getUniformSetElementBindingFromExpression, getUniformSetElementBindingFromFunctionBodyExpression, getNestedFunctionBindings, getMutableBindingSymbol, getShorthandStateBoundValue, getSymbolId, getUpdateExpressionOperand, isConstLocalBindingPath, isFunctionLikeWithBody, isLocalBindingPath, isStableConstLocalBindingPath, MUTATING_ASSIGNMENT_OPERATORS, mutationAffectsNarrow, normalizeExpressionPath, normalizeExpressionSourcePath, normalizeFunctionBodyPath, opaqueArgumentEscapeAffectsNarrow, pathsMatch, recordForOfLoopHeaderAliases, recordFunctionBodyConstBindings, recordExecutedExpressionAliases, recordVariableAliases, typeMayAliasMutableState, typedUpdateExpressionAffectsNarrow, } from './flow_shared.js';
3
3
  export { appendSegment, cloneState, isFunctionLikeWithBody, normalizeExpressionPath, recordExecutedExpressionAliases, recordVariableAliases, } from './flow_shared.js';
4
4
  const SYNCHRONOUS_ARRAY_CALLBACK_PARAMETER_BINDINGS = new Map([
5
5
  ['every', { callbackArgumentIndex: 0, elementParameterIndex: 0, arrayParameterIndex: 2 }],
@@ -389,10 +389,22 @@ function getLocalCallbackFunctionLike(context, expression, bindings) {
389
389
  }
390
390
  const symbol = getExpressionSymbol(context, expression);
391
391
  if (!symbol) {
392
- return undefined;
392
+ return getFunctionLikeFromExpression(context, expression);
393
393
  }
394
394
  const boundValue = bindings.boundValues.get(getSymbolId(context, symbol));
395
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
395
+ return boundValue
396
+ ? getFunctionLikeFromBoundValue(context, boundValue)
397
+ : getFunctionLikeFromExpression(context, expression);
398
+ }
399
+ function getStateCallbackFunctionLike(context, expression, state) {
400
+ expression = unwrapTransparentExpression(expression);
401
+ if (isFunctionLikeWithBody(expression)) {
402
+ return expression;
403
+ }
404
+ const boundValue = getStateExpressionBoundValue(context, expression, state);
405
+ return boundValue
406
+ ? getFunctionLikeFromBoundValue(context, boundValue)
407
+ : getFunctionLikeFromExpression(context, expression);
396
408
  }
397
409
  function arrayCallbackArgumentAffectsNarrow(context, receiver, member, callExpression, bindings, narrowPath, state) {
398
410
  const callbackBinding = member
@@ -437,12 +449,7 @@ function arrayCallbackExpressionAffectsNarrow(context, receiver, member, callExp
437
449
  if (!callbackArgument) {
438
450
  return false;
439
451
  }
440
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
441
- ? callbackArgument
442
- : (() => {
443
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
444
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
445
- })();
452
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
446
453
  if (!callbackDeclaration) {
447
454
  return false;
448
455
  }
@@ -509,12 +516,7 @@ function setCallbackExpressionAffectsNarrow(context, receiver, member, callExpre
509
516
  if (!callbackArgument) {
510
517
  return false;
511
518
  }
512
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
513
- ? callbackArgument
514
- : (() => {
515
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
516
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
517
- })();
519
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
518
520
  if (!callbackDeclaration) {
519
521
  return false;
520
522
  }
@@ -589,12 +591,7 @@ function mapCallbackExpressionAffectsNarrow(context, receiver, member, callExpre
589
591
  if (!callbackArgument) {
590
592
  return false;
591
593
  }
592
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
593
- ? callbackArgument
594
- : (() => {
595
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
596
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
597
- })();
594
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
598
595
  if (!callbackDeclaration) {
599
596
  return false;
600
597
  }
@@ -21,6 +21,7 @@ import {
21
21
  getExpressionSymbol,
22
22
  getFunctionBindings,
23
23
  getFunctionBodyCalledMember,
24
+ getFunctionLikeFromExpression,
24
25
  getFunctionLikeFromBoundMemberCall,
25
26
  getFunctionLikeFromBoundValue,
26
27
  getFunctionLikeFromCallExpression,
@@ -766,11 +767,30 @@ function getLocalCallbackFunctionLike(
766
767
 
767
768
  const symbol = getExpressionSymbol(context, expression);
768
769
  if (!symbol) {
769
- return undefined;
770
+ return getFunctionLikeFromExpression(context, expression);
770
771
  }
771
772
 
772
773
  const boundValue = bindings.boundValues.get(getSymbolId(context, symbol));
773
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
774
+ return boundValue
775
+ ? getFunctionLikeFromBoundValue(context, boundValue)
776
+ : getFunctionLikeFromExpression(context, expression);
777
+ }
778
+
779
+ function getStateCallbackFunctionLike(
780
+ context: AnalysisContext,
781
+ expression: ts.Expression,
782
+ state: AnalysisState,
783
+ ): ts.FunctionLikeDeclaration | undefined {
784
+ expression = unwrapTransparentExpression(expression);
785
+
786
+ if (isFunctionLikeWithBody(expression)) {
787
+ return expression;
788
+ }
789
+
790
+ const boundValue = getStateExpressionBoundValue(context, expression, state);
791
+ return boundValue
792
+ ? getFunctionLikeFromBoundValue(context, boundValue)
793
+ : getFunctionLikeFromExpression(context, expression);
774
794
  }
775
795
 
776
796
  function arrayCallbackArgumentAffectsNarrow(
@@ -865,12 +885,7 @@ function arrayCallbackExpressionAffectsNarrow(
865
885
  return false;
866
886
  }
867
887
 
868
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
869
- ? callbackArgument
870
- : (() => {
871
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
872
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
873
- })();
888
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
874
889
  if (!callbackDeclaration) {
875
890
  return false;
876
891
  }
@@ -1016,12 +1031,7 @@ function setCallbackExpressionAffectsNarrow(
1016
1031
  return false;
1017
1032
  }
1018
1033
 
1019
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
1020
- ? callbackArgument
1021
- : (() => {
1022
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
1023
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
1024
- })();
1034
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
1025
1035
  if (!callbackDeclaration) {
1026
1036
  return false;
1027
1037
  }
@@ -1183,12 +1193,7 @@ function mapCallbackExpressionAffectsNarrow(
1183
1193
  return false;
1184
1194
  }
1185
1195
 
1186
- const callbackDeclaration = isFunctionLikeWithBody(callbackArgument)
1187
- ? callbackArgument
1188
- : (() => {
1189
- const boundValue = getStateExpressionBoundValue(context, callbackArgument, state);
1190
- return boundValue ? getFunctionLikeFromBoundValue(context, boundValue) : undefined;
1191
- })();
1196
+ const callbackDeclaration = getStateCallbackFunctionLike(context, callbackArgument, state);
1192
1197
  if (!callbackDeclaration) {
1193
1198
  return false;
1194
1199
  }
@@ -1325,7 +1325,8 @@ function isInstalledSoundStdlibSourceFile(sourceFile) {
1325
1325
  const normalizedFileName = sourceFile.fileName.replaceAll('\\', '/');
1326
1326
  return normalizedFileName.includes('/node_modules/@soundscript/soundscript/') &&
1327
1327
  (normalizedFileName.endsWith('.d.ts') ||
1328
- normalizedFileName.endsWith('.sts'));
1328
+ normalizedFileName.endsWith('.sts') ||
1329
+ normalizedFileName.endsWith('.sts.ts'));
1329
1330
  }
1330
1331
  function isLocalBuiltinSoundStdlibSourceFile(sourceFile) {
1331
1332
  const normalizedFileName = sourceFile.fileName.replaceAll('\\', '/');
@@ -3214,10 +3215,21 @@ function classifyCurrentTypeNodeNewtypeRelation(context, sourceType, targetType,
3214
3215
  return createNominalNewtypeRelationMismatch(context, sourceType, targetType, targetIdentitySet);
3215
3216
  }
3216
3217
  function classifyCurrentTypeNodeNominalClassRelation(context, sourceType, targetType, targetTypeNode, sourceExpression, sourceTypeNode) {
3218
+ if (sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
3219
+ sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3220
+ sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
3221
+ sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)) {
3222
+ return undefined;
3223
+ }
3217
3224
  const targetIdentitySet = getDeclaredClassIdentitySetFromTypeNode(context, targetTypeNode);
3218
3225
  if (!targetIdentitySet) {
3219
3226
  return undefined;
3220
3227
  }
3228
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
3229
+ const targetFamily = getCanonicalResultClassFamilyForTargetIdentitySet(targetIdentitySet);
3230
+ if (sourceFamily !== undefined && sourceFamily === targetFamily) {
3231
+ return undefined;
3232
+ }
3221
3233
  const sourceIdentitySet = getDeclaredClassIdentitySetFromTypeNode(context, sourceTypeNode) ??
3222
3234
  getDeclaredClassIdentitySetFromExpression(context, sourceExpression);
3223
3235
  if (sourceIdentitySet &&
@@ -3506,6 +3518,11 @@ function sourceNewtypeMatchesTargetIdentity(context, sourceType, targetIdentity)
3506
3518
  });
3507
3519
  }
3508
3520
  function classifySourceTypeAgainstTargetClassIdentitySet(context, sourceType, targetType, targetIdentitySet) {
3521
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
3522
+ const targetFamily = getCanonicalResultClassFamilyForTargetIdentitySet(targetIdentitySet);
3523
+ if (sourceFamily !== undefined && sourceFamily === targetFamily) {
3524
+ return undefined;
3525
+ }
3509
3526
  if (targetIdentitySet.mode === 'union') {
3510
3527
  const normalizedSourceType = getSafeNonNullableRelationType(context, sourceType);
3511
3528
  if ((normalizedSourceType.flags & ts.TypeFlags.Never) !== 0) {
@@ -3562,7 +3579,8 @@ function classifySourceTypeAgainstTargetClassIdentitySet(context, sourceType, ta
3562
3579
  return undefined;
3563
3580
  }
3564
3581
  function classifyUnsoundNominalClassRelation(context, sourceType, targetType) {
3565
- if (sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3582
+ if (sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
3583
+ sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3566
3584
  sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
3567
3585
  sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)) {
3568
3586
  return undefined;
@@ -3606,7 +3624,8 @@ function classifyUnsoundNominalNewtypeRelation(context, sourceType, targetType,
3606
3624
  return undefined;
3607
3625
  }
3608
3626
  function classifyUnsoundGenericClassInstanceRelation(context, sourceType, targetType) {
3609
- if (sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3627
+ if (sharesCanonicalResultClassFamily(context, sourceType, targetType) ||
3628
+ sharesGenericAliasRelationFamily(context, sourceType, targetType) ||
3610
3629
  sharesExactGenericClassIdentityFamilies(context, sourceType, targetType) ||
3611
3630
  sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType)) {
3612
3631
  return undefined;
@@ -3683,6 +3702,141 @@ function sharesEquivalentTargetClassIdentitySets(context, sourceType, targetType
3683
3702
  return sourceIdentitySet.identities.length === targetIdentitySet.identities.length &&
3684
3703
  sourceIdentitySet.identities.every((sourceIdentity) => targetIdentitySet.identities.some((targetIdentity) => classIdentitiesMatch(context, sourceIdentity, targetIdentity)));
3685
3704
  }
3705
+ function isTrustedResultStdlibSourceFileName(fileName) {
3706
+ return /(?:^|[\\/])(?:index|result)(?:\.sts)?(?:\.d)?\.ts$/.test(fileName);
3707
+ }
3708
+ function getCanonicalResultClassFamilyForName(name) {
3709
+ switch (name) {
3710
+ case 'Err':
3711
+ case 'Ok':
3712
+ case 'Result':
3713
+ return 'result';
3714
+ case 'None':
3715
+ case 'Option':
3716
+ case 'Some':
3717
+ return 'option';
3718
+ default:
3719
+ return undefined;
3720
+ }
3721
+ }
3722
+ function getCanonicalResultClassFamilyForGenericRelationInfo(info) {
3723
+ const declarations = info.symbol.getDeclarations() ?? [];
3724
+ if (!declarations.some((declaration) => isTrustedSoundLibSourceFile(declaration.getSourceFile()) &&
3725
+ isTrustedResultStdlibSourceFileName(declaration.getSourceFile().fileName))) {
3726
+ return undefined;
3727
+ }
3728
+ return getCanonicalResultClassFamilyForName(info.name);
3729
+ }
3730
+ function getCanonicalResultClassFamilyForIdentity(identity) {
3731
+ const declarations = identity.symbol.getDeclarations() ?? [];
3732
+ if (!declarations.some((declaration) => isTrustedSoundLibSourceFile(declaration.getSourceFile()) &&
3733
+ isTrustedResultStdlibSourceFileName(declaration.getSourceFile().fileName))) {
3734
+ return undefined;
3735
+ }
3736
+ return getCanonicalResultClassFamilyForName(identity.symbol.getName());
3737
+ }
3738
+ function getCanonicalResultClassFamilyForTargetIdentitySet(identitySet) {
3739
+ let family;
3740
+ for (const identity of identitySet.identities) {
3741
+ const identityFamily = getCanonicalResultClassFamilyForIdentity(identity);
3742
+ if (!identityFamily) {
3743
+ return undefined;
3744
+ }
3745
+ if (family && family !== identityFamily) {
3746
+ return undefined;
3747
+ }
3748
+ family = identityFamily;
3749
+ }
3750
+ return family;
3751
+ }
3752
+ function getCanonicalResultClassFamilyForType(context, type, visitedTypeIds = new Set()) {
3753
+ const normalizedType = getSafeNonNullableRelationType(context, type);
3754
+ const rawTypeId = normalizedType.id;
3755
+ let visitedTypeId;
3756
+ if (typeof rawTypeId === 'number') {
3757
+ if (visitedTypeIds.has(rawTypeId)) {
3758
+ return undefined;
3759
+ }
3760
+ visitedTypeIds.add(rawTypeId);
3761
+ visitedTypeId = rawTypeId;
3762
+ }
3763
+ try {
3764
+ if ((normalizedType.flags & ts.TypeFlags.Union) !== 0) {
3765
+ let family;
3766
+ let sawConstituent = false;
3767
+ for (const constituentType of normalizedType.types) {
3768
+ const normalizedConstituentType = getSafeNonNullableRelationType(context, constituentType);
3769
+ if ((normalizedConstituentType.flags & ts.TypeFlags.Never) !== 0) {
3770
+ continue;
3771
+ }
3772
+ const constituentFamily = getCanonicalResultClassFamilyForType(context, normalizedConstituentType, visitedTypeIds);
3773
+ if (!constituentFamily) {
3774
+ return undefined;
3775
+ }
3776
+ if (family && family !== constituentFamily) {
3777
+ return undefined;
3778
+ }
3779
+ sawConstituent = true;
3780
+ family = constituentFamily;
3781
+ }
3782
+ return sawConstituent ? family : undefined;
3783
+ }
3784
+ if ((normalizedType.flags & ts.TypeFlags.Intersection) !== 0) {
3785
+ let family;
3786
+ for (const constituentType of normalizedType.types) {
3787
+ const constituentFamily = getCanonicalResultClassFamilyForType(context, constituentType, visitedTypeIds);
3788
+ if (!constituentFamily) {
3789
+ continue;
3790
+ }
3791
+ if (family && family !== constituentFamily) {
3792
+ return undefined;
3793
+ }
3794
+ family = constituentFamily;
3795
+ }
3796
+ return family;
3797
+ }
3798
+ const relationInfo = getGenericRelationTypeInfo(context, normalizedType);
3799
+ const relationFamily = relationInfo
3800
+ ? getCanonicalResultClassFamilyForGenericRelationInfo(relationInfo)
3801
+ : undefined;
3802
+ if (relationFamily) {
3803
+ return relationFamily;
3804
+ }
3805
+ const directIdentity = getDirectClassIdentity(context, normalizedType);
3806
+ const directFamily = directIdentity
3807
+ ? getCanonicalResultClassFamilyForIdentity(directIdentity)
3808
+ : undefined;
3809
+ if (directFamily) {
3810
+ return directFamily;
3811
+ }
3812
+ const identities = collectGenericClassIdentities(context, normalizedType);
3813
+ if (identities.length === 0) {
3814
+ return undefined;
3815
+ }
3816
+ let family;
3817
+ for (const identity of identities) {
3818
+ const identityFamily = getCanonicalResultClassFamilyForIdentity(identity);
3819
+ if (!identityFamily) {
3820
+ return undefined;
3821
+ }
3822
+ if (family && family !== identityFamily) {
3823
+ return undefined;
3824
+ }
3825
+ family = identityFamily;
3826
+ }
3827
+ return family;
3828
+ }
3829
+ finally {
3830
+ if (visitedTypeId !== undefined) {
3831
+ visitedTypeIds.delete(visitedTypeId);
3832
+ }
3833
+ }
3834
+ }
3835
+ function sharesCanonicalResultClassFamily(context, sourceType, targetType) {
3836
+ const sourceFamily = getCanonicalResultClassFamilyForType(context, sourceType);
3837
+ return sourceFamily !== undefined &&
3838
+ sourceFamily === getCanonicalResultClassFamilyForType(context, targetType);
3839
+ }
3686
3840
  function getGenericParameterNames(symbol, arity) {
3687
3841
  const typeParameters = getSymbolTypeParameterDeclarations(symbol);
3688
3842
  return typeParameters.length === arity