diff --git a/src/assets/build_assets.rs b/src/assets/build_assets.rs index 1c7b0fc4..357fc2e7 100644 --- a/src/assets/build_assets.rs +++ b/src/assets/build_assets.rs @@ -16,6 +16,9 @@ type OtherSyntaxLookup<'a> = HashMap; /// Used to look up what dependencies a given [SyntaxDefinition] has type SyntaxToDependencies = HashMap>; +/// Used to look up what other [SyntaxDefinition]s depend on a given [SyntaxDefinition] +type SyntaxToDependents<'a> = HashMap>; + /// Represents some other `*.sublime-syntax` file, i.e. another [SyntaxDefinition]. #[derive(Debug, Eq, PartialEq, Clone, Hash)] enum OtherSyntax { @@ -215,7 +218,8 @@ fn build_minimal_syntax_sets( let syntaxes = syntax_set_builder.syntaxes(); // Build the data structures we need for dependency resolution - let (other_syntax_lookup, syntax_to_dependencies) = generate_maps(syntaxes); + let (other_syntax_lookup, syntax_to_dependencies, syntax_to_dependents) = + generate_maps(syntaxes); // Create one minimal SyntaxSet from each (non-hidden) SyntaxDefinition syntaxes.iter().filter_map(move |syntax| { @@ -224,7 +228,12 @@ fn build_minimal_syntax_sets( } let mut builder = SyntaxSetDependencyBuilder::new(); - builder.add_with_dependencies(syntax, &other_syntax_lookup, &syntax_to_dependencies); + builder.add_with_dependencies( + syntax, + &other_syntax_lookup, + &syntax_to_dependencies, + &syntax_to_dependents, + ); let syntax_set = builder.build(); if std::env::var("BAT_PRINT_SYNTAX_DEPENDENCIES").is_ok() { @@ -237,22 +246,48 @@ fn build_minimal_syntax_sets( }) } -/// In order to analyze dependencies, we need two key pieces of data. -/// First, when we have a [OtherSyntax], we need to know what [SyntaxDefinition] that -/// corresponds to. Second, when we have a [SyntaxDefinition], we need to know -/// what dependencies it has. This functions generates that data for each syntax. -fn generate_maps(syntaxes: &[SyntaxDefinition]) -> (OtherSyntaxLookup, SyntaxToDependencies) { +/// In order to analyze dependencies, we need three key pieces of data. +/// +/// * When we have a [OtherSyntax], we need to know what [SyntaxDefinition] +/// that corresponds to +/// * When we have a [SyntaxDefinition], we need to know what dependencies it +/// has +/// * When we have a [SyntaxDefinition], we need to know what other syntaxes +/// depend on it +/// +/// This functions generates that data for each syntax. +fn generate_maps( + syntaxes: &[SyntaxDefinition], +) -> (OtherSyntaxLookup, SyntaxToDependencies, SyntaxToDependents) { let mut other_syntax_lookup = HashMap::new(); let mut syntax_to_dependencies = HashMap::new(); + let mut syntax_to_dependents = HashMap::new(); for syntax in syntaxes { - syntax_to_dependencies.insert(syntax.name.clone(), dependencies_for_syntax(syntax)); - other_syntax_lookup.insert(OtherSyntax::ByName(syntax.name.clone()), syntax); other_syntax_lookup.insert(OtherSyntax::ByScope(syntax.scope), syntax); } - (other_syntax_lookup, syntax_to_dependencies) + for syntax in syntaxes { + let dependencies = dependencies_for_syntax(syntax); + + for dependency in &dependencies { + if let Some(dependency) = other_syntax_lookup.get(dependency) { + syntax_to_dependents + .entry(dependency.name.clone()) + .or_insert_with(Vec::new) + .push(OtherSyntax::ByName(syntax.name.clone())); + } + } + + syntax_to_dependencies.insert(syntax.name.clone(), dependencies); + } + + ( + other_syntax_lookup, + syntax_to_dependencies, + syntax_to_dependents, + ) } /// Gets what external dependencies a given [SyntaxDefinition] has. @@ -322,6 +357,7 @@ impl SyntaxSetDependencyBuilder { syntax: &SyntaxDefinition, other_syntax_lookup: &OtherSyntaxLookup, syntax_to_dependencies: &SyntaxToDependencies, + syntax_to_dependents: &SyntaxToDependents, ) { let name = &syntax.name; if self.is_syntax_already_added(name) { @@ -330,18 +366,23 @@ impl SyntaxSetDependencyBuilder { self.syntax_set_builder.add(syntax.clone()); - let dependencies = syntax_to_dependencies.get(name); - if dependencies.is_none() { - eprintln!("ERROR: Unknown dependencies for {}", name); - return; + let mut syntaxes_to_add = vec![]; + if let Some(dependencies) = syntax_to_dependencies.get(name) { + syntaxes_to_add.extend(dependencies); } - - for dependency in dependencies.unwrap() { - if let Some(syntax_definition_dependency) = other_syntax_lookup.get(dependency) { + if let Some(dependents) = syntax_to_dependents.get(name) { + // This will later be enabled intelligently + if std::env::var("BAT_INCLUDE_SYNTAX_DEPENDENTS").is_ok() { + syntaxes_to_add.extend(dependents); + } + } + for syntax_to_add in syntaxes_to_add { + if let Some(syntax_to_add) = other_syntax_lookup.get(syntax_to_add) { self.add_with_dependencies( - syntax_definition_dependency, + syntax_to_add, other_syntax_lookup, syntax_to_dependencies, + syntax_to_dependents, ) } }