feat(xatu): add lint architecture
This commit was merged in pull request #71.
This commit is contained in:
84
src/xatu/parser.rs
Normal file
84
src/xatu/parser.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
use rowan::ast::AstNode;
|
||||
|
||||
use crate::{FileId, ast};
|
||||
|
||||
pub fn parse_file(file_id: FileId, source: &str) -> ast::ParsedFile {
|
||||
let parse = rnix::Root::parse(source);
|
||||
let source_len = source.len();
|
||||
|
||||
ast::ParsedFile {
|
||||
file_id,
|
||||
nodes: parse
|
||||
.syntax()
|
||||
.descendants()
|
||||
.filter_map(convert_node)
|
||||
.collect(),
|
||||
errors: parse
|
||||
.errors()
|
||||
.iter()
|
||||
.map(|error| convert_parse_error(error, source_len))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_parse_error(error: &rnix::ParseError, source_len: usize) -> ast::ParseError {
|
||||
ast::ParseError {
|
||||
range: parse_error_range(error, source_len),
|
||||
message: error.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_error_range(error: &rnix::ParseError, source_len: usize) -> ast::SourceRange {
|
||||
match error {
|
||||
rnix::ParseError::Unexpected(range)
|
||||
| rnix::ParseError::UnexpectedExtra(range)
|
||||
| rnix::ParseError::UnexpectedWanted(_, range, _)
|
||||
| rnix::ParseError::UnexpectedDoubleBind(range)
|
||||
| rnix::ParseError::DuplicatedArgs(range, _) => (*range).into(),
|
||||
|
||||
rnix::ParseError::UnexpectedEOF
|
||||
| rnix::ParseError::UnexpectedEOFWanted(_)
|
||||
| rnix::ParseError::RecursionLimitExceeded => ast::SourceRange {
|
||||
start: source_len,
|
||||
end: source_len,
|
||||
},
|
||||
|
||||
_ => ast::SourceRange {
|
||||
start: source_len,
|
||||
end: source_len,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_node(node: rnix::SyntaxNode) -> Option<ast::Node> {
|
||||
match node.kind() {
|
||||
rnix::SyntaxKind::NODE_INHERIT => convert_inherit(node),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_inherit(node: rnix::SyntaxNode) -> Option<ast::Node> {
|
||||
let inherit = rnix::ast::Inherit::cast(node)?;
|
||||
|
||||
Some(ast::Node {
|
||||
range: inherit.syntax().text_range().into(),
|
||||
data: ast::NodeData::Inherit(inherit.into()),
|
||||
})
|
||||
}
|
||||
|
||||
impl From<rnix::TextRange> for ast::SourceRange {
|
||||
fn from(range: rnix::TextRange) -> Self {
|
||||
Self {
|
||||
start: usize::from(range.start()),
|
||||
end: usize::from(range.end()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<rnix::ast::Inherit> for ast::Inherit {
|
||||
fn from(inherit: rnix::ast::Inherit) -> Self {
|
||||
Self {
|
||||
attr_count: inherit.attrs().count(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user