├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── .stylish-haskell.yaml ├── README.md ├── cabal.project ├── docs └── benchmarking_notes.md ├── script ├── bootstrap ├── build-and-upload ├── cibuild ├── profile ├── update-languages └── upload ├── tree-sitter-c-sharp ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── CSharp.hs └── tree-sitter-c-sharp.cabal ├── tree-sitter-go ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── Go.hs └── tree-sitter-go.cabal ├── tree-sitter-haskell ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── Haskell.hs ├── examples │ └── Demo.hs └── tree-sitter-haskell.cabal ├── tree-sitter-java ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── Java.hs └── tree-sitter-java.cabal ├── tree-sitter-json ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── JSON.hs └── tree-sitter-json.cabal ├── tree-sitter-nix ├── TreeSitter │ └── Nix.hs ├── internal │ └── TreeSitter │ │ └── Nix │ │ └── Internal.hs └── tree-sitter-nix.cabal ├── tree-sitter-ocaml ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── OCaml.hs └── tree-sitter-ocaml.cabal ├── tree-sitter-php ├── ChangeLog.md ├── TreeSitter │ └── PHP.hs └── tree-sitter-php.cabal ├── tree-sitter-python ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── Python.hs └── tree-sitter-python.cabal ├── tree-sitter-ql ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── QL.hs └── tree-sitter-ql.cabal ├── tree-sitter-ruby ├── ChangeLog.md ├── TreeSitter │ └── Ruby.hs └── tree-sitter-ruby.cabal ├── tree-sitter-rust ├── ChangeLog.md ├── Setup.hs ├── TreeSitter │ └── Rust.hs └── tree-sitter-rust.cabal ├── tree-sitter-tsx ├── ChangeLog.md ├── TreeSitter │ └── TSX.hs └── tree-sitter-tsx.cabal ├── tree-sitter-typescript ├── ChangeLog.md ├── TreeSitter │ └── TypeScript.hs └── tree-sitter-typescript.cabal └── tree-sitter ├── ChangeLog.md ├── LICENSE ├── README.md ├── Setup.hs ├── src ├── TreeSitter │ ├── Cursor.hs │ ├── Language.hs │ ├── Node.hs │ ├── Parser.hs │ ├── Symbol.hs │ └── Tree.hs └── bridge.c ├── test ├── Test.hs └── TreeSitter │ ├── Example.hs │ └── Strings │ └── Example.hs └── tree-sitter.cabal /.gitattributes: -------------------------------------------------------------------------------- 1 | vendor linguist-vendored 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Set update schedule for GitHub Actions 2 | 3 | version: 2 4 | updates: 5 | 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | # Check for updates to GitHub Actions every week 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Haskell CI 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "**" 7 | push: 8 | branches: 9 | - "master" 10 | 11 | jobs: 12 | generateMatrix: 13 | name: "Generate matrix from cabal" 14 | outputs: 15 | matrix: ${{ steps.set-matrix.outputs.matrix }} 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout base repo 19 | uses: actions/checkout@v4 20 | - name: Extract the tested GHC versions 21 | id: set-matrix 22 | uses: kleidukos/get-tested@v0.1.7.0 23 | with: 24 | cabal-file: tree-sitter/tree-sitter.cabal 25 | ubuntu-version: "latest" 26 | version: 0.1.7.0 27 | build: 28 | name: ${{ matrix.ghc }} on ${{ matrix.os }} 29 | needs: generateMatrix 30 | runs-on: ${{ matrix.os }} 31 | strategy: 32 | matrix: ${{ fromJSON(needs.generateMatrix.outputs.matrix) }} 33 | steps: 34 | - name: Checkout base repo 35 | uses: actions/checkout@v4 36 | - uses: haskell-actions/setup@v2 37 | name: Setup Haskell 38 | id: setup-haskell 39 | with: 40 | ghc-version: ${{ matrix.ghc }} 41 | cabal-version: "latest" 42 | - name: Freeze 43 | run: cabal freeze 44 | - name: Cache 45 | uses: actions/cache@v4 46 | with: 47 | path: ${{ steps.setup-haskell.outputs.cabal-store }} 48 | key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-cabal-${{ hashFiles('**/plan.json') }} 49 | restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}- 50 | - uses: actions/cache@v4 51 | name: Cache dist-newstyle 52 | with: 53 | path: dist-newstyle 54 | key: ${{ runner.os }}-${{ matrix.ghc }}-repo-dist 55 | - name: Install dependencies 56 | run: | 57 | git submodule update -i --recursive 58 | cabal update 59 | cabal configure --enable-benchmarks --enable-tests --write-ghc-environment-files=always -j2 -O0 60 | cabal build --only-dependencies all 61 | 62 | - name: Build & test 63 | run: | 64 | cabal build all 65 | cabal test all 66 | cabal haddock all 67 | cabal sdist all 68 | for p in tree-sitter* ; do echo "$p" ; cd "$p" ; cabal check ; cd ..; done 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .stack-work 3 | dist 4 | dist-newstyle 5 | cabal.project.local 6 | .ghc.environment.* 7 | profiles 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/tree-sitter"] 2 | path = tree-sitter/vendor/tree-sitter 3 | url = https://github.com/tree-sitter/tree-sitter.git 4 | [submodule "vendor/tree-sitter-go"] 5 | path = tree-sitter-go/vendor/tree-sitter-go 6 | url = https://github.com/tree-sitter/tree-sitter-go.git 7 | [submodule "vendor/tree-sitter-json"] 8 | path = tree-sitter-json/vendor/tree-sitter-json 9 | url = https://github.com/tree-sitter/tree-sitter-json.git 10 | [submodule "vendor/tree-sitter-python"] 11 | path = tree-sitter-python/vendor/tree-sitter-python 12 | url = https://github.com/tree-sitter/tree-sitter-python.git 13 | [submodule "vendor/tree-sitter-ruby"] 14 | path = tree-sitter-ruby/vendor/tree-sitter-ruby 15 | url = https://github.com/tree-sitter/tree-sitter-ruby.git 16 | [submodule "vendor/tree-sitter-typescript"] 17 | path = tree-sitter-typescript/vendor/tree-sitter-typescript 18 | url = https://github.com/tree-sitter/tree-sitter-typescript.git 19 | [submodule "languages/php/vendor/tree-sitter-php"] 20 | path = tree-sitter-php/vendor/tree-sitter-php 21 | url = https://github.com/tree-sitter/tree-sitter-php 22 | [submodule "languages/haskell/vendor/tree-sitter-haskell"] 23 | path = tree-sitter-haskell/vendor/tree-sitter-haskell 24 | url = https://github.com/tree-sitter/tree-sitter-haskell.git 25 | [submodule "languages/java/vendor/tree-sitter-java"] 26 | path = tree-sitter-java/vendor/tree-sitter-java 27 | url = https://github.com/tree-sitter/tree-sitter-java.git 28 | [submodule "languages/nix/vendor/tree-sitter-nix"] 29 | path = tree-sitter-nix/vendor/tree-sitter-nix 30 | url = https://github.com/cstrahan/tree-sitter-nix 31 | [submodule "languages/tsx/vendor/tree-sitter-typescript"] 32 | path = tree-sitter-tsx/vendor/tree-sitter-typescript 33 | url = https://github.com/tree-sitter/tree-sitter-typescript 34 | [submodule "tree-sitter-ql/vendor/tree-sitter-ql"] 35 | path = tree-sitter-ql/vendor/tree-sitter-ql 36 | url = https://github.com/tree-sitter/tree-sitter-ql 37 | [submodule "tree-sitter-rust/vendor/tree-sitter-rust"] 38 | path = tree-sitter-rust/vendor/tree-sitter-rust 39 | url = https://github.com/tree-sitter/tree-sitter-rust 40 | [submodule "tree-sitter-c-sharp/vendor/tree-sitter-c-sharp"] 41 | path = tree-sitter-c-sharp/vendor/tree-sitter-c-sharp 42 | url = https://github.com/tree-sitter/tree-sitter-c-sharp 43 | [submodule "tree-sitter-ocaml/vendor/tree-sitter-ocaml"] 44 | path = tree-sitter-ocaml/vendor/tree-sitter-ocaml 45 | url = https://github.com/tree-sitter/tree-sitter-ocaml 46 | -------------------------------------------------------------------------------- /.stylish-haskell.yaml: -------------------------------------------------------------------------------- 1 | # stylish-haskell configuration file 2 | # ================================== 3 | 4 | # The stylish-haskell tool is mainly configured by specifying steps. These steps 5 | # are a list, so they have an order, and one specific step may appear more than 6 | # once (if needed). Each file is processed by these steps in the given order. 7 | steps: 8 | # Convert some ASCII sequences to their Unicode equivalents. This is disabled 9 | # by default. 10 | # - unicode_syntax: 11 | # # In order to make this work, we also need to insert the UnicodeSyntax 12 | # # language pragma. If this flag is set to true, we insert it when it's 13 | # # not already present. You may want to disable it if you configure 14 | # # language extensions using some other method than pragmas. Default: 15 | # # true. 16 | # add_language_pragma: true 17 | 18 | # Align the right hand side of some elements. This is quite conservative 19 | # and only applies to statements where each element occupies a single 20 | # line. 21 | - simple_align: 22 | cases: true 23 | top_level_patterns: true 24 | records: true 25 | 26 | # Import cleanup 27 | - imports: 28 | # There are different ways we can align names and lists. 29 | # 30 | # - global: Align the import names and import list throughout the entire 31 | # file. 32 | # 33 | # - file: Like global, but don't add padding when there are no qualified 34 | # imports in the file. 35 | # 36 | # - group: Only align the imports per group (a group is formed by adjacent 37 | # import lines). 38 | # 39 | # - none: Do not perform any alignment. 40 | # 41 | # Default: global. 42 | align: group 43 | 44 | # The following options affect only import list alignment. 45 | # 46 | # List align has following options: 47 | # 48 | # - after_alias: Import list is aligned with end of import including 49 | # 'as' and 'hiding' keywords. 50 | # 51 | # > import qualified Data.List as List (concat, foldl, foldr, head, 52 | # > init, last, length) 53 | # 54 | # - with_alias: Import list is aligned with start of alias or hiding. 55 | # 56 | # > import qualified Data.List as List (concat, foldl, foldr, head, 57 | # > init, last, length) 58 | # 59 | # - new_line: Import list starts always on new line. 60 | # 61 | # > import qualified Data.List as List 62 | # > (concat, foldl, foldr, head, init, last, length) 63 | # 64 | # Default: after_alias 65 | list_align: after_alias 66 | 67 | # Right-pad the module names to align imports in a group: 68 | # 69 | # - true: a little more readable 70 | # 71 | # > import qualified Data.List as List (concat, foldl, foldr, 72 | # > init, last, length) 73 | # > import qualified Data.List.Extra as List (concat, foldl, foldr, 74 | # > init, last, length) 75 | # 76 | # - false: diff-safe 77 | # 78 | # > import qualified Data.List as List (concat, foldl, foldr, init, 79 | # > last, length) 80 | # > import qualified Data.List.Extra as List (concat, foldl, foldr, 81 | # > init, last, length) 82 | # 83 | # Default: true 84 | pad_module_names: false 85 | 86 | # Long list align style takes effect when import is too long. This is 87 | # determined by 'columns' setting. 88 | # 89 | # - inline: This option will put as much specs on same line as possible. 90 | # 91 | # - new_line: Import list will start on new line. 92 | # 93 | # - new_line_multiline: Import list will start on new line when it's 94 | # short enough to fit to single line. Otherwise it'll be multiline. 95 | # 96 | # - multiline: One line per import list entry. 97 | # Type with constructor list acts like single import. 98 | # 99 | # > import qualified Data.Map as M 100 | # > ( empty 101 | # > , singleton 102 | # > , ... 103 | # > , delete 104 | # > ) 105 | # 106 | # Default: inline 107 | long_list_align: new_line_multiline 108 | 109 | # Align empty list (importing instances) 110 | # 111 | # Empty list align has following options 112 | # 113 | # - inherit: inherit list_align setting 114 | # 115 | # - right_after: () is right after the module name: 116 | # 117 | # > import Vector.Instances () 118 | # 119 | # Default: inherit 120 | empty_list_align: inherit 121 | 122 | # List padding determines indentation of import list on lines after import. 123 | # This option affects 'long_list_align'. 124 | # 125 | # - : constant value 126 | # 127 | # - module_name: align under start of module name. 128 | # Useful for 'file' and 'group' align settings. 129 | list_padding: 4 130 | 131 | # Separate lists option affects formatting of import list for type 132 | # or class. The only difference is single space between type and list 133 | # of constructors, selectors and class functions. 134 | # 135 | # - true: There is single space between Foldable type and list of it's 136 | # functions. 137 | # 138 | # > import Data.Foldable (Foldable (fold, foldl, foldMap)) 139 | # 140 | # - false: There is no space between Foldable type and list of it's 141 | # functions. 142 | # 143 | # > import Data.Foldable (Foldable(fold, foldl, foldMap)) 144 | # 145 | # Default: true 146 | separate_lists: true 147 | 148 | # Space surround option affects formatting of import lists on a single 149 | # line. The only difference is single space after the initial 150 | # parenthesis and a single space before the terminal parenthesis. 151 | # 152 | # - true: There is single space associated with the enclosing 153 | # parenthesis. 154 | # 155 | # > import Data.Foo ( foo ) 156 | # 157 | # - false: There is no space associated with the enclosing parenthesis 158 | # 159 | # > import Data.Foo (foo) 160 | # 161 | # Default: false 162 | space_surround: false 163 | 164 | # Language pragmas 165 | - language_pragmas: 166 | # We can generate different styles of language pragma lists. 167 | # 168 | # - vertical: Vertical-spaced language pragmas, one per line. 169 | # 170 | # - compact: A more compact style. 171 | # 172 | # - compact_line: Similar to compact, but wrap each line with 173 | # `{-#LANGUAGE #-}'. 174 | # 175 | # Default: vertical. 176 | style: vertical 177 | 178 | # Align affects alignment of closing pragma brackets. 179 | # 180 | # - true: Brackets are aligned in same column. 181 | # 182 | # - false: Brackets are not aligned together. There is only one space 183 | # between actual import and closing bracket. 184 | # 185 | # Default: true 186 | align: false 187 | 188 | # stylish-haskell can detect redundancy of some language pragmas. If this 189 | # is set to true, it will remove those redundant pragmas. Default: true. 190 | remove_redundant: true 191 | 192 | # Replace tabs by spaces. This is disabled by default. 193 | # - tabs: 194 | # # Number of spaces to use for each tab. Default: 8, as specified by the 195 | # # Haskell report. 196 | # spaces: 8 197 | 198 | # Remove trailing whitespace 199 | - trailing_whitespace: {} 200 | 201 | # A common setting is the number of columns (parts of) code will be wrapped 202 | # to. Different steps take this into account. Default: 80. 203 | columns: 120 204 | 205 | # By default, line endings are converted according to the OS. You can override 206 | # preferred format here. 207 | # 208 | # - native: Native newline format. CRLF on Windows, LF on other OSes. 209 | # 210 | # - lf: Convert to LF ("\n"). 211 | # 212 | # - crlf: Convert to CRLF ("\r\n"). 213 | # 214 | # Default: native. 215 | newline: native 216 | 217 | # Sometimes, language extensions are specified in a cabal file or from the 218 | # command line instead of using language pragmas in the file. stylish-haskell 219 | # needs to be aware of these, so it can parse the file correctly. 220 | language_extensions: 221 | - DataKinds 222 | - DeriveFoldable 223 | - DeriveFunctor 224 | - DeriveGeneric 225 | - DeriveTraversable 226 | - DerivingVia 227 | - ExplicitNamespaces 228 | - ExplicitForAll 229 | - FlexibleContexts 230 | - FlexibleInstances 231 | - MultiParamTypeClasses 232 | - OverloadedStrings 233 | - RecordWildCards 234 | - StandaloneDeriving 235 | - StrictData 236 | - TypeApplications 237 | - TypeOperators 238 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # haskell-tree-sitter 2 | 3 | This is the repository for the Haskell bindings to the `tree-sitter` incremental parsing toolkit, alongside a set of packages providing `tree-sitter`-compatible grammars for various programming languages. 4 | 5 | For more information, consult the `README` files in each project subdirectory. 6 | -------------------------------------------------------------------------------- /cabal.project: -------------------------------------------------------------------------------- 1 | packages: tree-sitter tree-sitter-* 2 | -------------------------------------------------------------------------------- /docs/benchmarking_notes.md: -------------------------------------------------------------------------------- 1 | # Goal 2 | 3 | Measure and benchmark the new precise unmarshalling to enable some targeted performance improvements. 4 | 5 | ## Notes 6 | 7 | See `script/profile` for running benchmarks and producing profiles. 8 | 9 |
10 | First baseline 11 | 12 | NOTE: These are hard to compare as some were taken with profiling enabled and others not. cabal builds binaries for libraries with and without profiling (both .o and .p_o files), but executable are only built with the current flags. 13 | 14 | ## Baseline 15 | 16 | Using *.rb glob in: 17 | `../semantic/tmp/ruby-examples/ruby_spec/command_line` 18 | 19 | Benchmark benchmarks: RUNNING... 20 | benchmarked parsing/ruby 21 | time 74.59 ms (69.31 ms .. 85.18 ms) 22 | 0.975 R² (0.935 R² .. 0.998 R²) 23 | mean 76.93 ms (74.29 ms .. 79.79 ms) 24 | std dev 5.228 ms (3.679 ms .. 7.447 ms) 25 | variance introduced by outliers: 17% (moderately inflated) 26 | 27 | ## Optimization: Using a table of matchers 28 | 29 | Using an IntMap of matchers instead of chain `if then` for symbol matching. 30 | 31 | benchmarked parsing/ruby 32 | time 25.10 ms (20.56 ms .. 33.29 ms) 33 | 0.654 R² (0.489 R² .. 0.972 R²) 34 | mean 24.32 ms (21.84 ms .. 29.52 ms) 35 | std dev 7.700 ms (4.905 ms .. 11.64 ms) 36 | variance introduced by outliers: 89% (severely inflated) 37 | 38 | *This was an erroneous result as we didn't properly contruct the IntMap for choice.* 39 | 40 | ## Optimization: Using a table of matchers (actually implement choice) 41 | 42 | benchmarking parsing/ruby ... took 9.376 s, total 56 iterations 43 | benchmarked parsing/ruby 44 | time 153.7 ms (128.2 ms .. 167.1 ms) 45 | 0.959 R² (0.861 R² .. 0.999 R²) 46 | mean 176.0 ms (163.4 ms .. 194.8 ms) 47 | std dev 27.36 ms (12.27 ms .. 38.39 ms) 48 | variance introduced by outliers: 48% (moderately inflated) 49 | 50 | :( Made it slower... 51 | 52 | ## Optimization: Rob's (reicarnated as Alonzo) latest datastructure (church encoded binary tree) 53 | 54 | benchmarking parsing/ruby ... took 8.321 s, total 56 iterations 55 | benchmarked parsing/ruby 56 | time 154.1 ms (144.4 ms .. 162.1 ms) 57 | 0.995 R² (0.990 R² .. 0.999 R²) 58 | mean 149.8 ms (144.3 ms .. 154.3 ms) 59 | std dev 8.540 ms (5.969 ms .. 12.65 ms) 60 | variance introduced by outliers: 18% (moderately inflated) 61 | 62 | *About the same :(* 63 | 64 |
65 | 66 | ## Alternative baseline(s) 67 | 68 | Including baselines with and without profiling enabled. 69 | 70 | Compiled with optimization and profiling 71 | 72 | ``` 73 | benchmarks: True 74 | optimization: True 75 | tests: True 76 | profiling: True 77 | profiling-detail: all-functions 78 | 79 | benchmarking parsing/ruby ... took 10.67 s, total 56 iterations 80 | benchmarked parsing/ruby 81 | time 199.8 ms (194.6 ms .. 205.1 ms) 82 | 0.998 R² (0.995 R² .. 1.000 R²) 83 | mean 191.0 ms (186.1 ms .. 194.4 ms) 84 | std dev 7.579 ms (4.293 ms .. 11.86 ms) 85 | ``` 86 | 87 | --- 88 | 89 | Compiled with optimization but no profiling 90 | 91 | ``` 92 | benchmarks: True 93 | optimization: True 94 | tests: True 95 | profiling: False 96 | 97 | Up to date 98 | benchmarked parsing/ruby 99 | time 71.99 ms (69.16 ms .. 75.91 ms) 100 | 0.995 R² (0.989 R² .. 0.999 R²) 101 | mean 70.11 ms (68.69 ms .. 71.66 ms) 102 | std dev 2.806 ms (1.965 ms .. 4.370 ms) 103 | ``` 104 | 105 | ## With b tree matchers 106 | 107 | Compiled with optimization and profiling 108 | 109 | ``` 110 | benchmarks: True 111 | optimization: True 112 | tests: True 113 | profiling: True 114 | profiling-detail: all-functions 115 | 116 | benchmarking parsing/ruby ... took 15.81 s, total 56 iterations 117 | benchmarked parsing/ruby 118 | time 295.9 ms (282.4 ms .. 332.7 ms) 119 | 0.984 R² (0.957 R² .. 0.999 R²) 120 | mean 280.8 ms (267.5 ms .. 299.5 ms) 121 | std dev 23.29 ms (14.77 ms .. 31.79 ms) 122 | variance introduced by outliers: 28% (moderately inflated) 123 | ``` 124 | 125 | --- 126 | 127 | Compiled with optimization but no profiling 128 | 129 | ``` 130 | benchmarks: True 131 | optimization: True 132 | tests: True 133 | profiling: False 134 | 135 | benchmarked parsing/ruby 136 | time 51.67 ms (51.01 ms .. 52.32 ms) 137 | 0.999 R² (0.999 R² .. 1.000 R²) 138 | mean 50.58 ms (49.77 ms .. 51.15 ms) 139 | std dev 1.329 ms (927.3 μs .. 1.685 ms) 140 | ``` 141 | 142 | NOTES: slightly faster here. 143 | 144 | ## With IntMap matchers 145 | 146 | Compiled with optimization and profiling 147 | 148 | ``` 149 | benchmarks: True 150 | optimization: True 151 | tests: True 152 | profiling: True 153 | profiling-detail: all-functions 154 | 155 | benchmarking parsing/ruby ... took 13.38 s, total 56 iterations 156 | benchmarked parsing/ruby 157 | time 228.4 ms (200.3 ms .. 243.7 ms) 158 | 0.984 R² (0.958 R² .. 0.999 R²) 159 | mean 245.5 ms (233.0 ms .. 272.6 ms) 160 | std dev 27.34 ms (16.01 ms .. 40.56 ms) 161 | variance introduced by outliers: 38% (moderately inflated) 162 | ``` 163 | 164 | --- 165 | 166 | Compiled with optimization but no profiling 167 | 168 | ``` 169 | benchmarks: True 170 | optimization: True 171 | tests: True 172 | profiling: False 173 | 174 | benchmarked parsing/ruby 175 | time 64.81 ms (58.99 ms .. 70.49 ms) 176 | 0.981 R² (0.943 R² .. 0.998 R²) 177 | mean 65.60 ms (63.48 ms .. 69.94 ms) 178 | std dev 5.054 ms (2.421 ms .. 7.985 ms) 179 | variance introduced by outliers: 24% (moderately inflated) 180 | ``` 181 | 182 | ## Specializing runMatch's monad transformer stack and some inlining 183 | 184 | ``` 185 | benchmarks: True 186 | optimization: True 187 | tests: True 188 | profiling: False 189 | 190 | benchmarked parsing/ruby 191 | time 13.47 ms (13.21 ms .. 13.87 ms) 192 | 0.992 R² (0.975 R² .. 0.999 R²) 193 | mean 13.59 ms (13.45 ms .. 13.90 ms) 194 | std dev 556.5 μs (236.0 μs .. 1.048 ms) 195 | variance introduced by outliers: 15% (moderately inflated) 196 | ``` 197 | -------------------------------------------------------------------------------- /script/bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | git submodule sync && git submodule update --init --recursive 4 | 5 | cabal new-update 6 | -------------------------------------------------------------------------------- /script/build-and-upload: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: script/build-and-upload PROJECT_NAME 4 | # where PROJECT_NAME is one of the packages present in this repo: 5 | # tree-sitter-python, tree-sitter-ruby, etc. 6 | 7 | set -e 8 | 9 | PROJECT="$1" 10 | ROOT_DIR="$(dirname "$0")/.." 11 | CABAL_PATH="$ROOT_DIR/$PROJECT/$PROJECT.cabal" 12 | 13 | if [ -z "$PROJECT" ] 14 | then echo "USAGE: build_and_upload PROJECT_NAME"; exit 1 15 | fi 16 | 17 | if [ ! -f "$CABAL_PATH" ] 18 | then echo "Couldn't find .cabal file at $CABAL_PATH; is $PROJECT a valid tree-sitter package?"; exit 1 19 | fi 20 | 21 | set -x 22 | 23 | cabal v2-build "$PROJECT" 24 | TGZ_LOC="$(cabal v2-sdist "$PROJECT" | tail -n 1)" 25 | DOCS_LOC="$(cabal v2-haddock --haddock-for-hackage "$PROJECT" | tail -n 1)" 26 | PACKAGE_VERSION="$(basename "$TGZ_LOC" .tar.gz)" 27 | 28 | if [ ! -f "$TGZ_LOC" ] 29 | then echo "Bug in build_and_upload: $PACKAGE_FN doesn't point to a valid path"; exit 1 30 | fi 31 | 32 | set +x 33 | 34 | echo "You are planning to upload '$PACKAGE_VERSION'." 35 | read -rp "Is this correct? [y/n] " choice 36 | if [ "$choice" != "y" ] 37 | then echo "Aborting."; exit 1 38 | fi 39 | 40 | echo "Attempting to build $PACKAGE_VERSION from source" 41 | TEMP_PATH=$(mktemp -d) 42 | tar -xvf "$TGZ_LOC" -C "$TEMP_PATH" 43 | 44 | set -x 45 | ( 46 | cd "$TEMP_PATH/$PACKAGE_VERSION" 47 | pwd 48 | 49 | cabal v2-update 50 | cabal v2-build --disable-optimization 51 | ) 52 | set +x 53 | 54 | if wget -q --spider "https://hackage.haskell.org/package/$PACKAGE_VERSION" 55 | then 56 | echo "The package $PACKAGE_VERSION already exists on Hackage." 57 | echo "If you need to upload code changes, then bump the version number in $PROJECT/$PROJECT.cabal, make a PR, and run this script again." 58 | echo "Otherwise, if you need _only_ to loosen existing constraints in $PROJECT.cabal file, then you can create a new revision of this package on Hackage." 59 | echo "You'll need to make your changes by hand. Be sure to click the 'Review changes' button to check your work." 60 | read -rp "Do you want to open a browser so as to do this? [y/N]" choice 61 | if [ "$choice" == "y" ] 62 | then 63 | echo "Opening…" 64 | sleep 1 65 | open "https://hackage.haskell.org/package/$PACKAGE_VERSION/$PROJECT.cabal/edit" 66 | exit 0 67 | else 68 | echo "Aborting" 69 | exit 1 70 | fi 71 | fi 72 | 73 | echo "******************" 74 | echo "Uploading packages" 75 | echo "******************" 76 | 77 | echo -n "Hackage username: " 78 | read HACKAGE_USER 79 | echo 80 | echo -n "Hackage password: " 81 | read -s HACKAGE_PASS 82 | 83 | cabal upload --username="$HACKAGE_USER" --password="$HACKAGE_PASS" "$TGZ_LOC" 84 | cabal upload --username="$HACKAGE_USER" --password="$HACKAGE_PASS" --documentation "$DOCS_LOC" 85 | 86 | URL="https://hackage.haskell.org/package/$PACKAGE_VERSION/candidate" 87 | 88 | echo "Opening candidate URL in browser…" 89 | sleep 1 90 | open "$URL" 91 | 92 | echo "About to upload final version. Do you want to proceed?" 93 | echo "Full-fledged package uploads cannot be undone!" 94 | read -rp "Type 'yes' to continue. " choice 95 | if [ "$choice" != "yes" ] 96 | then echo "Aborting."; exit 1 97 | fi 98 | 99 | set -x 100 | 101 | cabal upload --username="$HACKAGE_USER" --password="$HACKAGE_PASS" --publish "$TGZ_LOC" 102 | cabal upload --username="$HACKAGE_USER" --password="$HACKAGE_PASS" --publish --documentation "$DOCS_LOC" 103 | 104 | echo "Tagging $PACKAGE_VERSION" 105 | git tag "$PACKAGE_VERSION" 106 | git push --tags 107 | -------------------------------------------------------------------------------- /script/cibuild: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export LC_CTYPE=en_US.UTF-8 4 | 5 | "$(dirname $0)/bootstrap" 2> /dev/null 6 | 7 | cabal new-test tree-sitter:test 8 | -------------------------------------------------------------------------------- /script/profile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Usage: script/profile 3 | 4 | set -ex 5 | cd "$(dirname "$0")/.." 6 | 7 | HEAD_SHA=$(git rev-parse --short HEAD) 8 | CURRENT_BRANCH=$(git symbolic-ref HEAD 2>/dev/null | awk -F/ {'print $NF'}) 9 | 10 | PROJECT_DIR="$(dirname $0)/.." 11 | PROFILES_DIR="$PROJECT_DIR/profiles" 12 | TODAY="$(date "+%Y-%m-%d")" 13 | NOW=$(date "+%H_%M_%S") 14 | PROFILE_DIR="$PROFILES_DIR/$TODAY/$NOW-$CURRENT_BRANCH-$HEAD_SHA" 15 | OUTFILE="$PROFILE_DIR/profile.out.log" 16 | ERRFILE="$PROFILE_DIR/profile.err.log" 17 | 18 | # cabal v2-configure --enable-profiling --profiling-detail=all-functions --enable-optimization 19 | cabal v2-build exe:benchmarks 20 | 21 | mkdir -p "$PROFILE_DIR" 22 | 23 | # NB: Do not try and use -N, it doesn't work and defaults to -N1. 24 | cores=$(sysctl -n machdep.cpu.core_count || echo 4) 25 | cabal v2-run exe:benchmarks -- +RTS -N$((cores * 2)) -p -sstderr -h -i0.1 -L1000 -xt -RTS > "$OUTFILE" 2> "$ERRFILE" 26 | # cabal v2-run exe:benchmarks -- +RTS -N$((cores * 2)) -A8m -n2m -p -sstderr -h -i0.1 -L1000 -xt -RTS > "$OUTFILE" 2> "$ERRFILE" 27 | 28 | cat "$ERRFILE" 29 | 30 | profiteur benchmarks.prof || true 31 | 32 | hp2pretty benchmarks.hp 33 | 34 | for f in "$PROJECT_DIR/"benchmarks.*; do 35 | if [ "$f" != "$PROJECT_DIR/"benchmarks.cabal ]; then 36 | mv "$f" "$PROFILE_DIR" 37 | fi 38 | done 39 | 40 | (>&2 echo "branch: $CURRENT_BRANCH ($HEAD_SHA)") 41 | 42 | open "$PROFILE_DIR" 43 | -------------------------------------------------------------------------------- /script/update-languages: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #/ Usage: script/update-languages [--build] 3 | 4 | CURRENT=$(pwd); 5 | 6 | script/bootstrap 7 | 8 | if [ "$1" = "--build" ]; then 9 | for language in $(ls . | grep tree-sitter); do 10 | echo "Building $language..." 11 | cabal new-build $language 12 | done 13 | else 14 | for language in $(ls . | grep tree-sitter); do 15 | if [ $language = "tree-sitter-tsx" ]; then 16 | cd $language/vendor/tree-sitter-typescript; 17 | elif [ $language = "tree-sitter-test-helpers" ]; then 18 | continue 19 | else 20 | cd $language/vendor/$language; 21 | fi 22 | echo $(pwd); 23 | git checkout master; git pull origin master; 24 | cd $CURRENT; 25 | done 26 | fi 27 | 28 | echo "Done" 29 | -------------------------------------------------------------------------------- /script/upload: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd "$(dirname "$0")/.." 6 | 7 | package="$1" 8 | publish="$2" 9 | 10 | usage() { 11 | echo "Usage: script/upload PACKAGE [--publish]" 12 | exit 1 13 | } 14 | 15 | if [ -z "$package" ]; then 16 | usage 17 | fi 18 | 19 | packageFile="$(cabal sdist "$package" | tail -1)" 20 | docsFile="$(cabal haddock --haddock-for-hackage "$package" | tail -1)" 21 | 22 | if [ -z "$publish" ]; then 23 | cabal upload "$packageFile" 24 | cabal upload --documentation "$docsFile" 25 | elif [ "$publish" = "--publish" ]; then 26 | cabal upload "$packageFile" --publish 27 | cabal upload --documentation "$docsFile" --publish 28 | else 29 | usage 30 | fi 31 | -------------------------------------------------------------------------------- /tree-sitter-c-sharp/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.1.0.0 2 | 3 | * add tree-sitter-c-sharp parser 4 | -------------------------------------------------------------------------------- /tree-sitter-c-sharp/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-c-sharp/TreeSitter/CSharp.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.CSharp 2 | ( tree_sitter_c_sharp 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_c_sharp 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-c-sharp/src/parser.c tree_sitter_c_sharp" tree_sitter_c_sharp :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-c-sharp/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-c-sharp/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-c-sharp/tree-sitter-c-sharp.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-c-sharp 3 | version: 0.1.0.1 4 | synopsis: Tree-sitter grammar/parser for C# 5 | description: This package provides a parser for C# suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-c-sharp 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson, Damien Guard 9 | maintainer: damieng@gmail.com 10 | copyright: 2020 GitHub 11 | category: Tree-sitter, CSharp, C# 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-c-sharp/src/node-types.json 14 | , vendor/tree-sitter-c-sharp/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.CSharp 46 | autogen-modules: Paths_tree_sitter_c_sharp 47 | other-modules: Paths_tree_sitter_c_sharp 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter ^>= 0.9.0.0 50 | Include-dirs: vendor/tree-sitter-c-sharp/src 51 | install-includes: tree_sitter/parser.h 52 | c-sources: vendor/tree-sitter-c-sharp/src/parser.c 53 | extra-libraries: stdc++ 54 | cc-options: -Wno-trigraphs 55 | 56 | source-repository head 57 | type: git 58 | location: https://github.com/tree-sitter/haskell-tree-sitter 59 | -------------------------------------------------------------------------------- /tree-sitter-go/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.5.0.2 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.5.0.0 7 | 8 | * remove CodeGen and Template Haskell splice 9 | * move contents of internal library into library and remove internal library 10 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 11 | -------------------------------------------------------------------------------- /tree-sitter-go/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-go/TreeSitter/Go.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Go 2 | ( tree_sitter_go 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_go 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-go/src/parser.c tree_sitter_go" tree_sitter_go :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-go/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-go/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-go/tree-sitter-go.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-go 3 | version: 0.5.0.3 4 | synopsis: Tree-sitter grammar/parser for Go 5 | description: This package provides a parser for Go suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-go 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: tclem@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, Go 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-go/src/node-types.json 14 | , vendor/tree-sitter-go/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.Go 46 | autogen-modules: Paths_tree_sitter_go 47 | other-modules: Paths_tree_sitter_go 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter 50 | include-dirs: vendor/tree-sitter-go/src 51 | install-includes: tree_sitter/parser.h 52 | c-sources: vendor/tree-sitter-go/src/parser.c 53 | 54 | source-repository head 55 | type: git 56 | location: https://github.com/tree-sitter/haskell-tree-sitter 57 | -------------------------------------------------------------------------------- /tree-sitter-haskell/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.3.0.1 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.3.0.0 7 | 8 | * remove CodeGen and Template Haskell splice 9 | * move contents of internal library into library and remove internal library 10 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 11 | -------------------------------------------------------------------------------- /tree-sitter-haskell/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-haskell/TreeSitter/Haskell.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Haskell 2 | ( tree_sitter_haskell 3 | , getNodeTypesPath 4 | ) where 5 | 6 | import Foreign.Ptr 7 | import TreeSitter.Language 8 | import Paths_tree_sitter_haskell 9 | 10 | foreign import ccall unsafe "vendor/tree-sitter-haskell/src/parser.c tree_sitter_haskell" tree_sitter_haskell :: Ptr Language 11 | 12 | getNodeTypesPath :: IO FilePath 13 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-haskell/src/node-types.json" 14 | -------------------------------------------------------------------------------- /tree-sitter-haskell/examples/Demo.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE RecordWildCards #-} 3 | module Main (main) where 4 | 5 | import TreeSitter.Parser 6 | import TreeSitter.Tree 7 | import TreeSitter.Haskell 8 | import TreeSitter.Node 9 | import Foreign.C.String 10 | import Foreign.Ptr ( Ptr 11 | , nullPtr 12 | ) 13 | import Foreign.Marshal.Alloc ( malloc ) 14 | import Foreign.Marshal.Array ( mallocArray ) 15 | import Foreign.Storable ( peek 16 | , peekElemOff 17 | , poke 18 | ) 19 | import Control.Monad 20 | 21 | 22 | main :: IO () 23 | main = do 24 | parser <- ts_parser_new 25 | _ <- ts_parser_set_language parser tree_sitter_haskell 26 | 27 | let source = 28 | "module Test (main) where\nimport Lib\nf1 = undefined\nf2 = undefined" 29 | 30 | (str, len) <- newCStringLen source 31 | tree <- ts_parser_parse_string parser nullPtr str len 32 | 33 | n <- malloc 34 | ts_tree_root_node_p tree n 35 | 36 | putStrLn "module (root) ------------" 37 | Node {..} <- peek n -- header, imports, and declarations 38 | let childCount = fromIntegral nodeChildCount 39 | 40 | children <- mallocArray childCount 41 | tsNode <- malloc 42 | poke tsNode nodeTSNode 43 | ts_node_copy_child_nodes tsNode children 44 | 45 | printChildren children childCount 46 | 47 | putStrLn "declarations ------------" 48 | Node {..} <- peekElemOff children 2 -- declarations: bind and bind 49 | let nextChildCount = fromIntegral nodeChildCount 50 | 51 | nextChildren <- mallocArray nextChildCount 52 | nextTsNode <- malloc 53 | poke nextTsNode nodeTSNode 54 | ts_node_copy_child_nodes nextTsNode nextChildren 55 | 56 | printChildren nextChildren nextChildCount 57 | 58 | putStrLn "END" 59 | 60 | printChildren :: Ptr Node -> Int -> IO () 61 | printChildren children count = forM_ 62 | [0 .. count - 1] 63 | (\n -> do 64 | child <- peekElemOff children n 65 | printNode child 66 | ) 67 | 68 | printNode :: Node -> IO () 69 | printNode n@(Node {..}) = do 70 | theType <- peekCString nodeType 71 | let TSPoint {..} = nodeStartPoint n 72 | start = "(" ++ show pointRow ++ "," ++ show pointColumn ++ ")" 73 | let TSPoint {..} = nodeEndPoint 74 | end = "(" ++ show pointRow ++ "," ++ show pointColumn ++ ")" 75 | putStrLn $ theType ++ start ++ "-" ++ end 76 | -------------------------------------------------------------------------------- /tree-sitter-haskell/tree-sitter-haskell.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.2 2 | name: tree-sitter-haskell 3 | version: 0.3.0.2 4 | synopsis: Tree-sitter grammar/parser for Haskell (with GHC extensions) 5 | description: This package provides a parser for Haskell suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-haskell 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: tclem@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, Haskell 12 | build-type: Simple 13 | extra-doc-files: ChangeLog.md 14 | 15 | common common 16 | default-language: Haskell2010 17 | ghc-options: 18 | -Weverything 19 | -Wno-all-missed-specialisations 20 | -Wno-implicit-prelude 21 | -Wno-missed-specialisations 22 | -Wno-missing-import-lists 23 | -Wno-missing-local-signatures 24 | -Wno-monomorphism-restriction 25 | -Wno-name-shadowing 26 | -Wno-safe 27 | -Wno-unsafe 28 | if (impl(ghc >= 8.6)) 29 | ghc-options: -Wno-star-is-type 30 | if (impl(ghc >= 8.8)) 31 | ghc-options: -Wno-missing-deriving-strategies 32 | if (impl(ghc >= 8.10)) 33 | ghc-options: 34 | -Wno-missing-safe-haskell-mode 35 | -Wno-prepositive-qualified-module 36 | if (impl(ghc >= 9.2)) 37 | ghc-options: 38 | -Wno-missing-kind-signatures 39 | -Wno-implicit-lift 40 | 41 | flag build-examples 42 | description: Build tree-sitter-haskell examples. 43 | default: False 44 | 45 | executable demo 46 | import: common 47 | main-is: Demo.hs 48 | if !flag(build-examples) 49 | buildable: False 50 | hs-source-dirs: examples 51 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 52 | build-depends: 53 | base 54 | , tree-sitter 55 | , tree-sitter-haskell 56 | 57 | library 58 | import: common 59 | exposed-modules: TreeSitter.Haskell 60 | autogen-modules: Paths_tree_sitter_haskell 61 | other-modules: Paths_tree_sitter_haskell 62 | build-depends: base >= 4.12 && < 5 63 | , tree-sitter 64 | Include-dirs: vendor/tree-sitter-haskell/src 65 | install-includes: tree_sitter/parser.h 66 | c-sources: vendor/tree-sitter-haskell/src/parser.c 67 | , vendor/tree-sitter-haskell/src/scanner.c 68 | cxx-sources: 69 | extra-libraries: stdc++ 70 | 71 | source-repository head 72 | type: git 73 | location: https://github.com/tree-sitter/haskell-tree-sitter 74 | -------------------------------------------------------------------------------- /tree-sitter-java/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.7.0.2 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.7.0.0 7 | 8 | * remove CodeGen and Template Haskell splice 9 | * move contents of internal library into library and remove internal library 10 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 11 | 12 | # v0.4.0.0 13 | 14 | * AST datatypes use a shared `Token` datatype for all anonymous leaves. 15 | * Bumps the lower bound on `tree-sitter` to 0.5. 16 | * AST named sum datatypes are represented as `newtype` wrappers around sums constructed with `:+:`. 17 | * AST named & anonymous sum types are represented as balanced binary trees of `:+:`s instead of right-chained lists. 18 | * Rename the `bytes` field of leaves to `text`. 19 | 20 | # v0.3.0.0 21 | 22 | * Adds AST datatypes in `TreeSitter.Java.AST` which you can use with `TreeSitter.Unmarshal`. 23 | -------------------------------------------------------------------------------- /tree-sitter-java/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-java/TreeSitter/Java.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Java 2 | ( tree_sitter_java 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_java 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-java/src/parser.c tree_sitter_java" tree_sitter_java :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-java/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-java/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-java/tree-sitter-java.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.2 2 | name: tree-sitter-java 3 | version: 0.7.0.3 4 | synopsis: Tree-sitter grammar/parser for Java 5 | description: This package provides a parser for Java suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-java 8 | author: Ayman Nadeem, Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey 9 | maintainer: tclem@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, Java 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-java/src/node-types.json 14 | , vendor/tree-sitter-java/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.Java 46 | autogen-modules: Paths_tree_sitter_java 47 | other-modules: Paths_tree_sitter_java 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter 50 | Include-dirs: vendor/tree-sitter-java/src 51 | install-includes: tree_sitter/parser.h 52 | c-sources: vendor/tree-sitter-java/src/parser.c 53 | extra-libraries: stdc++ 54 | 55 | source-repository head 56 | type: git 57 | location: https://github.com/tree-sitter/haskell-tree-sitter 58 | -------------------------------------------------------------------------------- /tree-sitter-json/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.7.0.2 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.7.0.0 7 | 8 | * remove CodeGen and Template Haskell splice 9 | * move contents of internal library into library and remove internal library 10 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 11 | 12 | # v0.3.0.0 13 | 14 | - Defines AST datatypes. 15 | - Bumps the lower bound on `tree-sitter` to 0.4. 16 | -------------------------------------------------------------------------------- /tree-sitter-json/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-json/TreeSitter/JSON.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.JSON 2 | ( tree_sitter_json 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_json 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-json/src/parser.c tree_sitter_json" tree_sitter_json :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-json/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-json/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-json/tree-sitter-json.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.2 2 | name: tree-sitter-json 3 | version: 0.7.0.3 4 | synopsis: Tree-sitter grammar/parser for JSON 5 | description: This package provides a parser for JSON suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-json 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: vera@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, JSON 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-json/src/node-types.json 14 | , vendor/tree-sitter-json/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.JSON 46 | autogen-modules: Paths_tree_sitter_json 47 | other-modules: Paths_tree_sitter_json 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter 50 | include-dirs: vendor/tree-sitter-json/src 51 | install-includes: tree_sitter/parser.h 52 | c-sources: vendor/tree-sitter-json/src/parser.c 53 | 54 | source-repository head 55 | type: git 56 | location: https://github.com/tree-sitter/haskell-tree-sitter 57 | -------------------------------------------------------------------------------- /tree-sitter-nix/TreeSitter/Nix.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | module TreeSitter.Nix ( 3 | tree_sitter_nix 4 | , Grammar(..) 5 | ) where 6 | 7 | import Language.Haskell.TH 8 | import TreeSitter.Language 9 | import TreeSitter.Nix.Internal 10 | 11 | -- Regenerate template haskell code when these files change: 12 | addDependentFileRelative "../vendor/tree-sitter-nix/src/parser.c" 13 | 14 | -- | Statically-known rules corresponding to symbols in the grammar. 15 | mkSymbolDatatype (mkName "Grammar") tree_sitter_nix 16 | -------------------------------------------------------------------------------- /tree-sitter-nix/internal/TreeSitter/Nix/Internal.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Nix.Internal ( 2 | tree_sitter_nix 3 | ) where 4 | 5 | import Foreign.Ptr 6 | import TreeSitter.Language 7 | 8 | foreign import ccall unsafe "vendor/tree-sitter-nix/src/parser.c tree_sitter_nix" tree_sitter_nix :: Ptr Language 9 | -------------------------------------------------------------------------------- /tree-sitter-nix/tree-sitter-nix.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.2 2 | name: tree-sitter-nix 3 | version: 0.2.0.2 4 | synopsis: tree-sitter Nix language bindings 5 | description: A parser for Nix for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-nix 8 | author: Robert Hensing 9 | maintainer: Robert Hensing 10 | copyright: Hercules Labs OÜ 11 | category: Web 12 | build-type: Simple 13 | -- extra-source-files: 14 | 15 | common common 16 | default-language: Haskell2010 17 | ghc-options: 18 | -Weverything 19 | -Wno-all-missed-specialisations 20 | -Wno-implicit-prelude 21 | -Wno-missed-specialisations 22 | -Wno-missing-import-lists 23 | -Wno-missing-local-signatures 24 | -Wno-monomorphism-restriction 25 | -Wno-name-shadowing 26 | -Wno-safe 27 | -Wno-unsafe 28 | if (impl(ghc >= 8.6)) 29 | ghc-options: -Wno-star-is-type 30 | if (impl(ghc >= 8.8)) 31 | ghc-options: -Wno-missing-deriving-strategies 32 | if (impl(ghc >= 8.10)) 33 | ghc-options: 34 | -Wno-missing-safe-haskell-mode 35 | -Wno-prepositive-qualified-module 36 | if (impl(ghc >= 9.2)) 37 | ghc-options: 38 | -Wno-missing-kind-signatures 39 | -Wno-implicit-lift 40 | 41 | library 42 | import: common 43 | exposed-modules: TreeSitter.Nix 44 | build-depends: 45 | , base >= 4.7 && < 5 46 | , tree-sitter >= 0.3 && < 1 47 | , template-haskell >= 2.12 && < 3 48 | , tree-sitter-nix-internal 49 | 50 | library tree-sitter-nix-internal 51 | import: common 52 | exposed-modules: TreeSitter.Nix.Internal 53 | hs-source-dirs: internal 54 | build-depends: base >= 4.7 && < 5 55 | , tree-sitter 56 | Include-dirs: vendor/tree-sitter-nix/src 57 | c-sources: vendor/tree-sitter-nix/src/parser.c 58 | vendor/tree-sitter-nix/src/scanner.c 59 | extra-libraries: stdc++ 60 | 61 | source-repository head 62 | type: git 63 | location: https://github.com/tree-sitter/haskell-tree-sitter 64 | -------------------------------------------------------------------------------- /tree-sitter-ocaml/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.1.0.0 2 | 3 | * add tree-sitter-ocaml parser 4 | -------------------------------------------------------------------------------- /tree-sitter-ocaml/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-ocaml/TreeSitter/OCaml.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.OCaml 2 | ( tree_sitter_ocaml 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_ocaml 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-ocaml/grammars/ocaml/src/parser.c tree_sitter_ocaml" tree_sitter_ocaml :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-ocaml/grammars/ocaml/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-ocaml/grammars/ocaml/test/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-ocaml/tree-sitter-ocaml.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-ocaml 3 | version: 0.1.0.1 4 | synopsis: Tree-sitter grammar/parser for OCaml 5 | description: This package provides a parser for OCaml suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-ocaml 8 | maintainer: rewinfrey@github.com 9 | copyright: 2020 GitHub, Anton Kochkov 10 | category: Tree-sitter, OCaml 11 | build-type: Simple 12 | data-files: vendor/tree-sitter-ocaml/grammars/ocaml/src/node-types.json 13 | , vendor/tree-sitter-ocaml/grammars/ocaml/test/corpus/*.txt 14 | extra-doc-files: ChangeLog.md 15 | 16 | common common 17 | default-language: Haskell2010 18 | ghc-options: 19 | -Weverything 20 | -Wno-all-missed-specialisations 21 | -Wno-implicit-prelude 22 | -Wno-missed-specialisations 23 | -Wno-missing-import-lists 24 | -Wno-missing-local-signatures 25 | -Wno-monomorphism-restriction 26 | -Wno-name-shadowing 27 | -Wno-safe 28 | -Wno-unsafe 29 | if (impl(ghc >= 8.6)) 30 | ghc-options: -Wno-star-is-type 31 | if (impl(ghc >= 8.8)) 32 | ghc-options: -Wno-missing-deriving-strategies 33 | if (impl(ghc >= 8.10)) 34 | ghc-options: 35 | -Wno-missing-safe-haskell-mode 36 | -Wno-prepositive-qualified-module 37 | if (impl(ghc >= 9.2)) 38 | ghc-options: 39 | -Wno-missing-kind-signatures 40 | -Wno-implicit-lift 41 | 42 | library 43 | import: common 44 | exposed-modules: TreeSitter.OCaml 45 | autogen-modules: Paths_tree_sitter_ocaml 46 | other-modules: Paths_tree_sitter_ocaml 47 | build-depends: base >= 4.12 && < 5 48 | , tree-sitter ^>= 0.9.0.0 49 | Include-dirs: vendor/tree-sitter-ocaml/grammars/ocaml/src 50 | install-includes: tree_sitter/parser.h 51 | c-sources: vendor/tree-sitter-ocaml/grammars/ocaml/src/parser.c 52 | , vendor/tree-sitter-ocaml/grammars/ocaml/src/scanner.c 53 | extra-libraries: stdc++ 54 | 55 | source-repository head 56 | type: git 57 | location: https://github.com/tree-sitter/haskell-tree-sitter 58 | -------------------------------------------------------------------------------- /tree-sitter-php/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.5.0.1 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.5.0.0 7 | 8 | * Major version bump since parser and symbols changed. 9 | 10 | # v0.4.0.0 11 | 12 | * add `data-files` to tree-sitter-php.cabal 13 | * major version bump since parser and its symbols changed 14 | 15 | # v0.3.0.1 16 | 17 | * add `data-files` to tree-sitter-php.cabal 18 | 19 | # v0.3.0.0 20 | 21 | * remove CodeGen and Template Haskell splice 22 | * move contents of internal library into library and remove internal library 23 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 24 | -------------------------------------------------------------------------------- /tree-sitter-php/TreeSitter/PHP.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.PHP 2 | ( tree_sitter_php 3 | , getNodeTypesPath 4 | ) where 5 | 6 | import Foreign.Ptr 7 | import TreeSitter.Language 8 | import Paths_tree_sitter_php 9 | 10 | foreign import ccall unsafe "vendor/tree-sitter-php/php/src/parser.c tree_sitter_php" tree_sitter_php :: Ptr Language 11 | 12 | getNodeTypesPath :: IO FilePath 13 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-php/php/src/node-types.json" 14 | -------------------------------------------------------------------------------- /tree-sitter-php/tree-sitter-php.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.2 2 | name: tree-sitter-php 3 | version: 0.5.0.2 4 | synopsis: Tree-sitter grammar/parser for PHP 5 | description: This package provides a parser for PHP suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-php 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: vera@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, PHP 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-php/php/src/node-types.json 14 | extra-doc-files: ChangeLog.md 15 | 16 | common common 17 | default-language: Haskell2010 18 | ghc-options: 19 | -Weverything 20 | -Wno-all-missed-specialisations 21 | -Wno-implicit-prelude 22 | -Wno-missed-specialisations 23 | -Wno-missing-import-lists 24 | -Wno-missing-local-signatures 25 | -Wno-monomorphism-restriction 26 | -Wno-name-shadowing 27 | -Wno-safe 28 | -Wno-unsafe 29 | if (impl(ghc >= 8.6)) 30 | ghc-options: -Wno-star-is-type 31 | if (impl(ghc >= 8.8)) 32 | ghc-options: -Wno-missing-deriving-strategies 33 | if (impl(ghc >= 8.10)) 34 | ghc-options: 35 | -Wno-missing-safe-haskell-mode 36 | -Wno-prepositive-qualified-module 37 | if (impl(ghc >= 9.2)) 38 | ghc-options: 39 | -Wno-missing-kind-signatures 40 | -Wno-implicit-lift 41 | 42 | library 43 | import: common 44 | exposed-modules: TreeSitter.PHP 45 | autogen-modules: Paths_tree_sitter_php 46 | other-modules: Paths_tree_sitter_php 47 | build-depends: base >= 4.12 && < 5 48 | , tree-sitter 49 | include-dirs: vendor/tree-sitter-php/php/src 50 | install-includes: tree_sitter/parser.h 51 | c-sources: vendor/tree-sitter-php/php/src/parser.c 52 | , vendor/tree-sitter-php/php/src/scanner.c 53 | extra-libraries: stdc++ 54 | 55 | source-repository head 56 | type: git 57 | location: https://github.com/tree-sitter/haskell-tree-sitter 58 | -------------------------------------------------------------------------------- /tree-sitter-python/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.9.0.3 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.9.0.1 7 | 8 | * fix file path for `node-types.json` 9 | 10 | # v0.9.0.0 11 | 12 | * remove CodeGen and Template Haskell splice 13 | * move contents of internal library into library and remove internal library 14 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 15 | 16 | # v0.6.0.0 17 | 18 | * AST datatypes use a shared `Token` datatype for all anonymous leaves. 19 | * Bumps the lower bound on `tree-sitter` to 0.5. 20 | * AST named sum datatypes are represented as `newtype` wrappers around sums constructed with `:+:`. 21 | * AST named & anonymous sum types are represented as balanced binary trees of `:+:`s instead of right-chained lists. 22 | * Rename the `bytes` field of leaves to `text`. 23 | 24 | # v0.5.0.0 25 | 26 | * Bumps `tree-sitter` to `^>= 0.4`. 27 | 28 | # v0.4.0.0 29 | 30 | * Fixes a bug where comments were mistakenly being added to `extraChildren` fields. ([#204](https://github.com/tree-sitter/haskell-tree-sitter/pull/203)) 31 | * Bumps to `tree-sitter-0.3.0.0`. 32 | 33 | # v0.3.0.0 34 | 35 | * Adds annotation fields to all generated data types. ([#181](https://github.com/tree-sitter/haskell-tree-sitter/pull/181)) 36 | * Fixes bug where nodes would be inserted into fields in reverse order. ([#195](https://github.com/tree-sitter/haskell-tree-sitter/issues/195)) 37 | * Pulled latest tree-sitter grammar. 38 | 39 | # v0.2.0.0 40 | 41 | * Adds `extraChildren` field to all applicable data types. ([#179](https://github.com/tree-sitter/haskell-tree-sitter/pull/179)) 42 | 43 | # v0.1.0.0 44 | 45 | * Initial release. 46 | -------------------------------------------------------------------------------- /tree-sitter-python/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-python/TreeSitter/Python.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Python 2 | ( tree_sitter_python 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_python 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-python/src/parser.c tree_sitter_python" tree_sitter_python :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-python/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-python/test/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-python/tree-sitter-python.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-python 3 | version: 0.9.0.4 4 | synopsis: Tree-sitter grammar/parser for Python 5 | description: This package provides a parser for Python suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-python 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: tclem@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, Python 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-python/src/node-types.json 14 | , vendor/tree-sitter-python/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.Python 46 | autogen-modules: Paths_tree_sitter_python 47 | other-modules: Paths_tree_sitter_python 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter 50 | Include-dirs: vendor/tree-sitter-python/src 51 | install-includes: tree_sitter/parser.h 52 | c-sources: vendor/tree-sitter-python/src/parser.c 53 | , vendor/tree-sitter-python/src/scanner.c 54 | extra-libraries: stdc++ 55 | 56 | source-repository head 57 | type: git 58 | location: https://github.com/tree-sitter/haskell-tree-sitter 59 | -------------------------------------------------------------------------------- /tree-sitter-ql/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.1.0.4 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.1.0.3 7 | 8 | * Bump tree-sitter-ql parser to use named field nodes for module expressions 9 | 10 | # v0.1.0.2 11 | 12 | * Bump tree-sitter-ql parser to use named field nodes 13 | 14 | # v0.1.0.1 15 | 16 | * Bump tree-sitter-ql parser to use consistent test structure (test/corpus/*.txt) 17 | 18 | # v0.1.0.0 19 | 20 | * add tree-sitter-ql parser 21 | -------------------------------------------------------------------------------- /tree-sitter-ql/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-ql/TreeSitter/QL.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.QL 2 | ( tree_sitter_ql 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_ql 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-ql/src/parser.c tree_sitter_ql" tree_sitter_ql :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-ql/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-ql/test/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-ql/tree-sitter-ql.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-ql 3 | version: 0.1.0.5 4 | synopsis: Tree-sitter grammar/parser for QL 5 | description: This package provides a parser for QL suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-ql 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: rewinfrey@github.com 10 | copyright: 2020 GitHub 11 | category: Tree-sitter, QL 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-ql/src/node-types.json 14 | , vendor/tree-sitter-ql/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.QL 46 | autogen-modules: Paths_tree_sitter_ql 47 | other-modules: Paths_tree_sitter_ql 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter ^>= 0.9.0.0 50 | Include-dirs: vendor/tree-sitter-ql/src 51 | install-includes: tree_sitter/parser.h 52 | c-sources: vendor/tree-sitter-ql/src/parser.c 53 | extra-libraries: stdc++ 54 | 55 | source-repository head 56 | type: git 57 | location: https://github.com/tree-sitter/haskell-tree-sitter 58 | -------------------------------------------------------------------------------- /tree-sitter-ruby/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.5.0.3 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.5.0.1 7 | 8 | * fix file path for `node-types.json` 9 | 10 | # v0.5.0.0 11 | 12 | * remove CodeGen and Template Haskell splice 13 | * move contents of internal library into library and remove internal library 14 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 15 | -------------------------------------------------------------------------------- /tree-sitter-ruby/TreeSitter/Ruby.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Ruby 2 | ( tree_sitter_ruby 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_ruby 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-ruby/src/parser.c tree_sitter_ruby" tree_sitter_ruby :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-ruby/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-ruby/test/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-ruby/tree-sitter-ruby.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-ruby 3 | version: 0.5.0.4 4 | synopsis: Tree-sitter grammar/parser for Ruby 5 | description: This package provides a parser for Ruby suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-ruby 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: tclem@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, Ruby 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-ruby/src/node-types.json 14 | , vendor/tree-sitter-ruby/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.Ruby 46 | autogen-modules: Paths_tree_sitter_ruby 47 | other-modules: Paths_tree_sitter_ruby 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter 50 | Include-dirs: vendor/tree-sitter-ruby/src 51 | install-includes: tree_sitter/parser.h 52 | c-sources: vendor/tree-sitter-ruby/src/parser.c 53 | , vendor/tree-sitter-ruby/src/scanner.c 54 | extra-libraries: stdc++ 55 | 56 | 57 | source-repository head 58 | type: git 59 | location: https://github.com/tree-sitter/haskell-tree-sitter 60 | -------------------------------------------------------------------------------- /tree-sitter-rust/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.1.0.1 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.1.0.0 7 | 8 | * add tree-sitter-rust parser 9 | -------------------------------------------------------------------------------- /tree-sitter-rust/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter-rust/TreeSitter/Rust.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Rust 2 | ( tree_sitter_rust 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_rust 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-rust/src/parser.c tree_sitter_rust" tree_sitter_rust :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-rust/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-rust/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-rust/tree-sitter-rust.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-rust 3 | version: 0.1.0.2 4 | synopsis: Tree-sitter grammar/parser for Rust 5 | description: This package provides a parser for Rust suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-rust 8 | maintainer: rewinfrey@github.com 9 | copyright: 2020 GitHub 10 | category: Tree-sitter, Rust 11 | build-type: Simple 12 | data-files: vendor/tree-sitter-rust/src/node-types.json 13 | , vendor/tree-sitter-rust/test/corpus/*.txt 14 | extra-doc-files: ChangeLog.md 15 | 16 | common common 17 | default-language: Haskell2010 18 | ghc-options: 19 | -Weverything 20 | -Wno-all-missed-specialisations 21 | -Wno-implicit-prelude 22 | -Wno-missed-specialisations 23 | -Wno-missing-import-lists 24 | -Wno-missing-local-signatures 25 | -Wno-monomorphism-restriction 26 | -Wno-name-shadowing 27 | -Wno-safe 28 | -Wno-unsafe 29 | if (impl(ghc >= 8.6)) 30 | ghc-options: -Wno-star-is-type 31 | if (impl(ghc >= 8.8)) 32 | ghc-options: -Wno-missing-deriving-strategies 33 | if (impl(ghc >= 8.10)) 34 | ghc-options: 35 | -Wno-missing-safe-haskell-mode 36 | -Wno-prepositive-qualified-module 37 | if (impl(ghc >= 9.2)) 38 | ghc-options: 39 | -Wno-missing-kind-signatures 40 | -Wno-implicit-lift 41 | 42 | library 43 | import: common 44 | exposed-modules: TreeSitter.Rust 45 | autogen-modules: Paths_tree_sitter_rust 46 | other-modules: Paths_tree_sitter_rust 47 | build-depends: base >= 4.12 && < 5 48 | , tree-sitter ^>= 0.9.0.0 49 | Include-dirs: vendor/tree-sitter-rust/src 50 | install-includes: tree_sitter/parser.h 51 | c-sources: vendor/tree-sitter-rust/src/parser.c 52 | , vendor/tree-sitter-rust/src/scanner.c 53 | extra-libraries: stdc++ 54 | 55 | source-repository head 56 | type: git 57 | location: https://github.com/tree-sitter/haskell-tree-sitter 58 | -------------------------------------------------------------------------------- /tree-sitter-tsx/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.5.0.2 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.5.0.0 7 | 8 | * remove CodeGen and Template Haskell splice 9 | * move contents of internal library into library and remove internal library 10 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 11 | -------------------------------------------------------------------------------- /tree-sitter-tsx/TreeSitter/TSX.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.TSX 2 | ( tree_sitter_tsx 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_tsx 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-typescript/tsx/src/parser.c tree_sitter_tsx" tree_sitter_tsx :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-typescript/tsx/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-typescript/tsx/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-tsx/tree-sitter-tsx.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-tsx 3 | version: 0.5.0.3 4 | synopsis: Tree-sitter grammar/parser for TSX 5 | description: This package provides a parser for TSX (TypeScript + XML) suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-tsx 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: vera@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, TypeScript 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-typescript/tsx/src/node-types.json 14 | , vendor/tree-sitter-typescript/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.TSX 46 | autogen-modules: Paths_tree_sitter_tsx 47 | other-modules: Paths_tree_sitter_tsx 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter 50 | Include-dirs: vendor/tree-sitter-typescript/tsx/src 51 | vendor/tree-sitter-typescript/common 52 | install-includes: tree_sitter/parser.h 53 | scanner.h 54 | c-sources: vendor/tree-sitter-typescript/tsx/src/parser.c 55 | , vendor/tree-sitter-typescript/tsx/src/scanner.c 56 | 57 | 58 | source-repository head 59 | type: git 60 | location: https://github.com/tree-sitter/haskell-tree-sitter 61 | -------------------------------------------------------------------------------- /tree-sitter-typescript/ChangeLog.md: -------------------------------------------------------------------------------- 1 | # v0.5.0.2 2 | 3 | * Support ghc 8.10. 4 | 5 | 6 | # v0.5.0.0 7 | 8 | * remove CodeGen and Template Haskell splice 9 | * move contents of internal library into library and remove internal library 10 | * add `getNodeTypesPath` to provide easier access to `node-types.json` file 11 | -------------------------------------------------------------------------------- /tree-sitter-typescript/TreeSitter/TypeScript.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.TypeScript 2 | ( tree_sitter_typescript 3 | , getNodeTypesPath 4 | , getTestCorpusDir 5 | ) where 6 | 7 | import Foreign.Ptr 8 | import TreeSitter.Language 9 | import Paths_tree_sitter_typescript 10 | 11 | foreign import ccall unsafe "vendor/tree-sitter-typescript/typescript/src/parser.c tree_sitter_typescript" tree_sitter_typescript :: Ptr Language 12 | 13 | getNodeTypesPath :: IO FilePath 14 | getNodeTypesPath = getDataFileName "vendor/tree-sitter-typescript/typescript/src/node-types.json" 15 | 16 | getTestCorpusDir :: IO FilePath 17 | getTestCorpusDir = getDataFileName "vendor/tree-sitter-typescript/typescript/corpus" 18 | -------------------------------------------------------------------------------- /tree-sitter-typescript/tree-sitter-typescript.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter-typescript 3 | version: 0.5.0.3 4 | synopsis: Tree-sitter grammar/parser for TypeScript 5 | description: This package provides a parser for TypeScript suitable for use with the tree-sitter package. 6 | license: BSD-3-Clause 7 | homepage: https://github.com/tree-sitter/haskell-tree-sitter/tree/master/tree-sitter-typescript 8 | author: Max Brunsfeld, Tim Clem, Rob Rix, Josh Vera, Rick Winfrey, Ayman Nadeem, Patrick Thomson 9 | maintainer: vera@github.com 10 | copyright: 2019 GitHub 11 | category: Tree-sitter, TypeScript 12 | build-type: Simple 13 | data-files: vendor/tree-sitter-typescript/typescript/src/node-types.json 14 | , vendor/tree-sitter-typescript/test/corpus/*.txt 15 | extra-doc-files: ChangeLog.md 16 | 17 | common common 18 | default-language: Haskell2010 19 | ghc-options: 20 | -Weverything 21 | -Wno-all-missed-specialisations 22 | -Wno-implicit-prelude 23 | -Wno-missed-specialisations 24 | -Wno-missing-import-lists 25 | -Wno-missing-local-signatures 26 | -Wno-monomorphism-restriction 27 | -Wno-name-shadowing 28 | -Wno-safe 29 | -Wno-unsafe 30 | if (impl(ghc >= 8.6)) 31 | ghc-options: -Wno-star-is-type 32 | if (impl(ghc >= 8.8)) 33 | ghc-options: -Wno-missing-deriving-strategies 34 | if (impl(ghc >= 8.10)) 35 | ghc-options: 36 | -Wno-missing-safe-haskell-mode 37 | -Wno-prepositive-qualified-module 38 | if (impl(ghc >= 9.2)) 39 | ghc-options: 40 | -Wno-missing-kind-signatures 41 | -Wno-implicit-lift 42 | 43 | library 44 | import: common 45 | exposed-modules: TreeSitter.TypeScript 46 | autogen-modules: Paths_tree_sitter_typescript 47 | other-modules: Paths_tree_sitter_typescript 48 | build-depends: base >= 4.12 && < 5 49 | , tree-sitter 50 | include-dirs: vendor/tree-sitter-typescript/typescript/src 51 | vendor/tree-sitter-typescript/common 52 | install-includes: tree_sitter/parser.h 53 | scanner.h 54 | c-sources: vendor/tree-sitter-typescript/typescript/src/parser.c 55 | , vendor/tree-sitter-typescript/typescript/src/scanner.c 56 | 57 | source-repository head 58 | type: git 59 | location: https://github.com/tree-sitter/haskell-tree-sitter 60 | -------------------------------------------------------------------------------- /tree-sitter/ChangeLog.md: -------------------------------------------------------------------------------- 1 | ### v0.9.0.4 2 | 3 | * Add `isMissing` flag for nodes. 4 | * Add bindings for the edit API. 5 | 6 | ### v0.9.0.3 7 | 8 | * Support `base-4.14` at least (GHC 8.10.7) 9 | * Support latest minor versions of 8.10, 9.0, 9.2 and 9.4 10 | 11 | ### v0.9.0.2 12 | 13 | * Remove `fused-effects` dependency. 14 | * Support ghc 8.10. 15 | 16 | 17 | ### v0.9.0.1 18 | 19 | * Remove `semantic-source` dependency. 20 | 21 | ### v0.9.0.0 22 | 23 | * Remove CodeGen files `Deserialize`, `GenerateSyntax`, `Unmarshal`, `Token` 24 | 25 | ### v0.8.0.2 26 | 27 | * Updates `tree-sitter` to fix an issue with improperly balanced subtrees leading to slowdowns when copying nodes. 28 | * Neither `ts_tree_cursor_copy_child_nodes` nor `ts_node_copy_child_nodes` is interruptible. 29 | 30 | 31 | ### v0.8.0.1 32 | 33 | * `ts_tree_cursor_copy_child_nodes` is interruptible. 34 | 35 | 36 | ### v0.5.0.0 37 | 38 | * Use a shared `Token` type for anonymous leaves in generated AST types. 39 | * Allow generated ASTs to override the representation for portions of the AST by defining specialized datatypes. Note that this should be used sparingly to keep the maintenance burden of the AST types low. 40 | * Generate named sum types as `newtype` wrappers around sums constructed with `:+:`. 41 | * Generate named & anonymous sum types as balanced binary trees of `:+:`s instead of right-chained lists. 42 | * Rename the `bytes` field of leaves to `text`. 43 | 44 | ### v0.4.0.0 45 | 46 | * `Unmarshal` has been split into `Unmarshal`, `UnmarshalAnn`, and `UnmarshalField`, with the first newly taking type constructors of kind `* -> *`. `UnmarshalAnn` can be used to unmarshal annotation types relating to the entire node, and `UnmarshalField` can be used to unmarshal fields of zero or more nodes. 47 | 48 | * `UnmarshalAnn` instances are provided for the `semantic-source` types `Loc`, `Range`, and `Span`. 49 | 50 | * AST datatypes are generated with `GHC.Generics.:+:` for anonymous sums in field positions instead of `Either`s. This makes it possible to define typeclasses over them at kind `* -> *` instead of only at kind `*`. 51 | 52 | * AST datatypes receive derived instances of `Foldable`, `Functor`, `Generic`, `Generic1`, and `Traversable`. 53 | 54 | ### v0.3.0.0 55 | 56 | * `Node` has a `nodeIsExtra` field stating whether it was produced via the `extras` rule. 57 | 58 | ### v0.2.1.0 59 | 60 | * Add `TreeSitter.Range` and `TreeSitter.Span`. 61 | 62 | ### v0.2.0.0 63 | 64 | * Add unmarshalling support with `TreeSitter.Unmarshal`. 65 | * Removes pointer-only constructors for bridged C types. 66 | 67 | ### v0.1.0.0 68 | 69 | * Initial release. 70 | -------------------------------------------------------------------------------- /tree-sitter/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright GitHub (c) 2015 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Author name here nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /tree-sitter/README.md: -------------------------------------------------------------------------------- 1 | # haskell-tree-sitter 2 | 3 | _NOTE: this project used to define Template Haskell splices for auto-generating language-specific, strongly-typed Haskell ASTs from tree-sitter grammars. This code has moved to [`Semantic`](https://github.com/github/semantic/tree/master/semantic-ast)._ 4 | 5 | ### Haskell bindings for tree-sitter 6 | 7 | This is a set of Haskell bindings to the [tree-sitter][tree-sitter] 8 | parsing library. tree-sitter is a modern incremental parsing toolkit 9 | with a great many useful features, including: 10 | 11 | * Incremental, error-correcting parses: one syntax error in a file 12 | will not prevent the rest of the file from being parsed. 13 | * Speed: tree-sitter is capable of parsing large files on every 14 | keystroke of a text editor. 15 | * A GLR algorithm capable of parsing nondeterministic and ambiguous 16 | grammars. 17 | 18 | This package provides interfaces to the official tree-sitter grammars 19 | for Haskell, Java, Go, JSON, TypeScript/JavaScript, PHP, Python, and 20 | Ruby. 21 | 22 | The interface is somewhat low-level: if you use this package, you'll 23 | probably want to add a step that munges a given `TreeSitter.Node` into 24 | a more Haskell-amenable data structure. 25 | 26 | There are some example executables provided with this project: 27 | 28 | * An example of using this library to parse, read, and print out AST nodes 29 | can be found [here](https://github.com/tree-sitter/haskell-tree-sitter/blob/master/tree-sitter-haskell/examples/Demo.hs) 30 | 31 | To build these executables, pass the `build-examples` flag to your build tool. 32 | 33 | [tree-sitter]: https://github.com/tree-sitter/tree-sitter 34 | -------------------------------------------------------------------------------- /tree-sitter/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /tree-sitter/src/TreeSitter/Cursor.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Cursor 2 | ( Cursor 3 | , withCursor 4 | , sizeOfCursor 5 | , ts_tree_cursor_new_p 6 | , ts_tree_cursor_delete 7 | , ts_tree_cursor_reset_p 8 | , ts_tree_cursor_current_node_p 9 | , ts_tree_cursor_current_field_name 10 | , ts_tree_cursor_current_field_id 11 | , ts_tree_cursor_goto_parent 12 | , ts_tree_cursor_goto_next_sibling 13 | , ts_tree_cursor_goto_first_child 14 | , ts_tree_cursor_goto_first_child_for_byte 15 | , ts_tree_cursor_copy_child_nodes 16 | ) where 17 | 18 | import Control.Exception as Exc 19 | import Data.Int 20 | import Data.Word 21 | import Foreign.C 22 | import Foreign.Marshal.Alloc 23 | import Foreign.Ptr 24 | import TreeSitter.Node 25 | 26 | -- | A cursor for traversing a tree. 27 | -- 28 | -- This type is uninhabited and used only for type safety within 'Ptr' values. 29 | data Cursor 30 | 31 | withCursor :: Ptr TSNode -> (Ptr Cursor -> IO a) -> IO a 32 | withCursor rootPtr action = allocaBytes sizeOfCursor $ \ cursor -> Exc.bracket 33 | (cursor <$ ts_tree_cursor_new_p rootPtr cursor) 34 | ts_tree_cursor_delete 35 | action 36 | 37 | -- | The size of a 'Cursor' in bytes. The tests verify that this value is the same as @sizeof(TSTreeCursor)@. 38 | sizeOfCursor :: Int 39 | sizeOfCursor = 32 40 | 41 | foreign import ccall unsafe "src/bridge.c ts_tree_cursor_new_p" ts_tree_cursor_new_p :: Ptr TSNode -> Ptr Cursor -> IO () 42 | foreign import ccall unsafe "ts_tree_cursor_delete" ts_tree_cursor_delete :: Ptr Cursor -> IO () 43 | foreign import ccall unsafe "src/bridge.c ts_tree_cursor_reset_p" ts_tree_cursor_reset_p :: Ptr Cursor -> Ptr TSNode -> IO () 44 | 45 | foreign import ccall unsafe "src/bridge.c ts_tree_cursor_current_node_p" ts_tree_cursor_current_node_p :: Ptr Cursor -> Ptr Node -> IO Bool 46 | foreign import ccall unsafe "ts_tree_cursor_current_field_name" ts_tree_cursor_current_field_name :: Ptr Cursor -> IO CString 47 | foreign import ccall unsafe "ts_tree_cursor_current_field_id" ts_tree_cursor_current_field_id :: Ptr Cursor -> IO FieldId 48 | 49 | foreign import ccall unsafe "ts_tree_cursor_goto_parent" ts_tree_cursor_goto_parent :: Ptr Cursor -> IO Bool 50 | foreign import ccall unsafe "ts_tree_cursor_goto_next_sibling" ts_tree_cursor_goto_next_sibling :: Ptr Cursor -> IO Bool 51 | foreign import ccall unsafe "ts_tree_cursor_goto_first_child" ts_tree_cursor_goto_first_child :: Ptr Cursor -> IO Bool 52 | foreign import ccall unsafe "ts_tree_cursor_goto_first_child_for_byte" ts_tree_cursor_goto_first_child_for_byte :: Ptr Cursor -> Word32 -> IO Int64 53 | 54 | foreign import ccall unsafe "src/bridge.c ts_tree_cursor_copy_child_nodes" ts_tree_cursor_copy_child_nodes :: Ptr Cursor -> Ptr Node -> IO Word32 55 | -------------------------------------------------------------------------------- /tree-sitter/src/TreeSitter/Language.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | module TreeSitter.Language 3 | ( module TreeSitter.Language 4 | , module TreeSitter.Symbol 5 | ) where 6 | 7 | import Data.Ix (Ix) 8 | import Data.List (mapAccumL) 9 | import qualified Data.Set as Set 10 | import Data.Traversable (for) 11 | import Data.Word 12 | import Foreign.C.String 13 | import Foreign.Ptr 14 | import Language.Haskell.TH 15 | import Language.Haskell.TH.Syntax 16 | import System.Directory 17 | import System.FilePath.Posix 18 | import TreeSitter.Symbol 19 | 20 | -- | A tree-sitter language. 21 | -- 22 | -- This type is uninhabited and used only for type safety within 'Ptr' values. 23 | data Language 24 | 25 | foreign import ccall unsafe "ts_language_symbol_count" ts_language_symbol_count :: Ptr Language -> IO Word32 26 | foreign import ccall unsafe "ts_language_symbol_name" ts_language_symbol_name :: Ptr Language -> TSSymbol -> IO CString 27 | foreign import ccall unsafe "ts_language_symbol_type" ts_language_symbol_type :: Ptr Language -> TSSymbol -> IO Int 28 | foreign import ccall unsafe "ts_language_symbol_for_name" ts_language_symbol_for_name :: Ptr Language -> CString -> Int -> Bool -> IO TSSymbol 29 | 30 | -- | TemplateHaskell construction of a datatype for the referenced Language. 31 | mkSymbolDatatype :: Name -> Ptr Language -> Q [Dec] 32 | mkSymbolDatatype name language = do 33 | symbols <- renameDups . map ((,) . fst <*> uncurry symbolToName) . (++ [(Regular, "ParseError")]) <$> runIO (languageSymbols language) 34 | Module _ modName <- thisModule 35 | let mkMatch symbolType str = match (conP (Name (OccName str) (NameQ modName)) []) (normalB [e|symbolType|]) [] 36 | datatype <- dataD (pure []) name [] Nothing (flip normalC [] . mkName . snd <$> symbols) 37 | [ derivClause Nothing (map conT [ ''Bounded, ''Enum, ''Eq, ''Ix, ''Ord, ''Show ]) ] 38 | symbolInstance <- [d| 39 | instance Symbol $(conT name) where 40 | symbolType = $(lamCaseE (uncurry mkMatch <$> symbols)) |] 41 | pure (datatype : symbolInstance) 42 | 43 | renameDups :: [(a, String)] -> [(a, String)] 44 | renameDups = snd . mapAccumL go mempty 45 | where go done (ty, name) = let name' = rename name in (Set.insert name' done, (ty, name')) 46 | where rename name | name `Set.member` done = rename (name ++ "'") 47 | | otherwise = name 48 | 49 | -- https://stackoverflow.com/questions/16163948/how-do-i-use-templatehaskells-adddependentfile-on-a-file-relative-to-the-file-b 50 | addDependentFileRelative :: FilePath -> Q [Dec] 51 | addDependentFileRelative relativeFile = do 52 | currentFilename <- loc_filename <$> location 53 | pwd <- runIO getCurrentDirectory 54 | 55 | let invocationRelativePath = takeDirectory (pwd currentFilename) relativeFile 56 | 57 | addDependentFile invocationRelativePath 58 | 59 | return [] 60 | 61 | 62 | languageSymbols :: Ptr Language -> IO [(SymbolType, String)] 63 | languageSymbols language = ts_language_symbol_count language >>= \ count -> for [0..fromIntegral (pred count)] $ \ symbol -> do 64 | cname <- ts_language_symbol_name language symbol 65 | name <- peekCString cname 66 | ty <- toEnum <$> ts_language_symbol_type language symbol 67 | pure (ty, name) 68 | -------------------------------------------------------------------------------- /tree-sitter/src/TreeSitter/Node.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric, GeneralizedNewtypeDeriving, RankNTypes, ScopedTypeVariables #-} 2 | {-# OPTIONS_GHC -funbox-strict-fields #-} 3 | module TreeSitter.Node 4 | ( Node(..) 5 | , nodeStartPoint 6 | , nodeStartByte 7 | , TSPoint(..) 8 | , TSNode(..) 9 | , FieldId(..) 10 | , ts_node_copy_child_nodes 11 | , ts_node_poke_p 12 | 13 | , evalStruct 14 | , peekStruct 15 | , pokeStruct 16 | ) where 17 | 18 | import Foreign 19 | import Foreign.C 20 | import GHC.Generics 21 | import TreeSitter.Symbol (TSSymbol) 22 | 23 | data Node = Node 24 | { nodeTSNode :: !TSNode 25 | , nodeType :: !CString 26 | , nodeSymbol :: !TSSymbol 27 | , nodeEndPoint :: !TSPoint 28 | , nodeEndByte :: !Word32 29 | , nodeChildCount :: !Word32 30 | , nodeFieldName :: !CString 31 | , nodeIsNamed :: !CBool 32 | , nodeIsExtra :: !CBool 33 | , nodeIsMissing :: !CBool 34 | } 35 | deriving (Show, Eq, Generic) 36 | 37 | nodeStartPoint :: Node -> TSPoint 38 | nodeStartPoint node = let TSNode _ p _ _ _ = nodeTSNode node in p 39 | 40 | nodeStartByte :: Node -> Word32 41 | nodeStartByte node = let TSNode b _ _ _ _ = nodeTSNode node in b 42 | 43 | data TSPoint = TSPoint { pointRow :: !Word32, pointColumn :: !Word32 } 44 | deriving (Show, Eq, Generic) 45 | 46 | data TSNode = TSNode !Word32 !TSPoint !Word32 !(Ptr ()) !(Ptr ()) 47 | deriving (Show, Eq, Generic) 48 | 49 | newtype FieldId = FieldId { getFieldId :: Word16 } 50 | deriving (Eq, Ord, Show, Storable) 51 | 52 | 53 | -- | 'Struct' is a strict 'Monad' with automatic alignment & advancing, & inferred type. 54 | newtype Struct a = Struct { runStruct :: forall b . Ptr b -> IO (a, Ptr a) } 55 | 56 | evalStruct :: Struct a -> Ptr b -> IO a 57 | evalStruct s p = fmap fst $! runStruct s p 58 | {-# INLINE evalStruct #-} 59 | 60 | peekStruct :: forall a . Storable a => Struct a 61 | peekStruct = Struct (\ p -> do 62 | let aligned = alignPtr (castPtr p) (alignment (undefined :: a)) 63 | a <- peek aligned 64 | pure (a, aligned `plusPtr` sizeOf a)) 65 | {-# INLINE peekStruct #-} 66 | 67 | pokeStruct :: Storable a => a -> Struct () 68 | pokeStruct a = Struct (\ p -> do 69 | let aligned = alignPtr (castPtr p) (alignment a) 70 | poke aligned a 71 | pure ((), castPtr aligned `plusPtr` sizeOf a)) 72 | {-# INLINE pokeStruct #-} 73 | 74 | 75 | instance Storable Node where 76 | alignment _ = alignment (undefined :: TSNode) 77 | {-# INLINE alignment #-} 78 | sizeOf _ = 80 79 | {-# INLINE sizeOf #-} 80 | peek = evalStruct $ Node <$> peekStruct 81 | <*> peekStruct 82 | <*> peekStruct 83 | <*> peekStruct 84 | <*> peekStruct 85 | <*> peekStruct 86 | <*> peekStruct 87 | <*> peekStruct 88 | <*> peekStruct 89 | <*> peekStruct 90 | {-# INLINE peek #-} 91 | poke ptr (Node n t s ep eb c fn nn ne nm) = flip evalStruct ptr $ do 92 | pokeStruct n 93 | pokeStruct t 94 | pokeStruct s 95 | pokeStruct ep 96 | pokeStruct eb 97 | pokeStruct c 98 | pokeStruct fn 99 | pokeStruct nn 100 | pokeStruct ne 101 | pokeStruct nm 102 | {-# INLINE poke #-} 103 | 104 | instance Storable TSPoint where 105 | alignment _ = alignment (0 :: Int32) 106 | {-# INLINE alignment #-} 107 | sizeOf _ = 8 108 | {-# INLINE sizeOf #-} 109 | peek = evalStruct $ TSPoint <$> peekStruct 110 | <*> peekStruct 111 | {-# INLINE peek #-} 112 | poke ptr (TSPoint r c) = flip evalStruct ptr $ do 113 | pokeStruct r 114 | pokeStruct c 115 | {-# INLINE poke #-} 116 | 117 | instance Storable TSNode where 118 | alignment _ = alignment (nullPtr :: Ptr ()) 119 | {-# INLINE alignment #-} 120 | sizeOf _ = 32 121 | {-# INLINE sizeOf #-} 122 | peek = evalStruct $ TSNode <$> peekStruct 123 | <*> peekStruct 124 | <*> peekStruct 125 | <*> peekStruct 126 | <*> peekStruct 127 | {-# INLINE peek #-} 128 | poke ptr (TSNode sb sp o4 p1 p2) = flip evalStruct ptr $ do 129 | pokeStruct sb 130 | pokeStruct sp 131 | pokeStruct o4 132 | pokeStruct p1 133 | pokeStruct p2 134 | {-# INLINE poke #-} 135 | 136 | instance Functor Struct where 137 | fmap f a = Struct go where 138 | go p = do 139 | (a', p') <- runStruct a p 140 | let fa = f a' 141 | fa `seq` p' `seq` pure (fa, castPtr p') 142 | {-# INLINE go #-} 143 | {-# INLINE fmap #-} 144 | 145 | instance Applicative Struct where 146 | pure a = Struct (\ p -> pure (a, castPtr p)) 147 | {-# INLINE pure #-} 148 | 149 | f <*> a = Struct go where 150 | go p = do 151 | (f', p') <- runStruct f p 152 | (a', p'') <- p' `seq` runStruct a (castPtr p') 153 | let fa = f' a' 154 | fa `seq` p'' `seq` pure (fa, castPtr p'') 155 | {-# INLINE go #-} 156 | {-# INLINE (<*>) #-} 157 | 158 | instance Monad Struct where 159 | return = pure 160 | {-# INLINE return #-} 161 | 162 | a >>= f = Struct go where 163 | go p = do 164 | (a', p') <- runStruct a p 165 | (fa', p'') <- p' `seq` runStruct (f a') (castPtr p') 166 | fa' `seq` p'' `seq` pure (fa', p'') 167 | {-# INLINE go #-} 168 | {-# INLINE (>>=) #-} 169 | 170 | 171 | foreign import ccall unsafe "src/bridge.c ts_node_copy_child_nodes" ts_node_copy_child_nodes :: Ptr TSNode -> Ptr Node -> IO () 172 | -- NB: this leaves the field name as NULL. 173 | foreign import ccall unsafe "src/bridge.c ts_node_poke_p" ts_node_poke_p :: Ptr TSNode -> Ptr Node -> IO () 174 | -------------------------------------------------------------------------------- /tree-sitter/src/TreeSitter/Parser.hs: -------------------------------------------------------------------------------- 1 | module TreeSitter.Parser 2 | ( Parser 3 | , withParser 4 | , withParseTree 5 | , ts_parser_new 6 | , ts_parser_parse_string 7 | , ts_parser_delete 8 | , ts_parser_set_language 9 | , ts_parser_timeout_micros 10 | , ts_parser_set_timeout_micros 11 | , ts_parser_log_to_stderr 12 | ) where 13 | 14 | import Control.Exception as Exc 15 | import Data.ByteString (ByteString) 16 | import Data.ByteString.Unsafe (unsafeUseAsCStringLen) 17 | import Foreign 18 | import Foreign.C 19 | import TreeSitter.Language 20 | import TreeSitter.Tree 21 | 22 | -- | A tree-sitter parser. 23 | -- 24 | -- This type is uninhabited and used only for type safety within 'Ptr' values. 25 | data Parser 26 | 27 | withParser :: Ptr Language -> (Ptr Parser -> IO a) -> IO a 28 | withParser language action = Exc.bracket 29 | ts_parser_new 30 | ts_parser_delete 31 | $ \ parser -> do 32 | _ <- ts_parser_set_language parser language 33 | action parser 34 | 35 | withParseTree :: Ptr Parser -> ByteString -> (Ptr Tree -> IO a) -> IO a 36 | withParseTree parser bytestring action = 37 | unsafeUseAsCStringLen bytestring $ \ (source, len) -> Exc.bracket 38 | (ts_parser_parse_string parser nullPtr source len) 39 | releaseTree 40 | action 41 | where releaseTree t 42 | | t == nullPtr = pure () 43 | | otherwise = ts_tree_delete t 44 | 45 | foreign import ccall safe "ts_parser_new" ts_parser_new :: IO (Ptr Parser) 46 | foreign import ccall safe "ts_parser_parse_string" ts_parser_parse_string :: Ptr Parser -> Ptr Tree -> CString -> Int -> IO (Ptr Tree) 47 | foreign import ccall safe "ts_parser_delete" ts_parser_delete :: Ptr Parser -> IO () 48 | foreign import ccall safe "ts_parser_set_language" ts_parser_set_language :: Ptr Parser -> Ptr Language -> IO Bool 49 | foreign import ccall safe "ts_parser_timeout_micros" ts_parser_timeout_micros :: Ptr Parser -> IO Word64 50 | foreign import ccall safe "ts_parser_set_timeout_micros" ts_parser_set_timeout_micros :: Ptr Parser -> Word64 -> IO () 51 | 52 | foreign import ccall safe "src/bridge.c ts_parser_log_to_stderr" ts_parser_log_to_stderr :: Ptr Parser -> IO () 53 | -------------------------------------------------------------------------------- /tree-sitter/src/TreeSitter/Symbol.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveLift, LambdaCase, ScopedTypeVariables #-} 2 | 3 | module TreeSitter.Symbol 4 | ( TSSymbol 5 | , fromTSSymbol 6 | , SymbolType(..) 7 | , Symbol(..) 8 | , symbolToName 9 | , toHaskellCamelCaseIdentifier 10 | , toHaskellPascalCaseIdentifier 11 | , escapeOperatorPunctuation 12 | , camelCase 13 | , capitalize 14 | ) where 15 | 16 | import Data.Char (isAlpha, isControl, toUpper) 17 | import Data.Function ((&)) 18 | import qualified Data.HashSet as HashSet 19 | import Data.Ix (Ix) 20 | import Data.List.Split (condense, split, whenElt) 21 | import Data.Word (Word16) 22 | import Language.Haskell.TH.Syntax 23 | 24 | type TSSymbol = Word16 25 | 26 | -- | Map a 'TSSymbol' to the corresponding value of a 'Symbol' datatype. 27 | -- 28 | -- This should be used instead of 'toEnum' to perform this conversion, because tree-sitter represents parse errors with the unsigned short @65535@, which is generally not contiguous with the other symbols. 29 | fromTSSymbol :: forall symbol. Symbol symbol => TSSymbol -> symbol 30 | fromTSSymbol symbol = toEnum (min (fromIntegral symbol) (fromEnum (maxBound :: symbol))) 31 | 32 | 33 | data SymbolType = Regular | Anonymous | Auxiliary 34 | deriving (Enum, Eq, Lift, Ord, Show) 35 | 36 | class (Bounded s, Enum s, Ix s, Ord s, Show s) => Symbol s where 37 | symbolType :: s -> SymbolType 38 | 39 | 40 | symbolToName :: SymbolType -> String -> String 41 | symbolToName ty name 42 | = prefixHidden name 43 | & toWords 44 | & filter (not . all (== '_')) 45 | & map escapeOperatorPunctuation 46 | & (>>= capitalize) 47 | & (prefix ++) 48 | where 49 | toWords = split (condense (whenElt (not . isAlpha))) 50 | 51 | prefixHidden s@('_':_) = "Hidden" ++ s 52 | prefixHidden s = s 53 | 54 | prefix = case ty of 55 | Regular -> "" 56 | Anonymous -> "Anon" 57 | Auxiliary -> "Aux" 58 | 59 | toHaskellCamelCaseIdentifier :: String -> String 60 | toHaskellCamelCaseIdentifier = addTickIfNecessary . escapeOperatorPunctuation . camelCase 61 | 62 | addTickIfNecessary :: String -> String 63 | addTickIfNecessary s 64 | | HashSet.member s reservedNames = s <> "'" 65 | | otherwise = s 66 | where 67 | reservedNames :: HashSet.HashSet String 68 | reservedNames = HashSet.fromList [ 69 | "as", "case", "class", "data", "default", "deriving", "do", "forall", 70 | "foreign", "hiding", "if", "then", "else", "import", "infix", "infixl", 71 | "infixr", "instance", "let", "in", "mdo", "module", "newtype", "proc", 72 | "qualified", "rec", "type", "where" 73 | ] 74 | 75 | toHaskellPascalCaseIdentifier :: String -> String 76 | toHaskellPascalCaseIdentifier = addTickIfNecessary . capitalize . escapeOperatorPunctuation . camelCase 77 | 78 | -- Ensures that we generate valid Haskell identifiers from 79 | -- the literal characters used for infix operators and punctuation. 80 | escapeOperatorPunctuation :: String -> String 81 | escapeOperatorPunctuation = concatMap $ \case 82 | '{' -> "LBrace" 83 | '}' -> "RBrace" 84 | '(' -> "LParen" 85 | ')' -> "RParen" 86 | '.' -> "Dot" 87 | ':' -> "Colon" 88 | ',' -> "Comma" 89 | '|' -> "Pipe" 90 | ';' -> "Semicolon" 91 | '*' -> "Star" 92 | '&' -> "Ampersand" 93 | '=' -> "Equal" 94 | '<' -> "LAngle" 95 | '>' -> "RAngle" 96 | '[' -> "LBracket" 97 | ']' -> "RBracket" 98 | '+' -> "Plus" 99 | '-' -> "Minus" 100 | '/' -> "Slash" 101 | '\\' -> "Backslash" 102 | '^' -> "Caret" 103 | '!' -> "Bang" 104 | '%' -> "Percent" 105 | '@' -> "At" 106 | '~' -> "Tilde" 107 | '?' -> "Question" 108 | '`' -> "Backtick" 109 | '#' -> "Hash" 110 | '$' -> "Dollar" 111 | '"' -> "DQuote" 112 | '\'' -> "SQuote" 113 | '\t' -> "Tab" 114 | '\n' -> "LF" 115 | '\r' -> "CR" 116 | ' ' -> "Space" 117 | other 118 | | isControl other -> escapeOperatorPunctuation (show other) 119 | | otherwise -> [other] 120 | 121 | -- | Convert a snake_case String to camelCase 122 | camelCase :: String -> String 123 | camelCase = go 124 | where 125 | go ('_':'_':xs) = "Underscore" <> go xs 126 | go ('_':xs) = go (capitalize xs) 127 | go (x:xs) = x : go xs 128 | go "" = "" 129 | 130 | -- | Capitalize a String 131 | capitalize :: String -> String 132 | capitalize (c:cs) = toUpper c : cs 133 | capitalize [] = [] 134 | -------------------------------------------------------------------------------- /tree-sitter/src/TreeSitter/Tree.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveGeneric #-} 2 | module TreeSitter.Tree 3 | ( Tree 4 | , TSInputEdit(..) 5 | , withRootNode 6 | , ts_tree_edit 7 | , ts_tree_delete 8 | , ts_tree_root_node_p 9 | ) where 10 | 11 | import Foreign 12 | import TreeSitter.Node 13 | import GHC.Generics 14 | 15 | -- | This type is uninhabited and used only for type safety within 'Ptr' values. 16 | data Tree 17 | 18 | withRootNode :: Ptr Tree -> (Ptr Node -> IO a) -> IO a 19 | withRootNode tree action = alloca $ \ ptr -> do 20 | ts_tree_root_node_p tree ptr 21 | action ptr 22 | 23 | -- | Locational info used for to adjust the source ranges of a 'Tree'\'s nodes. 24 | -- This record dirrectly corresponds to the C struct of the same name. 25 | data TSInputEdit = TSInputEdit 26 | { start_byte :: !Word32 27 | , old_end_byte :: !Word32 28 | , new_end_byte :: !Word32 29 | , start_point :: !TSPoint 30 | , old_end_point :: !TSPoint 31 | , new_end_point :: !TSPoint 32 | } 33 | deriving (Show, Eq, Generic) 34 | 35 | instance Storable TSInputEdit where 36 | alignment _ = alignment (0 :: Int32) 37 | sizeOf _ = 36 38 | peek = evalStruct $ 39 | TSInputEdit <$> peekStruct 40 | <*> peekStruct 41 | <*> peekStruct 42 | <*> peekStruct 43 | <*> peekStruct 44 | <*> peekStruct 45 | poke ptr (TSInputEdit sb oldEb newEb sp oldEp newEp) = 46 | flip evalStruct ptr $ do 47 | pokeStruct sb 48 | pokeStruct oldEb 49 | pokeStruct newEb 50 | pokeStruct sp 51 | pokeStruct oldEp 52 | pokeStruct newEp 53 | 54 | foreign import ccall safe "ts_tree_edit" ts_tree_edit :: Ptr Tree -> Ptr TSInputEdit -> IO () 55 | foreign import ccall safe "ts_tree_delete" ts_tree_delete :: Ptr Tree -> IO () 56 | foreign import ccall unsafe "src/bridge.c ts_tree_root_node_p" ts_tree_root_node_p :: Ptr Tree -> Ptr Node -> IO () 57 | -------------------------------------------------------------------------------- /tree-sitter/src/bridge.c: -------------------------------------------------------------------------------- 1 | #include "tree_sitter/api.h" 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct Node { 7 | TSNode node; 8 | const char *type; 9 | TSSymbol symbol; 10 | TSPoint endPoint; 11 | uint32_t endByte; 12 | uint32_t childCount; 13 | const char *fieldName; 14 | bool isNamed; 15 | bool isExtra; 16 | bool isMissing; 17 | } Node; 18 | 19 | void log_to_stdout(void *payload, TSLogType type, const char *message) { 20 | printf("%s\n", message); 21 | } 22 | 23 | void ts_parser_log_to_stderr(TSParser *parser) { 24 | ts_parser_set_logger(parser, (TSLogger) {.log = log_to_stdout, .payload = NULL}); 25 | } 26 | 27 | static inline void ts_node_poke(const char *fieldName, TSNode node, Node *out) { 28 | out->node = node; 29 | out->symbol = ts_node_symbol(node); 30 | out->type = ts_node_type(node); 31 | out->endPoint = ts_node_end_point(node); 32 | out->endByte = ts_node_end_byte(node); 33 | out->childCount = ts_node_child_count(node); 34 | out->fieldName = fieldName; 35 | out->isNamed = ts_node_is_named(node); 36 | out->isExtra = ts_node_is_extra(node); 37 | out->isMissing = ts_node_is_missing(node); 38 | } 39 | 40 | void ts_node_poke_p(TSNode *node, Node *out) { 41 | assert(node != NULL); 42 | ts_node_poke(NULL, *node, out); 43 | } 44 | 45 | void ts_tree_root_node_p(TSTree *tree, Node *outNode) { 46 | assert(tree != NULL); 47 | assert(outNode != NULL); 48 | TSNode root = ts_tree_root_node(tree); 49 | assert(root.id != NULL); 50 | ts_node_poke(NULL, root, outNode); 51 | } 52 | 53 | void ts_node_copy_child_nodes(const TSNode *parentNode, Node *outChildNodes) { 54 | assert(parentNode != NULL); 55 | assert(outChildNodes != NULL); 56 | TSTreeCursor curse = ts_tree_cursor_new(*parentNode); 57 | 58 | if (ts_tree_cursor_goto_first_child(&curse)) { 59 | do { 60 | TSNode current = ts_tree_cursor_current_node(&curse); 61 | ts_node_poke(ts_tree_cursor_current_field_name(&curse), current, outChildNodes); 62 | outChildNodes++; 63 | } while (ts_tree_cursor_goto_next_sibling(&curse)); 64 | } 65 | 66 | ts_tree_cursor_delete(&curse); 67 | } 68 | 69 | size_t sizeof_tsnode() { 70 | return sizeof(TSNode); 71 | } 72 | 73 | size_t sizeof_tspoint() { 74 | return sizeof(TSPoint); 75 | } 76 | 77 | size_t sizeof_node() { 78 | return sizeof(Node); 79 | } 80 | 81 | size_t sizeof_tstreecursor() { 82 | return sizeof(TSTreeCursor); 83 | } 84 | 85 | 86 | void ts_tree_cursor_new_p(TSNode *node, TSTreeCursor *outCursor) { 87 | assert(node != NULL); 88 | assert(outCursor != NULL); 89 | *outCursor = ts_tree_cursor_new(*node); 90 | } 91 | 92 | void ts_tree_cursor_reset_p(TSTreeCursor *cursor, TSNode *node) { 93 | assert(cursor != NULL); 94 | assert(node != NULL); 95 | ts_tree_cursor_reset(cursor, *node); 96 | } 97 | 98 | bool ts_tree_cursor_current_node_p(const TSTreeCursor *cursor, Node *outNode) { 99 | assert(cursor != NULL); 100 | assert(outNode != NULL); 101 | TSNode tsNode = ts_tree_cursor_current_node(cursor); 102 | if (!ts_node_is_null(tsNode)) { 103 | ts_node_poke(ts_tree_cursor_current_field_name(cursor), tsNode, outNode); 104 | } 105 | return false; 106 | } 107 | 108 | 109 | uint32_t ts_tree_cursor_copy_child_nodes(TSTreeCursor *cursor, Node *outChildNodes) { 110 | assert(cursor != NULL); 111 | assert(outChildNodes != NULL); 112 | uint32_t count = 0; 113 | 114 | if (ts_tree_cursor_goto_first_child(cursor)) { 115 | do { 116 | TSNode current = ts_tree_cursor_current_node(cursor); 117 | const char *fieldName = ts_tree_cursor_current_field_name(cursor); 118 | if (fieldName || (ts_node_is_named(current) && !ts_node_is_extra(current))) { 119 | ts_node_poke(fieldName, current, outChildNodes); 120 | count++; 121 | outChildNodes++; 122 | } 123 | } while (ts_tree_cursor_goto_next_sibling(cursor)); 124 | ts_tree_cursor_goto_parent(cursor); 125 | } 126 | return count; 127 | } 128 | -------------------------------------------------------------------------------- /tree-sitter/test/Test.hs: -------------------------------------------------------------------------------- 1 | module Main (main) where 2 | 3 | import Control.Monad 4 | import System.Exit (exitFailure) 5 | import System.IO (BufferMode (..), hSetBuffering, stderr, stdout) 6 | 7 | import qualified TreeSitter.Example 8 | import qualified TreeSitter.Strings.Example 9 | 10 | main :: IO () 11 | main = do 12 | hSetBuffering stdout LineBuffering 13 | hSetBuffering stderr LineBuffering 14 | 15 | results <- sequence [ 16 | TreeSitter.Example.tests 17 | , TreeSitter.Strings.Example.tests 18 | ] 19 | 20 | unless (and results) exitFailure 21 | -------------------------------------------------------------------------------- /tree-sitter/test/TreeSitter/Example.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | module TreeSitter.Example (tests) where 3 | 4 | import Control.Monad.IO.Class 5 | import Foreign 6 | import Foreign.C.Types 7 | import Hedgehog 8 | import TreeSitter.Cursor 9 | import TreeSitter.Node 10 | import TreeSitter.Parser 11 | 12 | tests :: IO Bool 13 | tests = checkSequential $$(discover) 14 | 15 | prop_TSNode_sizeOf = property $ 16 | sizeOf (undefined :: TSNode) === fromIntegral sizeof_tsnode 17 | 18 | prop_TSNode_roundtrips = property $ do 19 | peeked <- liftIO (with (TSNode 1 (TSPoint 2 3) 4 nullPtr nullPtr) peek) 20 | peeked === TSNode 1 (TSPoint 2 3) 4 nullPtr nullPtr 21 | 22 | prop_TSPoint_sizeOf = property $ 23 | sizeOf (undefined :: TSPoint) === fromIntegral sizeof_tspoint 24 | 25 | prop_TSPoint_roundtrips = property $ do 26 | peeked <- liftIO (with (TSPoint 1 2) peek) 27 | peeked === TSPoint 1 2 28 | 29 | prop_Node_sizeOf = property $ 30 | sizeOf (undefined :: Node) === fromIntegral sizeof_node 31 | 32 | prop_Node_roundtrips = property $ do 33 | peeked <- liftIO (with (Node (TSNode 1 (TSPoint 2 3) 4 nullPtr nullPtr) nullPtr 1 (TSPoint 4 5) 7 8 nullPtr 9 10 11) peek) 34 | peeked === Node (TSNode 1 (TSPoint 2 3) 4 nullPtr nullPtr) nullPtr 1 (TSPoint 4 5) 7 8 nullPtr 9 10 11 35 | 36 | prop_TSTreeCursor_sizeOf = property $ 37 | sizeOfCursor === fromIntegral sizeof_tstreecursor 38 | 39 | prop_Parser_timeout = property $ do 40 | parser <- liftIO ts_parser_new 41 | timeout <- liftIO (ts_parser_timeout_micros parser) 42 | timeout === 0 43 | liftIO (ts_parser_set_timeout_micros parser 1000) 44 | timeout <- liftIO (ts_parser_timeout_micros parser) 45 | timeout === 1000 46 | liftIO (ts_parser_delete parser) 47 | 48 | foreign import ccall unsafe "src/bridge.c sizeof_tsnode" sizeof_tsnode :: CSize 49 | foreign import ccall unsafe "src/bridge.c sizeof_tspoint" sizeof_tspoint :: CSize 50 | foreign import ccall unsafe "src/bridge.c sizeof_node" sizeof_node :: CSize 51 | foreign import ccall unsafe "src/bridge.c sizeof_tstreecursor" sizeof_tstreecursor :: CSize 52 | -------------------------------------------------------------------------------- /tree-sitter/test/TreeSitter/Strings/Example.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | module TreeSitter.Strings.Example (tests) where 3 | 4 | import Control.Monad 5 | import Data.Char 6 | import Data.Foldable 7 | import Hedgehog 8 | import qualified Hedgehog.Gen as Gen 9 | import qualified Hedgehog.Range as Range 10 | import TreeSitter.Symbol 11 | 12 | tests :: IO Bool 13 | tests = checkParallel $$(discover) 14 | 15 | -- | Generate permutations of alphabet and underscore combinations 16 | snakeChar :: MonadGen m => m Char 17 | snakeChar = Gen.choice 18 | [ pure '_' 19 | , Gen.alpha 20 | ] 21 | 22 | -- | Generator for snake_case JSON input 23 | genSnake :: Gen String 24 | genSnake = Gen.string (Range.constant 1 10) snakeChar 25 | 26 | prop_camelCase :: Property 27 | prop_camelCase = property $ do 28 | xs <- forAll $ Gen.string (Range.constant 1 5) snakeChar 29 | assert ('_' `notElem` camelCase xs) 30 | 31 | initialCaps :: MonadGen m => m Char 32 | initialCaps = Gen.frequency 33 | [ (10, Gen.upper) 34 | , (5, pure '_') 35 | , (1, Gen.lower) 36 | ] 37 | 38 | prop_capitalize :: Property 39 | prop_capitalize = property $ do 40 | x:xs <- forAll (Gen.string (Range.constant 1 5) initialCaps) 41 | y:_ <- pure $ capitalize (x:xs) 42 | when (isLower x) (assert (isUpper y)) 43 | 44 | prop_escapePunct :: Property 45 | prop_escapePunct = property $ do 46 | xs <- forAll $ Gen.string (Range.constant 1 5) (Gen.filter p Gen.ascii) 47 | traverse_ (assert . isAlphaNum) (escapeOperatorPunctuation xs) 48 | where p = not . (\c -> isSpace c || c == '_' ) 49 | -------------------------------------------------------------------------------- /tree-sitter/tree-sitter.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 2.4 2 | name: tree-sitter 3 | version: 0.9.0.3 4 | synopsis: Unstable bindings for the tree-sitter parsing library. 5 | description: Tree-sitter is a parser generator tool and an incremental parsing library. 6 | . 7 | We strongly recommend against depending on this library at this time; 8 | the data types and API are subject to rapid change. Future versions 9 | will provide more reliable parsers and a more stable API. 10 | homepage: http://github.com/tree-sitter/haskell-tree-sitter#readme 11 | license: BSD-3-Clause 12 | license-file: LICENSE 13 | author: Rob Rix, Josh Vera, Tim Clem, Rick Winfrey, Max Brunsfeld, Ayman Nadeem, Patrick Thomson 14 | maintainer: rob.rix@github.com 15 | copyright: 2019 GitHub 16 | category: Parsing, Tree-sitter 17 | build-type: Simple 18 | 19 | tested-with: 20 | GHC == 9.2.8 21 | GHC == 9.4.8 22 | GHC == 9.6.6 23 | GHC == 9.8.2 24 | 25 | extra-source-files: vendor/tree-sitter/lib/src/**/*.c 26 | , vendor/tree-sitter/lib/src/**/*.h 27 | 28 | extra-doc-files: ChangeLog.md 29 | 30 | common common 31 | default-language: Haskell2010 32 | ghc-options: 33 | -Weverything 34 | -Wno-all-missed-specialisations 35 | -Wno-implicit-prelude 36 | -Wno-missed-specialisations 37 | -Wno-missing-import-lists 38 | -Wno-missing-local-signatures 39 | -Wno-monomorphism-restriction 40 | -Wno-name-shadowing 41 | -Wno-safe 42 | -Wno-unsafe 43 | -Wno-star-is-type 44 | -Wno-missing-deriving-strategies 45 | -Wno-missing-safe-haskell-mode 46 | -Wno-prepositive-qualified-module 47 | if (impl(ghc >= 9.2)) 48 | ghc-options: 49 | -Wno-missing-kind-signatures 50 | -Wno-implicit-lift 51 | 52 | library 53 | import: common 54 | hs-source-dirs: src 55 | build-depends: 56 | , base >= 4.14.3.0 && < 5 57 | , bytestring >= 0.10.8.2 && < 0.13 58 | , containers ^>= 0.6.0.1 59 | , directory ^>= 1.3 60 | , filepath ^>= 1.4.1 61 | , split ^>= 0.2.3 62 | , template-haskell >= 2.12 && < 3 63 | , unordered-containers ^>= 0.2.9 64 | exposed-modules: TreeSitter.Parser 65 | , TreeSitter.Language 66 | , TreeSitter.Node 67 | , TreeSitter.Symbol 68 | , TreeSitter.Tree 69 | , TreeSitter.Cursor 70 | include-dirs: vendor/tree-sitter/lib/include 71 | , vendor/tree-sitter/lib/src 72 | install-includes: tree_sitter/api.h 73 | c-sources: src/bridge.c 74 | , vendor/tree-sitter/lib/src/lib.c 75 | cc-options: -std=c99 76 | 77 | test-suite test 78 | import: common 79 | type: exitcode-stdio-1.0 80 | hs-source-dirs: test 81 | main-is: Test.hs 82 | other-modules: TreeSitter.Example 83 | , TreeSitter.Strings.Example 84 | build-depends: base 85 | , tree-sitter 86 | , hedgehog >= 0.6 && <2 87 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 88 | 89 | source-repository head 90 | type: git 91 | location: https://github.com/tree-sitter/haskell-tree-sitter 92 | --------------------------------------------------------------------------------