Skip to content

Commit 55b7753

Browse files
authored
linter: remove Identifier wrapper type (#1139)
1 parent 849449c commit 55b7753

33 files changed

Lines changed: 359 additions & 285 deletions

crates/squawk_ide/src/code_actions/quote_identifier.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use rowan::TextSize;
22
use salsa::Database as Db;
3-
use squawk_syntax::{
4-
ast::{self, AstNode},
5-
quote::normalize_identifier,
6-
};
3+
use squawk_syntax::ast::{self, AstNode};
74

85
use crate::{db::File, offsets::token_from_offset};
96

@@ -18,25 +15,27 @@ pub(super) fn quote_identifier(
1815
let token = token_from_offset(db, file, offset)?;
1916
let parent = token.parent()?;
2017

21-
let name_node = if let Some(name) = ast::Name::cast(parent.clone()) {
22-
name.syntax().clone()
23-
} else if let Some(name_ref) = ast::NameRef::cast(parent) {
24-
name_ref.syntax().clone()
18+
let (is_quoted, text, text_range) = if let Some(name) = ast::Name::cast(parent.clone()) {
19+
(name.is_quoted(), name.text(), name.syntax().text_range())
20+
} else if let Some(name_ref) = ast::NameRef::cast(parent.clone()) {
21+
(
22+
name_ref.is_quoted(),
23+
name_ref.text(),
24+
name_ref.syntax().text_range(),
25+
)
2526
} else {
2627
return None;
2728
};
2829

29-
let text = name_node.text().to_string();
30-
31-
if text.starts_with('"') {
30+
if is_quoted {
3231
return None;
3332
}
3433

35-
let quoted = format!(r#""{}""#, normalize_identifier(&text));
34+
let quoted = format!(r#""{text}""#);
3635

3736
actions.push(CodeAction {
3837
title: "Quote identifier".to_owned(),
39-
edits: vec![squawk_linter::Edit::replace(name_node.text_range(), quoted)],
38+
edits: vec![squawk_linter::Edit::replace(text_range, quoted)],
4039
kind: ActionKind::RefactorRewrite,
4140
});
4241

crates/squawk_ide/src/code_actions/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ fn code_action_not_applicable_(
9595
allow_errors: bool,
9696
) -> bool {
9797
let fixture = Fixture::new(sql);
98-
let offset = fixture.marker().offset();
98+
let offset = fixture.marker().offset_before();
9999
let sql = fixture.sql();
100100
let db = Database::default();
101101
let file = File::new(&db, sql.into());

crates/squawk_ide/src/collect.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::ast_nav;
2-
use crate::builtins::builtins_file;
32
use crate::column_name::ColumnName;
4-
use crate::db::{File, parse};
3+
use crate::db::{File, list_files, parse};
54
use crate::goto_definition::goto_definition;
65
use crate::infer::{Type, infer_type_from_expr, infer_type_from_ty};
76
use crate::location::{Location, LocationKind};
@@ -216,7 +215,7 @@ pub(crate) fn create_table_as_columns_with_types(
216215
file: File,
217216
create_table_as: &ast::CreateTableAs,
218217
) -> Vec<(Name, Option<Type>)> {
219-
for file in [file, builtins_file(db)] {
218+
for file in list_files(db, file) {
220219
let columns = select_columns_with_types(db, file, &create_table_as.query());
221220
if !columns.is_empty() {
222221
return columns;
@@ -426,7 +425,7 @@ pub(crate) fn view_like_columns_with_types(
426425
.collect();
427426

428427
let mut base_columns = vec![];
429-
for file in [file, builtins_file(db)] {
428+
for file in list_files(db, file) {
430429
base_columns = select_columns_with_types(db, file, &create_view.query());
431430
if !base_columns.is_empty() {
432431
break;
@@ -464,7 +463,7 @@ pub(crate) fn with_table_columns_with_types(
464463
.collect();
465464

466465
let mut base_columns = vec![];
467-
for file in [file, builtins_file(db)] {
466+
for file in list_files(db, file) {
468467
base_columns = with_table_query_columns_with_types(db, file, with_table.clone());
469468
if !base_columns.is_empty() {
470469
break;
@@ -686,7 +685,7 @@ fn columns_for_star_from_table_ptr(
686685
columns_for_star_from_alias(db, file, &from_item, &alias)
687686
}
688687
Some(ast_nav::ParentSouce::WithTable(with_table)) => {
689-
for f in [file, builtins_file(db)] {
688+
for f in list_files(db, file) {
690689
let columns = with_table_columns_with_types(db, f, with_table.clone());
691690
if !columns.is_empty() {
692691
return columns;
@@ -826,7 +825,7 @@ pub(crate) fn star_column_names(db: &dyn Db, file: File, table_ptr: &SyntaxNodeP
826825
.filter_map(|column| column.name().map(|name| Name::from_node(&name)))
827826
.collect(),
828827
Some(ast_nav::ParentSouce::WithTable(with_table)) => {
829-
for file in [file, builtins_file(db)] {
828+
for file in list_files(db, file) {
830829
let columns: Vec<_> = with_table_columns_with_types(db, file, with_table.clone())
831830
.into_iter()
832831
.map(|(name, _)| name)

crates/squawk_ide/src/column_name.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ use squawk_syntax::{
33
ast::{self, AstNode},
44
};
55

6-
use squawk_syntax::quote::normalize_identifier;
7-
86
#[derive(Clone, Debug, PartialEq)]
97
pub(crate) enum ColumnName {
108
Column(String),
@@ -29,9 +27,10 @@ impl ColumnName {
2927
if let Some(as_name) = target.as_name()
3028
&& let Some(name_node) = as_name.name()
3129
{
32-
let text = name_node.text();
33-
let normalized = normalize_identifier(&text);
34-
return Some((ColumnName::Column(normalized), name_node.syntax().clone()));
30+
return Some((
31+
ColumnName::Column(name_node.text()),
32+
name_node.syntax().clone(),
33+
));
3534
}
3635
Self::inferred_from_target(target)
3736
}
@@ -133,7 +132,7 @@ fn name_from_type(ty: ast::Type, unknown_column: bool) -> Option<(ColumnName, Sy
133132
name.push_str("tz");
134133
};
135134
return Some((
136-
ColumnName::new(name.to_string(), unknown_column),
135+
ColumnName::new(name, unknown_column),
137136
time_type.syntax().clone(),
138137
));
139138
}
@@ -228,9 +227,10 @@ fn name_from_name_ref(
228227
}
229228
}
230229
}
231-
let text = name_ref.text();
232-
let normalized = normalize_identifier(&text);
233-
return Some((ColumnName::Column(normalized), name_ref.syntax().clone()));
230+
return Some((
231+
ColumnName::Column(name_ref.text()),
232+
name_ref.syntax().clone(),
233+
));
234234
}
235235

236236
/*

crates/squawk_ide/src/db.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::sync::Arc;
66

77
use crate::binder;
88
use crate::binder::Binder;
9+
use crate::builtins::builtins_file;
910

1011
#[salsa::input]
1112
pub struct File {
@@ -23,6 +24,11 @@ pub fn line_index(db: &dyn Db, file: File) -> LineIndex {
2324
LineIndex::new(file.content(db))
2425
}
2526

27+
#[inline]
28+
pub(crate) fn list_files(db: &dyn Db, file: File) -> impl Iterator<Item = File> {
29+
[file, builtins_file(db)].into_iter()
30+
}
31+
2632
#[salsa::tracked]
2733
pub fn bind(db: &dyn Db, file: File) -> Binder {
2834
let result = parse(db, file);

crates/squawk_ide/src/goto_definition.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use crate::builtins::builtins_file;
2-
use crate::db::{File, parse};
1+
use crate::db::{File, list_files, parse};
32
use crate::location::{Location, LocationKind};
43
use crate::offsets::token_from_offset;
54
use crate::resolve;
@@ -66,7 +65,7 @@ pub fn goto_definition(db: &dyn Db, file: File, offset: TextSize) -> SmallVec<[L
6665
}
6766

6867
if let Some(name_ref) = ast::NameRef::cast(parent.clone()) {
69-
for definition_file in [file, builtins_file(db)] {
68+
for definition_file in list_files(db, file) {
7069
if let Some(locations) = resolve::resolve_name_ref(db, definition_file, &name_ref) {
7170
return locations;
7271
}
@@ -82,7 +81,7 @@ pub fn goto_definition(db: &dyn Db, file: File, offset: TextSize) -> SmallVec<[L
8281
}
8382
});
8483
if let Some(ty) = type_node {
85-
for definition_file in [file, builtins_file(db)] {
84+
for definition_file in list_files(db, file) {
8685
let position = token.text_range().start();
8786
if let Some(ptr) =
8887
resolve::resolve_type_ptr_from_type(db, definition_file, &ty, position)

crates/squawk_ide/src/hover.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use crate::ast_nav;
2-
use crate::builtins::builtins_file;
32
use crate::collect;
43
use crate::column_name::ColumnName;
54
use crate::comments::preceding_comment;
6-
use crate::db::{File, bind, parse};
5+
use crate::db::{File, bind, list_files, parse};
76
use crate::infer::infer_type_from_expr;
87
use crate::location::{Location, LocationKind};
98
use crate::name;
@@ -548,7 +547,7 @@ fn hover_qualified_star(db: &dyn Db, file: File, field_expr: ast::FieldExpr) ->
548547

549548
fn hover_unqualified_star(db: &dyn Db, file: File, target: ast::Target) -> Option<Hover> {
550549
let mut results = vec![];
551-
for file in [file, builtins_file(db)] {
550+
for file in list_files(db, file) {
552551
results = hover_unqualified_star_with_binder(db, file, &target);
553552
if results.is_empty() && target_has_schema_qualified_from_item(&target) {
554553
continue;

crates/squawk_ide/src/name.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use smol_str::SmolStr;
22
use squawk_syntax::ast::{self, AstNode};
33
use std::fmt;
44

5-
use squawk_syntax::quote::normalize_identifier;
6-
75
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
86
pub(crate) struct Name(pub(crate) SmolStr);
97

@@ -23,15 +21,20 @@ impl fmt::Display for Schema {
2321
}
2422

2523
impl Name {
24+
// TODO: we should get rid of this and update the ast methods to return
25+
// normalized idents.
2626
pub(crate) fn from_string(text: impl Into<SmolStr>) -> Self {
2727
let text = text.into();
28-
let normalized = normalize_identifier(&text);
29-
Name(normalized.into())
28+
let text = text
29+
.strip_prefix('"')
30+
.and_then(|t| t.strip_suffix('"'))
31+
.map(|x| x.replace(r#""""#, "\""))
32+
.unwrap_or(text.to_ascii_lowercase());
33+
Name(text.into())
3034
}
3135
pub(crate) fn from_node(node: &impl ast::NameLike) -> Self {
32-
let text = node.syntax().text().to_string();
33-
let normalized = normalize_identifier(&text);
34-
Name(normalized.into())
36+
let text = node.text();
37+
Name(text.into())
3538
}
3639
}
3740

@@ -198,7 +201,7 @@ mod test {
198201
use super::*;
199202
#[test]
200203
fn name_case_insensitive_compare() {
201-
assert_eq!(Name::from_string("foo"), Name::from_string("FOO"));
204+
assert_eq!(Name::from_string("foo"), Name::from_string(r#""foo""#));
202205
}
203206

204207
#[test]

crates/squawk_ide/src/resolve.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
use crate::ast_nav;
1+
use crate::{ast_nav, db::list_files};
22
use rowan::TextSize;
33
use smallvec::{SmallVec, smallvec};
44
use squawk_syntax::{
55
SyntaxKind, SyntaxNode, SyntaxNodePtr,
66
ast::{self, AstNode},
77
};
88

9-
use crate::builtins::builtins_file;
109
use crate::column_name::ColumnName;
1110
use crate::db::File;
1211
use crate::location::{Location, LocationKind};
@@ -1379,7 +1378,7 @@ pub(crate) fn resolve_table_name(
13791378
position: TextSize,
13801379
) -> Option<(File, ResolvedTableName)> {
13811380
use ResolvedTableName::*;
1382-
for file in [file, builtins_file(db)] {
1381+
for file in list_files(db, file) {
13831382
let Some((ptr, kind)) = resolve_table_like(db, file, None, table_name, schema, position)
13841383
else {
13851384
continue;

crates/squawk_linter/src/rules/adding_field_with_default.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@ use std::sync::OnceLock;
22

33
use rustc_hash::FxHashSet;
44

5+
use squawk_syntax::ast;
56
use squawk_syntax::ast::AstNode;
67
use squawk_syntax::{Parse, SourceFile, SyntaxKind};
7-
use squawk_syntax::{ast, identifier::Identifier};
88

99
use crate::{Linter, Rule, Version, Violation};
1010

11-
fn non_volatile_funcs() -> &'static FxHashSet<Identifier> {
12-
static NON_VOLATILE_FUNCS: OnceLock<FxHashSet<Identifier>> = OnceLock::new();
11+
fn non_volatile_funcs() -> &'static FxHashSet<&'static str> {
12+
static NON_VOLATILE_FUNCS: OnceLock<FxHashSet<&'static str>> = OnceLock::new();
1313
NON_VOLATILE_FUNCS.get_or_init(|| {
1414
NON_VOLATILE_BUILT_IN_FUNCTIONS
1515
.split('\n')
1616
.map(|x| x.trim())
1717
.filter(|x| !x.is_empty())
18-
.map(Identifier::new)
1918
.collect()
2019
})
2120
}
@@ -41,8 +40,7 @@ fn is_non_volatile_or_const(expr: &ast::Expr) -> bool {
4140
return false;
4241
};
4342

44-
let non_volatile_name =
45-
non_volatile_funcs().contains(&Identifier::new(name_ref.text().as_str()));
43+
let non_volatile_name = non_volatile_funcs().contains(name_ref.text().as_str());
4644

4745
no_args && non_volatile_name
4846
} else {

0 commit comments

Comments
 (0)