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 rnix::ast::{self, AstToken, HasEntry};
|
||||
use rowan::ast::AstNode;
|
||||
use rowan::ast::{AstChildren, AstNode};
|
||||
use smol_str::SmolStr;
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -451,25 +451,20 @@ impl Compiler<'_, '_> {
|
|||
self.push_op(OpCode::OpList(Count(count)), &node);
|
||||
}
|
||||
|
||||
/// 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")
|
||||
}
|
||||
|
||||
/// Compiles inherited values in an attribute set. Inherited
|
||||
/// values are *always* inherited from the outer scope, even if
|
||||
/// there is a matching name within a recursive attribute set.
|
||||
fn compile_inherit_attrs(
|
||||
&mut self,
|
||||
slot: LocalIdx,
|
||||
inherits: AstChildren<ast::Inherit>,
|
||||
) -> usize {
|
||||
// Count the number of inherited values, so that the outer
|
||||
// constructor can emit the correct number of pairs when
|
||||
// constructing attribute sets.
|
||||
let mut count = 0;
|
||||
|
||||
// Inherits have to be evaluated before entering the scope of
|
||||
// a potentially recursive attribute sets (i.e. we always
|
||||
// inherit "from the outside").
|
||||
for inherit in node.inherits() {
|
||||
for inherit in inherits {
|
||||
match inherit.from() {
|
||||
Some(from) => {
|
||||
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() {
|
||||
count += 1;
|
||||
|
||||
|
|
Loading…
Reference in a new issue