Skip to content
Open
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
1 change: 1 addition & 0 deletions docs/src/content/docs/core-concepts/plugin-system.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ kit comes with built-in support for 12+ programming languages:
- **Dart** (`.dart`) - Classes, functions, mixins, enums, extensions
- **HCL/Terraform** (`.hcl`, `.tf`) - Resources, variables, modules
- **Haskell** (`.hs`) - Module header, functions (including lambda-binds), common type-level declarations
- **Swift** (`.swift`) - Classes, structs, enums, protocols, actors, extensions, functions

Each language supports comprehensive symbol extraction including:
- **Classes and interfaces** with inheritance relationships
Expand Down
42 changes: 42 additions & 0 deletions src/kit/queries/swift/tags.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
;; tags.scm for Swift symbol extraction (tree-sitter-swift)

; Function declarations
(function_declaration
name: (simple_identifier) @name) @definition.function

; Class declarations (keyword-differentiated from struct/enum/extension)
(class_declaration
"class"
name: (type_identifier) @name) @definition.class

; Actor declarations
(class_declaration
"actor"
name: (type_identifier) @name) @definition.actor

; Struct declarations
(class_declaration
"struct"
name: (type_identifier) @name) @definition.struct

; Enum declarations
(class_declaration
"enum"
name: (type_identifier) @name) @definition.enum

; Extension declarations (name field is user_type, not type_identifier)
(class_declaration
"extension"
name: (user_type) @name) @definition.extension

; Protocol declarations
(protocol_declaration
name: (type_identifier) @name) @definition.protocol

; Type alias declarations
(typealias_declaration
name: (type_identifier) @name) @definition.typealias

; Initializer declarations
(init_declaration
"init" @name) @definition.initializer
2 changes: 2 additions & 0 deletions src/kit/tree_sitter_symbol_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
".hxx": "cpp",
".zig": "zig",
".cs": "csharp",
".swift": "swift",
}


Expand Down Expand Up @@ -350,6 +351,7 @@ def reset_plugins(cls) -> None:
".hxx": "cpp",
".zig": "zig",
".cs": "csharp",
".swift": "swift",
}
LANGUAGES.clear()
LANGUAGES.update(original_languages)
Expand Down
91 changes: 91 additions & 0 deletions tests/test_swift_symbols.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import pytest

from kit.tree_sitter_symbol_extractor import TreeSitterSymbolExtractor

SWIFT_SAMPLE = """\
class Animal {
var name: String
init(name: String) {
self.name = name
}
}

struct Point {
var x: Int
var y: Int
}

enum Direction {
case north, south, east, west
}

extension Animal {
func speak() -> String {
return name
}
}

actor Worker {
func run() {}
}

protocol Drawable {
func draw()
}

typealias StringMap = [String: String]

func greet(person: String) -> String {
return "Hello, \\(person)!"
}
"""


def test_swift_parser_and_query_available():
parser = TreeSitterSymbolExtractor.get_parser(".swift")
query = TreeSitterSymbolExtractor.get_query(".swift")
if not parser or not query:
pytest.skip("Swift parser or query not available in this environment")

tree = parser.parse(SWIFT_SAMPLE.encode("utf-8"))
assert tree.root_node is not None


def test_swift_symbols():
parser = TreeSitterSymbolExtractor.get_parser(".swift")
query = TreeSitterSymbolExtractor.get_query(".swift")
if not parser or not query:
pytest.skip("Swift parser or query not available in this environment")

symbols = TreeSitterSymbolExtractor.extract_symbols(".swift", SWIFT_SAMPLE)
names = {s["name"] for s in symbols}
types = {s["type"] for s in symbols}
animal_symbols = [s for s in symbols if s["name"] == "Animal"]

assert "Animal" in names
assert "Point" in names
assert "Direction" in names
assert "Worker" in names
assert "Drawable" in names
assert "StringMap" in names
assert "greet" in names
assert "init" in names

assert len(animal_symbols) == 2
assert {s["type"] for s in animal_symbols} == {"class", "extension"}

assert "class" in types
assert "actor" in types
assert "struct" in types
assert "enum" in types
assert "extension" in types
assert "protocol" in types
assert "typealias" in types
assert "function" in types
assert "initializer" in types


def test_swift_in_supported_languages():
supported = TreeSitterSymbolExtractor.list_supported_languages()
assert "swift" in supported
assert ".swift" in supported["swift"]
1 change: 1 addition & 0 deletions tests/test_symbol_extraction_multilang.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
".java": "class Bar { void foo() {} }\n",
".rs": "fn foo() {}\nstruct Bar;\n",
".zig": "pub fn foo() void {}\npub const Bar = struct {};\n",
".swift": "func foo() -> Int { return 42 }\nclass Bar {}\n",
}


Expand Down
1 change: 1 addition & 0 deletions tests/test_tree_sitter_languages.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"c": b"int foo() { return 42; }\n",
"dart": b"int foo() { return 42; }\n",
"zig": b"pub fn foo() void { }\n",
"swift": b"func foo() -> Int { return 42 }\n",
}


Expand Down
Loading