Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add PHP language #52

Merged
merged 42 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
bb95dad
added tree-sitter-php
urbit-pilled Mar 22, 2024
b1493d1
fix CONTRIBUTING.md link
urbit-pilled Mar 22, 2024
4a5c70f
add tree-sitter-python to lsp and target_language
urbit-pilled Mar 22, 2024
7aacc80
added tree-sitter-php to resources
urbit-pilled Mar 22, 2024
a8f3731
added wasm
urbit-pilled Mar 22, 2024
1f1a15d
add metavariable to grammar (initial)
urbit-pilled Mar 22, 2024
fcc3fc7
udpated tree-sitter-gritql submodule
urbit-pilled Mar 22, 2024
b6ac729
initial php tests working now
urbit-pilled Mar 22, 2024
ae56041
updated node-types and grammar.js
urbit-pilled Mar 22, 2024
0229548
fix conflicting metavariable prefix and php variable prefix
urbit-pilled Mar 22, 2024
a379303
deleted c bindings
urbit-pilled Mar 22, 2024
3d442ec
updated tree-sitter grammar with metavariable prefix change
urbit-pilled Mar 22, 2024
48f5a27
updated tests
urbit-pilled Mar 25, 2024
eace2a4
updated gritql to accept ^ as prefix
urbit-pilled Mar 25, 2024
d5c1201
updated php with php_only as default
urbit-pilled Mar 25, 2024
197575d
took a lot of debugging to find this
urbit-pilled Mar 25, 2024
0a8d0fc
added php to patterns_directory
urbit-pilled Mar 25, 2024
f009c77
Merge branch 'main' into main
urbit-pilled Mar 25, 2024
bc91a14
fix merge
urbit-pilled Mar 25, 2024
4a5c69f
remove yaml snapshot basic_php test
urbit-pilled Mar 25, 2024
a3c0e4f
added 2 more php tests
urbit-pilled Mar 25, 2024
9acad21
idk about these snapshots
urbit-pilled Mar 26, 2024
2225d9a
fixed tests
urbit-pilled Mar 27, 2024
8b4dba9
restore the parse_correct_variable_ranges snapshots
urbit-pilled Mar 27, 2024
6c98c81
merge with main
urbit-pilled Mar 27, 2024
55ff702
revert php grammar changes so that semicolons are required in snippet
urbit-pilled Mar 27, 2024
8c77c49
Merge branch 'main' into main
urbit-pilled Mar 27, 2024
9f4f125
added tests
urbit-pilled Mar 27, 2024
fc90e44
updated php grammar with new fields and placed more grit_metavariables
urbit-pilled Mar 28, 2024
cbf8081
added tests
urbit-pilled Mar 28, 2024
16f4d8a
Merge pull request #1 from urbit-pilled/add_tests
urbit-pilled Mar 28, 2024
c432a14
fixed array support
urbit-pilled Mar 28, 2024
8a54196
updated php resources
urbit-pilled Mar 28, 2024
066da65
updated tree-sitter-gritql submodule
urbit-pilled Mar 29, 2024
b0870fb
merge with remote main
urbit-pilled Mar 29, 2024
17d80bc
fix conflicts
urbit-pilled Mar 29, 2024
c631247
updated edit_grammars.mjs
urbit-pilled Mar 29, 2024
c469d93
edit_grammar.mjs GNU compatibility issue fixed and changed php->metav…
urbit-pilled Mar 29, 2024
6fedda7
removed grammar conflict, using precedence instead
urbit-pilled Mar 29, 2024
27ea566
updated php grammar
urbit-pilled Mar 30, 2024
df1a576
regenerating php files
urbit-pilled Mar 30, 2024
fd4e1d6
removed named_child_count == 1 and added more grammar fields
urbit-pilled Mar 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@
[submodule "resources/language-submodules/tree-sitter-toml"]
path = resources/language-submodules/tree-sitter-toml
url = https://github.com/ikatyang/tree-sitter-toml
[submodule "resources/language-submodules/tree-sitter-php"]
path = resources/language-submodules/tree-sitter-php
url = https://github.com/tree-sitter/tree-sitter-php
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Here are the steps for adding a new target language:
3. Copy the grammar file into `resources/metavariable-grammars`. This alternative grammar is used for parsing `snippets` in GritQL.
4. Patch the metavariable grammar to include `$.grit_metavariable` anywhere we want to substitute a metavariable. This is usually at least `$identifier` and `$literal`.
- For a snippet to match, it also needs to be a field. Often you’ll want to wrap `$thing` like: `field('thing', choice($.grit_metavariable, $thing))`
5. Add a new language implementation in `crates/core/src/languages`. This involves implementing the `Language` trait and adding a new `Language` enum variant.
5. Add a new language implementation in `crates/core/languages/src`. This involves implementing the `Language` trait and adding a new `Language` enum variant.
6. Add `snippet_context_strings` [like this](https://github.com/getgrit/gritql/blob/main/crates/language/src/sql.rs#L52) to provide context for snippets to match in.
7. Add test cases for the language in `crates/core/src/test.rs`. This is a good time to add a few dozen test cases to ensure that the language is parsed correctly, and that the metavariable grammar is working.

Expand Down
24 changes: 24 additions & 0 deletions crates/core/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12725,3 +12725,27 @@ fn go_package_type() {
})
.unwrap();
}

