Start work on handling node supertypes
This commit is contained in:
parent
445dfda53e
commit
b79bd8693b
13 changed files with 513 additions and 280 deletions
|
|
@ -184,17 +184,23 @@ fn ensure_file<T: AsRef<[u8]>>(path: &PathBuf, f: impl Fn() -> T) -> Result<()>
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, PartialEq, Eq, Default)]
|
||||
struct NodeInfoJSON {
|
||||
fields: Option<BTreeMap<String, FieldInfoJSON>>,
|
||||
subtypes: Option<Vec<NodeTypeJSON>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct FieldTypeJSON {
|
||||
struct NodeTypeJSON {
|
||||
kind: String,
|
||||
named: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, PartialEq, Eq)]
|
||||
struct FieldInfoJSON {
|
||||
multiple: bool,
|
||||
required: bool,
|
||||
types: Vec<FieldTypeJSON>,
|
||||
types: Vec<NodeTypeJSON>,
|
||||
}
|
||||
|
||||
fn generate_field_info_json(
|
||||
|
|
@ -203,7 +209,7 @@ fn generate_field_info_json(
|
|||
simple_aliases: &AliasMap,
|
||||
variable_info: &Vec<VariableInfo>,
|
||||
) -> String {
|
||||
let mut map = BTreeMap::new();
|
||||
let mut node_types_json = BTreeMap::new();
|
||||
for (i, info) in variable_info.iter().enumerate() {
|
||||
let variable = &syntax_grammar.variables[i];
|
||||
if !variable.kind.is_visible() || info.fields.is_empty() {
|
||||
|
|
@ -214,60 +220,68 @@ fn generate_field_info_json(
|
|||
.get(&Symbol::non_terminal(i))
|
||||
.map_or(&variable.name, |alias| &alias.value);
|
||||
|
||||
let fields = map.entry(name.clone()).or_insert_with(|| BTreeMap::new());
|
||||
for (field, field_info) in info.fields.iter() {
|
||||
let field_info_json = fields.entry(field.clone()).or_insert(FieldInfoJSON {
|
||||
multiple: false,
|
||||
required: true,
|
||||
types: Vec::new(),
|
||||
});
|
||||
let node_type_json = node_types_json
|
||||
.entry(name.clone())
|
||||
.or_insert_with(|| NodeInfoJSON::default());
|
||||
|
||||
field_info_json.multiple |= field_info.multiple;
|
||||
field_info_json.required &= field_info.required;
|
||||
field_info_json.types.extend(field_info.types.iter().map(
|
||||
|child_type| match child_type {
|
||||
ChildType::Aliased(alias) => FieldTypeJSON {
|
||||
kind: alias.value.clone(),
|
||||
named: alias.is_named,
|
||||
},
|
||||
ChildType::Normal(symbol) => {
|
||||
if let Some(alias) = simple_aliases.get(&symbol) {
|
||||
FieldTypeJSON {
|
||||
kind: alias.value.clone(),
|
||||
named: alias.is_named,
|
||||
}
|
||||
} else {
|
||||
match symbol.kind {
|
||||
SymbolType::NonTerminal => {
|
||||
let variable = &syntax_grammar.variables[symbol.index];
|
||||
FieldTypeJSON {
|
||||
kind: variable.name.clone(),
|
||||
named: variable.kind == VariableType::Named,
|
||||
}
|
||||
if info.fields.len() > 0 {
|
||||
let mut fields_json = BTreeMap::new();
|
||||
for (field, field_info) in info.fields.iter() {
|
||||
let field_info_json = fields_json.entry(field.clone()).or_insert(FieldInfoJSON {
|
||||
multiple: false,
|
||||
required: true,
|
||||
types: Vec::new(),
|
||||
});
|
||||
|
||||
field_info_json.multiple |= field_info.multiple;
|
||||
field_info_json.required &= field_info.required;
|
||||
field_info_json.types.extend(field_info.types.iter().map(
|
||||
|child_type| match child_type {
|
||||
ChildType::Aliased(alias) => NodeTypeJSON {
|
||||
kind: alias.value.clone(),
|
||||
named: alias.is_named,
|
||||
},
|
||||
ChildType::Normal(symbol) => {
|
||||
if let Some(alias) = simple_aliases.get(&symbol) {
|
||||
NodeTypeJSON {
|
||||
kind: alias.value.clone(),
|
||||
named: alias.is_named,
|
||||
}
|
||||
SymbolType::Terminal => {
|
||||
let variable = &lexical_grammar.variables[symbol.index];
|
||||
FieldTypeJSON {
|
||||
kind: variable.name.clone(),
|
||||
named: variable.kind == VariableType::Named,
|
||||
} else {
|
||||
match symbol.kind {
|
||||
SymbolType::NonTerminal => {
|
||||
let variable = &syntax_grammar.variables[symbol.index];
|
||||
NodeTypeJSON {
|
||||
kind: variable.name.clone(),
|
||||
named: variable.kind == VariableType::Named,
|
||||
}
|
||||
}
|
||||
}
|
||||
SymbolType::External => {
|
||||
let variable = &syntax_grammar.external_tokens[symbol.index];
|
||||
FieldTypeJSON {
|
||||
kind: variable.name.clone(),
|
||||
named: variable.kind == VariableType::Named,
|
||||
SymbolType::Terminal => {
|
||||
let variable = &lexical_grammar.variables[symbol.index];
|
||||
NodeTypeJSON {
|
||||
kind: variable.name.clone(),
|
||||
named: variable.kind == VariableType::Named,
|
||||
}
|
||||
}
|
||||
SymbolType::External => {
|
||||
let variable = &syntax_grammar.external_tokens[symbol.index];
|
||||
NodeTypeJSON {
|
||||
kind: variable.name.clone(),
|
||||
named: variable.kind == VariableType::Named,
|
||||
}
|
||||
}
|
||||
_ => panic!("Unexpected symbol type"),
|
||||
}
|
||||
_ => panic!("Unexpected symbol type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
));
|
||||
field_info_json.types.sort_unstable();
|
||||
field_info_json.types.dedup();
|
||||
},
|
||||
));
|
||||
field_info_json.types.sort_unstable();
|
||||
field_info_json.types.dedup();
|
||||
}
|
||||
node_type_json.fields = Some(fields_json);
|
||||
}
|
||||
|
||||
}
|
||||
serde_json::to_string_pretty(&map).unwrap()
|
||||
serde_json::to_string_pretty(&node_types_json).unwrap()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue