2024-09-15 20:10:08 -07:00
|
|
|
use std::ffi::CStr;
|
|
|
|
|
|
|
|
|
|
use tree_sitter::{
|
|
|
|
|
ffi::{
|
|
|
|
|
ts_language_symbol_name, ts_language_symbol_type, TSSymbol, TSSymbolTypeAnonymous,
|
|
|
|
|
TSSymbolTypeAuxiliary, TSSymbolTypeRegular, TSSymbolTypeSupertype,
|
|
|
|
|
},
|
|
|
|
|
Parser,
|
|
|
|
|
};
|
2023-06-16 10:46:42 +03:00
|
|
|
|
2024-04-09 13:35:08 -04:00
|
|
|
use super::helpers::fixtures::get_language;
|
|
|
|
|
|
2023-06-16 10:46:42 +03:00
|
|
|
#[test]
|
|
|
|
|
fn test_lookahead_iterator() {
|
|
|
|
|
let mut parser = Parser::new();
|
|
|
|
|
let language = get_language("rust");
|
2023-11-27 15:50:08 -08:00
|
|
|
parser.set_language(&language).unwrap();
|
2023-06-16 10:46:42 +03:00
|
|
|
|
|
|
|
|
let tree = parser.parse("struct Stuff {}", None).unwrap();
|
|
|
|
|
|
|
|
|
|
let mut cursor = tree.walk();
|
|
|
|
|
|
|
|
|
|
assert!(cursor.goto_first_child()); // struct
|
|
|
|
|
assert!(cursor.goto_first_child()); // struct keyword
|
|
|
|
|
|
|
|
|
|
let next_state = cursor.node().next_parse_state();
|
|
|
|
|
assert_ne!(next_state, 0);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
next_state,
|
|
|
|
|
language.next_state(cursor.node().parse_state(), cursor.node().grammar_id())
|
|
|
|
|
);
|
|
|
|
|
assert!((next_state as usize) < language.parse_state_count());
|
|
|
|
|
assert!(cursor.goto_next_sibling()); // type_identifier
|
|
|
|
|
assert_eq!(next_state, cursor.node().parse_state());
|
|
|
|
|
assert_eq!(cursor.node().grammar_name(), "identifier");
|
|
|
|
|
assert_ne!(cursor.node().grammar_id(), cursor.node().kind_id());
|
|
|
|
|
|
2024-02-16 04:53:20 -05:00
|
|
|
let expected_symbols = ["//", "/*", "identifier", "line_comment", "block_comment"];
|
2023-08-02 21:36:52 +03:00
|
|
|
let mut lookahead = language.lookahead_iterator(next_state).unwrap();
|
2023-12-27 14:54:38 -08:00
|
|
|
assert_eq!(*lookahead.language(), language);
|
2023-06-16 10:46:42 +03:00
|
|
|
assert!(lookahead.iter_names().eq(expected_symbols));
|
|
|
|
|
|
|
|
|
|
lookahead.reset_state(next_state);
|
|
|
|
|
assert!(lookahead.iter_names().eq(expected_symbols));
|
|
|
|
|
|
2024-02-04 01:30:33 -05:00
|
|
|
lookahead.reset(&language, next_state);
|
2023-06-16 10:46:42 +03:00
|
|
|
assert!(lookahead
|
|
|
|
|
.map(|s| language.node_kind_for_id(s).unwrap())
|
|
|
|
|
.eq(expected_symbols));
|
|
|
|
|
}
|
2023-08-02 21:37:11 +03:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_lookahead_iterator_modifiable_only_by_mut() {
|
|
|
|
|
let mut parser = Parser::new();
|
|
|
|
|
let language = get_language("rust");
|
2023-11-27 15:50:08 -08:00
|
|
|
parser.set_language(&language).unwrap();
|
2023-08-02 21:37:11 +03:00
|
|
|
|
|
|
|
|
let tree = parser.parse("struct Stuff {}", None).unwrap();
|
|
|
|
|
|
|
|
|
|
let mut cursor = tree.walk();
|
|
|
|
|
|
|
|
|
|
assert!(cursor.goto_first_child()); // struct
|
|
|
|
|
assert!(cursor.goto_first_child()); // struct keyword
|
|
|
|
|
|
|
|
|
|
let next_state = cursor.node().next_parse_state();
|
|
|
|
|
assert_ne!(next_state, 0);
|
|
|
|
|
|
|
|
|
|
let mut lookahead = language.lookahead_iterator(next_state).unwrap();
|
|
|
|
|
let _ = lookahead.next();
|
|
|
|
|
|
|
|
|
|
let mut names = lookahead.iter_names();
|
|
|
|
|
let _ = names.next();
|
|
|
|
|
}
|
2024-09-15 20:10:08 -07:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_symbol_metadata_checks() {
|
|
|
|
|
let language = get_language("rust");
|
|
|
|
|
let ts_language = language.clone().into_raw();
|
|
|
|
|
for i in 0..language.node_kind_count() {
|
|
|
|
|
let ts_symbol: TSSymbol = i.try_into().unwrap();
|
|
|
|
|
unsafe {
|
|
|
|
|
let name = CStr::from_ptr(ts_language_symbol_name(ts_language, ts_symbol))
|
|
|
|
|
.to_str()
|
|
|
|
|
.unwrap();
|
|
|
|
|
match name {
|
|
|
|
|
"_type"
|
|
|
|
|
| "_expression"
|
|
|
|
|
| "_pattern"
|
|
|
|
|
| "_literal"
|
|
|
|
|
| "_literal_pattern"
|
|
|
|
|
| "_declaration_statement" => {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeSupertype
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeAuxiliary
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
"_raw_string_literal_start"
|
|
|
|
|
| "_raw_string_literal_end"
|
|
|
|
|
| "_line_doc_comment"
|
|
|
|
|
| "_error_sentinel" => {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeAuxiliary
|
|
|
|
|
);
|
|
|
|
|
assert_ne!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeSupertype
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
"enum_item" | "struct_item" | "type_item" => {
|
|
|
|
|
assert_ne!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeSupertype
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeRegular
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
"=>" | "[" | "]" | "(" | ")" | "{" | "}" => {
|
|
|
|
|
assert_ne!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeSupertype
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
ts_language_symbol_type(ts_language, ts_symbol),
|
|
|
|
|
TSSymbolTypeAnonymous
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|