Switch to new resolution system in ThemeRegistry

Nathan Sobo and Max Brunsfeld created

Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>

Change summary

Cargo.lock                      |   1 
zed/Cargo.toml                  |   1 
zed/assets/themes/_base.toml    |   6 
zed/src/theme.rs                |   2 
zed/src/theme/resolution.rs     | 441 ++++++++++++++++++++++++++++
zed/src/theme/resolve_tree.rs   | 275 -----------------
zed/src/theme/theme_registry.rs | 547 ----------------------------------
7 files changed, 464 insertions(+), 809 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -5917,6 +5917,7 @@ dependencies = [
  "http-auth-basic",
  "ignore",
  "image 0.23.14",
+ "indexmap",
  "lazy_static",
  "libc",
  "log",

zed/Cargo.toml 🔗

@@ -32,6 +32,7 @@ gpui = { path = "../gpui" }
 http-auth-basic = "0.1.3"
 ignore = "0.4"
 image = "0.23"
+indexmap = "1.6.2"
 lazy_static = "1.4.0"
 libc = "0.2"
 log = "0.4"

zed/assets/themes/_base.toml 🔗

@@ -67,6 +67,12 @@ sender = { extends = "$text.0", weight = "bold", margin.right = 8 }
 timestamp = "$text.2"
 padding.bottom = 6
 
+[chat_panel.pending_message]
+extends = "$chat_panel.message"
+body = { color = "$text.3.color" }
+sender = { color = "$text.3.color" }
+timestamp = { color = "$text.3.color" }
+
 [chat_panel.channel_select.item]
 padding = 4
 name = "$text.1"

zed/src/theme.rs 🔗

@@ -1,5 +1,5 @@
 mod highlight_map;
-mod resolve_tree;
+mod resolution;
 mod theme_registry;
 
 use anyhow::Result;

zed/src/theme/resolution.rs 🔗

@@ -0,0 +1,441 @@
+use anyhow::{anyhow, Result};
+use indexmap::IndexMap;
+use serde_json::Value;
+use std::{
+    cell::RefCell,
+    mem,
+    rc::{Rc, Weak},
+};
+
+pub fn resolve_references(value: Value) -> Result<Value> {
+    let tree = Tree::from_json(value)?;
+    tree.resolve()?;
+    tree.to_json()
+}
+
+#[derive(Clone)]
+enum Node {
+    Reference {
+        path: String,
+        parent: Option<Weak<RefCell<Node>>>,
+    },
+    Object {
+        base: Option<String>,
+        children: IndexMap<String, Tree>,
+        resolved: bool,
+        parent: Option<Weak<RefCell<Node>>>,
+    },
+    Array {
+        children: Vec<Tree>,
+        resolved: bool,
+        parent: Option<Weak<RefCell<Node>>>,
+    },
+    String(String),
+    Number(serde_json::Number),
+    Bool(bool),
+    Null,
+}
+
+#[derive(Clone)]
+struct Tree(Rc<RefCell<Node>>);
+
+impl Tree {
+    pub fn new(node: Node) -> Self {
+        Self(Rc::new(RefCell::new(node)))
+    }
+
+    fn from_json(value: Value) -> Result<Self> {
+        match value {
+            Value::String(value) => {
+                if let Some(path) = value.strip_prefix("$") {
+                    Ok(Self::new(Node::Reference {
+                        path: path.to_string(),
+                        parent: None,
+                    }))
+                } else {
+                    Ok(Self::new(Node::String(value)))
+                }
+            }
+            Value::Number(value) => Ok(Self::new(Node::Number(value))),
+            Value::Bool(value) => Ok(Self::new(Node::Bool(value))),
+            Value::Null => Ok(Self::new(Node::Null)),
+            Value::Object(object) => {
+                let tree = Self::new(Node::Object {
+                    base: Default::default(),
+                    children: Default::default(),
+                    resolved: false,
+                    parent: None,
+                });
+                let mut children = IndexMap::new();
+                let mut resolved = true;
+                let mut base = None;
+                for (key, value) in object.into_iter() {
+                    let value = if key == "extends" {
+                        if value.is_string() {
+                            if let Value::String(value) = value {
+                                base = value.strip_prefix("$").map(str::to_string);
+                                resolved = false;
+                                Self::new(Node::String(value))
+                            } else {
+                                unreachable!()
+                            }
+                        } else {
+                            Tree::from_json(value)?
+                        }
+                    } else {
+                        Tree::from_json(value)?
+                    };
+                    value
+                        .0
+                        .borrow_mut()
+                        .set_parent(Some(Rc::downgrade(&tree.0)));
+                    resolved &= value.is_resolved();
+                    children.insert(key.clone(), value);
+                }
+
+                *tree.0.borrow_mut() = Node::Object {
+                    base,
+                    children,
+                    resolved,
+                    parent: None,
+                };
+                Ok(tree)
+            }
+            Value::Array(elements) => {
+                let tree = Self::new(Node::Array {
+                    children: Default::default(),
+                    resolved: false,
+                    parent: None,
+                });
+
+                let mut children = Vec::new();
+                let mut resolved = true;
+                for element in elements {
+                    let child = Tree::from_json(element)?;
+                    child
+                        .0
+                        .borrow_mut()
+                        .set_parent(Some(Rc::downgrade(&tree.0)));
+                    resolved &= child.is_resolved();
+                    children.push(child);
+                }
+
+                *tree.0.borrow_mut() = Node::Array {
+                    children,
+                    resolved,
+                    parent: None,
+                };
+                Ok(tree)
+            }
+        }
+    }
+
+    fn to_json(&self) -> Result<Value> {
+        match &*self.0.borrow() {
+            Node::Reference { .. } => Err(anyhow!("unresolved tree")),
+            Node::String(value) => Ok(Value::String(value.clone())),
+            Node::Number(value) => Ok(Value::Number(value.clone())),
+            Node::Bool(value) => Ok(Value::Bool(*value)),
+            Node::Null => Ok(Value::Null),
+            Node::Object { children, .. } => {
+                let mut json_children = serde_json::Map::new();
+                for (key, value) in children {
+                    json_children.insert(key.clone(), value.to_json()?);
+                }
+                Ok(Value::Object(json_children))
+            }
+            Node::Array { children, .. } => {
+                let mut json_children = Vec::new();
+                for child in children {
+                    json_children.push(child.to_json()?);
+                }
+                Ok(Value::Array(json_children))
+            }
+        }
+    }
+
+    fn parent(&self) -> Option<Tree> {
+        match &*self.0.borrow() {
+            Node::Reference { parent, .. }
+            | Node::Object { parent, .. }
+            | Node::Array { parent, .. } => parent.as_ref().and_then(|p| p.upgrade()).map(Tree),
+            _ => None,
+        }
+    }
+
+    fn get(&self, path: &str) -> Result<Option<Tree>> {
+        let mut tree = self.clone();
+        for component in path.split('.') {
+            let node = tree.0.borrow();
+            match &*node {
+                Node::Object { children, .. } => {
+                    if let Some(subtree) = children.get(component).cloned() {
+                        drop(node);
+                        tree = subtree;
+                    } else {
+                        return Err(anyhow!(
+                            "key \"{}\" does not exist in path \"{}\"",
+                            component,
+                            path
+                        ));
+                    }
+                }
+                Node::Reference { .. } => return Ok(None),
+                Node::Array { .. }
+                | Node::String(_)
+                | Node::Number(_)
+                | Node::Bool(_)
+                | Node::Null => {
+                    return Err(anyhow!(
+                        "key \"{}\" in path \"{}\" is not an object",
+                        component,
+                        path
+                    ))
+                }
+            }
+        }
+
+        Ok(Some(tree))
+    }
+
+    fn is_resolved(&self) -> bool {
+        match &*self.0.borrow() {
+            Node::Reference { .. } => false,
+            Node::Object { resolved, .. } | Node::Array { resolved, .. } => *resolved,
+            Node::String(_) | Node::Number(_) | Node::Bool(_) | Node::Null => true,
+        }
+    }
+
+    fn update_resolved(&self) {
+        match &mut *self.0.borrow_mut() {
+            Node::Object {
+                resolved, children, ..
+            } => {
+                *resolved = children.values().all(|c| c.is_resolved());
+            }
+            Node::Array {
+                resolved, children, ..
+            } => {
+                *resolved = children.iter().all(|c| c.is_resolved());
+            }
+            _ => {}
+        }
+    }
+
+    pub fn resolve(&self) -> Result<()> {
+        let mut unresolved = vec![self.clone()];
+        let mut made_progress = true;
+
+        while made_progress && !unresolved.is_empty() {
+            made_progress = false;
+            for mut tree in mem::take(&mut unresolved) {
+                made_progress |= tree.resolve_subtree(self, &mut unresolved)?;
+                if tree.is_resolved() {
+                    while let Some(parent) = tree.parent() {
+                        parent.update_resolved();
+                        tree = parent;
+                    }
+                }
+            }
+        }
+
+        if unresolved.is_empty() {
+            Ok(())
+        } else {
+            Err(anyhow!("tree contains cycles"))
+        }
+    }
+
+    fn resolve_subtree(&self, root: &Tree, unresolved: &mut Vec<Tree>) -> Result<bool> {
+        let mut made_progress = false;
+        let borrow = self.0.borrow();
+        match &*borrow {
+            Node::Reference { path, parent } => {
+                if let Some(subtree) = root.get(&path)? {
+                    if subtree.is_resolved() {
+                        let parent = parent.clone();
+                        drop(borrow);
+                        let mut new_node = subtree.0.borrow().clone();
+                        new_node.set_parent(parent);
+                        *self.0.borrow_mut() = new_node;
+                        Ok(true)
+                    } else {
+                        unresolved.push(self.clone());
+                        Ok(false)
+                    }
+                } else {
+                    unresolved.push(self.clone());
+                    Ok(false)
+                }
+            }
+            Node::Object {
+                base,
+                children,
+                resolved,
+                ..
+            } => {
+                if *resolved {
+                    Ok(false)
+                } else {
+                    let mut children_resolved = true;
+                    for child in children.values() {
+                        made_progress |= child.resolve_subtree(root, unresolved)?;
+                        children_resolved &= child.is_resolved();
+                    }
+
+                    if children_resolved {
+                        let mut has_base = false;
+                        let mut resolved_base = None;
+                        if let Some(base) = base {
+                            has_base = true;
+                            if let Some(base) = root.get(base)? {
+                                if base.is_resolved() {
+                                    resolved_base = Some(base);
+                                }
+                            }
+                        }
+
+                        drop(borrow);
+
+                        if let Some(base) = resolved_base.as_ref() {
+                            self.extend_from(&base);
+                        }
+
+                        if let Node::Object { resolved, .. } = &mut *self.0.borrow_mut() {
+                            if has_base {
+                                if resolved_base.is_some() {
+                                    *resolved = true;
+                                } else {
+                                    unresolved.push(self.clone());
+                                }
+                            } else {
+                                *resolved = true;
+                            }
+                        }
+                    }
+
+                    Ok(made_progress)
+                }
+            }
+            Node::Array {
+                children, resolved, ..
+            } => {
+                if *resolved {
+                    Ok(false)
+                } else {
+                    let mut children_resolved = true;
+                    for child in children.iter() {
+                        made_progress |= child.resolve_subtree(root, unresolved)?;
+                        children_resolved &= child.is_resolved();
+                    }
+
+                    if children_resolved {
+                        drop(borrow);
+
+                        if let Node::Array { resolved, .. } = &mut *self.0.borrow_mut() {
+                            *resolved = true;
+                        }
+                    }
+
+                    Ok(made_progress)
+                }
+            }
+            Node::String(_) | Node::Number(_) | Node::Bool(_) | Node::Null => {
+                return Ok(false);
+            }
+        }
+    }
+
+    fn extend_from(&self, base: &Tree) {
+        if Rc::ptr_eq(&self.0, &base.0) {
+            return;
+        }
+
+        if let (
+            Node::Object { children, .. },
+            Node::Object {
+                children: base_children,
+                ..
+            },
+        ) = (&mut *self.0.borrow_mut(), &*base.0.borrow())
+        {
+            for (key, base_value) in base_children {
+                if let Some(value) = children.get(key) {
+                    value.extend_from(base_value);
+                } else {
+                    let base_value = base_value.clone();
+                    base_value
+                        .0
+                        .borrow_mut()
+                        .set_parent(Some(Rc::downgrade(&self.0)));
+                    children.insert(key.clone(), base_value);
+                }
+            }
+        }
+    }
+}
+
+impl Node {
+    fn set_parent(&mut self, new_parent: Option<Weak<RefCell<Node>>>) {
+        match self {
+            Node::Reference { parent, .. }
+            | Node::Object { parent, .. }
+            | Node::Array { parent, .. } => *parent = new_parent,
+            _ => {}
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_references() {
+        let json = serde_json::json!({
+            "a": {
+                "x": "$b.d"
+            },
+            "b": {
+                "c": "$a",
+                "d": "$e.f"
+            },
+            "e": {
+                "extends": "$a",
+                "f": "1"
+            }
+        });
+
+        assert_eq!(
+            resolve_references(json).unwrap(),
+            serde_json::json!({
+            "e": {
+              "f": "1",
+              "x": "1"
+            },
+            "a": {
+              "x": "1"
+            },
+            "b": {
+              "c": {
+                "x": "1"
+              },
+              "d": "1"
+            }})
+        )
+    }
+
+    #[test]
+    fn test_cycles() {
+        let json = serde_json::json!({
+            "a": {
+                "b": "$c.d"
+            },
+            "c": {
+                "d": "$a.b",
+            },
+        });
+
+        assert!(resolve_references(json).is_err());
+    }
+}

zed/src/theme/resolve_tree.rs 🔗

@@ -1,275 +0,0 @@
-use anyhow::{anyhow, Result};
-use serde_json::Value;
-use std::{
-    cell::RefCell,
-    collections::HashMap,
-    mem,
-    rc::{Rc, Weak},
-};
-
-pub fn resolve(value: Value) -> Result<Value> {
-    let tree = Tree::from_json(value)?;
-    tree.resolve()?;
-    tree.to_json()
-}
-
-#[derive(Clone)]
-enum Node {
-    Reference {
-        path: String,
-        parent: Option<Weak<RefCell<Node>>>,
-    },
-    Object {
-        base: Option<String>,
-        children: HashMap<String, Tree>,
-        resolved: bool,
-        parent: Option<Weak<RefCell<Node>>>,
-    },
-    String {
-        value: String,
-        parent: Option<Weak<RefCell<Node>>>,
-    },
-}
-
-#[derive(Clone)]
-struct Tree(Rc<RefCell<Node>>);
-
-impl Tree {
-    pub fn new(node: Node) -> Self {
-        Self(Rc::new(RefCell::new(node)))
-    }
-
-    fn from_json(value: Value) -> Result<Self> {
-        match value {
-            Value::String(s) => {
-                if let Some(path) = s.strip_prefix("$") {
-                    Ok(Self::new(Node::Reference {
-                        path: path.to_string(),
-                        parent: None,
-                    }))
-                } else {
-                    Ok(Self::new(Node::String {
-                        value: s,
-                        parent: None,
-                    }))
-                }
-            }
-            Value::Object(object) => {
-                let mut tree = Self::new(Node::Object {
-                    base: Default::default(),
-                    children: Default::default(),
-                    resolved: false,
-                    parent: None,
-                });
-                let mut children = HashMap::new();
-                let mut resolved = true;
-                let mut base = None;
-                for (key, value) in object.into_iter() {
-                    if key == "extends" {
-                        if let Value::String(s) = value {
-                            base = Some(s);
-                            resolved = false;
-                        }
-                    } else {
-                        let value = Tree::from_json(value)?;
-                        value
-                            .0
-                            .borrow_mut()
-                            .set_parent(Some(Rc::downgrade(&tree.0)));
-                        resolved &= value.is_resolved();
-                        children.insert(key.clone(), value);
-                    }
-                }
-
-                *tree.0.borrow_mut() = Node::Object {
-                    base,
-                    children,
-                    resolved,
-                    parent: None,
-                };
-                Ok(tree)
-            }
-            _ => return Err(anyhow!("unsupported json type")),
-        }
-    }
-
-    fn to_json(&self) -> Result<Value> {
-        match &*self.0.borrow() {
-            Node::Reference { .. } => Err(anyhow!("unresolved tree")),
-            Node::String { value, .. } => Ok(Value::String(value.clone())),
-            Node::Object { children, .. } => {
-                let mut json_children = serde_json::Map::new();
-                for (key, value) in children {
-                    json_children.insert(key.clone(), value.to_json()?);
-                }
-                Ok(Value::Object(json_children))
-            }
-            _ => unimplemented!(),
-        }
-    }
-
-    fn parent(&self) -> Option<Tree> {
-        match &*self.0.borrow() {
-            Node::Reference { parent, .. }
-            | Node::Object { parent, .. }
-            | Node::String { parent, .. } => parent.as_ref().and_then(|p| p.upgrade()).map(Tree),
-        }
-    }
-
-    fn get(&self, path: &str) -> Result<Option<Tree>> {
-        let mut tree = self.clone();
-        for component in path.split('.') {
-            let node = tree.0.borrow();
-            match &*node {
-                Node::Object { children, .. } => {
-                    if let Some(subtree) = children.get(component).cloned() {
-                        drop(node);
-                        tree = subtree;
-                    } else {
-                        return Err(anyhow!("key does not exist"));
-                    }
-                }
-                Node::Reference { .. } => return Ok(None),
-                Node::String { .. } => return Err(anyhow!("component is not an object")),
-            }
-        }
-
-        Ok(Some(tree))
-    }
-
-    fn is_resolved(&self) -> bool {
-        match &*self.0.borrow() {
-            Node::Reference { .. } => false,
-            Node::Object { resolved, .. } => *resolved,
-            Node::String { .. } => true,
-        }
-    }
-
-    fn update_resolved(&self) {
-        match &mut *self.0.borrow_mut() {
-            Node::Object {
-                resolved, children, ..
-            } => {
-                *resolved = children.values().all(|c| c.is_resolved());
-            }
-            _ => {}
-        }
-    }
-
-    pub fn resolve(&self) -> Result<()> {
-        let mut unresolved = vec![self.clone()];
-        let mut made_progress = true;
-        while made_progress && !unresolved.is_empty() {
-            made_progress = false;
-            dbg!("===========");
-            for mut tree in mem::take(&mut unresolved) {
-                made_progress |= tree.resolve_subtree(self, &mut unresolved)?;
-                if tree.is_resolved() {
-                    while let Some(parent) = tree.parent() {
-                        parent.update_resolved();
-                        tree = parent;
-                    }
-                }
-            }
-        }
-
-        if unresolved.is_empty() {
-            Ok(())
-        } else {
-            Err(anyhow!("could not resolve tree"))
-        }
-    }
-
-    fn resolve_subtree(&self, root: &Tree, unresolved: &mut Vec<Tree>) -> Result<bool> {
-        let mut made_progress = false;
-        let borrow = self.0.borrow();
-        match &*borrow {
-            Node::Reference { path, parent } => {
-                print!("entering reference ${}: ", path);
-                if let Some(subtree) = root.get(&path)? {
-                    if subtree.is_resolved() {
-                        println!("resolved");
-                        let parent = parent.clone();
-                        drop(borrow);
-                        let mut new_node = subtree.0.borrow().clone();
-                        new_node.set_parent(parent);
-                        *self.0.borrow_mut() = new_node;
-                        Ok(true)
-                    } else {
-                        println!("unresolved (but existing)");
-                        unresolved.push(self.clone());
-                        Ok(false)
-                    }
-                } else {
-                    println!("unresolved (referant does not exist)");
-                    unresolved.push(self.clone());
-                    Ok(false)
-                }
-            }
-            Node::Object {
-                base,
-                children,
-                resolved,
-                ..
-            } => {
-                if *resolved {
-                    println!("already resolved");
-                    Ok(false)
-                } else {
-                    let mut children_resolved = true;
-                    for (key, child) in children.iter() {
-                        println!("resolving subtree {}", key);
-                        made_progress |= child.resolve_subtree(root, unresolved)?;
-                        children_resolved &= child.is_resolved();
-                    }
-
-                    if children_resolved {
-                        drop(borrow);
-                        if let Node::Object { resolved, .. } = &mut *self.0.borrow_mut() {
-                            *resolved = true;
-                        }
-                    }
-
-                    Ok(made_progress)
-                }
-            }
-            Node::String { value, .. } => {
-                println!("terminating at string: {}", value);
-                return Ok(false);
-            }
-        }
-    }
-}
-
-impl Node {
-    fn set_parent(&mut self, new_parent: Option<Weak<RefCell<Node>>>) {
-        match self {
-            Node::Reference { parent, .. }
-            | Node::Object { parent, .. }
-            | Node::String { parent, .. } => *parent = new_parent,
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-
-    #[test]
-    fn test_basic() {
-        let json = serde_json::json!({
-            "a": {
-                "x": "$b.d"
-            },
-            "b": {
-                "c": "$a",
-                "d": "$e.f"
-            },
-            "e": {
-                "f": "1"
-            }
-        });
-
-        dbg!(resolve(json).unwrap());
-    }
-}

zed/src/theme/theme_registry.rs 🔗

@@ -1,8 +1,9 @@
-use anyhow::{anyhow, Context, Result};
+use super::resolution::resolve_references;
+use anyhow::{Context, Result};
 use gpui::{fonts, AssetSource, FontCache};
 use parking_lot::Mutex;
 use serde_json::{Map, Value};
-use std::{collections::HashMap, fmt, mem, sync::Arc};
+use std::{collections::HashMap, sync::Arc};
 
 use super::Theme;
 
@@ -13,30 +14,6 @@ pub struct ThemeRegistry {
     font_cache: Arc<FontCache>,
 }
 
-#[derive(Default)]
-struct KeyPathReferenceSet {
-    references: Vec<KeyPathReference>,
-    reference_ids_by_source: Vec<usize>,
-    reference_ids_by_target: Vec<usize>,
-    dependencies: Vec<(usize, usize)>,
-    dependency_counts: Vec<usize>,
-}
-
-#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
-struct KeyPathReference {
-    target: KeyPath,
-    source: KeyPath,
-}
-
-#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
-struct KeyPath(Vec<Key>);
-
-#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
-enum Key {
-    Array(usize),
-    Object(String),
-}
-
 impl ThemeRegistry {
     pub fn new(source: impl AssetSource, font_cache: Arc<FontCache>) -> Arc<Self> {
         Arc::new(Self {
@@ -111,41 +88,15 @@ impl ThemeRegistry {
             }
         }
 
+        let mut theme_data = Value::Object(theme_data);
+
         // Find all of the key path references in the object, and then sort them according
         // to their dependencies.
         if evaluate_references {
-            let mut key_path = KeyPath::default();
-            let mut references = KeyPathReferenceSet::default();
-            for (key, value) in theme_data.iter() {
-                key_path.0.push(Key::Object(key.clone()));
-                find_references(value, &mut key_path, &mut references);
-                key_path.0.pop();
-            }
-            let sorted_references = references
-                .top_sort()
-                .map_err(|key_paths| anyhow!("cycle for key paths: {:?}", key_paths))?;
-
-            // Now update objects to include the fields of objects they extend
-            for KeyPathReference { source, target } in sorted_references {
-                if let Some(source) = value_at(&mut theme_data, &source).cloned() {
-                    let target = value_at(&mut theme_data, &target).unwrap();
-                    if let Value::Object(target_object) = target.take() {
-                        if let Value::Object(mut source_object) = source {
-                            deep_merge_json(&mut source_object, target_object);
-                            *target = Value::Object(source_object);
-                        } else {
-                            Err(anyhow!("extended key path {} is not an object", source))?;
-                        }
-                    } else {
-                        *target = source;
-                    }
-                } else {
-                    Err(anyhow!("invalid key path '{}'", source))?;
-                }
-            }
+            theme_data = resolve_references(theme_data)?;
         }
 
-        let result = Arc::new(Value::Object(theme_data));
+        let result = Arc::new(theme_data);
         self.theme_data
             .lock()
             .insert(name.to_string(), result.clone());
@@ -154,311 +105,6 @@ impl ThemeRegistry {
     }
 }
 
-impl KeyPathReferenceSet {
-    fn insert(&mut self, reference: KeyPathReference) {
-        let id = self.references.len();
-        let source_ix = self
-            .reference_ids_by_source
-            .binary_search_by_key(&&reference.source, |id| &self.references[*id].source)
-            .unwrap_or_else(|i| i);
-        let target_ix = self
-            .reference_ids_by_target
-            .binary_search_by_key(&&reference.target, |id| &self.references[*id].target)
-            .unwrap_or_else(|i| i);
-
-        self.populate_dependencies(id, &reference);
-        self.reference_ids_by_source.insert(source_ix, id);
-        self.reference_ids_by_target.insert(target_ix, id);
-        self.references.push(reference);
-    }
-
-    fn top_sort(mut self) -> Result<Vec<KeyPathReference>, Vec<KeyPath>> {
-        let mut results = Vec::with_capacity(self.references.len());
-        let mut root_ids = Vec::with_capacity(self.references.len());
-
-        // Find the initial set of references that have no dependencies.
-        for (id, dep_count) in self.dependency_counts.iter().enumerate() {
-            if *dep_count == 0 {
-                root_ids.push(id);
-            }
-        }
-
-        while results.len() < root_ids.len() {
-            // Just to guarantee a stable result when the inputs are randomized,
-            // sort references lexicographically in absence of any dependency relationship.
-            root_ids[results.len()..].sort_by_key(|id| &self.references[*id]);
-
-            let root_id = root_ids[results.len()];
-            let root = mem::take(&mut self.references[root_id]);
-            results.push(root);
-
-            // Remove this reference as a dependency from any of its dependent references.
-            if let Ok(dep_ix) = self
-                .dependencies
-                .binary_search_by_key(&root_id, |edge| edge.0)
-            {
-                let mut first_dep_ix = dep_ix;
-                let mut last_dep_ix = dep_ix + 1;
-                while first_dep_ix > 0 && self.dependencies[first_dep_ix - 1].0 == root_id {
-                    first_dep_ix -= 1;
-                }
-                while last_dep_ix < self.dependencies.len()
-                    && self.dependencies[last_dep_ix].0 == root_id
-                {
-                    last_dep_ix += 1;
-                }
-
-                // If any reference no longer has any dependencies, then then mark it as a root.
-                // Preserve the references' original order where possible.
-                for (_, successor_id) in self.dependencies.drain(first_dep_ix..last_dep_ix) {
-                    self.dependency_counts[successor_id] -= 1;
-                    if self.dependency_counts[successor_id] == 0 {
-                        root_ids.push(successor_id);
-                    }
-                }
-            }
-        }
-
-        // If any references never became roots, then there are reference cycles
-        // in the set. Return an error containing all of the key paths that are
-        // directly involved in cycles.
-        if results.len() < self.references.len() {
-            let mut cycle_ref_ids = (0..self.references.len())
-                .filter(|id| !root_ids.contains(id))
-                .collect::<Vec<_>>();
-
-            // Iteratively remove any references that have no dependencies,
-            // so that the error will only indicate which key paths are directly
-            // involved in the cycles.
-            let mut done = false;
-            while !done {
-                done = true;
-                cycle_ref_ids.retain(|id| {
-                    if self.dependencies.iter().any(|dep| dep.0 == *id) {
-                        true
-                    } else {
-                        done = false;
-                        self.dependencies.retain(|dep| dep.1 != *id);
-                        false
-                    }
-                });
-            }
-
-            let mut cycle_key_paths = Vec::new();
-            for id in cycle_ref_ids {
-                let reference = &self.references[id];
-                cycle_key_paths.push(reference.target.clone());
-                cycle_key_paths.push(reference.source.clone());
-            }
-            cycle_key_paths.sort_unstable();
-            return Err(cycle_key_paths);
-        }
-
-        Ok(results)
-    }
-
-    fn populate_dependencies(&mut self, new_id: usize, new_reference: &KeyPathReference) {
-        self.dependency_counts.push(0);
-
-        // If an existing reference's source path starts with the new reference's
-        // target path, then insert this new reference before that existing reference.
-        for id in Self::reference_ids_for_key_path(
-            &new_reference.target.0,
-            &self.references,
-            &self.reference_ids_by_source,
-            KeyPathReference::source,
-            KeyPath::starts_with,
-        ) {
-            Self::add_dependency(
-                (new_id, id),
-                &mut self.dependencies,
-                &mut self.dependency_counts,
-            );
-        }
-
-        // If an existing reference's target path starts with the new reference's
-        // source path, then insert this new reference after that existing reference.
-        for id in Self::reference_ids_for_key_path(
-            &new_reference.source.0,
-            &self.references,
-            &self.reference_ids_by_target,
-            KeyPathReference::target,
-            KeyPath::starts_with,
-        ) {
-            Self::add_dependency(
-                (id, new_id),
-                &mut self.dependencies,
-                &mut self.dependency_counts,
-            );
-        }
-
-        // If an existing reference's source path is a prefix of the new reference's
-        // target path, then insert this new reference before that existing reference.
-        for prefix in new_reference.target.prefixes() {
-            for id in Self::reference_ids_for_key_path(
-                prefix,
-                &self.references,
-                &self.reference_ids_by_source,
-                KeyPathReference::source,
-                PartialEq::eq,
-            ) {
-                Self::add_dependency(
-                    (new_id, id),
-                    &mut self.dependencies,
-                    &mut self.dependency_counts,
-                );
-            }
-        }
-
-        // If an existing reference's target path is a prefix of the new reference's
-        // source path, then insert this new reference after that existing reference.
-        for prefix in new_reference.source.prefixes() {
-            for id in Self::reference_ids_for_key_path(
-                prefix,
-                &self.references,
-                &self.reference_ids_by_target,
-                KeyPathReference::target,
-                PartialEq::eq,
-            ) {
-                Self::add_dependency(
-                    (id, new_id),
-                    &mut self.dependencies,
-                    &mut self.dependency_counts,
-                );
-            }
-        }
-
-        // If an existing reference's target path is a prefix of the new reference's target path,
-        // then insert this new reference before that existing reference.
-        for prefix in new_reference.target.prefixes() {
-            for id in Self::reference_ids_for_key_path(
-                prefix,
-                &self.references,
-                &self.reference_ids_by_target,
-                KeyPathReference::target,
-                KeyPath::starts_with,
-            ) {
-                Self::add_dependency(
-                    (new_id, id),
-                    &mut self.dependencies,
-                    &mut self.dependency_counts,
-                );
-            }
-        }
-    }
-
-    // Find all existing references that satisfy a given predicate with respect
-    // to a given key path. Use a sorted array of reference ids in order to avoid
-    // performing unnecessary comparisons.
-    fn reference_ids_for_key_path<'a>(
-        key_path: &[Key],
-        references: &[KeyPathReference],
-        sorted_reference_ids: &'a [usize],
-        reference_attribute: impl Fn(&KeyPathReference) -> &KeyPath,
-        predicate: impl Fn(&KeyPath, &[Key]) -> bool,
-    ) -> impl Iterator<Item = usize> + 'a {
-        let ix = sorted_reference_ids
-            .binary_search_by_key(&key_path, |id| &reference_attribute(&references[*id]).0)
-            .unwrap_or_else(|i| i);
-
-        let mut start_ix = ix;
-        while start_ix > 0 {
-            let reference_id = sorted_reference_ids[start_ix - 1];
-            let reference = &references[reference_id];
-            if !predicate(&reference_attribute(reference), key_path) {
-                break;
-            }
-            start_ix -= 1;
-        }
-
-        let mut end_ix = ix;
-        while end_ix < sorted_reference_ids.len() {
-            let reference_id = sorted_reference_ids[end_ix];
-            let reference = &references[reference_id];
-            if !predicate(&reference_attribute(reference), key_path) {
-                break;
-            }
-            end_ix += 1;
-        }
-
-        sorted_reference_ids[start_ix..end_ix].iter().copied()
-    }
-
-    fn add_dependency(
-        (predecessor, successor): (usize, usize),
-        dependencies: &mut Vec<(usize, usize)>,
-        dependency_counts: &mut Vec<usize>,
-    ) {
-        let dependency = (predecessor, successor);
-        if let Err(i) = dependencies.binary_search(&dependency) {
-            dependencies.insert(i, dependency);
-        }
-        dependency_counts[successor] += 1;
-    }
-}
-
-impl KeyPathReference {
-    fn source(&self) -> &KeyPath {
-        &self.source
-    }
-
-    fn target(&self) -> &KeyPath {
-        &self.target
-    }
-}
-
-impl KeyPath {
-    fn new(string: &str) -> Self {
-        Self(
-            string
-                .split(".")
-                .map(|key| Key::Object(key.to_string()))
-                .collect(),
-        )
-    }
-
-    fn starts_with(&self, other: &[Key]) -> bool {
-        self.0.starts_with(&other)
-    }
-
-    fn prefixes(&self) -> impl Iterator<Item = &[Key]> {
-        (1..self.0.len()).map(move |end_ix| &self.0[0..end_ix])
-    }
-}
-
-impl PartialEq<[Key]> for KeyPath {
-    fn eq(&self, other: &[Key]) -> bool {
-        self.0.eq(other)
-    }
-}
-
-impl fmt::Debug for KeyPathReference {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "KeyPathReference {{ {} <- {} }}",
-            self.target, self.source
-        )
-    }
-}
-
-impl fmt::Display for KeyPath {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        for (i, key) in self.0.iter().enumerate() {
-            match key {
-                Key::Array(index) => write!(f, "[{}]", index)?,
-                Key::Object(key) => {
-                    if i > 0 {
-                        ".".fmt(f)?;
-                    }
-                    key.fmt(f)?;
-                }
-            }
-        }
-        Ok(())
-    }
-}
-
 fn deep_merge_json(base: &mut Map<String, Value>, extension: Map<String, Value>) {
     for (key, extension_value) in extension {
         if let Value::Object(extension_object) = extension_value {
@@ -473,69 +119,12 @@ fn deep_merge_json(base: &mut Map<String, Value>, extension: Map<String, Value>)
     }
 }
 
-fn find_references(value: &Value, key_path: &mut KeyPath, references: &mut KeyPathReferenceSet) {
-    match value {
-        Value::Array(vec) => {
-            for (ix, value) in vec.iter().enumerate() {
-                key_path.0.push(Key::Array(ix));
-                find_references(value, key_path, references);
-                key_path.0.pop();
-            }
-        }
-        Value::Object(map) => {
-            for (key, value) in map.iter() {
-                if key == "extends" {
-                    if let Some(source_path) = value.as_str().and_then(|s| s.strip_prefix("$")) {
-                        references.insert(KeyPathReference {
-                            source: KeyPath::new(source_path),
-                            target: key_path.clone(),
-                        });
-                    }
-                } else {
-                    key_path.0.push(Key::Object(key.to_string()));
-                    find_references(value, key_path, references);
-                    key_path.0.pop();
-                }
-            }
-        }
-        Value::String(string) => {
-            if let Some(source_path) = string.strip_prefix("$") {
-                references.insert(KeyPathReference {
-                    source: KeyPath::new(source_path),
-                    target: key_path.clone(),
-                });
-            }
-        }
-        _ => {}
-    }
-}
-
-fn value_at<'a>(object: &'a mut Map<String, Value>, key_path: &KeyPath) -> Option<&'a mut Value> {
-    let mut key_path = key_path.0.iter();
-    if let Some(Key::Object(first_key)) = key_path.next() {
-        let mut cur_value = object.get_mut(first_key);
-        for key in key_path {
-            if let Some(value) = cur_value {
-                match key {
-                    Key::Array(ix) => cur_value = value.get_mut(ix),
-                    Key::Object(key) => cur_value = value.get_mut(key),
-                }
-            } else {
-                return None;
-            }
-        }
-        cur_value
-    } else {
-        None
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
     use crate::{test::test_app_state, theme::DEFAULT_THEME_NAME};
+    use anyhow::anyhow;
     use gpui::MutableAppContext;
-    use rand::{prelude::StdRng, Rng};
 
     #[gpui::test]
     fn test_bundled_themes(cx: &mut MutableAppContext) {
@@ -593,6 +182,12 @@ mod tests {
 
         let registry = ThemeRegistry::new(assets, cx.font_cache().clone());
         let theme_data = registry.load("light", true).unwrap();
+
+        println!(
+            "{}",
+            serde_json::to_string_pretty(theme_data.as_ref()).unwrap()
+        );
+
         assert_eq!(
             theme_data.as_ref(),
             &serde_json::json!({
@@ -669,120 +264,6 @@ mod tests {
         );
     }
 
-    #[test]
-    fn test_key_path_reference_set_simple() {
-        let input_references = build_refs(&[
-            ("r", "a"),
-            ("a.b.c", "d"),
-            ("d.e", "f"),
-            ("t.u", "v"),
-            ("v.w", "x"),
-            ("v.y", "x"),
-            ("d.h", "i"),
-            ("v.z", "x"),
-            ("f.g", "d.h"),
-        ]);
-        let expected_references = build_refs(&[
-            ("d.h", "i"),
-            ("f.g", "d.h"),
-            ("d.e", "f"),
-            ("a.b.c", "d"),
-            ("r", "a"),
-            ("v.w", "x"),
-            ("v.y", "x"),
-            ("v.z", "x"),
-            ("t.u", "v"),
-        ])
-        .collect::<Vec<_>>();
-
-        let mut reference_set = KeyPathReferenceSet::default();
-        for reference in input_references {
-            reference_set.insert(reference);
-        }
-        assert_eq!(reference_set.top_sort().unwrap(), expected_references);
-    }
-
-    #[test]
-    fn test_key_path_reference_set_with_cycles() {
-        let input_references = build_refs(&[
-            ("x", "a.b"),
-            ("y", "x.c"),
-            ("a.b.c", "d.e"),
-            ("d.e.f", "g.h"),
-            ("g.h.i", "a"),
-        ]);
-
-        let mut reference_set = KeyPathReferenceSet::default();
-        for reference in input_references {
-            reference_set.insert(reference);
-        }
-
-        assert_eq!(
-            reference_set.top_sort().unwrap_err(),
-            &[
-                KeyPath::new("a"),
-                KeyPath::new("a.b.c"),
-                KeyPath::new("d.e"),
-                KeyPath::new("d.e.f"),
-                KeyPath::new("g.h"),
-                KeyPath::new("g.h.i"),
-            ]
-        );
-    }
-
-    #[gpui::test(iterations = 20)]
-    async fn test_key_path_reference_set_random(mut rng: StdRng) {
-        let examples: &[&[_]] = &[
-            // &[
-            //     ("n.d.h", "i"),
-            //     ("f.g", "n.d.h"),
-            //     ("n.d.e", "f"),
-            //     ("a.b.c", "n.d"),
-            //     ("r", "a"),
-            //     ("q.q.q", "r.s"),
-            //     ("r.t", "q"),
-            //     ("x.x", "r.r"),
-            //     ("v.w", "x"),
-            //     ("v.y", "x"),
-            //     ("v.z", "x"),
-            //     ("t.u", "v"),
-            // ],
-            &[
-                ("w.x.y.z", "t.u.z"),
-                ("x", "w.x"),
-                ("a.b.c1", "x.b1.c"),
-                ("a.b.c2", "x.b2.c"),
-            ],
-            &[
-                ("x.y.z", "m.n.n.o.p"),
-                ("x.y", "m.n.n.o.q"),
-                ("u.v.w", "x.y.z"),
-                ("a.b.c.d.e", "u.v"),
-                ("a.b.c.d.f", "u.v"),
-                ("a.b.c.d.g", "u.v"),
-                ("a.b.c.d", "u.v"),
-            ],
-        ];
-
-        for example in examples {
-            let expected_references = build_refs(example).collect::<Vec<_>>();
-            let mut input_references = expected_references.clone();
-            input_references.sort_by_key(|_| rng.gen_range(0..1000));
-            let mut reference_set = KeyPathReferenceSet::default();
-            for reference in input_references {
-                reference_set.insert(reference);
-            }
-            assert_eq!(reference_set.top_sort().unwrap(), expected_references);
-        }
-    }
-
-    fn build_refs<'a>(rows: &'a [(&str, &str)]) -> impl Iterator<Item = KeyPathReference> + 'a {
-        rows.iter().map(|(target, source)| KeyPathReference {
-            target: KeyPath::new(target),
-            source: KeyPath::new(source),
-        })
-    }
-
     struct TestAssets(&'static [(&'static str, &'static str)]);
 
     impl AssetSource for TestAssets {