1use tree_sitter_language::LanguageFn;
27
28extern "C" {
29 fn tree_sitter_php() -> *const ();
30 fn tree_sitter_php_only() -> *const ();
31}
32
33pub const LANGUAGE_PHP: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_php) };
37
38pub const LANGUAGE_PHP_ONLY: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_php_only) };
42
43pub const PHP_NODE_TYPES: &str = include_str!("../../php/src/node-types.json");
47pub const PHP_ONLY_NODE_TYPES: &str = include_str!("../../php_only/src/node-types.json");
48
49pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm");
51
52pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm");
54
55pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm");
57
58#[cfg(test)]
59mod tests {
60 #[test]
61 fn test_php_grammar() {
62 let mut parser = tree_sitter::Parser::new();
63 parser
64 .set_language(&super::LANGUAGE_PHP.into())
65 .expect("Error loading PHP parser");
66
67 let code = r#"<?php echo "Hello, World!";"#;
68
69 let tree = parser.parse(code, None).unwrap();
70 let root = tree.root_node();
71 assert!(!root.has_error());
72 }
73
74 #[test]
75 fn test_php_only_grammar() {
76 let mut parser = tree_sitter::Parser::new();
77 parser
78 .set_language(&super::LANGUAGE_PHP_ONLY.into())
79 .expect("Error loading PHP-Only parser");
80
81 let code = r#"echo "Hello, World!";"#;
82
83 let tree = parser.parse(code, None).unwrap();
84 let root = tree.root_node();
85 assert!(!root.has_error());
86 }
87
88 fn sequential_heredocs(prefix: &str, count: usize, tag: &str) -> String {
89 let block = format!("$a = <<<{tag}\nx\n{tag};\n");
90 let mut src = String::from(prefix);
91 src.reserve(block.len() * count);
92 for _ in 0..count {
93 src.push_str(&block);
94 }
95 src
96 }
97
98 fn assert_no_error(language: tree_sitter_language::LanguageFn, code: &str) {
99 let mut parser = tree_sitter::Parser::new();
100 parser
101 .set_language(&language.into())
102 .expect("Error loading parser");
103 let tree = parser.parse(code, None).unwrap();
104 assert!(!tree.root_node().has_error());
105 }
106
107 #[test]
108 fn test_many_sequential_heredocs() {
109 let long_tag = "HEREDOC_".repeat(30);
110 assert_no_error(
111 super::LANGUAGE_PHP,
112 &sequential_heredocs("<?php\n", 20, &long_tag),
113 );
114 assert_no_error(
115 super::LANGUAGE_PHP,
116 &sequential_heredocs("<?php\n", 250, "EOD"),
117 );
118 assert_no_error(
119 super::LANGUAGE_PHP_ONLY,
120 &sequential_heredocs("", 20, &long_tag),
121 );
122 assert_no_error(
123 super::LANGUAGE_PHP_ONLY,
124 &sequential_heredocs("", 250, "EOD"),
125 );
126 }
127}