Skip to content

Commit 346ea73

Browse files
helper, update grammar
1 parent 83934ed commit 346ea73

File tree

2 files changed

+71
-13
lines changed

2 files changed

+71
-13
lines changed

crates/pgt_treesitter/src/context/mod.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,42 @@ impl<'a> TreesitterContext<'a> {
826826
.unwrap_or(0)
827827
}
828828

829+
/// Returns true if the node under the cursor matches the field_name OR has a parent that matches the field_name.
830+
pub fn node_under_cursor_is_within_field_name(&self, name: &str) -> bool {
831+
self.node_under_cursor
832+
.as_ref()
833+
.map(|n| match n {
834+
NodeUnderCursor::TsNode(node) => {
835+
// It might seem weird that we have to check for the field_name from the parent,
836+
// but TreeSitter wants it this way, since nodes often can only be named in
837+
// the context of their parents.
838+
let root_node = self.tree.root_node();
839+
let mut cursor = node.walk();
840+
let mut parent = node.parent();
841+
842+
while let Some(p) = parent {
843+
if p == root_node {
844+
break;
845+
}
846+
847+
if p.children_by_field_name(name, &mut cursor).any(|c| {
848+
let r = c.range();
849+
// if the parent range contains the node range, the node is of the field_name.
850+
r.start_byte <= node.start_byte() && r.end_byte >= node.end_byte()
851+
}) {
852+
return true;
853+
} else {
854+
parent = p.parent();
855+
}
856+
}
857+
858+
return false;
859+
}
860+
NodeUnderCursor::CustomNode { .. } => false,
861+
})
862+
.unwrap_or(false)
863+
}
864+
829865
pub fn get_mentioned_relations(&self, key: &Option<String>) -> Option<&HashSet<String>> {
830866
if let Some(key) = key.as_ref() {
831867
let sanitized_key = key.replace('"', "");
@@ -1214,4 +1250,26 @@ mod tests {
12141250
_ => unreachable!(),
12151251
}
12161252
}
1253+
1254+
#[test]
1255+
fn tryout_node_field() {
1256+
let query = format!(
1257+
r#"create table foo (id int not null, compfoo som{}e_type);"#,
1258+
QueryWithCursorPosition::cursor_marker()
1259+
);
1260+
1261+
let (position, text) = QueryWithCursorPosition::from(query).get_text_and_position();
1262+
1263+
let tree = get_tree(text.as_str());
1264+
1265+
let params = TreeSitterContextParams {
1266+
position: (position as u32).into(),
1267+
text: &text,
1268+
tree: &tree,
1269+
};
1270+
1271+
let ctx = TreesitterContext::new(params);
1272+
1273+
assert!(ctx.node_under_cursor_is_within_field_name("custom_type"));
1274+
}
12171275
}

crates/pgt_treesitter_grammar/grammar.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ module.exports = grammar({
484484

485485
keyword_array: (_) => make_keyword("array"), // not included in _type since it's a constructor literal
486486

487-
_type: ($) =>
487+
type: ($) =>
488488
prec.left(
489489
seq(
490490
choice(
@@ -857,7 +857,7 @@ module.exports = grammar({
857857
seq(
858858
optional($._argmode),
859859
optional($.identifier),
860-
$._type,
860+
$.type,
861861
optional(seq(choice($.keyword_default, "="), $.literal))
862862
),
863863

@@ -1234,8 +1234,8 @@ module.exports = grammar({
12341234
$.function_arguments,
12351235
$.keyword_returns,
12361236
choice(
1237-
$._type,
1238-
seq($.keyword_setof, $._type),
1237+
$.type,
1238+
seq($.keyword_setof, $.type),
12391239
seq($.keyword_table, $.column_definitions),
12401240
$.keyword_trigger
12411241
),
@@ -1275,7 +1275,7 @@ module.exports = grammar({
12751275
function_declaration: ($) =>
12761276
seq(
12771277
$.identifier,
1278-
$._type,
1278+
$.type,
12791279
optional(
12801280
seq(
12811281
":=",
@@ -1523,7 +1523,7 @@ module.exports = grammar({
15231523
$.object_reference,
15241524
repeat(
15251525
choice(
1526-
seq($.keyword_as, $._type),
1526+
seq($.keyword_as, $.type),
15271527
seq(
15281528
$.keyword_increment,
15291529
optional($.keyword_by),
@@ -1781,7 +1781,7 @@ module.exports = grammar({
17811781
seq(
17821782
optional(seq($.keyword_set, $.keyword_data)),
17831783
$.keyword_type,
1784-
field("type", $._type)
1784+
field("type", $.type)
17851785
),
17861786
seq(
17871787
$.keyword_set,
@@ -1975,7 +1975,7 @@ module.exports = grammar({
19751975
choice(
19761976
repeat1(
19771977
choice(
1978-
seq($.keyword_as, $._type),
1978+
seq($.keyword_as, $.type),
19791979
seq($.keyword_increment, optional($.keyword_by), $.literal),
19801980
seq(
19811981
$.keyword_minvalue,
@@ -2057,7 +2057,7 @@ module.exports = grammar({
20572057
),
20582058
seq(
20592059
choice(
2060-
seq($.keyword_add, $.keyword_attribute, $.identifier, $._type),
2060+
seq($.keyword_add, $.keyword_attribute, $.identifier, $.type),
20612061
seq(
20622062
$.keyword_drop,
20632063
$.keyword_attribute,
@@ -2070,7 +2070,7 @@ module.exports = grammar({
20702070
$.identifier,
20712071
optional(seq($.keyword_set, $.keyword_data)),
20722072
$.keyword_type,
2073-
$._type
2073+
$.type
20742074
)
20752075
),
20762076
optional(seq($.keyword_collate, $.identifier)),
@@ -2624,7 +2624,7 @@ module.exports = grammar({
26242624
column_definition: ($) =>
26252625
seq(
26262626
field("name", $._column),
2627-
field("type", $._type),
2627+
field("type", $.type),
26282628
repeat($._column_constraint)
26292629
),
26302630

@@ -2810,7 +2810,7 @@ module.exports = grammar({
28102810
field("name", $.identifier)
28112811
),
28122812

2813-
implicit_cast: ($) => seq($._expression, "::", $._type),
2813+
implicit_cast: ($) => seq($._expression, "::", $.type),
28142814

28152815
// Postgres syntax for intervals
28162816
interval: ($) => seq($.keyword_interval, $._literal_string),
@@ -2819,7 +2819,7 @@ module.exports = grammar({
28192819
seq(
28202820
field("name", $.keyword_cast),
28212821
wrapped_in_parenthesis(
2822-
seq(field("parameter", $._expression), $.keyword_as, $._type)
2822+
seq(field("parameter", $._expression), $.keyword_as, $.type)
28232823
)
28242824
),
28252825

0 commit comments

Comments
 (0)