#[test]
fn call_php() {
run_test_no_match({
TestArg {
pattern: r#"
<?php
$color = "red";
`TEST`
echo "My car is " . $color . "<br>";
?>
|"#
.trim_margin()
.unwrap(),
source: r#"
|/* grit-ignore */
|echo "hello world"
|"#
.trim_margin()
.unwrap(),
}
})
.unwrap();
}
4 changes: 4 additions & 0 deletions crates/gritmodule/src/patterns_directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub struct PatternsDirectory {
sql: BTreeMap<String, String>,
vue: BTreeMap<String, String>,
toml: BTreeMap<String, String>,
php: BTreeMap<String, String>,
universal: BTreeMap<String, String>,
}

Expand Down Expand Up @@ -80,6 +81,7 @@ impl PatternsDirectory {
sql: BTreeMap::new(),
vue: BTreeMap::new(),
toml: BTreeMap::new(),
php: BTreeMap::new(),
universal: BTreeMap::new(),
}
}
Expand Down Expand Up @@ -109,6 +111,7 @@ impl PatternsDirectory {
PatternLanguage::Sql => &mut self.sql,
PatternLanguage::Vue => &mut self.vue,
PatternLanguage::Toml => &mut self.toml,
PatternLanguage::Php => &mut self.php,
PatternLanguage::Universal => &mut self.universal,
}
}
Expand All @@ -135,6 +138,7 @@ impl PatternsDirectory {
PatternLanguage::Sql => &self.sql,
PatternLanguage::Vue => &self.vue,
PatternLanguage::Toml => &self.toml,
PatternLanguage::Php => &self.php,
PatternLanguage::Universal => &self.universal,
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/language/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ tree-sitter-ruby = { path = "../../resources/language-metavariables/tree-sitter-
tree-sitter-sql = { path = "../../resources/language-metavariables/tree-sitter-sql", optional = true }
tree-sitter-vue = { path = "../../resources/language-metavariables/tree-sitter-vue", optional = true }
tree-sitter-toml = { path = "../../resources/language-metavariables/tree-sitter-toml", optional = true }
tree-sitter-php = { path = "../../resources/language-metavariables/tree-sitter-php", optional = true }
serde_json = { version = "1.0.91", features = ["preserve_order"] }
marzano-util = { path = "../util" }
regex = "1.7.1"
Expand Down Expand Up @@ -63,5 +64,6 @@ builtin-parser = [
"tree-sitter-sql",
"tree-sitter-vue",
"tree-sitter-toml",
"tree-sitter-php",
]
finder = ["ignore"]
1 change: 1 addition & 0 deletions crates/language/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod language;
pub mod markdown_block;
pub mod markdown_inline;
pub mod parent_traverse;
pub mod php;
pub mod python;
pub mod ruby;
pub mod rust;
Expand Down
67 changes: 67 additions & 0 deletions crates/language/src/php.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use std::sync::OnceLock;

use crate::language::{fields_for_nodes, Field, Language, SortId, TSLanguage};

static NODE_TYPES_STRING: &str = include_str!("../../../resources/node-types/php-node-types.json");

static NODE_TYPES: OnceLock<Vec<Vec<Field>>> = OnceLock::new();
static LANGUAGE: OnceLock<TSLanguage> = OnceLock::new();

#[cfg(not(feature = "builtin-parser"))]
fn language() -> TSLanguage {
unimplemented!(
"tree-sitter parser must be initialized before use when [builtin-parser] is off."
)
}
#[cfg(feature = "builtin-parser")]
fn language() -> TSLanguage {
tree_sitter_php::language_php().into()
}

#[derive(Debug, Clone)]
pub struct Php {
node_types: &'static [Vec<Field>],
metavariable_sort: SortId,
language: &'static TSLanguage,
}

impl Php {
pub(crate) fn new(lang: Option<TSLanguage>) -> Self {
let language = LANGUAGE.get_or_init(|| lang.unwrap_or_else(language));
let node_types = NODE_TYPES.get_or_init(|| fields_for_nodes(language, NODE_TYPES_STRING));
let metavariable_sort = language.id_for_node_kind("grit_metavariable", true);
Self {
node_types,
metavariable_sort,
language,
}
}
pub(crate) fn is_initialized() -> bool {
LANGUAGE.get().is_some()
}
}

impl Language for Php {
fn get_ts_language(&self) -> &TSLanguage {
self.language
}

fn comment_prefix(&self) -> &'static str {
"//"
}

fn language_name(&self) -> &'static str {
"Php"
}
fn snippet_context_strings(&self) -> &[(&'static str, &'static str)] {
&[("", "")]
}

fn node_types(&self) -> &[Vec<Field>] {
self.node_types
}

fn metavariable_sort(&self) -> SortId {
self.metavariable_sort
}
}
23 changes: 23 additions & 0 deletions crates/language/src/target_language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
language::{Field, FieldId, Language, SortId},
markdown_block::MarkdownBlock,
markdown_inline::MarkdownInline,
php::Php,
python::Python,
ruby::Ruby,
rust::Rust,
Expand Down Expand Up @@ -65,6 +66,7 @@ pub enum PatternLanguage {
Sql,
Vue,
Toml,
Php,
Universal,
}

