|
1 | 1 | # Contributing
|
2 | 2 |
|
3 |
| -This guide refers to Swift Development Snapshots. These can be downloaded from [swift.org/download](https://swift.org/download/#snapshots). |
4 |
| -If you are seeing issues, it is generally a good idea to re-try with the latest Swift Development Snapshot. |
| 3 | +## Building & Testing |
5 | 4 |
|
6 |
| -## Building |
| 5 | +swift-syntax is a SwiftPM package, so you can build and test it using anything that supports packages - opening in Xcode, Visual Studio Code with [Swift for Visual Studio Code](https://github.com/swift-server/vscode-swift) installed, or through the command line using `swift build` and `swift test`. |
7 | 6 |
|
8 |
| -The easiest option to build SwiftSyntax is to open it in Xcode. |
| 7 | +> 💡 Tip: Running swift-syntax’s self-parse tests takes the majority of testing time. If you want to iterate quickly, you can skip these tests: |
| 8 | +> - In Xcode |
| 9 | +> 1. Product -> Scheme -> Edit Scheme… |
| 10 | +> 2. Select the Arguments tab in the Run section |
| 11 | +> 3. Add a `SKIP_LONG_TESTS` environment variable with value `1` |
| 12 | +> - On the command line: Set the `SKIP_LONG_TESTS` environment variable to `1` when running tests, e.g by running `SKIP_LONG_TESTS=1 swift test` |
9 | 13 |
|
10 |
| -Alternatively you can also build it from the command line using `build-script.py`. To do this, perform the following steps |
11 |
| - |
12 |
| -1. Check `swift-syntax` and `swift-argument-parser` out side by side: |
13 |
| - ``` |
14 |
| - - (enclosing directory) |
15 |
| - - swift-argument-parser |
16 |
| - - swift-syntax |
17 |
| - ``` |
18 |
| -2. Execute the following command |
19 |
| - ```bash |
20 |
| - swift-syntax/build-script.py build --toolchain /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-<recent date>.xctoolchain/usr |
21 |
| - ``` |
| 14 | +> 💡 Tip: If you are only modifying the `SwiftParser` module, you can run only the parser tests by selecting the `SwiftParserTest` target. |
| 15 | +> - In Xcode: Select the `SwiftParserTest` scheme. If you can’t find it in your Schemes, you need to manually add it using Product -> Scheme -> New Scheme… |
| 16 | +> - On the command line: Run `swift test --test-product SwiftParserTests` |
22 | 17 |
|
23 | 18 | ## Formatting
|
24 | 19 |
|
25 |
| -SwiftSyntax is being formatted using [swift-format](http://github.com/apple/swift-format) to ensure a consistent style. |
26 |
| -
|
27 |
| -To format your changes run `format.py` at the root of this repository. If you have a `swift-format` executable ready, you can pass it to `format.py`. If you do not, `format.py` will build its own copy of `swift-format` in /tmp/swift-format. |
28 |
| -
|
29 |
| -CI will ensure that all hand-written source code is correctly formatted. Generated source code is not formatted to make it easier to spot changes when re-running code generation. |
30 |
| -
|
31 |
| -## Testing |
32 |
| -
|
33 |
| -Because of SwiftSyntax’s integration with the Swift compiler project, testing certain parts of the project is a little bit more involved than others. |
34 |
| -
|
35 |
| -The `SwiftParser` tests have no dependencies, other `XCTests` require you to use a matching Swift Development Snapshot, `lit`-based test require a compiler build. |
36 |
| -
|
37 |
| -Run the tests that you believe are necessary locally. CI will always run all test before allowing the PR to be merged. |
38 |
| -
|
39 |
| -### SwiftParser |
| 20 | +swift-syntax is formatted using [swift-format](http://github.com/apple/swift-format) to ensure a consistent style. |
40 | 21 |
|
41 |
| -If you are only modifying the `SwiftParser` module, you can just run the tests using Xcode by testing the `SwiftParserTest` target. |
| 22 | +To format your changes run `format.py` at the root of this repository. If you have a `swift-format` executable ready, you can pass it to `format.py`. If you do not, `format.py` will build its own copy of `swift-format` in `/tmp/swift-format`. |
42 | 23 |
|
43 |
| -If you can’t find it in your Schemes, you need to manually add it using Product -> Scheme -> New Scheme… |
| 24 | +If you are seeing surprising formatting results, you most likely have a `swift-format` installed on your system that’s not the most recent version built from the `main` branch. To fix this, clone [swift-format](http://github.com/apple/swift-format), build it using `swift build` and pass the freshly built executable to `format.py` as `--swift-format path/to/swift-format/.build/debug/swift-format`. Alternatively, you can uninstall `swift-format` on your system and `format.py` will build it from scratch. |
44 | 25 |
|
45 |
| -### XCTests |
| 26 | +Generated source code is not formatted to make it easier to spot changes when re-running code generation. |
46 | 27 |
|
47 |
| -To run the tests in Xcode, select the SwiftSyntax-Package scheme and hit Product -> Test. |
48 |
| -
|
49 |
| -You can also run the tests from the command line using |
50 |
| -```bash |
51 |
| -./build-script.py test --toolchain /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-<recent date>.xctoolchain/usr --skip-lit-tests |
52 |
| -``` |
| 28 | +## Generating Source Code |
53 | 29 |
|
54 |
| -If you are seeing issues regarding a mismatched parser library, try the following |
55 |
| -1. Update your Swift Development Snapshot |
56 |
| -2. Revert your swift-syntax checkout to the date of your Swift Development Snapshot |
57 |
| -3. Wait for a new Swift Development Snapshot |
58 |
| -4. If the above options are not possible, build your own Swift toolchain locally and use that toolchain as the `--toolchain` parameter for SwiftSyntax’s `build-script.py` invocations |
59 |
| - - Note: Building your own toolchain will take more than 1 hour and even longer if you are running into any issues. We do not recommend building your own Swift toolchain unless you are familiar with Swift compiler development. |
| 30 | +If you want to modify the generated files, open the [CodeGeneration](CodeGeneration) package and run the `generate-swift-syntax` executable. |
60 | 31 |
|
61 |
| -Tip: Running SwiftSyntax’s self-parse tests takes the majority of testing time. If you want to iterate quickly, you can skip these tests using the following steps: |
62 |
| -1. Product -> Scheme -> Edit Scheme… |
63 |
| -2. Select the Arguments tab in the Run section |
64 |
| -3. Add a `SKIP_LONG_TESTS` environment variable with value `1` |
| 32 | +## Additional Verification |
65 | 33 |
|
66 |
| -### Additional Verification |
| 34 | +swift-syntax has additional verification methods (see the sections below) that provide more extensive validation. They have a significant runtime impact on swift-syntax and are thus not enabled by default when building swift-syntax, but are enabled in CI. If CI fails and you are unable to reproduce the failure locally, make sure that `SKIP_LONG_TESTS` is not set and try enabling these validations. |
67 | 35 |
|
68 |
| -swift-syntax has two additional verification methods (see the two sections below) that provide more extensive validation. They have significant runtime impact on swift-syntax and are thus not enabled by default when building swift-syntax, but are enabled in CI. If CI fails and you are unable to reproduce the failure locally, make sure that `SKIP_LONG_TESTS` is not set and try enabling these validations. |
| 36 | +### RawSyntax Validation |
69 | 37 |
|
70 |
| -#### RawSyntax Validation |
| 38 | +When the `SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION` environment variable is set while building swift-syntax, SwiftSyntax will perform additional validation that the layout of the syntax tree is correct. It validates that |
| 39 | +1. every child of a syntax node has the correct kind, which should be guaranteed by the Swift type system in most cases |
| 40 | +2. each token only has one of the token kinds that is specified in the syntax tree layout of the `CodeGeneration` package. |
71 | 41 |
|
72 |
| -When the `SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION` environment variable is set while building swift-syntax (or the check for that variable has been changed to always return `true` in Package.swift), SwiftSyntax will perform additional validation that the layout of the syntax tree is correct. It validates that every child of a syntax node has the correct kind (which should be guaranteed by the Swift type system in most cases) and, more importantly, validates that each token only has one of the token kinds that is specified in the syntax tree layout of the `CodeGeneration` package. |
| 42 | +If this validation hits an assertion failure that a token is not accepted at a certain position in the syntax tree, double-check if the token kind that is being stored in the syntax tree actually makes sense here. If it does not, check if there is a parser bug or whether you need to remap the token kind. If it does make sense, add the token kind to `.token(choices:)` of the syntax node in CodeGeneration, re-generate that source code and run tests again. |
73 | 43 |
|
74 |
| -If this validation hits an assertion failure that a token is not accepted at a certain position in the syntax tree, double check if the token kind that is being stored in the syntax tree actually makes sense here. If it does not, check if there is a parser bug or whether you need to remap the token kind. If it does make sense, add the token kind to `.token(choices:)` of the syntax node in CodeGeneration, re-generate that source code and run tests again. |
| 44 | +> 💡 Tip: If you want to run tests in Xcode with RawSyntax validation enabled, you can also modify Package.swift and replace the check for `SWIFTSYNTAX_ENABLE_RAWSYNTAX_VALIDATION` with `true`. |
75 | 45 |
|
76 |
| -#### Test Case Mutation |
| 46 | +### Test Case Mutation |
77 | 47 |
|
78 |
| -When the `SWIFTPARSER_ENABLE_ALTERNATE_TOKEN_INTROSPECTION` environment variable is set while building swift-syntax (or the check for that variable has been changed to always return `true` in Package.swift), SwiftParser records alternative tokens that the parser was looking for at specific offsets in the source file (e.g. whether it also checked for a `struct` keyword when the source code contained a `class` keyword). It will then use that information to mutate the test case by e.g. substituting `class` by `struct`. |
| 48 | +When the `SWIFTPARSER_ENABLE_ALTERNATE_TOKEN_INTROSPECTION` environment variable is set while building swift-syntax, SwiftParser records alternative tokens that the parser was looking for at specific offsets in the source file, e.g. whether it also checked for a `struct` keyword when the source code contained a `class` keyword. It will then use that information to mutate the test case by e.g. substituting `class` with `struct`. |
79 | 49 |
|
80 | 50 | When testing finds one of these failures, it will show you the syntax tree that produced the failure. Create a new test case with the source code the failure gives you and fix the failure.
|
81 | 51 |
|
82 |
| -### `lit`-based Tests |
83 |
| - |
84 |
| -A few tests are based LLVM’s `lit` and `FileCheck` tools. |
85 |
| -To run these, build `FileCheck`, e.g. by building the Swift compiler and run the tests using the following command: |
86 |
| -```bash |
87 |
| -./build-script.py test --toolchain /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-<recent date>.xctoolchain/usr --filecheck-exec /path/to/build/Release+Asserts/llvm-macosx-x86_64/bin/FileCheck |
88 |
| -``` |
89 |
| - |
90 |
| -## Generating Source Code |
91 |
| - |
92 |
| -If you want to modify the code-generated files, perform the following steps: |
93 |
| - |
94 |
| -1. Check out `swift` next to `swift-syntax` |
95 |
| - ``` |
96 |
| - - (enclosing directory) |
97 |
| - - swift |
98 |
| - - swift-argument-parser |
99 |
| - - swift-syntax |
100 |
| - ``` |
101 |
| -2. Run the following command |
102 |
| - ```bash |
103 |
| - swift-syntax/build-script.py generate-source-code --toolchain /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-<recent date>.xctoolchain/usr |
104 |
| - ``` |
105 |
| -3. The new source-generated file will be written into your `Sources` directory. |
106 |
| -
|
107 | 52 | ## Swift Version
|
108 | 53 |
|
109 |
| -We require that SwiftSyntax builds with the latest released compiler and the previous major version (e.g. with Swift 5.8 and Swift 5.7). |
| 54 | +We require that swift-syntax builds with the latest released compiler and the previous major version (e.g. with Swift 5.8 and Swift 5.7). |
0 commit comments