Skip to content

Commit 057d5cf

Browse files
authored
ide: initial goto def for create property graph (#1074)
1 parent 78d5ed9 commit 057d5cf

10 files changed

Lines changed: 266 additions & 1 deletion

File tree

crates/squawk_ide/src/binder.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,9 @@ fn bind_stmt(b: &mut Binder, stmt: ast::Stmt) {
283283
ast::Stmt::Listen(listen) => bind_listen(b, listen),
284284
ast::Stmt::Set(set) => bind_set(b, set),
285285
ast::Stmt::CreatePolicy(create_policy) => bind_create_policy(b, create_policy),
286+
ast::Stmt::CreatePropertyGraph(create_property_graph) => {
287+
bind_create_property_graph(b, create_property_graph)
288+
}
286289
_ => (),
287290
}
288291
}
@@ -773,6 +776,30 @@ fn bind_create_policy(b: &mut Binder, create_policy: ast::CreatePolicy) {
773776
b.scopes[root].insert(policy_name, policy_id);
774777
}
775778

779+
fn bind_create_property_graph(b: &mut Binder, create_property_graph: ast::CreatePropertyGraph) {
780+
let Some(path) = create_property_graph.path() else {
781+
return;
782+
};
783+
let Some(property_graph_name) = item_name(&path) else {
784+
return;
785+
};
786+
let name_ptr = path_to_ptr(&path);
787+
let Some(schema) = schema_name(b, &path, false) else {
788+
return;
789+
};
790+
791+
let property_graph_id = b.symbols.alloc(Symbol {
792+
kind: SymbolKind::PropertyGraph,
793+
ptr: name_ptr,
794+
schema: Some(schema),
795+
params: None,
796+
table: None,
797+
});
798+
799+
let root = b.root_scope();
800+
b.scopes[root].insert(property_graph_name, property_graph_id);
801+
}
802+
776803
fn bind_create_event_trigger(b: &mut Binder, create_event_trigger: ast::CreateEventTrigger) {
777804
let Some(name) = create_event_trigger.name() else {
778805
return;

crates/squawk_ide/src/classify.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub(crate) enum NameRefClass {
3939
PreparedStatement,
4040
Procedure,
4141
ProcedureCall,
42+
PropertyGraph,
4243
QualifiedColumn,
4344
Role,
4445
Routine,
@@ -310,6 +311,16 @@ pub(crate) fn classify_name_ref(node: &SyntaxNode) -> Option<NameRefClass> {
310311
return Some(NameRefClass::Schema);
311312
}
312313

314+
if let Some(parent) = node.parent()
315+
&& let Some(path) = ast::PathSegment::cast(parent)
316+
.and_then(|p| p.syntax().parent().and_then(ast::Path::cast))
317+
&& let Some(stmt_parent) = path.syntax().parent()
318+
&& (ast::AlterPropertyGraph::can_cast(stmt_parent.kind())
319+
|| ast::DropPropertyGraph::can_cast(stmt_parent.kind()))
320+
{
321+
return Some(NameRefClass::PropertyGraph);
322+
}
323+
313324
// Check for function/procedure reference in CREATE OPERATOR / CREATE AGGREGATE
314325
// before the type check
315326
for ancestor in node.ancestors() {
@@ -373,6 +384,10 @@ pub(crate) fn classify_name_ref(node: &SyntaxNode) -> Option<NameRefClass> {
373384
|| ast::Table::can_cast(ancestor.kind())
374385
|| ast::Inherits::can_cast(ancestor.kind())
375386
|| ast::PartitionOf::can_cast(ancestor.kind())
387+
|| ast::VertexTableDef::can_cast(ancestor.kind())
388+
|| ast::EdgeTableDef::can_cast(ancestor.kind())
389+
|| ast::SourceVertexTable::can_cast(ancestor.kind())
390+
|| ast::DestVertexTable::can_cast(ancestor.kind())
376391
{
377392
return Some(NameRefClass::Table);
378393
}
@@ -754,6 +769,7 @@ pub(crate) enum NameClass {
754769
name: ast::Name,
755770
},
756771
CreateView(ast::CreateView),
772+
CreatePropertyGraph(ast::CreatePropertyGraph),
757773
DeclareCursor(ast::Declare),
758774
PrepareStatement(ast::Prepare),
759775
Listen(ast::Listen),
@@ -829,6 +845,9 @@ pub(crate) fn classify_name(name: &ast::Name) -> Option<NameClass> {
829845
}
830846
return Some(NameClass::CreateView(create_view));
831847
}
848+
if let Some(create_property_graph) = ast::CreatePropertyGraph::cast(ancestor.clone()) {
849+
return Some(NameClass::CreatePropertyGraph(create_property_graph));
850+
}
832851
if let Some(declare) = ast::Declare::cast(ancestor.clone()) {
833852
return Some(NameClass::DeclareCursor(declare));
834853
}
@@ -931,6 +950,9 @@ pub(crate) fn classify_def_node(def_node: &SyntaxNode) -> Option<NameRefClass> {
931950
if ast::CreatePolicy::can_cast(ancestor.kind()) {
932951
return Some(NameRefClass::Policy);
933952
}
953+
if ast::CreatePropertyGraph::can_cast(ancestor.kind()) {
954+
return Some(NameRefClass::PropertyGraph);
955+
}
934956
if ast::Declare::can_cast(ancestor.kind()) {
935957
return Some(NameRefClass::Cursor);
936958
}

crates/squawk_ide/src/document_symbols.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub enum DocumentSymbolKind {
2121
EventTrigger,
2222
Role,
2323
Policy,
24+
PropertyGraph,
2425
Type,
2526
Enum,
2627
Index,
@@ -152,6 +153,11 @@ pub fn document_symbols(db: &dyn Db, file: File) -> Vec<DocumentSymbol> {
152153
symbols.push(symbol);
153154
}
154155
}
156+
ast::Stmt::CreatePropertyGraph(create_property_graph) => {
157+
if let Some(symbol) = create_property_graph_symbol(create_property_graph) {
158+
symbols.push(symbol);
159+
}
160+
}
155161
ast::Stmt::CreateType(create_type) => {
156162
if let Some(symbol) = create_type_symbol(&binder, create_type) {
157163
symbols.push(symbol);
@@ -679,6 +685,27 @@ fn create_policy_symbol(create_policy: ast::CreatePolicy) -> Option<DocumentSymb
679685
})
680686
}
681687

688+
fn create_property_graph_symbol(
689+
create_property_graph: ast::CreatePropertyGraph,
690+
) -> Option<DocumentSymbol> {
691+
let path = create_property_graph.path()?;
692+
let name_node = path.segment()?.name()?;
693+
694+
let name = path.syntax().text().to_string();
695+
696+
let full_range = create_property_graph.syntax().text_range();
697+
let focus_range = name_node.syntax().text_range();
698+
699+
Some(DocumentSymbol {
700+
name,
701+
detail: None,
702+
kind: DocumentSymbolKind::PropertyGraph,
703+
full_range,
704+
focus_range,
705+
children: vec![],
706+
})
707+
}
708+
682709
fn create_type_symbol(
683710
binder: &binder::Binder,
684711
create_type: ast::CreateType,
@@ -892,6 +919,7 @@ mod tests {
892919
DocumentSymbolKind::EventTrigger => "event trigger",
893920
DocumentSymbolKind::Role => "role",
894921
DocumentSymbolKind::Policy => "policy",
922+
DocumentSymbolKind::PropertyGraph => "property graph",
895923
DocumentSymbolKind::Type => "type",
896924
DocumentSymbolKind::Enum => "enum",
897925
DocumentSymbolKind::Index => "index",
@@ -1395,6 +1423,23 @@ create function my_schema.hello() returns void as $$ select 1; $$ language sql;
13951423
");
13961424
}
13971425

1426+
#[test]
1427+
fn create_property_graph() {
1428+
assert_snapshot!(symbols("
1429+
create property graph foo.bar
1430+
vertex tables (t key (a) no properties);
1431+
"), @"
1432+
info: property graph: foo.bar
1433+
╭▸
1434+
2 │ create property graph foo.bar
1435+
│ │ ━━━ focus range
1436+
│ ┌─┘
1437+
│ │
1438+
3 │ │ vertex tables (t key (a) no properties);
1439+
╰╴└─────────────────────────────────────────┘ full range
1440+
");
1441+
}
1442+
13981443
#[test]
13991444
fn create_type() {
14001445
assert_snapshot!(

crates/squawk_ide/src/goto_definition.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ pub enum LocationKind {
146146
Policy,
147147
PreparedStatement,
148148
Procedure,
149+
PropertyGraph,
149150
Role,
150151
Schema,
151152
Sequence,
@@ -188,6 +189,7 @@ impl From<NameRefClass> for LocationKind {
188189
NameRefClass::NamedArgParameter => LocationKind::NamedArgParameter,
189190
NameRefClass::Policy => LocationKind::Policy,
190191
NameRefClass::PreparedStatement => LocationKind::PreparedStatement,
192+
NameRefClass::PropertyGraph => LocationKind::PropertyGraph,
191193
NameRefClass::Role => LocationKind::Role,
192194
NameRefClass::Schema => LocationKind::Schema,
193195
NameRefClass::Sequence => LocationKind::Sequence,
@@ -9343,4 +9345,69 @@ select '10'::dec$0;
93439345
╰╴ ─ 1. source
93449346
");
93459347
}
9348+
9349+
#[test]
9350+
fn goto_create_property_graph() {
9351+
assert_snapshot!(goto("
9352+
create table buzz.boo(a int, b int);
9353+
create property graph foo.bar
9354+
vertex tables (buzz.boo$0 key (a, b) no properties)
9355+
edge tables (foo.bar key (x, y)
9356+
source key (a, b) references k (t, y)
9357+
destination key (q, t) references a (r, j)
9358+
properties all columns);
9359+
"), @"
9360+
╭▸
9361+
2 │ create table buzz.boo(a int, b int);
9362+
│ ─── 2. destination
9363+
3 │ create property graph foo.bar
9364+
4 │ vertex tables (buzz.boo key (a, b) no properties)
9365+
╰╴ ─ 1. source
9366+
");
9367+
9368+
assert_snapshot!(goto("
9369+
create table foo.bar(x int, y int);
9370+
create property graph g
9371+
vertex tables (boo key (a, b) no properties)
9372+
edge tables (foo.bar$0 key (x, y)
9373+
source key (a, b) references k (t, y)
9374+
destination key (q, t) references a (r, j)
9375+
properties all columns);
9376+
"), @"
9377+
╭▸
9378+
2 │ create table foo.bar(x int, y int);
9379+
│ ─── 2. destination
9380+
9381+
5 │ edge tables (foo.bar key (x, y)
9382+
╰╴ ─ 1. source
9383+
");
9384+
}
9385+
9386+
#[test]
9387+
fn goto_drop_property_graph() {
9388+
assert_snapshot!(goto("
9389+
create property graph foo.bar vertex tables (t key (a) no properties);
9390+
drop property graph foo.ba$0r;
9391+
"), @"
9392+
╭▸
9393+
2 │ create property graph foo.bar vertex tables (t key (a) no properties);
9394+
│ ─── 2. destination
9395+
3 │ drop property graph foo.bar;
9396+
╰╴ ─ 1. source
9397+
");
9398+
}
9399+
9400+
#[test]
9401+
fn goto_alter_property_graph() {
9402+
assert_snapshot!(goto("
9403+
create property graph foo.bar vertex tables (t key (a) no properties);
9404+
alter property graph foo.ba$0r rename to baz;
9405+
"), @"
9406+
╭▸
9407+
2 │ create property graph foo.bar vertex tables (t key (a) no properties);
9408+
│ ─── 2. destination
9409+
3 │ alter property graph foo.bar rename to baz;
9410+
╰╴ ─ 1. source
9411+
");
9412+
}
93469413
}

crates/squawk_ide/src/hover.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ pub fn hover(db: &dyn Db, file: File, offset: TextSize) -> Option<Hover> {
191191
NameClass::CreateView(create_view) => {
192192
return format_create_view(&create_view, &binder);
193193
}
194+
NameClass::CreatePropertyGraph(create_property_graph) => {
195+
return format_create_property_graph(&create_property_graph, &binder);
196+
}
194197
NameClass::DeclareCursor(declare) => {
195198
return format_declare_cursor(&declare);
196199
}
@@ -286,6 +289,7 @@ fn hover_name_ref(
286289
NameRefClass::PreparedStatement => hover_prepared_statement(root, name_ref, binder),
287290
NameRefClass::Channel => hover_channel(root, name_ref, binder),
288291
NameRefClass::Window => hover_window(root, name_ref, binder),
292+
NameRefClass::PropertyGraph => hover_property_graph(root, name_ref, binder),
289293
}
290294
}
291295

@@ -1107,6 +1111,24 @@ fn hover_policy(
11071111
format_create_policy(&create_policy, binder)
11081112
}
11091113

1114+
fn hover_property_graph(
1115+
root: &SyntaxNode,
1116+
name_ref: &ast::NameRef,
1117+
binder: &binder::Binder,
1118+
) -> Option<Hover> {
1119+
let property_graph_ptr = resolve::resolve_name_ref_ptrs(binder, root, name_ref)?
1120+
.into_iter()
1121+
.next()?;
1122+
1123+
let property_graph_name_node = property_graph_ptr.to_node(root);
1124+
1125+
let create_property_graph = property_graph_name_node
1126+
.ancestors()
1127+
.find_map(ast::CreatePropertyGraph::cast)?;
1128+
1129+
format_create_property_graph(&create_property_graph, binder)
1130+
}
1131+
11101132
fn hover_event_trigger(
11111133
root: &SyntaxNode,
11121134
name_ref: &ast::NameRef,
@@ -1447,6 +1469,18 @@ fn format_create_policy(
14471469
)))
14481470
}
14491471

1472+
fn format_create_property_graph(
1473+
create_property_graph: &ast::CreatePropertyGraph,
1474+
binder: &binder::Binder,
1475+
) -> Option<Hover> {
1476+
let path = create_property_graph.path()?;
1477+
let (schema, name) = resolve::resolve_property_graph_info(binder, &path)?;
1478+
Some(Hover::snippet(format!(
1479+
"property graph {}.{}",
1480+
schema, name
1481+
)))
1482+
}
1483+
14501484
fn format_create_event_trigger(create_event_trigger: &ast::CreateEventTrigger) -> Option<Hover> {
14511485
let name = create_event_trigger.name()?.syntax().text().to_string();
14521486
Some(Hover::snippet(format!("event trigger {}", name)))
@@ -4972,11 +5006,49 @@ notify updates$0;
49725006
assert_snapshot!(check_hover("
49735007
listen updates;
49745008
unlisten updates$0;
4975-
"), @r"
5009+
"), @"
49765010
hover: listen updates
49775011
╭▸
49785012
3 │ unlisten updates;
49795013
╰╴ ─ hover
49805014
");
49815015
}
5016+
5017+
#[test]
5018+
fn hover_property_graph_on_create() {
5019+
assert_snapshot!(check_hover("
5020+
create property graph foo.ba$0r vertex tables (t key (a) no properties);
5021+
"), @"
5022+
hover: property graph foo.bar
5023+
╭▸
5024+
2 │ create property graph foo.bar vertex tables (t key (a) no properties);
5025+
╰╴ ─ hover
5026+
");
5027+
}
5028+
5029+
#[test]
5030+
fn hover_property_graph_on_drop() {
5031+
assert_snapshot!(check_hover("
5032+
create property graph foo.bar vertex tables (t key (a) no properties);
5033+
drop property graph foo.ba$0r;
5034+
"), @"
5035+
hover: property graph foo.bar
5036+
╭▸
5037+
3 │ drop property graph foo.bar;
5038+
╰╴ ─ hover
5039+
");
5040+
}
5041+
5042+
#[test]
5043+
fn hover_property_graph_on_alter() {
5044+
assert_snapshot!(check_hover("
5045+
create property graph foo.bar vertex tables (t key (a) no properties);
5046+
alter property graph foo.ba$0r rename to baz;
5047+
"), @"
5048+
hover: property graph foo.bar
5049+
╭▸
5050+
3 │ alter property graph foo.bar rename to baz;
5051+
╰╴ ─ hover
5052+
");
5053+
}
49825054
}

0 commit comments

Comments
 (0)