mirror of
https://github.com/sharkdp/bat.git
synced 2025-04-14 23:00:37 +01:00
build_assets.rs: Add code to track dependents of each syntax
This information is useful when you want to build several SyntaxSets, but without having to duplicate SyntaxDefinitions. For example: "Rust" has no dependencies. But "Markdown" depends on "Rust". With the data structures this code adds, we know that "Rust" is a dependent syntax for "Markdown", and can construct a SyntaxSet that takes that into account. Note that code has a temporary environment flag to ignore any information about dependents when constructing SyntaxSets. Code that makes use of the new data structure will be added later.
This commit is contained in:
parent
a6dc25a216
commit
5143f3ad43
@ -16,6 +16,9 @@ type OtherSyntaxLookup<'a> = HashMap<OtherSyntax, &'a SyntaxDefinition>;
|
|||||||
/// Used to look up what dependencies a given [SyntaxDefinition] has
|
/// Used to look up what dependencies a given [SyntaxDefinition] has
|
||||||
type SyntaxToDependencies = HashMap<SyntaxName, Vec<OtherSyntax>>;
|
type SyntaxToDependencies = HashMap<SyntaxName, Vec<OtherSyntax>>;
|
||||||
|
|
||||||
|
/// Used to look up what other [SyntaxDefinition]s depend on a given [SyntaxDefinition]
|
||||||
|
type SyntaxToDependents<'a> = HashMap<SyntaxName, Vec<OtherSyntax>>;
|
||||||
|
|
||||||
/// Represents some other `*.sublime-syntax` file, i.e. another [SyntaxDefinition].
|
/// Represents some other `*.sublime-syntax` file, i.e. another [SyntaxDefinition].
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||||
enum OtherSyntax {
|
enum OtherSyntax {
|
||||||
@ -215,7 +218,8 @@ fn build_minimal_syntax_sets(
|
|||||||
let syntaxes = syntax_set_builder.syntaxes();
|
let syntaxes = syntax_set_builder.syntaxes();
|
||||||
|
|
||||||
// Build the data structures we need for dependency resolution
|
// 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
|
// Create one minimal SyntaxSet from each (non-hidden) SyntaxDefinition
|
||||||
syntaxes.iter().filter_map(move |syntax| {
|
syntaxes.iter().filter_map(move |syntax| {
|
||||||
@ -224,7 +228,12 @@ fn build_minimal_syntax_sets(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut builder = SyntaxSetDependencyBuilder::new();
|
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();
|
let syntax_set = builder.build();
|
||||||
|
|
||||||
if std::env::var("BAT_PRINT_SYNTAX_DEPENDENCIES").is_ok() {
|
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.
|
/// In order to analyze dependencies, we need three 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
|
/// * When we have a [OtherSyntax], we need to know what [SyntaxDefinition]
|
||||||
/// what dependencies it has. This functions generates that data for each syntax.
|
/// that corresponds to
|
||||||
fn generate_maps(syntaxes: &[SyntaxDefinition]) -> (OtherSyntaxLookup, SyntaxToDependencies) {
|
/// * 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 other_syntax_lookup = HashMap::new();
|
||||||
let mut syntax_to_dependencies = HashMap::new();
|
let mut syntax_to_dependencies = HashMap::new();
|
||||||
|
let mut syntax_to_dependents = HashMap::new();
|
||||||
|
|
||||||
for syntax in syntaxes {
|
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::ByName(syntax.name.clone()), syntax);
|
||||||
other_syntax_lookup.insert(OtherSyntax::ByScope(syntax.scope), 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.
|
/// Gets what external dependencies a given [SyntaxDefinition] has.
|
||||||
@ -322,6 +357,7 @@ impl SyntaxSetDependencyBuilder {
|
|||||||
syntax: &SyntaxDefinition,
|
syntax: &SyntaxDefinition,
|
||||||
other_syntax_lookup: &OtherSyntaxLookup,
|
other_syntax_lookup: &OtherSyntaxLookup,
|
||||||
syntax_to_dependencies: &SyntaxToDependencies,
|
syntax_to_dependencies: &SyntaxToDependencies,
|
||||||
|
syntax_to_dependents: &SyntaxToDependents,
|
||||||
) {
|
) {
|
||||||
let name = &syntax.name;
|
let name = &syntax.name;
|
||||||
if self.is_syntax_already_added(name) {
|
if self.is_syntax_already_added(name) {
|
||||||
@ -330,18 +366,23 @@ impl SyntaxSetDependencyBuilder {
|
|||||||
|
|
||||||
self.syntax_set_builder.add(syntax.clone());
|
self.syntax_set_builder.add(syntax.clone());
|
||||||
|
|
||||||
let dependencies = syntax_to_dependencies.get(name);
|
let mut syntaxes_to_add = vec![];
|
||||||
if dependencies.is_none() {
|
if let Some(dependencies) = syntax_to_dependencies.get(name) {
|
||||||
eprintln!("ERROR: Unknown dependencies for {}", name);
|
syntaxes_to_add.extend(dependencies);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if let Some(dependents) = syntax_to_dependents.get(name) {
|
||||||
for dependency in dependencies.unwrap() {
|
// This will later be enabled intelligently
|
||||||
if let Some(syntax_definition_dependency) = other_syntax_lookup.get(dependency) {
|
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(
|
self.add_with_dependencies(
|
||||||
syntax_definition_dependency,
|
syntax_to_add,
|
||||||
other_syntax_lookup,
|
other_syntax_lookup,
|
||||||
syntax_to_dependencies,
|
syntax_to_dependencies,
|
||||||
|
syntax_to_dependents,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user