Expand Down Expand Up @@ -92,6 +94,7 @@ impl fmt::Display for PatternLanguage {
PatternLanguage::Vue => write!(f, "vue"),
PatternLanguage::Toml => write!(f, "toml"),
PatternLanguage::Universal => write!(f, "universal"),
PatternLanguage::Php => write!(f, "php"),
}
}
}
Expand Down Expand Up @@ -119,6 +122,7 @@ impl From<&TargetLanguage> for PatternLanguage {
TargetLanguage::Sql(_) => PatternLanguage::Sql,
TargetLanguage::Vue(_) => PatternLanguage::Vue,
TargetLanguage::Toml(_) => PatternLanguage::Toml,
TargetLanguage::Php(_) => PatternLanguage::Php,
}
}
}
Expand Down Expand Up @@ -146,6 +150,7 @@ impl PatternLanguage {
PatternLanguage::Sql => Sql::is_initialized(),
PatternLanguage::Vue => Vue::is_initialized(),
PatternLanguage::Toml => Toml::is_initialized(),
PatternLanguage::Php => Php::is_initialized(),
PatternLanguage::Universal => false,
}
}
Expand Down Expand Up @@ -240,6 +245,7 @@ impl PatternLanguage {
PatternLanguage::Sql => &["sql"],
PatternLanguage::Vue => &["vue"],
PatternLanguage::Toml => &["toml"],
PatternLanguage::Php => &["php", "phps", "phar", "phtml", "pht"],
PatternLanguage::Universal => &[],
}
}
Expand All @@ -266,6 +272,7 @@ impl PatternLanguage {
PatternLanguage::Sql => Some("sql"),
PatternLanguage::Vue => Some("vue"),
PatternLanguage::Toml => Some("toml"),
PatternLanguage::Php => Some("php"),
PatternLanguage::Universal => None,
}
}
Expand All @@ -289,6 +296,7 @@ impl PatternLanguage {
"yaml" | "yml" => Some(Self::Yaml),
"sql" => Some(Self::Sql),
"vue" => Some(Self::Vue),
"php" | "phps" | "phar" | "phtml" | "pht" => Some(Self::Php),
_ => None,
}
}
Expand Down Expand Up @@ -327,6 +335,7 @@ impl PatternLanguage {
PatternLanguage::Sql,
PatternLanguage::Vue,
PatternLanguage::Toml,
PatternLanguage::Php,
]
}

