Skip to content

Commit

Permalink
Fix: use config and diagnostc from invalid_block in attribute place.
Browse files Browse the repository at this point in the history
Also add tests and remove unused structure.
  • Loading branch information
vldm committed Jul 28, 2024
1 parent 4a1cffa commit e5b7f3c
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 28 deletions.
9 changes: 2 additions & 7 deletions src/node/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,6 @@ impl AttributeValueExpr {
}
}

#[derive(Clone, Debug, syn_derive::ToTokens)]
pub struct AttributeValueBlock {
pub token_eq: Token![=],
pub value: NodeBlock,
}

#[derive(Clone, Debug, syn_derive::ToTokens)]
pub enum KeyedAttributeValue {
Binding(FnBinding),
Expand Down Expand Up @@ -263,7 +257,8 @@ impl ParseRecoverable for KeyedAttribute {
KVAttributeValue::Expr(parse_quote!(#vbl))
}

Err(_) if input.fork().peek(Brace) => {
Err(err) if input.fork().peek(Brace) && parser.config().recover_block => {
parser.push_diagnostic(err);
let ivb = parser.parse_simple(input)?;
KVAttributeValue::InvalidBraced(ivb)
}
Expand Down
4 changes: 2 additions & 2 deletions src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ mod parser_ext;
mod raw_text;

pub use attribute::{
AttributeValueBlock, AttributeValueExpr, FnBinding, KVAttributeValue, KeyedAttribute,
KeyedAttributeValue, NodeAttribute,
AttributeValueExpr, FnBinding, KVAttributeValue, KeyedAttribute, KeyedAttributeValue,
NodeAttribute,
};
pub use node_name::{NodeName, NodeNameFragment};
pub use node_value::{InvalidBlock, NodeBlock};
Expand Down
17 changes: 0 additions & 17 deletions src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,6 @@ pub trait Visitor<Custom> {
) -> bool {
true
}
fn visit_attribute_block(
&mut self,
_key: &mut NodeName,
_value: &mut AttributeValueBlock,
) -> bool {
true
}
}

#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Ord, Copy, Eq)]
Expand Down Expand Up @@ -378,16 +371,6 @@ where
KVAttributeValue::InvalidBraced(braced) => self.visit_invalid_block(braced),
}
}
fn visit_attribute_block(
&mut self,
key: &mut NodeName,
value: &mut AttributeValueBlock,
) -> bool {
visit_inner!(self.visitor.visit_attribute_block(key, value));

self.visit_node_name(key);
self.visit_block(&mut value.value)
}

fn visit_invalid_block(&mut self, block: &mut InvalidBlock) -> bool {
visit_inner!(self.visitor.visit_invalid_block(block));
Expand Down
71 changes: 69 additions & 2 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use rstml::{
node::{
CustomNode, KeyedAttribute, KeyedAttributeValue, Node, NodeAttribute, NodeElement,
NodeName, NodeType,
CustomNode, KVAttributeValue, KeyedAttribute, KeyedAttributeValue, Node, NodeAttribute,
NodeElement, NodeName, NodeType,
},
parse2,
recoverable::{ParseRecoverable, RecoverableContext},
Expand Down Expand Up @@ -974,6 +974,73 @@ fn test_single_element_with_different_attributes() -> Result<()> {
Ok(())
}

#[test]
fn test_invalid_blocks() -> Result<()> {
// test that invalid blocks can be parsed in recoverable mode
// usefull for IDEs
let tokens = quote! {
<foo>{block.} </foo>
};

let config = ParserConfig::new().recover_block(true);
let (nodes, diagnostics) = Parser::new(config)
.parse_recoverable(tokens.clone())
.split_vec();

let Node::Block(block) = get_element_child(&nodes, 0, 0) else {
panic!("expected block")
};

assert_eq!(block.to_token_stream().to_string(), "{ block . }");
assert_eq!(diagnostics.len(), 1);
let dbg_diag = format!("{:?}", diagnostics[0]);
assert!(dbg_diag.contains("unexpected end of input, expected identifier or integer"));
// same should not work if recover_block = false
let config = ParserConfig::new();
let (nodes, diagnostics) = Parser::new(config).parse_recoverable(tokens).split_vec();
let node = get_element(&nodes, 0);
assert!(node.children.is_empty());
// TODO: Cleanup errors
assert!(diagnostics.len() > 1);
Ok(())
}

#[test]
fn test_invalid_blocks_in_attr() -> Result<()> {
// test that invalid blocks can be parsed in recoverable mode
// usefull for IDEs
let tokens = quote! {
<foo foo={block.}> </foo>
};

let config = ParserConfig::new().recover_block(true);
let (nodes, diagnostics) = Parser::new(config)
.parse_recoverable(tokens.clone())
.split_vec();

let attr = get_element_attribute(&nodes, 0, 0);
let KeyedAttributeValue::Value(eq_val) = &attr.possible_value else {
panic!("expected value")
};

let KVAttributeValue::InvalidBraced(block) = &eq_val.value else {
panic!("expected invalid block")
};

assert_eq!(block.to_token_stream().to_string(), "{ block . }");

assert_eq!(diagnostics.len(), 1);
let dbg_diag = format!("{:?}", diagnostics[0]);
assert!(dbg_diag.contains("unexpected end of input, expected identifier or integer"));
// same should not work if recover_block = false
let config = ParserConfig::new();
let (nodes, diagnostics) = Parser::new(config).parse_recoverable(tokens).split_vec();
let node = get_element(&nodes, 0);
assert!(node.attributes().is_empty());
assert_eq!(diagnostics.len(), 1);
Ok(())
}

#[test]
fn test_empty_input() -> Result<()> {
let tokens = quote! {};
Expand Down

0 comments on commit e5b7f3c

Please sign in to comment.