Skip to content

Commit e0a55cc

Browse files
prg318Lukas Sabotablopker
authored
Add support for the swift programming language (#190)
* Add support for the swift programming language * Limit version number for swift --------- Co-authored-by: Lukas Sabota <[email protected]> Co-authored-by: Bo Lopker <[email protected]>
1 parent 0d39da7 commit e0a55cc

File tree

7 files changed

+197
-0
lines changed

7 files changed

+197
-0
lines changed

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ tree-sitter-python = "<0.26.0"
5959
tree-sitter-r = "1.1.0"
6060
tree-sitter-ruby = "0.23.1"
6161
tree-sitter-rust = "<0.25.0"
62+
tree-sitter-swift = "<0.8.0"
6263
tree-sitter-toml-ng = "<0.8.0"
6364
tree-sitter-typescript = "0.23.2"
6465
tree-sitter-zig = "<2"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ Codebook is in active development. As better dictionaries are added, words that
151151
| Python ||
152152
| Ruby ||
153153
| Rust ||
154+
| Swift | ⚠️ |
154155
| TOML ||
155156
| TypeScript ||
156157
| Typst | ⚠️ |

crates/codebook/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ tree-sitter-python.workspace = true
4646
tree-sitter-r.workspace = true
4747
tree-sitter-ruby.workspace = true
4848
tree-sitter-rust.workspace = true
49+
tree-sitter-swift.workspace = true
4950
tree-sitter-toml-ng.workspace = true
5051
tree-sitter-typescript.workspace = true
5152
codebook-tree-sitter-typst.workspace = true

crates/codebook/src/queries.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub enum LanguageType {
2222
R,
2323
Ruby,
2424
Rust,
25+
Swift,
2526
TOML,
2627
Text,
2728
Typescript,
@@ -151,6 +152,13 @@ pub static LANGUAGE_SETTINGS: &[LanguageSetting] = &[
151152
query: include_str!("queries/go.scm"),
152153
extensions: &["go"],
153154
},
155+
LanguageSetting {
156+
type_: LanguageType::Swift,
157+
ids: &["swift"],
158+
dictionary_ids: &["swift"],
159+
query: include_str!("queries/swift.scm"),
160+
extensions: &["swift"],
161+
},
154162
LanguageSetting {
155163
type_: LanguageType::TOML,
156164
ids: &["toml"],
@@ -248,6 +256,7 @@ impl LanguageSetting {
248256
LanguageType::R => Some(tree_sitter_r::LANGUAGE.into()),
249257
LanguageType::Ruby => Some(tree_sitter_ruby::LANGUAGE.into()),
250258
LanguageType::Rust => Some(tree_sitter_rust::LANGUAGE.into()),
259+
LanguageType::Swift => Some(tree_sitter_swift::LANGUAGE.into()),
251260
LanguageType::TOML => Some(tree_sitter_toml_ng::LANGUAGE.into()),
252261
LanguageType::Text => None,
253262
LanguageType::Typescript => Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
(comment) @comment
2+
(multiline_comment) @comment
3+
4+
(class_declaration
5+
name: (type_identifier) @identifier)
6+
7+
(function_declaration
8+
name: (simple_identifier) @identifier)
9+
10+
(protocol_declaration
11+
name: (type_identifier) @identifier)
12+
13+
(property_declaration
14+
name: (pattern) @identifier)
15+
16+
(parameter
17+
name: (simple_identifier) @identifier)
18+
19+
(line_string_literal) @string
20+
(multi_line_string_literal) @string
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
use codebook::{
2+
parser::{TextRange, WordLocation},
3+
queries::LanguageType,
4+
};
5+
6+
mod utils;
7+
8+
#[test]
9+
fn test_swift_simple() {
10+
utils::init_logging();
11+
let processor = utils::get_processor();
12+
let sample_text = r#"
13+
// Misspell on a sepaate line
14+
class Object { // comment at the end of the lne
15+
// Comment can be inented
16+
func bar() {
17+
}
18+
func opttions() {
19+
}
20+
}
21+
22+
/* func foobar()
23+
* {
24+
* These wors are
25+
* comented out but should be identified
26+
*/
27+
28+
func doStuff(_ nunber: Int)
29+
{
30+
}
31+
func doMoar(_ nunber: Int)
32+
{
33+
}
34+
func doAgain(frm: number: Int)
35+
{
36+
}
37+
class Foo2 {
38+
class MyThig {
39+
}
40+
41+
// frozen_string_lteral: true
42+
43+
var x = "helo"
44+
45+
protocol enumrable {
46+
}
47+
"#;
48+
let expected = vec![
49+
"Moar", "Thig", "comented", "enumrable", "frm", "helo", "inented", "lne", "lteral", "nunber", "opttions", "sepaate", "wors"
50+
];
51+
let binding = processor
52+
.spell_check(sample_text, Some(LanguageType::Swift), None)
53+
.to_vec();
54+
let mut misspelled = binding
55+
.iter()
56+
.map(|r| r.word.as_str())
57+
.collect::<Vec<&str>>();
58+
misspelled.sort();
59+
println!("Misspelled words: {misspelled:?}");
60+
assert_eq!(misspelled, expected);
61+
}
62+
63+
#[test]
64+
fn test_swift_code() {
65+
utils::init_logging();
66+
let sample_ruby_code = r#"
67+
func send_notfication(to recipient: String, _ subject: String, body: String)
68+
{
69+
// This method sends an email with potentialy misspelled content
70+
let email = Email(to: recipient,
71+
subject: "URGENT: #{subject}",
72+
body: "Dear valued custommer,\n\n#{body}\n\nRegads,\nSuport Team")
73+
email.send()
74+
}
75+
76+
if status == "complette" || status == "partialy_compleet" {
77+
mark_as_finnished(item)
78+
}
79+
"#;
80+
81+
let expected = vec![
82+
WordLocation::new(
83+
"potentialy".to_string(),
84+
vec![TextRange {
85+
start_byte: 119,
86+
end_byte: 129,
87+
}],
88+
),
89+
WordLocation::new(
90+
"compleet".to_string(),
91+
vec![TextRange {
92+
start_byte: 368,
93+
end_byte: 376,
94+
}],
95+
),
96+
WordLocation::new(
97+
"notfication".to_string(),
98+
vec![TextRange {
99+
start_byte: 11,
100+
end_byte: 22,
101+
}],
102+
),
103+
WordLocation::new(
104+
"Regads".to_string(),
105+
vec![TextRange {
106+
start_byte: 277,
107+
end_byte: 283,
108+
}],
109+
),
110+
WordLocation::new(
111+
"complette".to_string(),
112+
vec![TextRange {
113+
start_byte: 334,
114+
end_byte: 343,
115+
}],
116+
),
117+
WordLocation::new(
118+
"custommer".to_string(),
119+
vec![TextRange {
120+
start_byte: 252,
121+
end_byte: 261,
122+
}],
123+
),
124+
WordLocation::new(
125+
"Suport".to_string(),
126+
vec![TextRange {
127+
start_byte: 286,
128+
end_byte: 292,
129+
}],
130+
),
131+
WordLocation::new(
132+
"partialy".to_string(),
133+
vec![TextRange {
134+
start_byte: 359,
135+
end_byte: 367,
136+
}],
137+
),
138+
];
139+
let not_expected = vec!["finnished"];
140+
let processor = utils::get_processor();
141+
let misspelled = processor
142+
.spell_check(sample_ruby_code, Some(LanguageType::Swift), None)
143+
.to_vec();
144+
println!("Misspelled words: {misspelled:?}");
145+
for e in &expected {
146+
let miss = misspelled.iter().find(|r| r.word == e.word).unwrap();
147+
println!("Expecting: {e:?}");
148+
assert_eq!(miss.locations, e.locations);
149+
}
150+
for word in not_expected {
151+
println!("Not expecting: {word:?}");
152+
assert!(!misspelled.iter().any(|r| r.word == word));
153+
}
154+
}

0 commit comments

Comments
 (0)