Add Swift support

pull/225/head
cherryblossom 2022-04-09 16:36:30 +07:00
parent 782b8f809e
commit b87d6c99f7
No known key found for this signature in database
GPG Key ID: 03B34648D6DEB639
13 changed files with 517389 additions and 1 deletions

@ -207,6 +207,11 @@ fn main() {
src_dir: "vendor/tree-sitter-scala-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser {
name: "tree-sitter-swift",
src_dir: "vendor/tree-sitter-swift-src",
extra_files: vec!["scanner.c"],
},
TreeSitterParser {
name: "tree-sitter-toml",
src_dir: "vendor/tree-sitter-toml-src",

@ -29,6 +29,7 @@ Difftastic supports the following programming languages.
| Ruby | [tree-sitter/tree-sitter-ruby](https://github.com/tree-sitter/tree-sitter-ruby) |
| Rust | [tree-sitter/tree-sitter-rust](https://github.com/tree-sitter/tree-sitter-rust) ([forked](https://github.com/Wilfred/tree-sitter-rust/tree/non_special_token)) |
| Scala | [tree-sitter/tree-sitter-scala](https://github.com/tree-sitter/tree-sitter-scala) |
| Swift | [alex-pinkus/tree-sitter-swift](https://github.com/alex-pinkus/tree-sitter-swift) |
| TypeScript, TSX | [tree-sitter/tree-sitter-typescript](https://github.com/tree-sitter/tree-sitter-typescript) |
| Zig | [maxxnino/tree-sitter-zig](https://github.com/maxxnino/tree-sitter-zig) |

@ -139,6 +139,9 @@ a1d8070fda3b8fa65886a90bde64a2ab -
sample_files/small_before.js sample_files/small_after.js
27bcac13aa17141718a3e6b8c0ac8f47 -
sample_files/swift_before.swift sample_files/swift_after.swift
eeab25a68552f051a6392b5e713fbd29 -
sample_files/syntax_error_before.js sample_files/syntax_error_after.js
fe636ad27b1aa75e0b153dfe248023bb -

@ -0,0 +1,3 @@
func f(_ x: Int) -> Int {
x * 3
}

@ -0,0 +1,3 @@
func f(_ x: Int) -> Int {
x * 2
}

@ -49,6 +49,7 @@ pub enum Language {
Ruby,
Rust,
Scala,
Swift,
Toml,
Tsx,
TypeScript,
@ -122,6 +123,7 @@ fn from_emacs_mode_header(src: &str) -> Option<Language> {
"rust" => Some(Rust),
"scala" => Some(Scala),
"sh" => Some(Bash),
"swift" => Some(Swift),
"toml" => Some(Toml),
"tuareg" => Some(OCaml),
"typescript" => Some(TypeScript),
@ -160,6 +162,7 @@ fn from_shebang(src: &str) -> Option<Language> {
"perl" => return Some(Perl),
"python" | "python2" | "python3" => return Some(Python),
"ruby" | "macruby" | "rake" | "jruby" | "rbx" => return Some(Ruby),
"swift" => return Some(Swift),
"deno" | "ts-node" => return Some(TypeScript),
_ => {}
}
@ -234,6 +237,7 @@ pub fn from_extension(extension: &OsStr) -> Option<Language> {
"rb" | "builder" | "spec" | "rake" => Some(Ruby),
"rs" => Some(Rust),
"scala" | "sbt" | "sc" => Some(Scala),
"swift" => Some(Swift),
"toml" => Some(Toml),
"ts" => Some(TypeScript),
"tsx" => Some(Tsx),

@ -67,7 +67,7 @@ fn prefer_outer_delimiter(language: guess_language::Language) -> bool {
// the inner delimiter is more relevant.
Bash | C | CPlusPlus | CSharp | Css | Dart | Elixir | Elm | Gleam | Go | Haskell | Java
| JavaScript | Jsx | Kotlin | Lua | Nix | OCaml | OCamlInterface | Perl | Php | Python
| Ruby | Rust | Scala | Tsx | TypeScript | Yaml | Zig => false,
| Ruby | Rust | Scala | Swift | Tsx | TypeScript | Yaml | Zig => false,
}
}

@ -73,6 +73,7 @@ extern "C" {
fn tree_sitter_ruby() -> ts::Language;
fn tree_sitter_rust() -> ts::Language;
fn tree_sitter_scala() -> ts::Language;
fn tree_sitter_swift() -> ts::Language;
fn tree_sitter_toml() -> ts::Language;
fn tree_sitter_tsx() -> ts::Language;
fn tree_sitter_typescript() -> ts::Language;
@ -578,6 +579,20 @@ pub fn from_language(language: guess::Language) -> TreeSitterConfig {
.unwrap(),
}
}
Swift => {
let language = unsafe { tree_sitter_swift() };
TreeSitterConfig {
name: "Swift",
language,
atom_nodes: ["_string_literal"].into(),
delimiter_tokens: vec![("{", "}"), ("(", ")"), ("[", "]"), ("<", ">")],
highlight_query: ts::Query::new(
language,
include_str!("../vendor/highlights/swift.scm"),
)
.unwrap(),
}
}
Toml => {
let language = unsafe { tree_sitter_toml() };
TreeSitterConfig {

@ -0,0 +1 @@
../tree-sitter-swift/queries/highlights.scm

@ -0,0 +1 @@
tree-sitter-swift/src

@ -1,6 +1,8 @@
node_modules
/src/*
!/src/scanner.c
!/src/parser.c
!/src/tree_sitter
*.swp
/build
/test

File diff suppressed because it is too large Load Diff

@ -0,0 +1,224 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define ts_builtin_sym_error ((TSSymbol)-1)
#define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
typedef uint16_t TSStateId;
#ifndef TREE_SITTER_API_H_
typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage;
#endif
typedef struct {
TSFieldId field_id;
uint8_t child_index;
bool inherited;
} TSFieldMapEntry;
typedef struct {
uint16_t index;
uint16_t length;
} TSFieldMapSlice;
typedef struct {
bool visible;
bool named;
bool supertype;
} TSSymbolMetadata;
typedef struct TSLexer TSLexer;
struct TSLexer {
int32_t lookahead;
TSSymbol result_symbol;
void (*advance)(TSLexer *, bool);
void (*mark_end)(TSLexer *);
uint32_t (*get_column)(TSLexer *);
bool (*is_at_included_range_start)(const TSLexer *);
bool (*eof)(const TSLexer *);
};
typedef enum {
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
TSParseActionTypeRecover,
} TSParseActionType;
typedef union {
struct {
uint8_t type;
TSStateId state;
bool extra;
bool repetition;
} shift;
struct {
uint8_t type;
uint8_t child_count;
TSSymbol symbol;
int16_t dynamic_precedence;
uint16_t production_id;
} reduce;
uint8_t type;
} TSParseAction;
typedef struct {
uint16_t lex_state;
uint16_t external_lex_state;
} TSLexMode;
typedef union {
TSParseAction action;
struct {
uint8_t count;
bool reusable;
} entry;
} TSParseActionEntry;
struct TSLanguage {
uint32_t version;
uint32_t symbol_count;
uint32_t alias_count;
uint32_t token_count;
uint32_t external_token_count;
uint32_t state_count;
uint32_t large_state_count;
uint32_t production_id_count;
uint32_t field_count;
uint16_t max_alias_sequence_length;
const uint16_t *parse_table;
const uint16_t *small_parse_table;
const uint32_t *small_parse_table_map;
const TSParseActionEntry *parse_actions;
const char * const *symbol_names;
const char * const *field_names;
const TSFieldMapSlice *field_map_slices;
const TSFieldMapEntry *field_map_entries;
const TSSymbolMetadata *symbol_metadata;
const TSSymbol *public_symbol_map;
const uint16_t *alias_map;
const TSSymbol *alias_sequences;
const TSLexMode *lex_modes;
bool (*lex_fn)(TSLexer *, TSStateId);
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
TSSymbol keyword_capture_token;
struct {
const bool *states;
const TSSymbol *symbol_map;
void *(*create)(void);
void (*destroy)(void *);
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
unsigned (*serialize)(void *, char *);
void (*deserialize)(void *, const char *, unsigned);
} external_scanner;
const TSStateId *primary_state_ids;
};
/*
* Lexer Macros
*/
#define START_LEXER() \
bool result = false; \
bool skip = false; \
bool eof = false; \
int32_t lookahead; \
goto start; \
next_state: \
lexer->advance(lexer, skip); \
start: \
skip = false; \
lookahead = lexer->lookahead;
#define ADVANCE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define SKIP(state_value) \
{ \
skip = true; \
state = state_value; \
goto next_state; \
}
#define ACCEPT_TOKEN(symbol_value) \
result = true; \
lexer->result_symbol = symbol_value; \
lexer->mark_end(lexer);
#define END_STATE() return result;
/*
* Parse Table Macros
*/
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
#define STATE(id) id
#define ACTIONS(id) id
#define SHIFT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value \
} \
}}
#define SHIFT_REPEAT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value, \
.repetition = true \
} \
}}
#define SHIFT_EXTRA() \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.extra = true \
} \
}}
#define REDUCE(symbol_val, child_count_val, ...) \
{{ \
.reduce = { \
.type = TSParseActionTypeReduce, \
.symbol = symbol_val, \
.child_count = child_count_val, \
__VA_ARGS__ \
}, \
}}
#define RECOVER() \
{{ \
.type = TSParseActionTypeRecover \
}}
#define ACCEPT_INPUT() \
{{ \
.type = TSParseActionTypeAccept \
}}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_