Skip to content

Commit

Permalink
node-types: Fix handling of simple aliased inlined rules
Browse files Browse the repository at this point in the history
  • Loading branch information
maxbrunsfeld committed Nov 13, 2019
1 parent 1d2f171 commit a2bbc73
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 7 deletions.
3 changes: 2 additions & 1 deletion cli/src/generate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ fn generate_parser_for_grammar_with_opts(
next_abi: bool,
report_symbol_name: Option<&str>,
) -> Result<GeneratedParser> {
let variable_info = node_types::get_variable_info(&syntax_grammar, &lexical_grammar)?;
let variable_info =
node_types::get_variable_info(&syntax_grammar, &lexical_grammar, &simple_aliases)?;
let node_types_json = node_types::generate_node_types_json(
&syntax_grammar,
&lexical_grammar,
Expand Down
74 changes: 68 additions & 6 deletions cli/src/generate/node_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ impl ChildQuantity {
pub(crate) fn get_variable_info(
syntax_grammar: &SyntaxGrammar,
lexical_grammar: &LexicalGrammar,
simple_aliases: &AliasMap,
) -> Result<Vec<VariableInfo>> {
let child_type_is_visible = |t: &ChildType| {
variable_type_for_child_type(t, syntax_grammar, lexical_grammar) >= VariableType::Anonymous
Expand Down Expand Up @@ -174,6 +175,8 @@ pub(crate) fn get_variable_info(
let child_symbol = step.symbol;
let child_type = if let Some(alias) = &step.alias {
ChildType::Aliased(alias.clone())
} else if let Some(alias) = simple_aliases.get(&step.symbol) {
ChildType::Aliased(alias.clone())
} else {
ChildType::Normal(child_symbol)
};
Expand Down Expand Up @@ -223,8 +226,7 @@ pub(crate) fn get_variable_info(
if child_symbol.is_non_terminal()
&& !syntax_grammar.supertype_symbols.contains(&child_symbol)
&& step.alias.is_none()
&& (!child_type_is_visible(&child_type)
|| syntax_grammar.variables_to_inline.contains(&child_symbol))
&& !child_type_is_visible(&child_type)
{
let child_variable_info = &result[child_symbol.index];

Expand Down Expand Up @@ -345,7 +347,7 @@ pub(crate) fn get_variable_info(
}

// Update all of the node type lists to account for node visiblity:
// * Wherever possible, repalce lists of subtypes with their supertypes.
// * Wherever possible, replace lists of subtypes with their supertypes.
// * Remove other hidden node types.
for i in 0..result.len() {
let mut variable_info = VariableInfo::default();
Expand Down Expand Up @@ -398,7 +400,9 @@ fn variable_type_for_child_type(
}
ChildType::Normal(symbol) => {
if syntax_grammar.supertype_symbols.contains(&symbol) {
return VariableType::Named;
VariableType::Named
} else if syntax_grammar.variables_to_inline.contains(&symbol) {
VariableType::Hidden
} else {
match symbol.kind {
SymbolType::NonTerminal => syntax_grammar.variables[symbol.index].kind,
Expand Down Expand Up @@ -956,6 +960,61 @@ mod tests {
);
}

#[test]
fn test_node_types_with_inlined_rules() {
let node_types = get_node_types(InputGrammar {
name: String::new(),
word_token: None,
extra_symbols: Vec::new(),
external_tokens: Vec::new(),
expected_conflicts: Vec::new(),
variables_to_inline: vec!["v2".to_string()],
supertype_symbols: vec![],
variables: vec![
Variable {
name: "v1".to_string(),
kind: VariableType::Named,
rule: Rule::seq(vec![Rule::named("v2"), Rule::named("v3")]),
},
// v2 should not appear in the node types, since it is inlined
Variable {
name: "v2".to_string(),
kind: VariableType::Named,
rule: Rule::alias(Rule::string("a"), "x".to_string(), true),
},
Variable {
name: "v3".to_string(),
kind: VariableType::Named,
rule: Rule::string("b"),
},
],
});

assert_eq!(
node_types[0],
NodeInfoJSON {
kind: "v1".to_string(),
named: true,
subtypes: None,
children: Some(FieldInfoJSON {
multiple: true,
required: true,
types: vec![
NodeTypeJSON {
kind: "v3".to_string(),
named: true,
},
NodeTypeJSON {
kind: "x".to_string(),
named: true,
},
]
}),
fields: Some(BTreeMap::new()),
}
);
}

#[test]
fn test_node_types_for_aliased_nodes() {
let node_types = get_node_types(InputGrammar {
Expand Down Expand Up @@ -1158,6 +1217,7 @@ mod tests {
vec![],
),
&build_lexical_grammar(),
&AliasMap::new(),
)
.unwrap();

Expand Down Expand Up @@ -1238,6 +1298,7 @@ mod tests {
vec![],
),
&build_lexical_grammar(),
&AliasMap::new(),
)
.unwrap();

Expand All @@ -1258,7 +1319,6 @@ mod tests {
.collect::<HashMap<_, _>>()
);

//
assert_eq!(
variable_info[0].children_without_fields,
FieldInfo {
Expand Down Expand Up @@ -1312,6 +1372,7 @@ mod tests {
vec![Symbol::non_terminal(1)],
),
&build_lexical_grammar(),
&AliasMap::new(),
)
.unwrap();

Expand All @@ -1336,7 +1397,8 @@ mod tests {
fn get_node_types(grammar: InputGrammar) -> Vec<NodeInfoJSON> {
let (syntax_grammar, lexical_grammar, _, simple_aliases) =
prepare_grammar(&grammar).unwrap();
let variable_info = get_variable_info(&syntax_grammar, &lexical_grammar).unwrap();
let variable_info =
get_variable_info(&syntax_grammar, &lexical_grammar, &simple_aliases).unwrap();
generate_node_types_json(
&syntax_grammar,
&lexical_grammar,
Expand Down

0 comments on commit a2bbc73

Please sign in to comment.