Expand Down Expand Up @@ -361,6 +370,7 @@ impl PatternLanguage {
PatternLanguage::Sql => Ok(TargetLanguage::Sql(Sql::new(Some(lang)))),
PatternLanguage::Vue => Ok(TargetLanguage::Vue(Vue::new(Some(lang)))),
PatternLanguage::Toml => Ok(TargetLanguage::Toml(Toml::new(Some(lang)))),
PatternLanguage::Php => Ok(TargetLanguage::Php(Php::new(Some(lang)))),
PatternLanguage::Universal => Err("Cannot convert universal to TSLang".to_string()),
}
}
Expand Down Expand Up @@ -449,6 +459,13 @@ pub fn expand_paths(
PatternLanguage::Toml => {
file_types.select("toml");
}
PatternLanguage::Php => {
file_types.select("php");
file_types.select("phtml");
file_types.select("phar");
file_types.select("pht");
file_types.select("phps");
}
PatternLanguage::Universal => {}
}
}
Expand Down Expand Up @@ -496,6 +513,7 @@ pub enum TargetLanguage {
Vue(Vue),
Toml(Toml),
Sql(Sql),
Php(Php),
}

// when built to wasm the language must be initialized with a parser at least once
Expand Down Expand Up @@ -528,6 +546,7 @@ impl TryFrom<PatternLanguage> for TargetLanguage {
PatternLanguage::Sql => Ok(TargetLanguage::Sql(Sql::new(None))),
PatternLanguage::Vue => Ok(TargetLanguage::Vue(Vue::new(None))),
PatternLanguage::Toml => Ok(TargetLanguage::Toml(Toml::new(None))),
PatternLanguage::Php => Ok(TargetLanguage::Php(Php::new(None))),
PatternLanguage::Universal => {
Err("cannot instantiate Universal as a target language".to_string())
}
Expand Down Expand Up @@ -558,6 +577,7 @@ impl fmt::Display for TargetLanguage {
TargetLanguage::Sql(_) => write!(f, "sql"),
TargetLanguage::Vue(_) => write!(f, "vue"),
TargetLanguage::Toml(_) => write!(f, "toml"),
TargetLanguage::Php(_) => write!(f, "php"),
}
}
}
Expand Down Expand Up @@ -601,6 +621,7 @@ impl TargetLanguage {
TargetLanguage::Sql(_) => PatternLanguage::Sql,
TargetLanguage::Vue(_) => PatternLanguage::Vue,
TargetLanguage::Toml(_) => PatternLanguage::Toml,
TargetLanguage::Php(_) => PatternLanguage::Php,
}
}

Expand All @@ -626,6 +647,7 @@ impl TargetLanguage {
TargetLanguage::Sql(_) => false,
TargetLanguage::Vue(_) => false,
TargetLanguage::Toml(_) => false,
TargetLanguage::Php(_) => false,
}
}

Expand All @@ -651,6 +673,7 @@ impl TargetLanguage {
| TargetLanguage::Rust(_)
| TargetLanguage::Solidity(_)
| TargetLanguage::Tsx(_)
| TargetLanguage::Php(_)
| TargetLanguage::TypeScript(_) => format!("// {}\n", text),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be updated to use the comment_prefix method from the Language trait instead of redefining it here.

TargetLanguage::Python(_)
| TargetLanguage::Hcl(_)
Expand Down
2 changes: 2 additions & 0 deletions crates/lsp/src/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub fn language_id_to_pattern_language(language_id: &str) -> Option<PatternLangu
"sql" => Some(PatternLanguage::Sql),
"vue" => Some(PatternLanguage::Vue),
"toml" => Some(PatternLanguage::Toml),
"php" => Some(PatternLanguage::Php),
_ => None,
}
}
Expand Down Expand Up @@ -48,6 +49,7 @@ pub fn target_language_to_language_id(target_language: TargetLanguage) -> &'stat
TargetLanguage::Sql(_) => "sql",
TargetLanguage::Vue(_) => "vue",
TargetLanguage::Toml(_) => "toml",
TargetLanguage::Php(_) => "php",
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/wasm-bindings/src/match_pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ fn pattern_language_to_path(lang: &PatternLanguage) -> Result<String, JsError> {
PatternLanguage::Sql => Ok("/tree-sitter-sql.wasm"),
PatternLanguage::Vue => Ok("/tree-sitter-vue.wasm"),
PatternLanguage::Toml => Ok("/tree-sitter-toml.wasm"),
PatternLanguage::Php => Ok("/tree-sitter-php.wasm"),
PatternLanguage::Universal => Err(JsError::new("Universal does not have a parser")),
}?;
let final_file = format!("{}{}", get_parser_path(), wasm_file);
Expand Down
3 changes: 2 additions & 1 deletion resources/edit_grammars.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ const allLanguages = [
'typescript',
'yaml',
'toml',
'vue'
'vue',
'php'
];

// For these languages, copyMvGrammar is optional
Expand Down
Loading