optimize
This commit is contained in:
@@ -144,17 +144,20 @@ export const resolvePath = (currentDir: string, path: NixValue): NixPath => {
|
|||||||
|
|
||||||
export const select = (obj: NixValue, attrpath: NixValue[], span?: string): NixValue => {
|
export const select = (obj: NixValue, attrpath: NixValue[], span?: string): NixValue => {
|
||||||
if (span) {
|
if (span) {
|
||||||
const pathStrings = attrpath.map((a) => forceStringValue(a));
|
|
||||||
const path = pathStrings.join(".");
|
|
||||||
const message = path ? `while selecting attribute [${path}]` : "while selecting attribute";
|
|
||||||
|
|
||||||
if (callStack.length >= MAX_STACK_DEPTH) {
|
if (callStack.length >= MAX_STACK_DEPTH) {
|
||||||
callStack.shift();
|
callStack.shift();
|
||||||
}
|
}
|
||||||
callStack.push({ span, message });
|
const frame: StackFrame = { span, message: "while selecting attribute" };
|
||||||
|
callStack.push(frame);
|
||||||
try {
|
try {
|
||||||
return selectImpl(obj, attrpath);
|
return selectImpl(obj, attrpath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
try {
|
||||||
|
const path = attrpath.map((a) => forceStringValue(a)).join(".");
|
||||||
|
if (path) frame.message = `while selecting attribute [${path}]`;
|
||||||
|
} catch {
|
||||||
|
throw enrichError(error);
|
||||||
|
}
|
||||||
throw enrichError(error);
|
throw enrichError(error);
|
||||||
} finally {
|
} finally {
|
||||||
callStack.pop();
|
callStack.pop();
|
||||||
@@ -167,8 +170,8 @@ export const select = (obj: NixValue, attrpath: NixValue[], span?: string): NixV
|
|||||||
function selectImpl(obj: NixValue, attrpath: NixValue[]): NixValue {
|
function selectImpl(obj: NixValue, attrpath: NixValue[]): NixValue {
|
||||||
let attrs = forceAttrs(obj);
|
let attrs = forceAttrs(obj);
|
||||||
|
|
||||||
for (const attr of attrpath.slice(0, -1)) {
|
for (let i = 0; i < attrpath.length - 1; i++) {
|
||||||
const key = forceStringValue(attr);
|
const key = forceStringValue(attrpath[i]);
|
||||||
if (!attrs.has(key)) {
|
if (!attrs.has(key)) {
|
||||||
throw new Error(`Attribute '${key}' not found`);
|
throw new Error(`Attribute '${key}' not found`);
|
||||||
}
|
}
|
||||||
@@ -190,17 +193,20 @@ export const selectWithDefault = (
|
|||||||
span?: string,
|
span?: string,
|
||||||
): NixValue => {
|
): NixValue => {
|
||||||
if (span) {
|
if (span) {
|
||||||
const pathStrings = attrpath.map((a) => forceStringValue(a));
|
|
||||||
const path = pathStrings.join(".");
|
|
||||||
const message = path ? `while selecting attribute [${path}]` : "while selecting attribute";
|
|
||||||
|
|
||||||
if (callStack.length >= MAX_STACK_DEPTH) {
|
if (callStack.length >= MAX_STACK_DEPTH) {
|
||||||
callStack.shift();
|
callStack.shift();
|
||||||
}
|
}
|
||||||
callStack.push({ span, message });
|
const frame: StackFrame = { span, message: "while selecting attribute" };
|
||||||
|
callStack.push(frame);
|
||||||
try {
|
try {
|
||||||
return selectWithDefaultImpl(obj, attrpath, defaultVal);
|
return selectWithDefaultImpl(obj, attrpath, defaultVal);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
try {
|
||||||
|
const path = attrpath.map((a) => forceStringValue(a)).join(".");
|
||||||
|
if (path) frame.message = `while selecting attribute [${path}]`;
|
||||||
|
} catch {
|
||||||
|
throw enrichError(error);
|
||||||
|
}
|
||||||
throw enrichError(error);
|
throw enrichError(error);
|
||||||
} finally {
|
} finally {
|
||||||
callStack.pop();
|
callStack.pop();
|
||||||
@@ -216,8 +222,8 @@ function selectWithDefaultImpl(obj: NixValue, attrpath: NixValue[], defaultVal:
|
|||||||
return defaultVal;
|
return defaultVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const attr of attrpath.slice(0, -1)) {
|
for (let i = 0; i < attrpath.length - 1; i++) {
|
||||||
const key = forceStringValue(attr);
|
const key = forceStringValue(attrpath[i]);
|
||||||
if (!attrs.has(key)) {
|
if (!attrs.has(key)) {
|
||||||
return defaultVal;
|
return defaultVal;
|
||||||
}
|
}
|
||||||
@@ -242,8 +248,8 @@ export const hasAttr = (obj: NixValue, attrpath: NixValue[]): NixBool => {
|
|||||||
}
|
}
|
||||||
let attrs = forced;
|
let attrs = forced;
|
||||||
|
|
||||||
for (const attr of attrpath.slice(0, -1)) {
|
for (let i = 0; i < attrpath.length - 1; i++) {
|
||||||
const key = forceStringNoCtx(attr);
|
const key = forceStringNoCtx(attrpath[i]);
|
||||||
if (!attrs.has(key)) {
|
if (!attrs.has(key)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,11 +49,12 @@ export const getStringValue = (s: string | StringWithContext): string => {
|
|||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const emptyContext: NixStringContext = new Set();
|
||||||
export const getStringContext = (s: string | StringWithContext): NixStringContext => {
|
export const getStringContext = (s: string | StringWithContext): NixStringContext => {
|
||||||
if (isStringWithContext(s)) {
|
if (isStringWithContext(s)) {
|
||||||
return s.context;
|
return s.context;
|
||||||
}
|
}
|
||||||
return new Set();
|
return emptyContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mergeContexts = (...contexts: NixStringContext[]): NixStringContext => {
|
export const mergeContexts = (...contexts: NixStringContext[]): NixStringContext => {
|
||||||
|
|||||||
@@ -35,10 +35,10 @@ export class NixArgs {
|
|||||||
allowed: Set<string>;
|
allowed: Set<string>;
|
||||||
ellipsis: boolean;
|
ellipsis: boolean;
|
||||||
positions: Map<string, string>;
|
positions: Map<string, string>;
|
||||||
constructor(required: string[], optional: string[], positions: Record<string, string>, ellipsis: boolean) {
|
constructor(required: string[], optional: string[], positions: Map<string, string>, ellipsis: boolean) {
|
||||||
this.required = required;
|
this.required = required;
|
||||||
this.optional = optional;
|
this.optional = optional;
|
||||||
this.positions = new Map(Object.entries(positions));
|
this.positions = positions;
|
||||||
this.ellipsis = ellipsis;
|
this.ellipsis = ellipsis;
|
||||||
this.allowed = new Set(required.concat(optional));
|
this.allowed = new Set(required.concat(optional));
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ export const mkFunction = (
|
|||||||
f: (arg: NixValue) => NixValue,
|
f: (arg: NixValue) => NixValue,
|
||||||
required: string[],
|
required: string[],
|
||||||
optional: string[],
|
optional: string[],
|
||||||
positions: Record<string, string>,
|
positions: Map<string, string>,
|
||||||
ellipsis: boolean,
|
ellipsis: boolean,
|
||||||
): NixFunction => {
|
): NixFunction => {
|
||||||
const func: NixFunction = f;
|
const func: NixFunction = f;
|
||||||
@@ -86,12 +86,10 @@ export const mkAttrs = (attrs: NixAttrs, keys: NixValue[], values: NixValue[]):
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const mkAttrsWithPos = (
|
export const mkAttrsWithPos = (
|
||||||
obj: Record<string, NixValue>,
|
attrs: NixAttrs,
|
||||||
positions: Record<string, string>,
|
positions: Map<string, string>,
|
||||||
dyns?: { dynKeys: NixValue[]; dynVals: NixValue[]; dynSpans: string[] },
|
dyns?: { dynKeys: NixValue[]; dynVals: NixValue[]; dynSpans: string[] },
|
||||||
): NixAttrs => {
|
): NixAttrs => {
|
||||||
const attrs: NixAttrs = new Map(Object.entries(obj));
|
|
||||||
|
|
||||||
if (dyns) {
|
if (dyns) {
|
||||||
const len = dyns.dynKeys.length;
|
const len = dyns.dynKeys.length;
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
@@ -101,12 +99,12 @@ export const mkAttrsWithPos = (
|
|||||||
}
|
}
|
||||||
const str = forceStringNoCtx(key);
|
const str = forceStringNoCtx(key);
|
||||||
attrs.set(str, dyns.dynVals[i]);
|
attrs.set(str, dyns.dynVals[i]);
|
||||||
positions[str] = dyns.dynSpans[i];
|
positions.set(str, dyns.dynSpans[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(positions).length > 0) {
|
if (positions.size > 0) {
|
||||||
attrs[ATTR_POSITIONS] = new Map(Object.entries(positions));
|
attrs[ATTR_POSITIONS] = positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
return attrs;
|
return attrs;
|
||||||
|
|||||||
@@ -458,11 +458,11 @@ impl<Ctx: CodegenContext> Compile<Ctx> for Func {
|
|||||||
joined(optional.iter(), ",", |ctx: &Ctx, buf, &(sym, _)| {
|
joined(optional.iter(), ",", |ctx: &Ctx, buf, &(sym, _)| {
|
||||||
code!(buf, ctx; ctx.get_sym(sym));
|
code!(buf, ctx; ctx.get_sym(sym));
|
||||||
})
|
})
|
||||||
"],{"
|
"],new Map()"
|
||||||
joined(required.iter().chain(optional.iter()), ",", |ctx: &Ctx, buf, &(sym, span)| {
|
joined(required.iter().chain(optional.iter()), "", |ctx: &Ctx, buf, &(sym, span)| {
|
||||||
code!(buf, ctx; ctx.get_sym(sym) ":" span);
|
code!(buf, ctx; ".set(" ctx.get_sym(sym) "," span ")");
|
||||||
})
|
})
|
||||||
"},"
|
","
|
||||||
ellipsis
|
ellipsis
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
@@ -574,21 +574,21 @@ impl<Ctx: CodegenContext> Compile<Ctx> for AttrSet {
|
|||||||
fn compile(&self, ctx: &Ctx, buf: &mut CodeBuffer) {
|
fn compile(&self, ctx: &Ctx, buf: &mut CodeBuffer) {
|
||||||
if !self.dyns.is_empty() {
|
if !self.dyns.is_empty() {
|
||||||
code!(buf, ctx;
|
code!(buf, ctx;
|
||||||
"Nix.mkAttrsWithPos({"
|
"Nix.mkAttrsWithPos(new Map()"
|
||||||
joined(self.stcs.iter(), ",", |ctx: &Ctx, buf, (&sym, &(expr, _))| {
|
joined(self.stcs.iter(), "", |ctx: &Ctx, buf, (&sym, &(expr, _))| {
|
||||||
let key = ctx.get_sym(sym);
|
let key = ctx.get_sym(sym);
|
||||||
let val = ctx.get_ir(expr);
|
let val = ctx.get_ir(expr);
|
||||||
|
|
||||||
code!(
|
code!(
|
||||||
buf, ctx;
|
buf, ctx;
|
||||||
key ":Nix.withContext(\"while evaluating the attribute '" escaped(&key) "'\"," val.span() ",()=>(" val "))"
|
".set(" key ",Nix.withContext(\"while evaluating the attribute '" escaped(&key) "'\"," val.span() ",()=>(" val ")))"
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
"},{"
|
",new Map()"
|
||||||
joined(self.stcs.iter(), ",", |ctx: &Ctx, buf, (&sym, &(_, span))| {
|
joined(self.stcs.iter(), "", |ctx: &Ctx, buf, (&sym, &(_, span))| {
|
||||||
code!(buf, ctx; ctx.get_sym(sym) ":" span);
|
code!(buf, ctx; ".set(" ctx.get_sym(sym) "," span ")");
|
||||||
})
|
})
|
||||||
"},{dynKeys:["
|
",{dynKeys:["
|
||||||
joined(self.dyns.iter(), ",", |ctx: &Ctx, buf, (key, _, _)| {
|
joined(self.dyns.iter(), ",", |ctx: &Ctx, buf, (key, _, _)| {
|
||||||
code!(buf, ctx; ctx.get_ir(*key));
|
code!(buf, ctx; ctx.get_ir(*key));
|
||||||
})
|
})
|
||||||
@@ -608,21 +608,21 @@ impl<Ctx: CodegenContext> Compile<Ctx> for AttrSet {
|
|||||||
);
|
);
|
||||||
} else if !self.stcs.is_empty() {
|
} else if !self.stcs.is_empty() {
|
||||||
code!(buf, ctx;
|
code!(buf, ctx;
|
||||||
"Nix.mkAttrsWithPos({"
|
"Nix.mkAttrsWithPos(new Map()"
|
||||||
joined(self.stcs.iter(), ",", |ctx: &Ctx, buf, (&sym, &(expr, _))| {
|
joined(self.stcs.iter(), "", |ctx: &Ctx, buf, (&sym, &(expr, _))| {
|
||||||
let key = ctx.get_sym(sym);
|
let key = ctx.get_sym(sym);
|
||||||
let val = ctx.get_ir(expr);
|
let val = ctx.get_ir(expr);
|
||||||
|
|
||||||
code!(
|
code!(
|
||||||
buf, ctx;
|
buf, ctx;
|
||||||
key ":Nix.withContext(\"while evaluating the attribute '" escaped(&key) "'\"," val.span() ",()=>(" val "))"
|
".set(" key ",Nix.withContext(\"while evaluating the attribute '" escaped(&key) "'\"," val.span() ",()=>(" val ")))"
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
"},{"
|
",new Map()"
|
||||||
joined(self.stcs.iter(), ",", |ctx: &Ctx, buf, (&sym, &(_, span))| {
|
joined(self.stcs.iter(), "", |ctx: &Ctx, buf, (&sym, &(_, span))| {
|
||||||
code!(buf, ctx; ctx.get_sym(sym) ":" span);
|
code!(buf, ctx; ".set(" ctx.get_sym(sym) "," span ")");
|
||||||
})
|
})
|
||||||
"})"
|
")"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
code!(buf, ctx; "new Map()");
|
code!(buf, ctx; "new Map()");
|
||||||
|
|||||||
Reference in New Issue
Block a user