Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ tree-sitter-python = "<0.26.0"
tree-sitter-r = "1.1.0"
tree-sitter-ruby = "0.23.1"
tree-sitter-rust = "<0.25.0"
tree-sitter-swift = "<0.8.0"
tree-sitter-toml-ng = "<0.8.0"
tree-sitter-typescript = "0.23.2"
tree-sitter-zig = "<2"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ Codebook is in active development. As better dictionaries are added, words that
| Python | ✅ |
| Ruby | ✅ |
| Rust | ✅ |
| Swift | ⚠️ |
| TOML | ✅ |
| TypeScript | ✅ |
| Typst | ⚠️ |
Expand Down
1 change: 1 addition & 0 deletions crates/codebook/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ tree-sitter-python.workspace = true
tree-sitter-r.workspace = true
tree-sitter-ruby.workspace = true
tree-sitter-rust.workspace = true
tree-sitter-swift.workspace = true
tree-sitter-toml-ng.workspace = true
tree-sitter-typescript.workspace = true
codebook-tree-sitter-typst.workspace = true
Expand Down
9 changes: 9 additions & 0 deletions crates/codebook/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum LanguageType {
R,
Ruby,
Rust,
Swift,
TOML,
Text,
Typescript,
Expand Down Expand Up @@ -151,6 +152,13 @@ pub static LANGUAGE_SETTINGS: &[LanguageSetting] = &[
query: include_str!("queries/go.scm"),
extensions: &["go"],
},
LanguageSetting {
type_: LanguageType::Swift,
ids: &["swift"],
dictionary_ids: &["swift"],
query: include_str!("queries/swift.scm"),
extensions: &["swift"],
},
LanguageSetting {
type_: LanguageType::TOML,
ids: &["toml"],
Expand Down Expand Up @@ -248,6 +256,7 @@ impl LanguageSetting {
LanguageType::R => Some(tree_sitter_r::LANGUAGE.into()),
LanguageType::Ruby => Some(tree_sitter_ruby::LANGUAGE.into()),
LanguageType::Rust => Some(tree_sitter_rust::LANGUAGE.into()),
LanguageType::Swift => Some(tree_sitter_swift::LANGUAGE.into()),
LanguageType::TOML => Some(tree_sitter_toml_ng::LANGUAGE.into()),
LanguageType::Text => None,
LanguageType::Typescript => Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
Expand Down
20 changes: 20 additions & 0 deletions crates/codebook/src/queries/swift.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(comment) @comment
(multiline_comment) @comment

(class_declaration
name: (type_identifier) @identifier)

(function_declaration
name: (simple_identifier) @identifier)

(protocol_declaration
name: (type_identifier) @identifier)

(property_declaration
name: (pattern) @identifier)

(parameter
name: (simple_identifier) @identifier)

(line_string_literal) @string
(multi_line_string_literal) @string
154 changes: 154 additions & 0 deletions crates/codebook/tests/test_swift.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
use codebook::{
parser::{TextRange, WordLocation},
queries::LanguageType,
};

mod utils;

#[test]
fn test_swift_simple() {
utils::init_logging();
let processor = utils::get_processor();
let sample_text = r#"
// Misspell on a sepaate line
class Object { // comment at the end of the lne
// Comment can be inented
func bar() {
}
func opttions() {
}
}

/* func foobar()
* {
* These wors are
* comented out but should be identified
*/

func doStuff(_ nunber: Int)
{
}
func doMoar(_ nunber: Int)
{
}
func doAgain(frm: number: Int)
{
}
class Foo2 {
class MyThig {
}

// frozen_string_lteral: true

var x = "helo"

protocol enumrable {
}
"#;
let expected = vec![
"Moar", "Thig", "comented", "enumrable", "frm", "helo", "inented", "lne", "lteral", "nunber", "opttions", "sepaate", "wors"
];
let binding = processor
.spell_check(sample_text, Some(LanguageType::Swift), None)
.to_vec();
let mut misspelled = binding
.iter()
.map(|r| r.word.as_str())
.collect::<Vec<&str>>();
misspelled.sort();
println!("Misspelled words: {misspelled:?}");
assert_eq!(misspelled, expected);
}

#[test]
fn test_swift_code() {
utils::init_logging();
let sample_ruby_code = r#"
func send_notfication(to recipient: String, _ subject: String, body: String)
{
// This method sends an email with potentialy misspelled content
let email = Email(to: recipient,
subject: "URGENT: #{subject}",
body: "Dear valued custommer,\n\n#{body}\n\nRegads,\nSuport Team")
email.send()
}

if status == "complette" || status == "partialy_compleet" {
mark_as_finnished(item)
}
"#;

let expected = vec![
WordLocation::new(
"potentialy".to_string(),
vec![TextRange {
start_byte: 119,
end_byte: 129,
}],
),
WordLocation::new(
"compleet".to_string(),
vec![TextRange {
start_byte: 368,
end_byte: 376,
}],
),
WordLocation::new(
"notfication".to_string(),
vec![TextRange {
start_byte: 11,
end_byte: 22,
}],
),
WordLocation::new(
"Regads".to_string(),
vec![TextRange {
start_byte: 277,
end_byte: 283,
}],
),
WordLocation::new(
"complette".to_string(),
vec![TextRange {
start_byte: 334,
end_byte: 343,
}],
),
WordLocation::new(
"custommer".to_string(),
vec![TextRange {
start_byte: 252,
end_byte: 261,
}],
),
WordLocation::new(
"Suport".to_string(),
vec![TextRange {
start_byte: 286,
end_byte: 292,
}],
),
WordLocation::new(
"partialy".to_string(),
vec![TextRange {
start_byte: 359,
end_byte: 367,
}],
),
];
let not_expected = vec!["finnished"];
let processor = utils::get_processor();
let misspelled = processor
.spell_check(sample_ruby_code, Some(LanguageType::Swift), None)
.to_vec();
println!("Misspelled words: {misspelled:?}");
for e in &expected {
let miss = misspelled.iter().find(|r| r.word == e.word).unwrap();
println!("Expecting: {e:?}");
assert_eq!(miss.locations, e.locations);
}
for word in not_expected {
println!("Not expecting: {word:?}");
assert!(!misspelled.iter().any(|r| r.word == word));
}
}