refactor(tvix/eval): extract attribute set inherit into helper
This will be re-used between the code paths for recursive/non-recursive sets, and it might even be possible to unify it with the logic for compiling `let inherit ...`. Change-Id: I960a061048ac583a6e932e11ff6e642d9fc3093e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6464 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
5eda0fbd86
commit
bb34665abd
1 changed files with 31 additions and 18 deletions
|
@ -17,7 +17,7 @@ mod scope;
|
||||||
|
|
||||||
use path_clean::PathClean;
|
use path_clean::PathClean;
|
||||||
use rnix::ast::{self, AstToken, HasEntry};
|
use rnix::ast::{self, AstToken, HasEntry};
|
||||||
use rowan::ast::AstNode;
|
use rowan::ast::{AstChildren, AstNode};
|
||||||
use smol_str::SmolStr;
|
use smol_str::SmolStr;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -451,25 +451,20 @@ impl Compiler<'_, '_> {
|
||||||
self.push_op(OpCode::OpList(Count(count)), &node);
|
self.push_op(OpCode::OpList(Count(count)), &node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile attribute set literals into equivalent bytecode.
|
/// Compiles inherited values in an attribute set. Inherited
|
||||||
///
|
/// values are *always* inherited from the outer scope, even if
|
||||||
/// This is complicated by a number of features specific to Nix
|
/// there is a matching name within a recursive attribute set.
|
||||||
/// attribute sets, most importantly:
|
fn compile_inherit_attrs(
|
||||||
///
|
&mut self,
|
||||||
/// 1. Keys can be dynamically constructed through interpolation.
|
slot: LocalIdx,
|
||||||
/// 2. Keys can refer to nested attribute sets.
|
inherits: AstChildren<ast::Inherit>,
|
||||||
/// 3. Attribute sets can (optionally) be recursive.
|
) -> usize {
|
||||||
fn compile_attr_set(&mut self, slot: LocalIdx, node: ast::AttrSet) {
|
// Count the number of inherited values, so that the outer
|
||||||
if node.rec_token().is_some() {
|
// constructor can emit the correct number of pairs when
|
||||||
todo!("recursive attribute sets are not yet implemented")
|
// constructing attribute sets.
|
||||||
}
|
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
|
|
||||||
// Inherits have to be evaluated before entering the scope of
|
for inherit in inherits {
|
||||||
// a potentially recursive attribute sets (i.e. we always
|
|
||||||
// inherit "from the outside").
|
|
||||||
for inherit in node.inherits() {
|
|
||||||
match inherit.from() {
|
match inherit.from() {
|
||||||
Some(from) => {
|
Some(from) => {
|
||||||
for ident in inherit.idents() {
|
for ident in inherit.idents() {
|
||||||
|
@ -508,6 +503,24 @@ impl Compiler<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compile attribute set literals into equivalent bytecode.
|
||||||
|
///
|
||||||
|
/// This is complicated by a number of features specific to Nix
|
||||||
|
/// attribute sets, most importantly:
|
||||||
|
///
|
||||||
|
/// 1. Keys can be dynamically constructed through interpolation.
|
||||||
|
/// 2. Keys can refer to nested attribute sets.
|
||||||
|
/// 3. Attribute sets can (optionally) be recursive.
|
||||||
|
fn compile_attr_set(&mut self, slot: LocalIdx, node: ast::AttrSet) {
|
||||||
|
if node.rec_token().is_some() {
|
||||||
|
todo!("recursive attribute sets are not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut count = self.compile_inherit_attrs(slot, node.inherits());
|
||||||
|
|
||||||
for kv in node.attrpath_values() {
|
for kv in node.attrpath_values() {
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue