|
| 1 | + |
| 2 | +[](https://crates.io/crates/tree-sitter-swift) |
| 3 | +[](https://www.npmjs.com/package/tree-sitter-swift) |
| 4 | +[](https://github.com/alex-pinkus/tree-sitter-swift/actions/workflows/top-repos.yml) |
| 5 | + |
| 6 | +# tree-sitter-swift |
| 7 | + |
| 8 | +This contains a [`tree-sitter`](https://tree-sitter.github.io/tree-sitter) grammar for the Swift programming language. |
| 9 | + |
| 10 | +## Getting started |
| 11 | + |
| 12 | +To use this parser to parse Swift code, you'll want to depend on either the Rust crate or the NPM package. |
| 13 | + |
| 14 | +### Rust |
| 15 | + |
| 16 | +To use the Rust crate, you'll add this to your `Cargo.toml`: |
| 17 | + |
| 18 | +``` |
| 19 | +tree-sitter = "0.23.0" |
| 20 | +tree-sitter-swift = "=0.7.0" |
| 21 | +``` |
| 22 | + |
| 23 | +Then you can use a `tree-sitter` parser with the language declared here: |
| 24 | + |
| 25 | +``` |
| 26 | +let mut parser = tree_sitter::Parser::new(); |
| 27 | +parser.set_language(tree_sitter_swift::language())?; |
| 28 | +
|
| 29 | +// ... |
| 30 | +
|
| 31 | +let tree = parser.parse(&my_source_code, None) |
| 32 | + .ok_or_else(|| /* error handling code */)?; |
| 33 | +``` |
| 34 | + |
| 35 | +### Javascript |
| 36 | + |
| 37 | +To use this from NPM, you'll add similar dependencies to `package.json`: |
| 38 | + |
| 39 | +``` |
| 40 | +"dependencies: { |
| 41 | + "tree-sitter-swift": "0.7.0", |
| 42 | + "tree-sitter": "^0.22.1" |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +Your usage of the parser will look like: |
| 47 | + |
| 48 | +``` |
| 49 | +const Parser = require("tree-sitter"); |
| 50 | +const Swift = require("tree-sitter-swift"); |
| 51 | +
|
| 52 | +const parser = new Parser(); |
| 53 | +parser.setLanguage(Swift); |
| 54 | +
|
| 55 | +// ... |
| 56 | +
|
| 57 | +const tree = parser.parse(mySourceCode); |
| 58 | +``` |
| 59 | + |
| 60 | +### Editing the grammar |
| 61 | + |
| 62 | +With this package checked out, a common workflow for editing the grammar will look something like: |
| 63 | + |
| 64 | +1. Make a change to `grammar.ts`. |
| 65 | +2. Run `npm install && npm test` to see whether the change has had impact on existing parsing behavior. The default |
| 66 | + `npm test` target requires `valgrind` to be installed; if you do not have it installed, and do not wish to, you can |
| 67 | + substitute `tree-sitter test` directly. |
| 68 | +3. Run `tree-sitter parse` on some real Swift codebase and see whether (or where) it fails. |
| 69 | +4. Use any failures to create new corpus test cases. |
| 70 | + |
| 71 | +## Contributions |
| 72 | + |
| 73 | +All contributions to this repository are welcome. |
| 74 | + |
| 75 | +If said contribution is to check generated files (e.g., `parser.c`) into the repository, be aware that your contribution will not be accepted. Make sure to read the [FAQ entry](https://github.com/alex-pinkus/tree-sitter-swift?tab=readme-ov-file#where-is-your-parserc) and the [prior](https://github.com/alex-pinkus/tree-sitter-swift/issues/362) [discussions](https://github.com/alex-pinkus/tree-sitter-swift/pull/315) and [compromises](https://github.com/alex-pinkus/tree-sitter-swift/issues/149) that have occurred already on this topic. |
| 76 | + |
| 77 | +## Using tree-sitter-swift in Web Assembly |
| 78 | + |
| 79 | +To use tree-sitter-swift as a language for the web bindings version tree-sitter, which will likely be a more modern version than the published node |
| 80 | +module. [see](https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/README.md). Follow the instructions below |
| 81 | + |
| 82 | +1. Install the node modules `npm install web-tree-sitter tree-sitter-swift` |
| 83 | +2. Run the tree-sitter cli to create the wasm bundle |
| 84 | + ```sh |
| 85 | + $ npx tree-sitter build-asm ./node_modules/tree-sitter |
| 86 | + ``` |
| 87 | +3. Boot tree-sitter wasm like this. |
| 88 | + |
| 89 | +```js |
| 90 | +const Parser = require("web-tree-sitter"); |
| 91 | +async function run() { |
| 92 | + //needs to happen first |
| 93 | + await Parser.init(); |
| 94 | + //wait for the load of swift |
| 95 | + const Swift = await Parser.Language.load("./tree-sitter-swift.wasm"); |
| 96 | + |
| 97 | + const parser = new Parser(); |
| 98 | + parser.setLanguage(Swift); |
| 99 | + |
| 100 | + //Parse your swift code here. |
| 101 | + const tree = parser.parse('print("Hello, World!")'); |
| 102 | +} |
| 103 | +//if you want to run this |
| 104 | +run().then(console.log, console.error); |
| 105 | +``` |
| 106 | + |
| 107 | +## Frequently asked questions |
| 108 | + |
| 109 | +### Where is your `parser.c`? |
| 110 | + |
| 111 | +This repository currently omits most of the code that is autogenerated during a build. This means, for instance, that |
| 112 | +`grammar.json` and `parser.c` are both only available following a build. It also significantly reduces noise during |
| 113 | +diffs. |
| 114 | + |
| 115 | +The side benefit of not checking in `parser.c` is that you can guarantee backwards compatibility. Parsers generated by |
| 116 | +the tree-sitter CLI aren't always backwards compatible. If you need a parser, generate it yourself using the CLI; all |
| 117 | +the information to do so is available in this package. By doing that, you'll also know for sure that your parser version |
| 118 | +and your library version are compatible. |
| 119 | + |
| 120 | +If you need a `parser.c`, and you don't care about the tree-sitter version, but you don't have a local setup that would |
| 121 | +allow you to obtain the parser, you can just download one from a recent workflow run in this package. To do so: |
| 122 | + |
| 123 | +- Go to the [GitHub actions page](https://github.com/alex-pinkus/tree-sitter-swift/actions) for this |
| 124 | + repository. |
| 125 | +- Click on the "Publish `grammar.json` and `parser.c`" action for the appropriate commit. |
| 126 | +- Go down to `Artifacts` and click on `generated-parser-src`. All the relevant parser files will be available in your |
| 127 | + download. |
0 commit comments