Skip to content

Commit 269412d

Browse files
authored
ide: support hover with * in queries (#818)
- goto def subquery support - goto def on `.` goes to the prev token
1 parent 33b71c2 commit 269412d

8 files changed

Lines changed: 1411 additions & 435 deletions

File tree

crates/squawk_ide/src/classify.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ pub(crate) fn classify_name_ref(name_ref: &ast::NameRef) -> Option<NameRefClass>
254254
}
255255
}
256256
if let Some(references_constraint) = ast::ReferencesConstraint::cast(ancestor.clone()) {
257+
// TODO: the ast is too flat here
257258
if let Some(column_ref) = references_constraint.column()
258259
&& column_ref
259260
.syntax()

crates/squawk_ide/src/expand_selection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ mod tests {
307307
let root = file.syntax();
308308

309309
let mut range = TextRange::empty(offset);
310-
let mut results = Vec::new();
310+
let mut results = vec![];
311311

312312
for _ in 0..20 {
313313
let new_range = extend_selection(root, range);

crates/squawk_ide/src/find_references.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::offsets::token_from_offset;
33
use crate::resolve;
44
use rowan::{TextRange, TextSize};
55
use smallvec::{SmallVec, smallvec};
6+
use squawk_syntax::SyntaxNode;
67
use squawk_syntax::{
78
SyntaxNodePtr,
89
ast::{self, AstNode},
@@ -11,17 +12,17 @@ use squawk_syntax::{
1112

1213
pub fn find_references(file: &ast::SourceFile, offset: TextSize) -> Vec<TextRange> {
1314
let binder = binder::bind(file);
14-
let Some(targets) = find_targets(file, offset, &binder) else {
15+
let root = file.syntax();
16+
let Some(targets) = find_targets(file, root, offset, &binder) else {
1517
return vec![];
1618
};
1719

1820
let mut refs = vec![];
19-
2021
for node in file.syntax().descendants() {
2122
match_ast! {
2223
match node {
2324
ast::NameRef(name_ref) => {
24-
if let Some(found_refs) = resolve::resolve_name_ref(&binder, &name_ref)
25+
if let Some(found_refs) = resolve::resolve_name_ref(&binder, root, &name_ref)
2526
&& found_refs.iter().any(|ptr| targets.contains(ptr))
2627
{
2728
refs.push(name_ref.syntax().text_range());
@@ -44,6 +45,7 @@ pub fn find_references(file: &ast::SourceFile, offset: TextSize) -> Vec<TextRang
4445

4546
fn find_targets(
4647
file: &ast::SourceFile,
48+
root: &SyntaxNode,
4749
offset: TextSize,
4850
binder: &Binder,
4951
) -> Option<SmallVec<[SyntaxNodePtr; 1]>> {
@@ -55,7 +57,7 @@ fn find_targets(
5557
}
5658

5759
if let Some(name_ref) = ast::NameRef::cast(parent.clone()) {
58-
return resolve::resolve_name_ref(binder, &name_ref);
60+
return resolve::resolve_name_ref(binder, root, &name_ref);
5961
}
6062

6163
None

crates/squawk_ide/src/goto_definition.rs

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ pub fn goto_definition(file: ast::SourceFile, offset: TextSize) -> SmallVec<[Tex
5858

5959
if let Some(name_ref) = ast::NameRef::cast(parent.clone()) {
6060
let binder_output = binder::bind(&file);
61-
if let Some(ptrs) = resolve::resolve_name_ref(&binder_output, &name_ref) {
61+
let root = file.syntax();
62+
if let Some(ptrs) = resolve::resolve_name_ref(&binder_output, root, &name_ref) {
6263
return ptrs
6364
.iter()
6465
.map(|ptr| ptr.to_node(file.syntax()).text_range())
@@ -243,6 +244,34 @@ drop table t$0;
243244
");
244245
}
245246

247+
#[test]
248+
fn goto_definition_on_dot_prefers_previous_token() {
249+
assert_snapshot!(goto("
250+
create table t(a int);
251+
select t.$0a from t;
252+
"), @r"
253+
╭▸
254+
2 │ create table t(a int);
255+
│ ─ 2. destination
256+
3 │ select t.a from t;
257+
╰╴ ─ 1. source
258+
");
259+
}
260+
261+
#[test]
262+
fn goto_with_table_star() {
263+
assert_snapshot!(goto("
264+
with t as (select 1 a)
265+
select t$0.* from t;
266+
"), @r"
267+
╭▸
268+
2 │ with t as (select 1 a)
269+
│ ─ 2. destination
270+
3 │ select t.* from t;
271+
╰╴ ─ 1. source
272+
");
273+
}
274+
246275
#[test]
247276
fn goto_drop_sequence() {
248277
assert_snapshot!(goto("
@@ -2415,6 +2444,32 @@ select a$0 from x;
24152444
");
24162445
}
24172446

2447+
#[test]
2448+
fn goto_cte_qualified_column_prefers_cte_over_table() {
2449+
assert_snapshot!(goto("
2450+
create table u(id int, b int);
2451+
with u as (select 1 id, 2 b)
2452+
select u.id$0 from u;
2453+
"), @r"
2454+
╭▸
2455+
3 │ with u as (select 1 id, 2 b)
2456+
│ ── 2. destination
2457+
4 │ select u.id from u;
2458+
╰╴ ─ 1. source
2459+
");
2460+
}
2461+
2462+
#[test]
2463+
fn goto_subquery_qualified_column() {
2464+
assert_snapshot!(goto("
2465+
select t.a$0 from (select 1 a) t;
2466+
"), @r"
2467+
╭▸
2468+
2 │ select t.a from (select 1 a) t;
2469+
╰╴ ─ 1. source ─ 2. destination
2470+
");
2471+
}
2472+
24182473
#[test]
24192474
fn goto_cte_multiple_columns() {
24202475
assert_snapshot!(goto("
@@ -2474,6 +2529,50 @@ select a$0 from y;
24742529
");
24752530
}
24762531

2532+
#[test]
2533+
fn goto_cte_qualified_star_join_column() {
2534+
assert_snapshot!(goto("
2535+
create table u(id int, b int);
2536+
create table t(id int, a int);
2537+
2538+
with k as (
2539+
select u.* from t join u on a = b
2540+
)
2541+
select b$0 from k;
2542+
"), @r"
2543+
╭▸
2544+
2 │ create table u(id int, b int);
2545+
│ ─ 2. destination
2546+
2547+
8 │ select b from k;
2548+
╰╴ ─ 1. source
2549+
");
2550+
}
2551+
2552+
#[test]
2553+
fn goto_cte_qualified_star_join_column_with_partial_column_list() {
2554+
assert_snapshot!(goto("
2555+
with
2556+
u as (
2557+
select 1 id, 2 b
2558+
),
2559+
t as (
2560+
select 1 id, 2 a
2561+
),
2562+
k(x) as (
2563+
select u.* from t join u on a = b
2564+
)
2565+
select b$0 from k;
2566+
"), @r"
2567+
╭▸
2568+
4 │ select 1 id, 2 b
2569+
│ ─ 2. destination
2570+
2571+
12 │ select b from k;
2572+
╰╴ ─ 1. source
2573+
");
2574+
}
2575+
24772576
#[test]
24782577
fn goto_cte_reference_inside_cte() {
24792578
assert_snapshot!(goto("
@@ -2614,6 +2713,32 @@ select a$0 from (select * from foo.t);
26142713
");
26152714
}
26162715

2716+
#[test]
2717+
fn goto_subquery_column_qualified_star_join() {
2718+
assert_snapshot!(goto("
2719+
create table t(a int);
2720+
create table u(b int);
2721+
select b$0 from (select u.* from t join u on a = b);
2722+
"), @r"
2723+
╭▸
2724+
3 │ create table u(b int);
2725+
│ ─ 2. destination
2726+
4 │ select b from (select u.* from t join u on a = b);
2727+
╰╴ ─ 1. source
2728+
");
2729+
}
2730+
2731+
#[test]
2732+
fn goto_subquery_column_qualified_star_join_not_found() {
2733+
goto_not_found(
2734+
"
2735+
create table t(a int);
2736+
create table u(b int);
2737+
select a$0 from (select u.* from t join u on a = b);
2738+
",
2739+
);
2740+
}
2741+
26172742
#[test]
26182743
fn goto_insert_table() {
26192744
assert_snapshot!(goto("

0 commit comments

Comments
 (0)