Skip to content

Commit

Permalink
Merge branch 'getgrit:main' into chore/improve-contrib-guide
Browse files Browse the repository at this point in the history
  • Loading branch information
ayewo authored Apr 1, 2024
2 parents 81d47d9 + 43b48f8 commit e7edd40
Show file tree
Hide file tree
Showing 100 changed files with 386,944 additions and 14,710 deletions.
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 @@ -82,7 +82,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
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/core/src/pattern/code_snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ fn process_snippet_content(
if lang.exact_variable_regex().is_match(source.trim()) {
match source.trim() {
"$_" => return Ok(Pattern::Underscore),
"^_" => return Ok(Pattern::Underscore),
name => {
let var = register_variable(
name,
Expand Down
1 change: 1 addition & 0 deletions crates/core/src/pattern/dynamic_snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ impl DynamicSnippet {
let source_string = raw_source
.replace("\\n", "\n")
.replace("\\$", "$")
.replace("\\^", "^")
.replace("\\`", "`")
.replace("\\\"", "\"")
.replace("\\\\", "\\");
Expand Down
21 changes: 13 additions & 8 deletions crates/core/src/pattern/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,13 @@ use super::{
r#where::Where, rewrite::Rewrite, some::Some, string_constant::StringConstant,
variable::Variable, within::Within, Node, State,
};
use marzano_util::node_with_source::NodeWithSource;
use crate::context::Context;
use crate::pattern::register_variable;
use crate::pattern::string_constant::AstLeafNode;
use anyhow::{anyhow, bail, Result};
use core::fmt::Debug;
use grit_util::{traverse, Order};
use grit_util::{traverse, Order, AstNode};
use marzano_language::language::{Field, GritMetaValue};
use marzano_language::{language::Language, language::SnippetNode};
use marzano_util::analysis_logs::AnalysisLogs;
Expand Down Expand Up @@ -482,7 +483,7 @@ impl Pattern {
}
if node_types[sort as usize].is_empty() {
let content = node.utf8_text(text)?;
if node.named_child_count() == 0
if (node.named_child_count() == 0)
&& lang.replaced_metavariable_regex().is_match(&content)
{
let regex = implicit_metavariable_regex(
Expand Down Expand Up @@ -539,14 +540,18 @@ impl Pattern {
)
})
.collect::<Result<Vec<Pattern>>>()?;
// assumes that non multiple field has exactly one element

// TODO check if Pattern is Dots, and error at compile time,
// dots only makes sense in a list.
if !field.multiple() {
let lang = lang.get_ts_language();
let field_name = lang.field_name_for_id(field_id).unwrap();
let message = format!("field {} was empty!", field_name);
return Ok((field_id, false, nodes_list.pop().expect(&message)));
if !field.multiple() {
if nodes_list.len() == 1 {
return Ok((field_id, false, nodes_list.pop().unwrap()));
}
let field_node = node.child_by_field_id(field_id).unwrap();
let field_node_with_source = NodeWithSource::new(field_node.clone(), str::from_utf8(text).unwrap());
return Ok((field_id, false, Pattern::AstLeafNode(AstLeafNode::new(
field_node.kind_id(), field_node_with_source.text(), lang,
)?)));
}
if nodes_list.len() == 1
&& matches!(
Expand Down
2 changes: 1 addition & 1 deletion crates/core/src/pattern/variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ fn register_variable_optional_range(
}
return Ok(Variable::new(GLOBAL_VARS_SCOPE_INDEX, *i));
}
let (name_map, scope_index) = if name.starts_with("$GLOBAL_") {
let (name_map, scope_index) = if name.starts_with("$GLOBAL_") || name.starts_with("^GLOBAL_") {
(global_vars, GLOBAL_VARS_SCOPE_INDEX)
} else {
(vars, scope_index)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: apps/marzano/core/src/test.rs
source: crates/core/src/test.rs
expression: results
---
- __typename: Rewrite
Expand Down Expand Up @@ -63,4 +63,3 @@ expression: results
reason: ~
- __typename: DoneFile
relativeFilePath: foo.py

240 changes: 240 additions & 0 deletions crates/core/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12834,6 +12834,245 @@ fn go_package_type() {
.unwrap();
}

#[test]
fn php_no_match() {
run_test_no_match({
TestArg {
pattern: r#"
|language php
|
|`TEST`
|"#
.trim_margin()
.unwrap(),
source: r#"
|echo "hello world"
|"#
.trim_margin()
.unwrap(),
}
})
.unwrap();
}


#[test]
fn php_simple_match() {
run_test_expected({
TestArgExpected {
pattern: r#"
|language php
|
|`echo ^x;` => `^x + ^x;`
|"#
.trim_margin()
.unwrap(),
source: r#"
|echo "duplicate this message";
|"#
.trim_margin()
.unwrap(),
expected: r#"
|"duplicate this message" + "duplicate this message";
|"#
.trim_margin()
.unwrap(),
}
})
.unwrap();
}

#[test]
fn php_until() {
run_test_expected({
TestArgExpected {
pattern: r#"
|language php
|
|contains bubble `foo(^x)` => `bar(^x)` until `foo(^_)`
|"#
.trim_margin()
.unwrap(),
source: r#"
| foo(another(foo(x)));
|"#
.trim_margin()
.unwrap(),
expected: r#"
| bar(another(foo(x)));
|"#
.trim_margin()
.unwrap(),
}
})
.unwrap();
}

#[test]
fn php_quote_snippet_rewrite() {
run_test_expected({
TestArgExpected {
pattern: r#"
|language php
|php"foo" => php"bar"
|"#
.trim_margin()
.unwrap(),
source: r#"$a = $foo;"#.to_owned(),
expected: r#"$a = $bar;"#.to_owned(),
}
})
.unwrap();
}

#[test]
fn php_if_statement() {
run_test_expected(
TestArgExpected {
pattern: r#"
|language php
|
|`$a = 12;` => `$b=24;`
|"#
.trim_margin()
.unwrap(),
source: r#"
|#
|if (!$foo = $bar) {
| $a = 12;
|}
|"#
.trim_margin().
unwrap(),
expected: r#"
|#
|if (!$foo = $bar) {
| $b=24;
|}
|"#
.trim_margin()
.unwrap(),
}
)
.unwrap();
}

#[test]
fn php_delete_include() {
run_test_expected(
TestArgExpected {
pattern: r#"
|language php
|
|`include ^package;` => .
|"#
.trim_margin()
.unwrap(),
source: r#"
|include 'test.php';
|$test = "";
|"#
.trim_margin().
unwrap(),
expected: r#"
|
|$test = "";
|"#
.trim_margin()
.unwrap(),
}
)
.unwrap();
}

#[test]
fn php_function_modifier() {
run_test_expected(
TestArgExpected {
pattern: r#"
|language php
|
|`class ^_ { ^mod function ^name(){ ^_ } }` where {
| ^mod => `private`,
| ^name => `modified`,
|}
|"#
.trim_margin()
.unwrap(),
source: r#"
|class Log {
| public function printHello()
| {
| echo $this->public;
| echo $this->protected;
| echo $this->private;
| }
|}
|"#
.trim_margin().
unwrap(),
expected: r#"
|class Log {
| private function modified()
| {
| echo $this->public;
| echo $this->protected;
| echo $this->private;
| }
|}
|"#
.trim_margin()
.unwrap(),
}
)
.unwrap();
}

#[test]
fn php_rewrite_arrow_function() {
run_test_expected(
TestArgExpected {
pattern: r#"
|language php
|
|`fn(^a) => ^_` => `fn(^a) => $x * $x`
|"#
.trim_margin()
.unwrap(),
source: "$fn1 = fn($x) => $x + $y;"
.trim_margin().
unwrap(),
expected: "$fn1 = fn($x) => $x * $x;"
.trim_margin()
.unwrap(),
}
)
.unwrap();
}

#[test]
fn php_array() {
run_test_expected(
TestArgExpected {
pattern: r#"
|language php
|
|`^a=>^_` => `^a=>24`
|"#
.trim_margin()
.unwrap(),
source: r#"$fn1 = array("a"=>1, "b"=>2, "c"=>3);"#
.trim_margin().
unwrap(),
expected: r#"$fn1 = array("a"=>24, "b"=>24, "c"=>24);"#
.trim_margin()
.unwrap(),
}
)
.unwrap();
}


#[test]
fn css_property_value() {
run_test_match(TestArg {
Expand All @@ -12852,6 +13091,7 @@ fn css_property_value() {
|"#
.trim_margin()
.unwrap(),

})
.unwrap();
}
Expand Down
Loading

0 comments on commit e7edd40

Please sign in to comment.