diff --git a/.lazy.lua b/.lazy.lua new file mode 100644 index 0000000..5b4380c --- /dev/null +++ b/.lazy.lua @@ -0,0 +1,7 @@ +vim.lsp.config("biome", { + root_dir = function (bufnr, on_dir) + on_dir(vim.fn.getcwd()) + end +}) + +return {} diff --git a/biome.json b/biome.json index 8e38991..c2bc1e8 100644 --- a/biome.json +++ b/biome.json @@ -17,6 +17,13 @@ "lineWidth": 110, "lineEnding": "lf" }, + "linter": { + "rules": { + "style": { + "useNamingConvention": "warn" + } + } + }, "javascript": { "formatter": { "arrowParentheses": "always", diff --git a/nix-js/runtime-ts/src/builtins/arithmetic.ts b/nix-js/runtime-ts/src/builtins/arithmetic.ts index 6d6f879..00acfd4 100644 --- a/nix-js/runtime-ts/src/builtins/arithmetic.ts +++ b/nix-js/runtime-ts/src/builtins/arithmetic.ts @@ -3,33 +3,33 @@ */ import type { NixBool, NixInt, NixNumber, NixValue } from "../types"; -import { force_numeric, coerce_numeric, force_int } from "../type-assert"; +import { forceNumeric, coerceNumeric, forceInt } from "../type-assert"; export const add = (a: NixValue) => (b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) + (bv as any); }; export const sub = (a: NixValue) => (b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) - (bv as any); }; export const mul = (a: NixValue) => (b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) * (bv as any); }; export const div = (a: NixValue) => (b: NixValue): NixNumber => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); if (bv === 0 || bv === 0n) { throw new RangeError("Division by zero"); @@ -42,28 +42,28 @@ export const div = export const bitAnd = (a: NixValue) => (b: NixValue): NixInt => { - const av = force_int(a); - const bv = force_int(b); + const av = forceInt(a); + const bv = forceInt(b); return av & bv; }; export const bitOr = (a: NixValue) => (b: NixValue): NixInt => { - const av = force_int(a); - const bv = force_int(b); + const av = forceInt(a); + const bv = forceInt(b); return av | bv; }; export const bitXor = (a: NixValue) => (b: NixValue): NixInt => { - const av = force_int(a); - const bv = force_int(b); + const av = forceInt(a); + const bv = forceInt(b); return av ^ bv; }; export const lessThan = (a: NixValue) => (b: NixValue): NixBool => - force_numeric(a) < force_numeric(b); + forceNumeric(a) < forceNumeric(b); diff --git a/nix-js/runtime-ts/src/builtins/attrs.ts b/nix-js/runtime-ts/src/builtins/attrs.ts index 1eb1f95..d8ebf7b 100644 --- a/nix-js/runtime-ts/src/builtins/attrs.ts +++ b/nix-js/runtime-ts/src/builtins/attrs.ts @@ -3,30 +3,30 @@ */ import type { NixValue, NixAttrs, NixList } from "../types"; -import { force_attrs, force_string, force_function, force_list } from "../type-assert"; +import { forceAttrs, forceString, forceFunction, forceList } from "../type-assert"; -export const attrNames = (set: NixValue): string[] => Object.keys(force_attrs(set)).sort(); +export const attrNames = (set: NixValue): string[] => Object.keys(forceAttrs(set)).sort(); -export const attrValues = (set: NixValue): NixValue[] => Object.values(force_attrs(set)); +export const attrValues = (set: NixValue): NixValue[] => Object.values(forceAttrs(set)); export const getAttr = (s: NixValue) => (set: NixValue): NixValue => - force_attrs(set)[force_string(s)]; + forceAttrs(set)[forceString(s)]; export const hasAttr = (s: NixValue) => (set: NixValue): boolean => - Object.hasOwn(force_attrs(set), force_string(s)); + Object.hasOwn(forceAttrs(set), forceString(s)); export const mapAttrs = (f: NixValue) => (attrs: NixValue): NixAttrs => { const new_attrs: NixAttrs = {}; - const forced_attrs = force_attrs(attrs); - const forced_f = force_function(f); + const forced_attrs = forceAttrs(attrs); + const forced_f = forceFunction(f); for (const key in forced_attrs) { - new_attrs[key] = forced_f(key)(forced_attrs[key]); + new_attrs[key] = forceFunction(forced_f(key))(forced_attrs[key]); } return new_attrs; }; @@ -35,8 +35,8 @@ export const removeAttrs = (attrs: NixValue) => (list: NixValue): NixAttrs => { const new_attrs: NixAttrs = {}; - const forced_attrs = force_attrs(attrs); - const forced_list = force_list(list); + const forced_attrs = forceAttrs(attrs); + const forced_list = forceList(list); for (const key in forced_attrs) { if (!(key in forced_list)) { @@ -48,10 +48,10 @@ export const removeAttrs = export const listToAttrs = (e: NixValue): NixAttrs => { const attrs: NixAttrs = {}; - const forced_e = [...force_list(e)].reverse(); + const forced_e = [...forceList(e)].reverse(); for (const obj of forced_e) { - const item = force_attrs(obj); - attrs[force_string(item.name)] = item.value; + const item = forceAttrs(obj); + attrs[forceString(item.name)] = item.value; } return attrs; }; @@ -59,8 +59,8 @@ export const listToAttrs = (e: NixValue): NixAttrs => { export const intersectAttrs = (e1: NixValue) => (e2: NixValue): NixAttrs => { - const f1 = force_attrs(e1); - const f2 = force_attrs(e2); + const f1 = forceAttrs(e1); + const f2 = forceAttrs(e2); const attrs: NixAttrs = {}; for (const key of Object.keys(f2)) { if (Object.hasOwn(f1, key)) { @@ -73,9 +73,9 @@ export const intersectAttrs = export const catAttrs = (attr: NixValue) => (list: NixValue): NixList => { - const key = force_string(attr); - return force_list(list) - .map((set) => force_attrs(set)[key]) + const key = forceString(attr); + return forceList(list) + .map((set) => forceAttrs(set)[key]) .filter((val) => val !== undefined); }; @@ -83,10 +83,10 @@ export const groupBy = (f: NixValue) => (list: NixValue): NixAttrs => { const attrs: NixAttrs = {}; - const forced_f = force_function(f); - const forced_list = force_list(list); + const forced_f = forceFunction(f); + const forced_list = forceList(list); for (const elem of forced_list) { - const key = force_string(forced_f(elem)); + const key = forceString(forced_f(elem)); if (!attrs[key]) attrs[key] = []; (attrs[key] as NixList).push(elem); } diff --git a/nix-js/runtime-ts/src/builtins/conversion.ts b/nix-js/runtime-ts/src/builtins/conversion.ts index 21f2e4b..31f4caf 100644 --- a/nix-js/runtime-ts/src/builtins/conversion.ts +++ b/nix-js/runtime-ts/src/builtins/conversion.ts @@ -191,6 +191,6 @@ export const coerceToString = ( * @param value - The value to convert to a string * @returns The string representation */ -export const toString = (value: NixValue): string => { +export const toStringFunc = (value: NixValue): string => { return coerceToString(value, StringCoercionMode.ToString, false); }; diff --git a/nix-js/runtime-ts/src/builtins/functional.ts b/nix-js/runtime-ts/src/builtins/functional.ts index 64e7c6e..063f6a3 100644 --- a/nix-js/runtime-ts/src/builtins/functional.ts +++ b/nix-js/runtime-ts/src/builtins/functional.ts @@ -4,7 +4,7 @@ import { CatchableError, type NixValue } from "../types"; import { force } from "../thunk"; -import { force_string } from "../type-assert"; +import { forceString } from "../type-assert"; export const seq = (e1: NixValue) => @@ -24,7 +24,7 @@ export const abort = (s: NixValue): never => { }; export const throwFunc = (s: NixValue): never => { - throw new CatchableError(force_string(s)); + throw new CatchableError(forceString(s)); }; export const trace = (e1: NixValue, e2: NixValue): NixValue => { diff --git a/nix-js/runtime-ts/src/builtins/index.ts b/nix-js/runtime-ts/src/builtins/index.ts index 1c3c0ec..129189b 100644 --- a/nix-js/runtime-ts/src/builtins/index.ts +++ b/nix-js/runtime-ts/src/builtins/index.ts @@ -211,7 +211,7 @@ export const builtins: any = { fromTOML: mkPrimop(conversion.fromTOML, "fromTOML", 1), toJSON: mkPrimop(conversion.toJSON, "toJSON", 1), toXML: mkPrimop(conversion.toXML, "toXML", 1), - toString: mkPrimop(conversion.toString, "toString", 1), + toString: mkPrimop(conversion.toStringFunc, "toString", 1), addErrorContext: mkPrimop(misc.addErrorContext, "addErrorContext", 1), appendContext: mkPrimop(misc.appendContext, "appendContext", 1), diff --git a/nix-js/runtime-ts/src/builtins/io.ts b/nix-js/runtime-ts/src/builtins/io.ts index a20ebb1..f1c1040 100644 --- a/nix-js/runtime-ts/src/builtins/io.ts +++ b/nix-js/runtime-ts/src/builtins/io.ts @@ -3,23 +3,20 @@ * Implemented via Rust ops exposed through deno_core */ +import { forceString } from "../type-assert"; import type { NixValue } from "../types"; -import { force_string } from "../type-assert"; // Declare Deno.core.ops global (provided by deno_core runtime) export const importFunc = (path: NixValue): NixValue => { // For MVP: only support string paths // TODO: After implementing path type, also accept path values - const pathStr = force_string(path); + const pathStr = forceString(path); // Call Rust op - returns JS code string const code = Deno.core.ops.op_import(pathStr); - // Eval in current context - returns V8 value directly! - // (0, eval) = indirect eval = global scope - // Wrap in parentheses to ensure object literals are parsed correctly - return (0, eval)(`(${code})`); + return Function(`return (${code})`)(); }; export const scopedImport = @@ -61,7 +58,7 @@ export const readDir = (path: NixValue): never => { }; export const readFile = (path: NixValue): string => { - const pathStr = force_string(path); + const pathStr = forceString(path); return Deno.core.ops.op_read_file(pathStr); }; @@ -70,7 +67,7 @@ export const readFileType = (path: NixValue): never => { }; export const pathExists = (path: NixValue): boolean => { - const pathStr = force_string(path); + const pathStr = forceString(path); return Deno.core.ops.op_path_exists(pathStr); }; diff --git a/nix-js/runtime-ts/src/builtins/list.ts b/nix-js/runtime-ts/src/builtins/list.ts index 94f269a..dfecbd6 100644 --- a/nix-js/runtime-ts/src/builtins/list.ts +++ b/nix-js/runtime-ts/src/builtins/list.ts @@ -5,38 +5,38 @@ import type { NixValue, NixList, NixAttrs } from "../types"; import { force } from "../thunk"; -import { force_list, force_function, force_numeric, force_int } from "../type-assert"; +import { forceList, forceFunction, forceInt } from "../type-assert"; export const map = (f: NixValue) => (list: NixValue): NixList => - force_list(list).map(force_function(f)); + forceList(list).map(forceFunction(f)); export const filter = (f: NixValue) => (list: NixValue): NixList => - force_list(list).filter(force_function(f)); + forceList(list).filter(forceFunction(f)); export const length = (e: NixValue): bigint => { const forced = force(e); if (typeof forced === "string") return BigInt(forced.length); - return BigInt(force_list(forced).length); + return BigInt(forceList(forced).length); }; -export const head = (list: NixValue): NixValue => force_list(list)[0]; +export const head = (list: NixValue): NixValue => forceList(list)[0]; -export const tail = (list: NixValue): NixList => force_list(list).slice(1); +export const tail = (list: NixValue): NixList => forceList(list).slice(1); export const elem = (x: NixValue) => (xs: NixValue): boolean => - force_list(xs).includes(force(x)); + forceList(xs).includes(force(x)); export const elemAt = (xs: NixValue) => (n: NixValue): NixValue => { - const list = force_list(xs); - const idx = Number(force_int(n)); + const list = forceList(xs); + const idx = Number(forceInt(n)); if (idx < 0 || idx >= list.length) { throw new RangeError(`Index ${idx} out of bounds for list of length ${list.length}`); @@ -46,16 +46,16 @@ export const elemAt = }; export const concatLists = (lists: NixValue): NixList => { - return force_list(lists).reduce((acc: NixList, cur: NixValue) => { - return acc.concat(force_list(cur)); + return forceList(lists).reduce((acc: NixList, cur: NixValue) => { + return acc.concat(forceList(cur)); }, []); }; export const concatMap = (f: NixValue) => (lists: NixValue): NixList => { - const fn = force_function(f); - return force_list(lists).reduce((acc: NixList, cur: NixValue) => { + const fn = forceFunction(f); + return forceList(lists).reduce((acc: NixList, cur: NixValue) => { return acc.concat(force(fn(cur)) as NixList); }, []); }; @@ -64,20 +64,20 @@ export const foldlPrime = (op_fn: NixValue) => (nul: NixValue) => (list: NixValue): NixValue => { - const forced_op = force_function(op_fn); - return force_list(list).reduce((acc: NixValue, cur: NixValue) => { - return forced_op(acc)(cur); + const forced_op = forceFunction(op_fn); + return forceList(list).reduce((acc: NixValue, cur: NixValue) => { + return forceFunction(forced_op(acc))(cur); }, nul); }; export const sort = (cmp: NixValue) => (list: NixValue): NixList => { - const forced_list = [...force_list(list)]; - const forced_cmp = force_function(cmp); + const forced_list = [...forceList(list)]; + const forced_cmp = forceFunction(cmp); return forced_list.sort((a, b) => { - if (force(forced_cmp(a)(b))) return -1; - if (force(forced_cmp(b)(a))) return 1; + if (force(forceFunction(forced_cmp(a))(b))) return -1; + if (force(forceFunction(forced_cmp(b))(a))) return 1; return 0; }); }; @@ -85,8 +85,8 @@ export const sort = export const partition = (pred: NixValue) => (list: NixValue): NixAttrs => { - const forced_list = force_list(list); - const forced_pred = force_function(pred); + const forced_list = forceList(list); + const forced_pred = forceFunction(pred); const attrs: NixAttrs = { right: [], wrong: [], @@ -104,8 +104,8 @@ export const partition = export const genList = (f: NixValue) => (len: NixValue): NixList => { - const func = force_function(f); - const length = force_int(len); + const func = forceFunction(f); + const length = forceInt(len); if (length < 0) { throw new TypeError(`genList length must be non-negative integer, got ${length}`); @@ -117,9 +117,9 @@ export const genList = export const all = (pred: NixValue) => (list: NixValue): boolean => - force_list(list).every(force_function(pred)); + forceList(list).every(forceFunction(pred)); export const any = (pred: NixValue) => (list: NixValue): boolean => - force_list(list).some(force_function(pred)); + forceList(list).some(forceFunction(pred)); diff --git a/nix-js/runtime-ts/src/builtins/math.ts b/nix-js/runtime-ts/src/builtins/math.ts index 0c6e668..f8c09d4 100644 --- a/nix-js/runtime-ts/src/builtins/math.ts +++ b/nix-js/runtime-ts/src/builtins/math.ts @@ -3,16 +3,16 @@ */ import type { NixValue } from "../types"; -import { force_numeric } from "../type-assert"; +import { forceNumeric } from "../type-assert"; export const ceil = (x: NixValue): bigint => { - const val = force_numeric(x); + const val = forceNumeric(x); if (typeof val === "bigint") return val; // Already an integer return BigInt(Math.ceil(val)); // Convert to integer }; export const floor = (x: NixValue): bigint => { - const val = force_numeric(x); + const val = forceNumeric(x); if (typeof val === "bigint") return val; // Already an integer return BigInt(Math.floor(val)); // Convert to integer }; diff --git a/nix-js/runtime-ts/src/builtins/string.ts b/nix-js/runtime-ts/src/builtins/string.ts index e223cbb..7b90688 100644 --- a/nix-js/runtime-ts/src/builtins/string.ts +++ b/nix-js/runtime-ts/src/builtins/string.ts @@ -3,27 +3,27 @@ */ import type { NixValue } from "../types"; -import { force_string, force_list, force_int } from "../type-assert"; +import { forceString, forceList, forceInt } from "../type-assert"; -export const stringLength = (e: NixValue): number => force_string(e).length; +export const stringLength = (e: NixValue): number => forceString(e).length; export const substring = (start: NixValue) => (len: NixValue) => (s: NixValue): string => { - const str = force_string(s); - const startPos = Number(force_int(start)); - const length = Number(force_int(len)); + const str = forceString(s); + const startPos = Number(forceInt(start)); + const length = Number(forceInt(len)); return str.substring(startPos, startPos + length); }; export const concatStringsSep = (sep: NixValue) => (list: NixValue): string => - force_list(list).join(force_string(sep)); + forceList(list).join(forceString(sep)); export const baseNameOf = (x: NixValue): string => { - const str = force_string(x); + const str = forceString(x); if (str.length === 0) return ""; let last = str.length - 1; diff --git a/nix-js/runtime-ts/src/helpers.ts b/nix-js/runtime-ts/src/helpers.ts index e9a125a..8bde89b 100644 --- a/nix-js/runtime-ts/src/helpers.ts +++ b/nix-js/runtime-ts/src/helpers.ts @@ -3,7 +3,7 @@ */ import type { NixValue, NixAttrs, NixBool } from "./types"; -import { force_attrs, force_string } from "./type-assert"; +import { forceAttrs, forceString } from "./type-assert"; import { isAttrs } from "./builtins/type-check"; /** @@ -14,7 +14,7 @@ import { isAttrs } from "./builtins/type-check"; * @returns Absolute path string */ export const resolvePath = (path: NixValue): string => { - const path_str = force_string(path); + const path_str = forceString(path); return Deno.core.ops.op_resolve_path(path_str); }; @@ -28,8 +28,8 @@ export const resolvePath = (path: NixValue): string => { * @throws Error if obj is null/undefined or key not found */ export const select = (obj: NixValue, key: NixValue): NixValue => { - const forced_obj = force_attrs(obj); - const forced_key = force_string(key); + const forced_obj = forceAttrs(obj); + const forced_key = forceString(key); if (!(forced_key in forced_obj)) { throw new Error(`Attribute '${forced_key}' not found`); @@ -48,8 +48,8 @@ export const select = (obj: NixValue, key: NixValue): NixValue => { * @returns obj[key] if exists, otherwise default_val */ export const selectWithDefault = (obj: NixValue, key: NixValue, default_val: NixValue): NixValue => { - const attrs = force_attrs(obj); - const forced_key = force_string(key); + const attrs = forceAttrs(obj); + const forced_key = forceString(key); if (!(forced_key in attrs)) { return default_val; @@ -65,7 +65,7 @@ export const hasAttr = (obj: NixValue, attrpath: NixValue[]): NixBool => { let attrs = obj; for (const attr of attrpath.slice(0, -1)) { - const cur = attrs[force_string(attr)]; + const cur = attrs[forceString(attr)]; if (!isAttrs(cur)) { return false; } @@ -94,7 +94,7 @@ export const validateParams = ( required: string[] | null, allowed: string[] | null, ): NixAttrs => { - const forced_arg = force_attrs(arg); + const forced_arg = forceAttrs(arg); // Check required parameters if (required) { diff --git a/nix-js/runtime-ts/src/index.ts b/nix-js/runtime-ts/src/index.ts index d597048..ee76379 100644 --- a/nix-js/runtime-ts/src/index.ts +++ b/nix-js/runtime-ts/src/index.ts @@ -4,7 +4,7 @@ * All functionality is exported via the global `Nix` object */ -import { createThunk, force, is_thunk, IS_THUNK } from "./thunk"; +import { createThunk, force, isThunk, IS_THUNK } from "./thunk"; import { select, selectWithDefault, validateParams, resolvePath, hasAttr } from "./helpers"; import { op } from "./operators"; import { builtins, PRIMOP_METADATA } from "./builtins"; @@ -18,7 +18,7 @@ export type NixRuntime = typeof Nix; export const Nix = { createThunk, force, - is_thunk, + isThunk, IS_THUNK, hasAttr, diff --git a/nix-js/runtime-ts/src/operators.ts b/nix-js/runtime-ts/src/operators.ts index e90ad5d..9fa9774 100644 --- a/nix-js/runtime-ts/src/operators.ts +++ b/nix-js/runtime-ts/src/operators.ts @@ -5,7 +5,7 @@ import type { NixValue, NixList, NixAttrs } from "./types"; import { force } from "./thunk"; -import { force_numeric, force_list, force_attrs, coerce_numeric } from "./type-assert"; +import { forceNumeric, forceList, forceAttrs, coerceNumeric } from "./type-assert"; /** * Operator object exported as Nix.op @@ -15,22 +15,22 @@ export const op = { // Arithmetic operators - preserve int/float distinction add: (a: NixValue, b: NixValue): bigint | number => { // FIXME: String & Path - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) + (bv as any); }, sub: (a: NixValue, b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) - (bv as any); }, mul: (a: NixValue, b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) * (bv as any); }, div: (a: NixValue, b: NixValue): bigint | number => { - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); if (bv === 0 || bv === 0n) { throw new RangeError("Division by zero"); @@ -54,22 +54,22 @@ export const op = { }, lt: (a: NixValue, b: NixValue): boolean => { // FIXME: Non-numeric - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) < (bv as any); }, lte: (a: NixValue, b: NixValue): boolean => { // FIXME: Non-numeric - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) <= (bv as any); }, gt: (a: NixValue, b: NixValue): boolean => { // FIXME: Non-numeric - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) > (bv as any); }, gte: (a: NixValue, b: NixValue): boolean => { // FIXME: Non-numeric - const [av, bv] = coerce_numeric(force_numeric(a), force_numeric(b)); + const [av, bv] = coerceNumeric(forceNumeric(a), forceNumeric(b)); return (av as any) >= (bv as any); }, @@ -81,11 +81,11 @@ export const op = { // List concatenation concat: (a: NixValue, b: NixValue): NixList => { - return Array.prototype.concat.call(force_list(a), force_list(b)); + return Array.prototype.concat.call(forceList(a), forceList(b)); }, // Attribute set update (merge) update: (a: NixValue, b: NixValue): NixAttrs => { - return { ...force_attrs(a), ...force_attrs(b) }; + return { ...forceAttrs(a), ...forceAttrs(b) }; }, }; diff --git a/nix-js/runtime-ts/src/thunk.ts b/nix-js/runtime-ts/src/thunk.ts index 5ee1a7d..c5553a7 100644 --- a/nix-js/runtime-ts/src/thunk.ts +++ b/nix-js/runtime-ts/src/thunk.ts @@ -34,7 +34,7 @@ export class NixThunk implements NixThunkInterface { * @param value - Value to check * @returns true if value is a NixThunk */ -export const is_thunk = (value: unknown): value is NixThunkInterface => { +export const isThunk = (value: unknown): value is NixThunkInterface => { return value !== null && typeof value === "object" && IS_THUNK in value && value[IS_THUNK] === true; }; @@ -47,7 +47,7 @@ export const is_thunk = (value: unknown): value is NixThunkInterface => { * @returns The forced/evaluated value */ export const force = (value: NixValue): NixStrictValue => { - if (!is_thunk(value)) { + if (!isThunk(value)) { return value; } diff --git a/nix-js/runtime-ts/src/type-assert.ts b/nix-js/runtime-ts/src/type-assert.ts index 74cc33f..e9c74f2 100644 --- a/nix-js/runtime-ts/src/type-assert.ts +++ b/nix-js/runtime-ts/src/type-assert.ts @@ -5,7 +5,6 @@ import type { NixValue, NixList, NixAttrs, NixFunction, NixInt, NixFloat, NixNumber } from "./types"; import { force } from "./thunk"; -import { isAttrs } from "./builtins/type-check"; const typeName = (value: NixValue): string => { const val = force(value); @@ -26,7 +25,7 @@ const typeName = (value: NixValue): string => { * Force a value and assert it's a list * @throws TypeError if value is not a list after forcing */ -export const force_list = (value: NixValue): NixList => { +export const forceList = (value: NixValue): NixList => { const forced = force(value); if (!Array.isArray(forced)) { throw new TypeError(`Expected list, got ${typeName(forced)}`); @@ -38,7 +37,7 @@ export const force_list = (value: NixValue): NixList => { * Force a value and assert it's a function * @throws TypeError if value is not a function after forcing */ -export const force_function = (value: NixValue): NixFunction => { +export const forceFunction = (value: NixValue): NixFunction => { const forced = force(value); if (typeof forced !== "function") { throw new TypeError(`Expected function, got ${typeName(forced)}`); @@ -50,7 +49,7 @@ export const force_function = (value: NixValue): NixFunction => { * Force a value and assert it's an attribute set * @throws TypeError if value is not an attribute set after forcing */ -export const force_attrs = (value: NixValue): NixAttrs => { +export const forceAttrs = (value: NixValue): NixAttrs => { const forced = force(value); if (typeof forced !== "object" || Array.isArray(forced) || forced === null) { throw new TypeError(`Expected attribute set, got ${typeName(forced)}`); @@ -62,7 +61,7 @@ export const force_attrs = (value: NixValue): NixAttrs => { * Force a value and assert it's a string * @throws TypeError if value is not a string after forcing */ -export const force_string = (value: NixValue): string => { +export const forceString = (value: NixValue): string => { const forced = force(value); if (typeof forced !== "string") { throw new TypeError(`Expected string, got ${typeName(forced)}`); @@ -74,7 +73,7 @@ export const force_string = (value: NixValue): string => { * Force a value and assert it's a boolean * @throws TypeError if value is not a boolean after forcing */ -export const force_bool = (value: NixValue): boolean => { +export const forceBool = (value: NixValue): boolean => { const forced = force(value); if (typeof forced !== "boolean") { throw new TypeError(`Expected boolean, got ${typeName(forced)}`); @@ -86,7 +85,7 @@ export const force_bool = (value: NixValue): boolean => { * Force a value and extract int value * @throws TypeError if value is not an int */ -export const force_int = (value: NixValue): NixInt => { +export const forceInt = (value: NixValue): NixInt => { const forced = force(value); if (typeof forced === "bigint") { return forced; @@ -98,7 +97,7 @@ export const force_int = (value: NixValue): NixInt => { * Force a value and extract float value * @throws TypeError if value is not a float */ -export const force_float = (value: NixValue): NixFloat => { +export const forceFloat = (value: NixValue): NixFloat => { const forced = force(value); if (typeof forced === "number") { return forced; @@ -110,7 +109,7 @@ export const force_float = (value: NixValue): NixFloat => { * Force a value and extract numeric value (int or float) * @throws TypeError if value is not a numeric type */ -export const force_numeric = (value: NixValue): NixNumber => { +export const forceNumeric = (value: NixValue): NixNumber => { const forced = force(value); if (typeof forced === "bigint" || typeof forced === "number") { return forced; @@ -123,7 +122,7 @@ export const force_numeric = (value: NixValue): NixNumber => { * Rule: If either is float, convert both to float; otherwise keep as bigint * @returns [a, b] tuple of coerced values */ -export const coerce_numeric = (a: NixNumber, b: NixNumber): [NixFloat, NixFloat] | [NixInt, NixInt] => { +export const coerceNumeric = (a: NixNumber, b: NixNumber): [NixFloat, NixFloat] | [NixInt, NixInt] => { const aIsInt = typeof a === "bigint"; const bIsInt = typeof b === "bigint"; diff --git a/nix-js/runtime-ts/src/types.ts b/nix-js/runtime-ts/src/types.ts index 8c1f039..3728a78 100644 --- a/nix-js/runtime-ts/src/types.ts +++ b/nix-js/runtime-ts/src/types.ts @@ -15,7 +15,7 @@ export type NixNull = null; // Nix composite types export type NixList = NixValue[]; export type NixAttrs = { [key: string]: NixValue }; -export type NixFunction = (...args: any[]) => any; +export type NixFunction = (arg: NixValue) => NixValue; /** * Interface for lazy thunk values @@ -42,11 +42,7 @@ export type NixStrictValue = Exclude; * CatchableError: Error type thrown by `builtins.throw` * This can be caught by `builtins.tryEval` */ -export class CatchableError extends Error { - constructor(msg: string) { - super(msg); - } -} +export class CatchableError extends Error {} // Operator function signatures export type BinaryOp = (a: T, b: U) => R; diff --git a/nix-js/src/codegen.rs b/nix-js/src/codegen.rs index fe7ed9b..9d20e13 100644 --- a/nix-js/src/codegen.rs +++ b/nix-js/src/codegen.rs @@ -199,11 +199,7 @@ impl Compile for Let { } let body = ctx.get_ir(self.body).compile(ctx); - format!( - "(()=>{{{}; return {}}})()", - js_statements.join(";"), - body - ) + format!("(()=>{{{}; return {}}})()", js_statements.join(";"), body) } } @@ -293,7 +289,10 @@ impl Compile for ConcatStrings { .map(|part| { let compiled = ctx.get_ir(*part).compile(ctx); // TODO: copyToStore - format!("Nix.coerceToString({}, Nix.StringCoercionMode.Interpolation, false)", compiled) + format!( + "Nix.coerceToString({}, Nix.StringCoercionMode.Interpolation, false)", + compiled + ) }) .collect(); diff --git a/nix-js/src/ir/downgrade.rs b/nix-js/src/ir/downgrade.rs index dd31593..5340522 100644 --- a/nix-js/src/ir/downgrade.rs +++ b/nix-js/src/ir/downgrade.rs @@ -77,7 +77,6 @@ impl Downgrade for ast::Path { path_str } else { let current_dir = ctx.get_current_dir(); - dbg!(¤t_dir); current_dir .join(&path_str) @@ -172,29 +171,22 @@ impl Downgrade for ast::AttrSet { // rec { a = 1; b = a; } => let a = 1; b = a; in { inherit a b; } let entries: Vec<_> = self.entries().collect(); - let (binding_sccs, body) = - downgrade_let_bindings(entries, ctx, |ctx, binding_keys| { - // Create plain attrset as body with inherit - let mut attrs = AttrSet { - stcs: HashMap::new(), - dyns: Vec::new(), - }; + let (binding_sccs, body) = downgrade_let_bindings(entries, ctx, |ctx, binding_keys| { + // Create plain attrset as body with inherit + let mut attrs = AttrSet { + stcs: HashMap::new(), + dyns: Vec::new(), + }; - for sym in binding_keys { - let expr = ctx.lookup(*sym)?; - attrs.stcs.insert(*sym, expr); - } - - Ok(ctx.new_expr(attrs.to_ir())) - })?; - - Ok(ctx.new_expr( - Let { - body, - binding_sccs, + for sym in binding_keys { + let expr = ctx.lookup(*sym)?; + attrs.stcs.insert(*sym, expr); } - .to_ir(), - )) + + Ok(ctx.new_expr(attrs.to_ir())) + })?; + + Ok(ctx.new_expr(Let { body, binding_sccs }.to_ir())) } } @@ -299,13 +291,7 @@ impl Downgrade for ast::LetIn { let (binding_sccs, body) = downgrade_let_bindings(entries, ctx, |ctx, _binding_keys| body_expr.downgrade(ctx))?; - Ok(ctx.new_expr( - Let { - body, - binding_sccs, - } - .to_ir(), - )) + Ok(ctx.new_expr(Let { body, binding_sccs }.to_ir())) } } diff --git a/nix-js/src/ir/utils.rs b/nix-js/src/ir/utils.rs index 12a4ea1..62d4cc9 100644 --- a/nix-js/src/ir/utils.rs +++ b/nix-js/src/ir/utils.rs @@ -323,7 +323,7 @@ where body, scc_info, required_params: required, - allowed_params: allowed + allowed_params: allowed, }) } @@ -348,7 +348,11 @@ where F: FnOnce(&mut Ctx, &[SymId]) -> Result, { let slots: Vec<_> = ctx.reserve_slots(binding_keys.len()).collect(); - let let_bindings: HashMap<_, _> = binding_keys.iter().copied().zip(slots.iter().copied()).collect(); + let let_bindings: HashMap<_, _> = binding_keys + .iter() + .copied() + .zip(slots.iter().copied()) + .collect(); ctx.push_dep_tracker(&slots); diff --git a/nix-js/tests/functions.rs b/nix-js/tests/functions.rs index 912a292..cd6cba2 100644 --- a/nix-js/tests/functions.rs +++ b/nix-js/tests/functions.rs @@ -77,10 +77,7 @@ fn nested_function_parameters() { #[test] fn pattern_param_simple_reference_in_default() { - assert_eq!( - eval("({ a, b ? a }: b) { a = 10; }"), - Value::Int(10) - ); + assert_eq!(eval("({ a, b ? a }: b) { a = 10; }"), Value::Int(10)); } #[test] diff --git a/nix-js/tests/io_operations.rs b/nix-js/tests/io_operations.rs index 84c6ebb..ab1989b 100644 --- a/nix-js/tests/io_operations.rs +++ b/nix-js/tests/io_operations.rs @@ -90,8 +90,7 @@ fn import_with_complex_dependency_graph() { std::fs::write(&utils_path, "{ double = x: x * 2; }").unwrap(); let math_path = temp_dir.path().join("math.nix"); - let math_content = - r#"let utils = import ./utils.nix; in { triple = x: x + utils.double x; }"#; + let math_content = r#"let utils = import ./utils.nix; in { triple = x: x + utils.double x; }"#; std::fs::write(&math_path, math_content).unwrap(); let main_path = temp_dir.path().join("main.nix"); diff --git a/nix-js/tests/to_string.rs b/nix-js/tests/to_string.rs index 80b863d..456674b 100644 --- a/nix-js/tests/to_string.rs +++ b/nix-js/tests/to_string.rs @@ -5,7 +5,10 @@ use utils::eval; #[test] fn string_returns_as_is() { - assert_eq!(eval(r#"toString "hello""#), Value::String("hello".to_string())); + assert_eq!( + eval(r#"toString "hello""#), + Value::String("hello".to_string()) + ); } #[test] @@ -67,10 +70,7 @@ fn list_with_multiple_empty_lists() { eval("toString [1 [] [] 2]"), Value::String("1 2".to_string()) ); - assert_eq!( - eval("toString [[] [] 1]"), - Value::String("1".to_string()) - ); + assert_eq!(eval("toString [[] [] 1]"), Value::String("1".to_string())); } #[test] @@ -112,7 +112,9 @@ fn attrs_with_to_string_method() { #[test] fn attrs_to_string_self_reference() { assert_eq!( - eval(r#"let obj = { x = 42; __toString = self: "x is ${toString self.x}"; }; in toString obj"#), + eval( + r#"let obj = { x = 42; __toString = self: "x is ${toString self.x}"; }; in toString obj"# + ), Value::String("x is 42".to_string()) ); } @@ -120,9 +122,7 @@ fn attrs_to_string_self_reference() { #[test] fn attrs_to_string_priority() { assert_eq!( - eval( - r#"toString { __toString = self: "custom"; outPath = "/nix/store/foo"; }"# - ), + eval(r#"toString { __toString = self: "custom"; outPath = "/nix/store/foo"; }"#), Value::String("custom".to_string()) ); }