├── .coffeelintignore ├── .github ├── no-response.yml └── workflows │ └── build.yml ├── .gitignore ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── coffeelint.json ├── grammars ├── java server pages (jsp).cson ├── java.cson ├── javaproperties.cson ├── junit test report.cson ├── tree-sitter-java.cson └── unified expression language (el).cson ├── package-lock.json ├── package.json ├── settings └── language-java.cson ├── snippets └── language-java.cson └── spec ├── java-spec.coffee ├── tree-sitter-java-spec.coffee └── unified-el-spec.coffee /.coffeelintignore: -------------------------------------------------------------------------------- 1 | spec/fixtures 2 | -------------------------------------------------------------------------------- /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-no-response - https://github.com/probot/no-response 2 | 3 | # Number of days of inactivity before an issue is closed for lack of response 4 | daysUntilClose: 28 5 | 6 | # Label requiring a response 7 | responseRequiredLabel: more-information-needed 8 | 9 | # Comment to post when closing an issue for lack of response. Set to `false` to disable. 10 | closeComment: > 11 | This issue has been automatically closed because there has been no response 12 | to our request for more information from the original author. With only the 13 | information that is currently in the issue, we don't have enough information 14 | to take action. Please reach out if you have or find the answers we need so 15 | that we can investigate further. 16 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | jobs: 13 | test: 14 | runs-on: ${{ matrix.os }} 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | os: [ ubuntu-latest, macos-latest, windows-latest ] 19 | channel: [ stable, beta ] 20 | steps: 21 | - uses: actions/checkout@v2 22 | 23 | - name: Install Atom and APM (Linux) 24 | if: ${{ matrix.os == 'ubuntu-latest' }} 25 | run: | 26 | curl -s -L "https://atom.io/download/deb?channel=${{ matrix.channel }}" -o "atom-amd64.deb" 27 | /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 28 | dpkg-deb -x atom-amd64.deb ${HOME}/atom 29 | if [ ${{ matrix.channel }} == "stable" ]; then 30 | APP_DIR="${HOME}/atom/usr/share/atom" 31 | else 32 | APP_DIR="${HOME}/atom/usr/share/atom-${{ matrix.channel }}" 33 | fi 34 | echo DISPLAY=":99" >> $GITHUB_ENV 35 | echo "${APP_DIR}" >> $GITHUB_PATH 36 | echo "${APP_DIR}/resources/app/apm/node_modules/.bin" >> $GITHUB_PATH 37 | echo "./node_modules/.bin" >> $GITHUB_PATH 38 | 39 | - name: Install Atom and APM (MacOS) 40 | if: ${{ matrix.os == 'macos-latest' }} 41 | run: | 42 | curl -s -L "https://atom.io/download/mac?channel=${{ matrix.channel }}" -o "atom.zip" 43 | mkdir ${HOME}/.atom && unzip -q atom.zip -d ${HOME}/.atom 44 | if [ ${{ matrix.channel }} == "stable" ]; then 45 | APP_DIR="${HOME}/.atom/Atom.app/Contents/Resources/app" 46 | else 47 | APP_DIR="${HOME}/.atom/Atom ${{ matrix.channel }}.app/Contents/Resources/app" 48 | fi 49 | ln -s "${APP_DIR}/atom.sh" "${APP_DIR}/atom" 50 | echo "${APP_DIR}" >> $GITHUB_PATH 51 | echo "${APP_DIR}/apm/bin" >> $GITHUB_PATH 52 | echo "./node_modules/.bin" >> $GITHUB_PATH 53 | 54 | - name: Install Atom and APM (Windows) 55 | if: ${{ matrix.os == 'windows-latest' }} 56 | run: | 57 | Invoke-WebRequest -Uri "https://atom.io/download/windows_zip?channel=${{ matrix.channel }}" -OutFile "atom.zip" 58 | Unzip "atom.zip" 59 | $ATOM_CHANNEL = "Atom" 60 | if ("${{ matrix.channel }}" -ne "stable") { 61 | $ATOM_CHANNEL += " " 62 | $ATOM_CHANNEL += "${{ matrix.channel }}".substring(0, 1).toupper() 63 | $ATOM_CHANNEL += "${{ matrix.channel }}".substring(1).tolower() 64 | } 65 | echo npm_config_msvs_version="2019" >> ${env:GITHUB_ENV} 66 | echo "$ATOM_CHANNEL/resources/cli" >> ${env:GITHUB_PATH} 67 | echo "$ATOM_CHANNEL/resources/app/apm/bin" >> ${env:GITHUB_PATH} 68 | echo "./node_modules/.bin" >> ${env:GITHUB_PATH} 69 | 70 | - name: Print Atom and APM versions 71 | run: | 72 | atom -v 73 | apm -v 74 | 75 | - name: Install dependencies 76 | run: | 77 | apm install 78 | apm clean 79 | npm install 80 | 81 | - name: Test 82 | run: | 83 | atom --test spec 84 | 85 | - name: Lint 86 | run: | 87 | coffeelint grammars 88 | coffeelint spec 89 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | See the [Atom contributing guide](https://atom.io/docs/latest/contributing) 2 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ### Prerequisites 10 | 11 | * [ ] Put an X between the brackets on this line if you have done all of the following: 12 | * Reproduced the problem in Safe Mode: http://flight-manual.atom.io/hacking-atom/sections/debugging/#using-safe-mode 13 | * Followed all applicable steps in the debugging guide: http://flight-manual.atom.io/hacking-atom/sections/debugging/ 14 | * Checked the FAQs on the message board for common solutions: https://discuss.atom.io/c/faq 15 | * Checked that your issue isn't already filed: https://github.com/issues?utf8=✓&q=is%3Aissue+user%3Aatom 16 | * Checked that there is not already an Atom package that provides the described functionality: https://atom.io/packages 17 | 18 | ### Description 19 | 20 | [Description of the issue] 21 | 22 | ### Steps to Reproduce 23 | 24 | 1. [First Step] 25 | 2. [Second Step] 26 | 3. [and so on...] 27 | 28 | **Expected behavior:** [What you expect to happen] 29 | 30 | **Actual behavior:** [What actually happens] 31 | 32 | **Reproduces how often:** [What percentage of the time does it reproduce?] 33 | 34 | ### Versions 35 | 36 | You can get this information from copy and pasting the output of `atom --version` and `apm --version` from the command line. Also, please include the OS and what version of the OS you're running. 37 | 38 | ### Additional Information 39 | 40 | Any additional information, configuration or data that might be necessary to reproduce the issue. 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 GitHub Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------- 23 | 24 | This package was derived from a TextMate bundle located at 25 | https://github.com/textmate/java.tmbundle and distributed under the following 26 | license, located in `README.mdown`: 27 | 28 | Permission to copy, use, modify, sell and distribute this 29 | software is granted. This software is provided "as is" without 30 | express or implied warranty, and with no claim as to its 31 | suitability for any purpose. 32 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Requirements 2 | 3 | * Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. 4 | * All new code requires tests to ensure against regressions 5 | 6 | ### Description of the Change 7 | 8 | 13 | 14 | ### Alternate Designs 15 | 16 | 17 | 18 | ### Benefits 19 | 20 | 21 | 22 | ### Possible Drawbacks 23 | 24 | 25 | 26 | ### Applicable Issues 27 | 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##### Atom and all repositories under Atom will be archived on December 15, 2022. Learn more in our [official announcement](https://github.blog/2022-06-08-sunsetting-atom/) 2 | # Java language support in Atom 3 | ![build](https://github.com/atom/language-java/workflows/build/badge.svg) 4 | [![Dependency Status](https://david-dm.org/atom/language-java.svg)](https://david-dm.org/atom/language-java) 5 | 6 | Add syntax highlighting and snippets to Java/JSP files in Atom. 7 | 8 | Originally [converted](http://flight-manual.atom.io/hacking-atom/sections/converting-from-textmate) from the [Java TextMate bundle](https://github.com/textmate/java.tmbundle). 9 | 10 | Contributions are greatly appreciated. Please fork this repository and open a pull request to add snippets, make grammar tweaks, etc. 11 | -------------------------------------------------------------------------------- /coffeelint.json: -------------------------------------------------------------------------------- 1 | { 2 | "max_line_length": { 3 | "level": "ignore" 4 | }, 5 | "no_empty_param_list": { 6 | "level": "error" 7 | }, 8 | "arrow_spacing": { 9 | "level": "error" 10 | }, 11 | "no_interpolation_in_single_quotes": { 12 | "level": "error" 13 | }, 14 | "no_debugger": { 15 | "level": "error" 16 | }, 17 | "prefer_english_operator": { 18 | "level": "error" 19 | }, 20 | "colon_assignment_spacing": { 21 | "spacing": { 22 | "left": 0, 23 | "right": 1 24 | }, 25 | "level": "error" 26 | }, 27 | "braces_spacing": { 28 | "spaces": 0, 29 | "level": "error" 30 | }, 31 | "spacing_after_comma": { 32 | "level": "error" 33 | }, 34 | "no_stand_alone_at": { 35 | "level": "error" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /grammars/java server pages (jsp).cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'text.html.jsp' 2 | 'name': 'JavaServer Pages' 3 | 'fileTypes': [ 4 | 'jsp' 5 | 'jspf' 6 | 'jspx' 7 | 'tag' 8 | ] 9 | 'injections': 10 | 'text.html.jsp - (meta.embedded.block.jsp | meta.embedded.line.jsp | meta.tag | comment), meta.tag string.quoted': 11 | 'patterns': [ 12 | { 13 | 'include': '#comment' 14 | } 15 | { 16 | 'include': '#declaration' 17 | } 18 | { 19 | 'include': '#expression' 20 | } 21 | { 22 | 'include': '#el_expression' 23 | } 24 | { 25 | 'include': '#tags' 26 | } 27 | { 28 | 'begin': '(^\\s*)(?=<%(?=\\s))' 29 | 'beginCaptures': 30 | '0': 31 | 'name': 'punctuation.whitespace.embedded.leading.erb' 32 | 'end': '(?!\\G)(\\s*$\\n)?' 33 | 'endCaptures': 34 | '0': 35 | 'name': 'punctuation.whitespace.embedded.trailing.erb' 36 | 'patterns': [ 37 | { 38 | 'include': '#scriptlet' 39 | } 40 | ] 41 | } 42 | { 43 | 'include': '#scriptlet' 44 | } 45 | ] 46 | 'patterns': [ 47 | { 48 | 'include': '#xml_tags' 49 | } 50 | { 51 | 'include': 'text.html.basic' 52 | } 53 | ] 54 | 'repository': 55 | 'comment': 56 | 'begin': '<%--' 57 | 'captures': 58 | '0': 59 | 'name': 'punctuation.definition.comment.jsp' 60 | 'end': '--%>' 61 | 'name': 'comment.block.jsp' 62 | 'declaration': 63 | 'begin': '<%!' 64 | 'beginCaptures': 65 | '0': 66 | 'name': 'punctuation.section.embedded.begin.jsp' 67 | 'contentName': 'source.java' 68 | 'end': '(%)>' 69 | 'endCaptures': 70 | '0': 71 | 'name': 'punctuation.section.embedded.end.jsp' 72 | '1': 73 | 'name': 'source.java' 74 | 'name': 'meta.embedded.line.declaration.jsp' 75 | 'patterns': [ 76 | { 77 | 'include': 'source.java' 78 | } 79 | ] 80 | 'el_expression': 81 | 'begin': '\\$\\{' 82 | 'beginCaptures': 83 | '0': 84 | 'name': 'punctuation.section.embedded.begin.jsp' 85 | 'contentName': 'source.java' 86 | 'end': '(\\})' 87 | 'endCaptures': 88 | '0': 89 | 'name': 'punctuation.section.embedded.end.jsp' 90 | '1': 91 | 'name': 'source.java' 92 | 'name': 'meta.embedded.line.el_expression.jsp' 93 | 'patterns': [ 94 | { 95 | 'include': 'source.java.el' 96 | } 97 | ] 98 | 'expression': 99 | 'begin': '<%=' 100 | 'beginCaptures': 101 | '0': 102 | 'name': 'punctuation.section.embedded.begin.jsp' 103 | 'contentName': 'source.java' 104 | 'end': '(%)>' 105 | 'endCaptures': 106 | '0': 107 | 'name': 'punctuation.section.embedded.end.jsp' 108 | '1': 109 | 'name': 'source.java' 110 | 'name': 'meta.embedded.line.expression.jsp' 111 | 'patterns': [ 112 | { 113 | 'include': 'source.java' 114 | } 115 | ] 116 | 'scriptlet': 117 | 'begin': '<%' 118 | 'beginCaptures': 119 | '0': 120 | 'name': 'punctuation.section.embedded.begin.jsp' 121 | 'contentName': 'source.java' 122 | 'end': '(%)>' 123 | 'endCaptures': 124 | '0': 125 | 'name': 'punctuation.section.embedded.end.jsp' 126 | '1': 127 | 'name': 'source.java' 128 | 'name': 'meta.embedded.block.scriptlet.jsp' 129 | 'patterns': [ 130 | { 131 | 'match': '\\{' 132 | 'name': 'punctuation.section.scope.begin.java' 133 | } 134 | { 135 | 'match': '\\}' 136 | 'name': 'punctuation.section.scope.end.java' 137 | } 138 | { 139 | 'include': 'source.java' 140 | } 141 | ] 142 | 'tags': 143 | 'begin': '(<%@)\\s*(?=(attribute|include|page|tag|taglib|variable)\\s)' 144 | 'beginCaptures': 145 | '1': 146 | 'name': 'punctuation.definition.tag.begin.jsp' 147 | 'end': '%>' 148 | 'endCaptures': 149 | '0': 150 | 'name': 'punctuation.definition.tag.end.jsp' 151 | 'name': 'meta.tag.template.include.jsp' 152 | 'patterns': [ 153 | { 154 | 'begin': '\\G(attribute)(?=\\s)' 155 | 'captures': 156 | '1': 157 | 'name': 'keyword.control.attribute.jsp' 158 | 'end': '(?=%>)' 159 | 'patterns': [ 160 | { 161 | 'captures': 162 | '1': 163 | 'name': 'entity.other.attribute-name.jsp' 164 | '2': 165 | 'name': 'punctuation.separator.key-value.jsp' 166 | '3': 167 | 'name': 'string.quoted.double.jsp' 168 | '4': 169 | 'name': 'punctuation.definition.string.begin.jsp' 170 | '5': 171 | 'name': 'punctuation.definition.string.end.jsp' 172 | 'match': '(name|required|fragment|rtexprvalue|type|description)(=)((")[^"]*("))' 173 | } 174 | ] 175 | } 176 | { 177 | 'begin': '\\G(include)(?=\\s)' 178 | 'captures': 179 | '1': 180 | 'name': 'keyword.control.include.jsp' 181 | 'end': '(?=%>)' 182 | 'patterns': [ 183 | { 184 | 'captures': 185 | '1': 186 | 'name': 'entity.other.attribute-name.jsp' 187 | '2': 188 | 'name': 'punctuation.separator.key-value.jsp' 189 | '3': 190 | 'name': 'string.quoted.double.jsp' 191 | '4': 192 | 'name': 'punctuation.definition.string.begin.jsp' 193 | '5': 194 | 'name': 'punctuation.definition.string.end.jsp' 195 | 'match': '(file)(=)((")[^"]*("))' 196 | } 197 | ] 198 | } 199 | { 200 | 'begin': '\\G(page)(?=\\s)' 201 | 'captures': 202 | '1': 203 | 'name': 'keyword.control.page.jsp' 204 | 'end': '(?=%>)' 205 | 'patterns': [ 206 | { 207 | 'captures': 208 | '1': 209 | 'name': 'entity.other.attribute-name.jsp' 210 | '2': 211 | 'name': 'punctuation.separator.key-value.jsp' 212 | '3': 213 | 'name': 'string.quoted.double.jsp' 214 | '4': 215 | 'name': 'punctuation.definition.string.begin.jsp' 216 | '5': 217 | 'name': 'punctuation.definition.string.end.jsp' 218 | 'match': '(language|extends|import|session|buffer|autoFlush|isThreadSafe|info|errorPage|isErrorPage|contentType|pageEncoding|isElIgnored)(=)((")[^"]*("))' 219 | } 220 | ] 221 | } 222 | { 223 | 'begin': '\\G(tag)(?=\\s)' 224 | 'captures': 225 | '1': 226 | 'name': 'keyword.control.tag.jsp' 227 | 'end': '(?=%>)' 228 | 'patterns': [ 229 | { 230 | 'captures': 231 | '1': 232 | 'name': 'entity.other.attribute-name.jsp' 233 | '2': 234 | 'name': 'punctuation.separator.key-value.jsp' 235 | '3': 236 | 'name': 'string.quoted.double.jsp' 237 | '4': 238 | 'name': 'punctuation.definition.string.begin.jsp' 239 | '5': 240 | 'name': 'punctuation.definition.string.end.jsp' 241 | 'match': '(display-name|body-content|dynamic-attributes|small-icon|large-icon|description|example|language|import|pageEncoding|isELIgnored)(=)((")[^"]*("))' 242 | } 243 | ] 244 | } 245 | { 246 | 'begin': '\\G(taglib)(?=\\s)' 247 | 'captures': 248 | '1': 249 | 'name': 'keyword.control.taglib.jsp' 250 | 'end': '(?=%>)' 251 | 'patterns': [ 252 | { 253 | 'captures': 254 | '1': 255 | 'name': 'entity.other.attribute-name.jsp' 256 | '2': 257 | 'name': 'punctuation.separator.key-value.jsp' 258 | '3': 259 | 'name': 'string.quoted.double.jsp' 260 | '4': 261 | 'name': 'punctuation.definition.string.begin.jsp' 262 | '5': 263 | 'name': 'punctuation.definition.string.end.jsp' 264 | 'match': '(uri|tagdir|prefix)(=)((")[^"]*("))' 265 | } 266 | ] 267 | } 268 | { 269 | 'begin': '\\G(variable)(?=\\s)' 270 | 'captures': 271 | '1': 272 | 'name': 'keyword.control.variable.jsp' 273 | 'end': '(?=%>)' 274 | 'patterns': [ 275 | { 276 | 'captures': 277 | '1': 278 | 'name': 'entity.other.attribute-name.jsp' 279 | '2': 280 | 'name': 'punctuation.separator.key-value.jsp' 281 | '3': 282 | 'name': 'string.quoted.double.jsp' 283 | '4': 284 | 'name': 'punctuation.definition.string.begin.jsp' 285 | '5': 286 | 'name': 'punctuation.definition.string.end.jsp' 287 | 'match': '(name-given|alias|variable-class|declare|scope|description)(=)((")[^"]*("))' 288 | } 289 | ] 290 | } 291 | ] 292 | 'xml_tags': 293 | 'patterns': [ 294 | { 295 | 'begin': '(^\\s*)(?=)' 296 | 'beginCaptures': 297 | '0': 298 | 'name': 'punctuation.whitespace.embedded.leading.erb' 299 | 'end': '(?!\\G)(\\s*$\\n)?' 300 | 'endCaptures': 301 | '0': 302 | 'name': 'punctuation.whitespace.embedded.trailing.erb' 303 | 'patterns': [ 304 | { 305 | 'include': '#embedded' 306 | } 307 | ] 308 | } 309 | { 310 | 'include': '#embedded' 311 | } 312 | { 313 | 'include': '#directive' 314 | } 315 | { 316 | 'include': '#actions' 317 | } 318 | ] 319 | 'repository': 320 | 'actions': 321 | 'patterns': [ 322 | { 323 | 'begin': '(' 330 | 'endCaptures': 331 | '0': 332 | 'name': 'punctuation.definition.tag.end.jsp' 333 | 'name': 'meta.tag.template.attribute.jsp' 334 | 'patterns': [ 335 | { 336 | 'captures': 337 | '1': 338 | 'name': 'entity.other.attribute-name.jsp' 339 | '2': 340 | 'name': 'punctuation.separator.key-value.jsp' 341 | '3': 342 | 'name': 'string.quoted.double.jsp' 343 | '4': 344 | 'name': 'punctuation.definition.string.begin.jsp' 345 | '5': 346 | 'name': 'punctuation.definition.string.end.jsp' 347 | 'match': '(name|trim)(=)((")[^"]*("))' 348 | } 349 | ] 350 | } 351 | { 352 | 'captures': 353 | '1': 354 | 'name': 'punctuation.definition.tag.begin.jsp' 355 | '2': 356 | 'name': 'entity.name.tag.jsp' 357 | '3': 358 | 'name': 'punctuation.definition.tag.end.jsp' 359 | 'match': '()' 360 | 'name': 'meta.tag.template.body.jsp' 361 | } 362 | { 363 | 'begin': '(' 370 | 'endCaptures': 371 | '0': 372 | 'name': 'punctuation.definition.tag.end.jsp' 373 | 'name': 'meta.tag.template.element.jsp' 374 | 'patterns': [ 375 | { 376 | 'captures': 377 | '1': 378 | 'name': 'entity.other.attribute-name.jsp' 379 | '2': 380 | 'name': 'punctuation.separator.key-value.jsp' 381 | '3': 382 | 'name': 'string.quoted.double.jsp' 383 | '4': 384 | 'name': 'punctuation.definition.string.begin.jsp' 385 | '5': 386 | 'name': 'punctuation.definition.string.end.jsp' 387 | 'match': '(name)(=)((")[^"]*("))' 388 | } 389 | ] 390 | } 391 | { 392 | 'begin': '(<)(jsp:doBody)\\b' 393 | 'beginCaptures': 394 | '1': 395 | 'name': 'punctuation.definition.tag.begin.jsp' 396 | '2': 397 | 'name': 'entity.name.tag.jsp' 398 | 'end': '/>' 399 | 'endCaptures': 400 | '0': 401 | 'name': 'punctuation.definition.tag.end.jsp' 402 | 'name': 'meta.tag.template.dobody.jsp' 403 | 'patterns': [ 404 | { 405 | 'captures': 406 | '1': 407 | 'name': 'entity.other.attribute-name.jsp' 408 | '2': 409 | 'name': 'punctuation.separator.key-value.jsp' 410 | '3': 411 | 'name': 'string.quoted.double.jsp' 412 | '4': 413 | 'name': 'punctuation.definition.string.begin.jsp' 414 | '5': 415 | 'name': 'punctuation.definition.string.end.jsp' 416 | 'match': '(var|varReader|scope)(=)((")[^"]*("))' 417 | } 418 | ] 419 | } 420 | { 421 | 'begin': '(' 428 | 'endCaptures': 429 | '0': 430 | 'name': 'punctuation.definition.tag.end.jsp' 431 | 'name': 'meta.tag.template.forward.jsp' 432 | 'patterns': [ 433 | { 434 | 'captures': 435 | '1': 436 | 'name': 'entity.other.attribute-name.jsp' 437 | '2': 438 | 'name': 'punctuation.separator.key-value.jsp' 439 | '3': 440 | 'name': 'string.quoted.double.jsp' 441 | '4': 442 | 'name': 'punctuation.definition.string.begin.jsp' 443 | '5': 444 | 'name': 'punctuation.definition.string.end.jsp' 445 | 'match': '(page)(=)((")[^"]*("))' 446 | } 447 | ] 448 | } 449 | { 450 | 'begin': '(<)(jsp:param)\\b' 451 | 'beginCaptures': 452 | '1': 453 | 'name': 'punctuation.definition.tag.begin.jsp' 454 | '2': 455 | 'name': 'entity.name.tag.jsp' 456 | 'end': '/>' 457 | 'endCaptures': 458 | '0': 459 | 'name': 'punctuation.definition.tag.end.jsp' 460 | 'name': 'meta.tag.template.param.jsp' 461 | 'patterns': [ 462 | { 463 | 'captures': 464 | '1': 465 | 'name': 'entity.other.attribute-name.jsp' 466 | '2': 467 | 'name': 'punctuation.separator.key-value.jsp' 468 | '3': 469 | 'name': 'string.quoted.double.jsp' 470 | '4': 471 | 'name': 'punctuation.definition.string.begin.jsp' 472 | '5': 473 | 'name': 'punctuation.definition.string.end.jsp' 474 | 'match': '(name|value)(=)((")[^"]*("))' 475 | } 476 | ] 477 | } 478 | { 479 | 'begin': '(<)(jsp:getProperty)\\b' 480 | 'beginCaptures': 481 | '1': 482 | 'name': 'punctuation.definition.tag.begin.jsp' 483 | '2': 484 | 'name': 'entity.name.tag.jsp' 485 | 'end': '/>' 486 | 'endCaptures': 487 | '0': 488 | 'name': 'punctuation.definition.tag.end.jsp' 489 | 'name': 'meta.tag.template.getproperty.jsp' 490 | 'patterns': [ 491 | { 492 | 'captures': 493 | '1': 494 | 'name': 'entity.other.attribute-name.jsp' 495 | '2': 496 | 'name': 'punctuation.separator.key-value.jsp' 497 | '3': 498 | 'name': 'string.quoted.double.jsp' 499 | '4': 500 | 'name': 'punctuation.definition.string.begin.jsp' 501 | '5': 502 | 'name': 'punctuation.definition.string.end.jsp' 503 | 'match': '(name|property)(=)((")[^"]*("))' 504 | } 505 | ] 506 | } 507 | { 508 | 'begin': '(' 515 | 'endCaptures': 516 | '0': 517 | 'name': 'punctuation.definition.tag.end.jsp' 518 | 'name': 'meta.tag.template.include.jsp' 519 | 'patterns': [ 520 | { 521 | 'captures': 522 | '1': 523 | 'name': 'entity.other.attribute-name.jsp' 524 | '2': 525 | 'name': 'punctuation.separator.key-value.jsp' 526 | '3': 527 | 'name': 'string.quoted.double.jsp' 528 | '4': 529 | 'name': 'punctuation.definition.string.begin.jsp' 530 | '5': 531 | 'name': 'punctuation.definition.string.end.jsp' 532 | 'match': '(page|flush)(=)((")[^"]*("))' 533 | } 534 | ] 535 | } 536 | { 537 | 'begin': '(<)(jsp:invoke)\\b' 538 | 'beginCaptures': 539 | '1': 540 | 'name': 'punctuation.definition.tag.begin.jsp' 541 | '2': 542 | 'name': 'entity.name.tag.jsp' 543 | 'end': '/>' 544 | 'endCaptures': 545 | '0': 546 | 'name': 'punctuation.definition.tag.end.jsp' 547 | 'name': 'meta.tag.template.invoke.jsp' 548 | 'patterns': [ 549 | { 550 | 'captures': 551 | '1': 552 | 'name': 'entity.other.attribute-name.jsp' 553 | '2': 554 | 'name': 'punctuation.separator.key-value.jsp' 555 | '3': 556 | 'name': 'string.quoted.double.jsp' 557 | '4': 558 | 'name': 'punctuation.definition.string.begin.jsp' 559 | '5': 560 | 'name': 'punctuation.definition.string.end.jsp' 561 | 'match': '(fragment|var|varReader|scope)(=)((")[^"]*("))' 562 | } 563 | ] 564 | } 565 | { 566 | 'begin': '(<)(jsp:output)\\b' 567 | 'beginCaptures': 568 | '1': 569 | 'name': 'punctuation.definition.tag.begin.jsp' 570 | '2': 571 | 'name': 'entity.name.tag.jsp' 572 | 'end': '/>' 573 | 'endCaptures': 574 | '0': 575 | 'name': 'punctuation.definition.tag.end.jsp' 576 | 'name': 'meta.tag.template.output.jsp' 577 | 'patterns': [ 578 | { 579 | 'captures': 580 | '1': 581 | 'name': 'entity.other.attribute-name.jsp' 582 | '2': 583 | 'name': 'punctuation.separator.key-value.jsp' 584 | '3': 585 | 'name': 'string.quoted.double.jsp' 586 | '4': 587 | 'name': 'punctuation.definition.string.begin.jsp' 588 | '5': 589 | 'name': 'punctuation.definition.string.end.jsp' 590 | 'match': '(omit-xml-declaration|doctype-root-element|doctype-system|doctype-public)(=)((")[^"]*("))' 591 | } 592 | ] 593 | } 594 | { 595 | 'begin': '(' 602 | 'endCaptures': 603 | '0': 604 | 'name': 'punctuation.definition.tag.end.jsp' 605 | 'name': 'meta.tag.template.plugin.jsp' 606 | 'patterns': [ 607 | { 608 | 'captures': 609 | '1': 610 | 'name': 'entity.other.attribute-name.jsp' 611 | '2': 612 | 'name': 'punctuation.separator.key-value.jsp' 613 | '3': 614 | 'name': 'string.quoted.double.jsp' 615 | '4': 616 | 'name': 'punctuation.definition.string.begin.jsp' 617 | '5': 618 | 'name': 'punctuation.definition.string.end.jsp' 619 | 'match': '(type|code|codebase|name|archive|align|height|hspace|jreversion|nspluginurl|iepluginurl)(=)((")[^"]*("))' 620 | } 621 | ] 622 | } 623 | { 624 | 'captures': 625 | '1': 626 | 'name': 'punctuation.definition.tag.begin.jsp' 627 | '2': 628 | 'name': 'entity.name.tag.jsp' 629 | '3': 630 | 'name': 'punctuation.definition.tag.end.jsp' 631 | 'end': '>' 632 | 'match': '()' 633 | 'name': 'meta.tag.template.fallback.jsp' 634 | } 635 | { 636 | 'begin': '(' 643 | 'endCaptures': 644 | '0': 645 | 'name': 'punctuation.definition.tag.end.jsp' 646 | 'name': 'meta.tag.template.root.jsp' 647 | 'patterns': [ 648 | { 649 | 'captures': 650 | '1': 651 | 'name': 'entity.other.attribute-name.jsp' 652 | '2': 653 | 'name': 'punctuation.separator.key-value.jsp' 654 | '3': 655 | 'name': 'string.quoted.double.jsp' 656 | '4': 657 | 'name': 'punctuation.definition.string.begin.jsp' 658 | '5': 659 | 'name': 'punctuation.definition.string.end.jsp' 660 | 'match': '(xmlns|version|xmlns:taglibPrefix)(=)((")[^"]*("))' 661 | } 662 | ] 663 | } 664 | { 665 | 'begin': '(<)(jsp:setProperty)\\b' 666 | 'beginCaptures': 667 | '1': 668 | 'name': 'punctuation.definition.tag.begin.jsp' 669 | '2': 670 | 'name': 'entity.name.tag.jsp' 671 | 'end': '/>' 672 | 'endCaptures': 673 | '0': 674 | 'name': 'punctuation.definition.tag.end.jsp' 675 | 'name': 'meta.tag.template.setproperty.jsp' 676 | 'patterns': [ 677 | { 678 | 'captures': 679 | '1': 680 | 'name': 'entity.other.attribute-name.jsp' 681 | '2': 682 | 'name': 'punctuation.separator.key-value.jsp' 683 | '3': 684 | 'name': 'string.quoted.double.jsp' 685 | '4': 686 | 'name': 'punctuation.definition.string.begin.jsp' 687 | '5': 688 | 'name': 'punctuation.definition.string.end.jsp' 689 | 'match': '(name|property|value)(=)((")[^"]*("))' 690 | } 691 | ] 692 | } 693 | { 694 | 'captures': 695 | '1': 696 | 'name': 'punctuation.definition.tag.begin.jsp' 697 | '2': 698 | 'name': 'entity.name.tag.jsp' 699 | '3': 700 | 'name': 'punctuation.definition.tag.end.jsp' 701 | 'end': '>' 702 | 'match': '()' 703 | 'name': 'meta.tag.template.text.jsp' 704 | } 705 | { 706 | 'begin': '(' 713 | 'endCaptures': 714 | '0': 715 | 'name': 'punctuation.definition.tag.end.jsp' 716 | 'name': 'meta.tag.template.usebean.jsp' 717 | 'patterns': [ 718 | { 719 | 'captures': 720 | '1': 721 | 'name': 'entity.other.attribute-name.jsp' 722 | '2': 723 | 'name': 'punctuation.separator.key-value.jsp' 724 | '3': 725 | 'name': 'string.quoted.double.jsp' 726 | '4': 727 | 'name': 'punctuation.definition.string.begin.jsp' 728 | '5': 729 | 'name': 'punctuation.definition.string.end.jsp' 730 | 'match': '(id|scope|class|type|beanName)(=)((")[^"]*("))' 731 | } 732 | ] 733 | } 734 | ] 735 | 'directive': 736 | 'begin': '(<)(jsp:directive\\.(?=(attribute|include|page|tag|variable)\\s))' 737 | 'beginCaptures': 738 | '1': 739 | 'name': 'punctuation.definition.tag.begin.jsp' 740 | '2': 741 | 'name': 'entity.name.tag.jsp' 742 | 'end': '/>' 743 | 'endCaptures': 744 | '0': 745 | 'name': 'punctuation.definition.tag.end.jsp' 746 | 'name': 'meta.tag.template.$3.jsp' 747 | 'patterns': [ 748 | { 749 | 'begin': '\\G(attribute)(?=\\s)' 750 | 'captures': 751 | '1': 752 | 'name': 'entity.name.tag.jsp' 753 | 'end': '(?=/>)' 754 | 'patterns': [ 755 | { 756 | 'captures': 757 | '1': 758 | 'name': 'entity.other.attribute-name.jsp' 759 | '2': 760 | 'name': 'punctuation.separator.key-value.jsp' 761 | '3': 762 | 'name': 'string.quoted.double.jsp' 763 | '4': 764 | 'name': 'punctuation.definition.string.begin.jsp' 765 | '5': 766 | 'name': 'punctuation.definition.string.end.jsp' 767 | 'match': '(name|required|fragment|rtexprvalue|type|description)(=)((")[^"]*("))' 768 | } 769 | ] 770 | } 771 | { 772 | 'begin': '\\G(include)(?=\\s)' 773 | 'captures': 774 | '1': 775 | 'name': 'entity.name.tag.jsp' 776 | 'end': '(?=/>)' 777 | 'patterns': [ 778 | { 779 | 'captures': 780 | '1': 781 | 'name': 'entity.other.attribute-name.jsp' 782 | '2': 783 | 'name': 'punctuation.separator.key-value.jsp' 784 | '3': 785 | 'name': 'string.quoted.double.jsp' 786 | '4': 787 | 'name': 'punctuation.definition.string.begin.jsp' 788 | '5': 789 | 'name': 'punctuation.definition.string.end.jsp' 790 | 'match': '(file)(=)((")[^"]*("))' 791 | } 792 | ] 793 | } 794 | { 795 | 'begin': '\\G(page)(?=\\s)' 796 | 'captures': 797 | '1': 798 | 'name': 'entity.name.tag.jsp' 799 | 'end': '(?=/>)' 800 | 'patterns': [ 801 | { 802 | 'captures': 803 | '1': 804 | 'name': 'entity.other.attribute-name.jsp' 805 | '2': 806 | 'name': 'punctuation.separator.key-value.jsp' 807 | '3': 808 | 'name': 'string.quoted.double.jsp' 809 | '4': 810 | 'name': 'punctuation.definition.string.begin.jsp' 811 | '5': 812 | 'name': 'punctuation.definition.string.end.jsp' 813 | 'match': '(language|extends|import|session|buffer|autoFlush|isThreadSafe|info|errorPage|isErrorPage|contentType|pageEncoding|isElIgnored)(=)((")[^"]*("))' 814 | } 815 | ] 816 | } 817 | { 818 | 'begin': '\\G(tag)(?=\\s)' 819 | 'captures': 820 | '1': 821 | 'name': 'entity.name.tag.jsp' 822 | 'end': '(?=/>)' 823 | 'patterns': [ 824 | { 825 | 'captures': 826 | '1': 827 | 'name': 'entity.other.attribute-name.jsp' 828 | '2': 829 | 'name': 'punctuation.separator.key-value.jsp' 830 | '3': 831 | 'name': 'string.quoted.double.jsp' 832 | '4': 833 | 'name': 'punctuation.definition.string.begin.jsp' 834 | '5': 835 | 'name': 'punctuation.definition.string.end.jsp' 836 | 'match': '(display-name|body-content|dynamic-attributes|small-icon|large-icon|description|example|language|import|pageEncoding|isELIgnored)(=)((")[^"]*("))' 837 | } 838 | ] 839 | } 840 | { 841 | 'begin': '\\G(variable)(?=\\s)' 842 | 'captures': 843 | '1': 844 | 'name': 'entity.name.tag.jsp' 845 | 'end': '(?=/>)' 846 | 'patterns': [ 847 | { 848 | 'captures': 849 | '1': 850 | 'name': 'entity.other.attribute-name.jsp' 851 | '2': 852 | 'name': 'punctuation.separator.key-value.jsp' 853 | '3': 854 | 'name': 'string.quoted.double.jsp' 855 | '4': 856 | 'name': 'punctuation.definition.string.begin.jsp' 857 | '5': 858 | 'name': 'punctuation.definition.string.end.jsp' 859 | 'match': '(name-given|alias|variable-class|declare|scope|description)(=)((")[^"]*("))' 860 | } 861 | ] 862 | } 863 | ] 864 | 'embedded': 865 | 'begin': '(<)(jsp:(declaration|expression|scriptlet))(>)' 866 | 'beginCaptures': 867 | '0': 868 | 'name': 'meta.tag.template.$3.jsp' 869 | '1': 870 | 'name': 'punctuation.definition.tag.begin.jsp' 871 | '2': 872 | 'name': 'entity.name.tag.jsp' 873 | '4': 874 | 'name': 'punctuation.definition.tag.end.jsp' 875 | 'contentName': 'source.java' 876 | 'end': '((<)/)(jsp:\\3)(>)' 877 | 'endCaptures': 878 | '0': 879 | 'name': 'meta.tag.template.$4.jsp' 880 | '1': 881 | 'name': 'punctuation.definition.tag.begin.jsp' 882 | '2': 883 | 'name': 'source.java' 884 | '3': 885 | 'name': 'entity.name.tag.jsp' 886 | '4': 887 | 'name': 'punctuation.definition.tag.end.jsp' 888 | 'name': 'meta.embedded.block.jsp' 889 | 'patterns': [ 890 | { 891 | 'include': 'source.java' 892 | } 893 | ] 894 | -------------------------------------------------------------------------------- /grammars/java.cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'source.java' 2 | 'name': 'Java' 3 | 'fileTypes': [ 4 | 'java' 5 | 'bsh' 6 | ] 7 | 'patterns': [ 8 | { 9 | 'begin': '\\b(package)\\b\\s*' 10 | 'beginCaptures': 11 | '1': 12 | 'name': 'keyword.other.package.java' 13 | 'end': '\\s*(;)' 14 | 'endCaptures': 15 | '1': 16 | 'name': 'punctuation.terminator.java' 17 | 'name': 'meta.package.java' 18 | 'contentName': 'storage.modifier.package.java' 19 | 'patterns': [ 20 | { 21 | 'include': '#comments' 22 | } 23 | { 24 | 'match': '(?<=\\.)\\s*\\.|\\.(?=\\s*;)' 25 | 'name': 'invalid.illegal.character_not_allowed_here.java' 26 | } 27 | { 28 | 'match': '(?' 752 | 'endCaptures': 753 | '0': 754 | 'name': 'punctuation.bracket.angle.java' 755 | 'patterns': [ 756 | { 757 | 'match': '\\b(extends|super)\\b' 758 | 'name': 'storage.modifier.$1.java' 759 | } 760 | { 761 | 'match': '(?>>?|~|\\^)' 819 | 'name': 'keyword.operator.bitwise.java' 820 | } 821 | { 822 | 'match': '((&|\\^|\\||<<|>>>?)=)' 823 | 'name': 'keyword.operator.assignment.bitwise.java' 824 | } 825 | { 826 | 'match': '(===?|!=|<=|>=|<>|<|>)' 827 | 'name': 'keyword.operator.comparison.java' 828 | } 829 | { 830 | 'match': '([+*/%-]=)' 831 | 'name': 'keyword.operator.assignment.arithmetic.java' 832 | } 833 | { 834 | 'match': '(=)' 835 | 'name': 'keyword.operator.assignment.java' 836 | } 837 | { 838 | 'match': '(\\-\\-|\\+\\+)' 839 | 'name': 'keyword.operator.increment-decrement.java' 840 | } 841 | { 842 | 'match': '(\\-|\\+|\\*|\\/|%)' 843 | 'name': 'keyword.operator.arithmetic.java' 844 | } 845 | { 846 | 'match': '(!|&&|\\|\\|)' 847 | 'name': 'keyword.operator.logical.java' 848 | } 849 | { 850 | 'match': '(\\||&)' 851 | 'name': 'keyword.operator.bitwise.java' 852 | } 853 | { 854 | 'match': '\\b(const|goto)\\b' 855 | 'name': 'keyword.reserved.java' 856 | } 857 | ] 858 | 'lambda-expression': 859 | 'patterns': [ 860 | { 861 | 'match': '->' 862 | 'name': 'storage.type.function.arrow.java' 863 | } 864 | ] 865 | 'member-variables': 866 | 'begin': '(?=private|protected|public|native|synchronized|abstract|threadsafe|transient|static|final)' 867 | 'end': '(?=\\=|;)' 868 | 'patterns': [ 869 | { 870 | 'include': '#storage-modifiers' 871 | } 872 | { 873 | 'include': '#variables' 874 | } 875 | { 876 | 'include': '#primitive-arrays' 877 | } 878 | { 879 | 'include': '#object-types' 880 | } 881 | ] 882 | 'method-call': 883 | 'begin': '(\\.)\\s*([A-Za-z_$][\\w$]*)\\s*(\\()' 884 | 'beginCaptures': 885 | '1': 886 | 'name': 'punctuation.separator.period.java' 887 | '2': 888 | 'name': 'entity.name.function.java' 889 | '3': 890 | 'name': 'punctuation.definition.parameters.begin.bracket.round.java' 891 | 'end': '\\)' 892 | 'endCaptures': 893 | '0': 894 | 'name': 'punctuation.definition.parameters.end.bracket.round.java' 895 | 'name': 'meta.method-call.java' 896 | 'patterns': [ 897 | { 898 | 'include': '#code' 899 | } 900 | ] 901 | 'methods': 902 | 'begin': '(?!new)(?=[\\w<].*\\s+)(?=([^=/]|/(?!/))+\\()' 903 | 'end': '(})|(?=;)' 904 | 'endCaptures': 905 | '1': 906 | 'name': 'punctuation.section.method.end.bracket.curly.java' 907 | 'name': 'meta.method.java' 908 | 'patterns': [ 909 | { 910 | 'include': '#storage-modifiers' 911 | } 912 | { 913 | 'begin': '(\\w+)\\s*(\\()' 914 | 'beginCaptures': 915 | '1': 916 | 'name': 'entity.name.function.java' 917 | '2': 918 | 'name': 'punctuation.definition.parameters.begin.bracket.round.java' 919 | 'end': '\\)' 920 | 'endCaptures': 921 | '0': 922 | 'name': 'punctuation.definition.parameters.end.bracket.round.java' 923 | 'name': 'meta.method.identifier.java' 924 | 'patterns': [ 925 | { 926 | 'include': '#parameters' 927 | } 928 | { 929 | 'include': '#parens' 930 | } 931 | { 932 | 'include': '#comments' 933 | } 934 | ] 935 | } 936 | { 937 | 'include': '#generics' 938 | } 939 | { 940 | 'begin': '(?=\\w.*\\s+\\w+\\s*\\()' 941 | 'end': '(?=\\s+\\w+\\s*\\()' 942 | 'name': 'meta.method.return-type.java' 943 | 'patterns': [ 944 | { 945 | 'include': '#all-types' 946 | } 947 | { 948 | 'include': '#parens' 949 | } 950 | { 951 | 'include': '#comments' 952 | } 953 | ] 954 | } 955 | { 956 | 'include': '#throws' 957 | } 958 | { 959 | 'begin': '{' 960 | 'beginCaptures': 961 | '0': 962 | 'name': 'punctuation.section.method.begin.bracket.curly.java' 963 | 'end': '(?=})' 964 | 'contentName': 'meta.method.body.java' 965 | 'patterns': [ 966 | { 967 | 'include': '#code' 968 | } 969 | ] 970 | } 971 | { 972 | 'include': '#comments' 973 | } 974 | ] 975 | 'module': 976 | # a uniquely named, reusable group of related packages, as well as resources (such as images 977 | # and XML files). 978 | 'begin': '((open)\\s)?(module)\\s+(\\w+)' 979 | 'end': '}' 980 | 'beginCaptures': 981 | '1': 982 | 'name': 'storage.modifier.java' 983 | '3': 984 | 'name': 'storage.modifier.java' 985 | '4': 986 | 'name': 'entity.name.type.module.java' 987 | 'endCaptures': 988 | '0': 989 | 'name': 'punctuation.section.module.end.bracket.curly.java' 990 | 'name': 'meta.module.java' 991 | 'patterns': [ 992 | { 993 | 'begin': '{' 994 | 'beginCaptures': 995 | '0': 996 | 'name': 'punctuation.section.module.begin.bracket.curly.java' 997 | 'end': '(?=})' 998 | 'contentName': 'meta.module.body.java' 999 | 'patterns': [ 1000 | # TODO: Write more rules for module grammar 1001 | { 1002 | 'include': '#comments' 1003 | } 1004 | { 1005 | 'include': '#comments-javadoc' 1006 | } 1007 | { 1008 | 'match': '\\b(requires|transitive|exports|opens|to|uses|provides|with)\\b' 1009 | 'name': 'keyword.module.java' 1010 | } 1011 | ] 1012 | } 1013 | ] 1014 | 'numbers': 1015 | # See http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.1 (integers) 1016 | # and http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.2 (floats) 1017 | # for the official specifications 1018 | 'patterns': [ 1019 | { 1020 | 'match': '''(?x) 1021 | \\b(? 1103 | 'match': '\\b((?:[A-Za-z_]\\w*\\s*\\.\\s*)*[A-Z_]\\w*)\\s*(?=<)' 1104 | 'captures': 1105 | '1': 1106 | 'patterns': [ 1107 | { 1108 | 'match': '[A-Za-z_]\\w*' 1109 | 'name': 'storage.type.java' 1110 | } 1111 | { 1112 | 'match': '\\.' 1113 | 'name': 'punctuation.separator.period.java' 1114 | } 1115 | ] 1116 | } 1117 | { 1118 | # If the above fails *then* just look for Wow 1119 | # (must be followed by a variable name, we use '\n' to cover multi-line definitions, 1120 | # or varargs for function definitions) 1121 | 'match': '\\b((?:[A-Za-z_]\\w*\\s*\\.\\s*)*[A-Z_]\\w*)\\b((?=\\s*[A-Za-z$_\\n])|(?=\\s*\\.\\.\\.))' 1122 | 'captures': 1123 | '1': 1124 | 'patterns': [ 1125 | { 1126 | 'match': '[A-Za-z_]\\w*' 1127 | 'name': 'storage.type.java' 1128 | } 1129 | { 1130 | 'match': '\\.' 1131 | 'name': 'punctuation.separator.period.java' 1132 | } 1133 | ] 1134 | } 1135 | ] 1136 | 'object-types-inherited': 1137 | 'patterns': [ 1138 | { 1139 | 'include': '#generics' 1140 | } 1141 | { 1142 | 'match': '\\b(?:[A-Z]\\w*\\s*(\\.)\\s*)*[A-Z]\\w*\\b' 1143 | 'name': 'entity.other.inherited-class.java' 1144 | 'captures': 1145 | '1': 1146 | 'name': 'punctuation.separator.period.java' 1147 | } 1148 | { 1149 | 'match': ',' 1150 | 'name': 'punctuation.separator.delimiter.java' 1151 | } 1152 | ] 1153 | 'objects': 1154 | # obj in obj.prop, obj.methodCall() 1155 | 'match': '(?)?(\\()' 1305 | 'beginCaptures': 1306 | '1': 1307 | 'name': 'storage.modifier.java' 1308 | '2': 1309 | 'name': 'entity.name.type.record.java' 1310 | '3': 1311 | 'patterns': [ 1312 | { 1313 | 'include': '#generics' 1314 | } 1315 | ] 1316 | '4': 1317 | 'name': 'punctuation.definition.parameters.begin.bracket.round.java' 1318 | 'end': '\\)' 1319 | 'endCaptures': 1320 | '0': 1321 | 'name': 'punctuation.definition.parameters.end.bracket.round.java' 1322 | 'name': 'meta.record.identifier.java' 1323 | 'patterns': [ 1324 | { 1325 | 'include': '#code' 1326 | } 1327 | ] 1328 | } 1329 | { 1330 | 'begin': '(implements)\\s' 1331 | 'beginCaptures': 1332 | '1': 1333 | 'name': 'storage.modifier.implements.java' 1334 | 'end': '(?=\\s*\\{)' # by design, records cannot extend any other class 1335 | 'name': 'meta.definition.class.implemented.interfaces.java' 1336 | 'patterns': [ 1337 | { 1338 | 'include': '#object-types-inherited' 1339 | } 1340 | { 1341 | 'include': '#comments' 1342 | } 1343 | ] 1344 | } 1345 | { 1346 | 'include': '#record-body' 1347 | } 1348 | ] 1349 | 'record-body': 1350 | 'begin': '{' 1351 | 'beginCaptures': 1352 | '0': 1353 | 'name': 'punctuation.section.class.begin.bracket.curly.java' 1354 | 'end': '(?=})' 1355 | 'name': 'meta.record.body.java' 1356 | 'patterns': [ 1357 | { 1358 | 'include': '#record-constructor' 1359 | } 1360 | { 1361 | 'include': '#class-body' 1362 | } 1363 | ] 1364 | 'record-constructor': 1365 | 'begin': '(?!new)(?=[\\w<].*\\s+)(?=([^\\(=/]|/(?!/))+(?={))' 1366 | 'end': '(})|(?=;)' 1367 | 'endCaptures': 1368 | '1': 1369 | 'name': 'punctuation.section.method.end.bracket.curly.java' 1370 | 'name': 'meta.method.java' 1371 | 'patterns': [ 1372 | { 1373 | 'include': '#storage-modifiers' 1374 | } 1375 | { 1376 | 'begin': '(\\w+)' 1377 | 'beginCaptures': 1378 | '1': 1379 | 'name': 'entity.name.function.java' 1380 | 'end': '(?=\\s*{)' 1381 | 'name': 'meta.method.identifier.java' 1382 | 'patterns': [ 1383 | { 1384 | 'include': '#comments' 1385 | } 1386 | ] 1387 | } 1388 | { 1389 | 'include': '#comments' 1390 | } 1391 | { 1392 | 'begin': '{' 1393 | 'beginCaptures': 1394 | '0': 1395 | 'name': 'punctuation.section.method.begin.bracket.curly.java' 1396 | 'end': '(?=})' 1397 | 'contentName': 'meta.method.body.java' 1398 | 'patterns': [ 1399 | { 1400 | 'include': '#code' 1401 | } 1402 | ] 1403 | } 1404 | ] 1405 | 'static-initializer': 1406 | 'patterns': [ 1407 | { 1408 | 'include': '#anonymous-block-and-instance-initializer' 1409 | } 1410 | { 1411 | 'match': 'static' 1412 | 'name': 'storage.modifier.java' 1413 | } 1414 | ] 1415 | 'storage-modifiers': 1416 | 'match': '\\b(public|private|protected|static|final|native|synchronized|abstract|threadsafe|transient|volatile|default|strictfp|sealed|non-sealed)\\b' 1417 | 'name': 'storage.modifier.java' 1418 | 'strings': 1419 | 'patterns': [ 1420 | { 1421 | 'begin': '"' 1422 | 'beginCaptures': 1423 | '0': 1424 | 'name': 'punctuation.definition.string.begin.java' 1425 | 'end': '"' 1426 | 'endCaptures': 1427 | '0': 1428 | 'name': 'punctuation.definition.string.end.java' 1429 | 'name': 'string.quoted.double.java' 1430 | 'patterns': [ 1431 | { 1432 | 'match': '\\\\.' 1433 | 'name': 'constant.character.escape.java' 1434 | } 1435 | ] 1436 | } 1437 | { 1438 | 'begin': '\'' 1439 | 'beginCaptures': 1440 | '0': 1441 | 'name': 'punctuation.definition.string.begin.java' 1442 | 'end': '\'' 1443 | 'endCaptures': 1444 | '0': 1445 | 'name': 'punctuation.definition.string.end.java' 1446 | 'name': 'string.quoted.single.java' 1447 | 'patterns': [ 1448 | { 1449 | 'match': '\\\\.' 1450 | 'name': 'constant.character.escape.java' 1451 | } 1452 | ] 1453 | } 1454 | ] 1455 | 'throws': 1456 | 'begin': 'throws' 1457 | 'beginCaptures': 1458 | '0': 1459 | 'name': 'storage.modifier.java' 1460 | 'end': '(?={|;)' 1461 | 'name': 'meta.throwables.java' 1462 | 'patterns': [ 1463 | { 1464 | 'match': ',' 1465 | 'name': 'punctuation.separator.delimiter.java' 1466 | } 1467 | { 1468 | 'match': '[a-zA-Z$_][\\.a-zA-Z0-9$_]*' 1469 | 'name': 'storage.type.java' 1470 | } 1471 | ] 1472 | 'try-catch-finally': 1473 | 'patterns': [ 1474 | # try block 1475 | { 1476 | 'begin': '\\btry\\b' 1477 | 'beginCaptures': 1478 | '0': 1479 | 'name': 'keyword.control.try.java' 1480 | 'end': '}' 1481 | 'endCaptures': 1482 | '0': 1483 | 'name': 'punctuation.section.try.end.bracket.curly.java' 1484 | 'name': 'meta.try.java' 1485 | 'patterns': [ 1486 | { 1487 | 'begin': '\\(' 1488 | 'beginCaptures': 1489 | '0': 1490 | 'name': 'punctuation.section.try.resources.begin.bracket.round.java' 1491 | 'end': '\\)' 1492 | 'endCaptures': 1493 | '0': 1494 | 'name': 'punctuation.section.try.resources.end.bracket.round.java' 1495 | 'name': 'meta.try.resources.java' 1496 | 'patterns': [ 1497 | { 1498 | 'include': '#code' 1499 | } 1500 | ] 1501 | } 1502 | { 1503 | 'begin': '{' 1504 | 'beginCaptures': 1505 | '0': 1506 | 'name': 'punctuation.section.try.begin.bracket.curly.java' 1507 | 'end': '(?=})' 1508 | 'contentName': 'meta.try.body.java' 1509 | 'patterns': [ 1510 | { 1511 | 'include': '#code' 1512 | } 1513 | ] 1514 | } 1515 | ] 1516 | } 1517 | # catch block 1518 | { 1519 | 'begin': '\\b(catch)\\b' 1520 | 'beginCaptures': 1521 | '1': 1522 | 'name': 'keyword.control.catch.java' 1523 | 'end': '}' 1524 | 'endCaptures': 1525 | '0': 1526 | 'name': 'punctuation.section.catch.end.bracket.curly.java' 1527 | 'name': 'meta.catch.java' 1528 | 'patterns': [ 1529 | { 1530 | 'include': '#comments' 1531 | } 1532 | { 1533 | 'begin': '\\(' 1534 | 'beginCaptures': 1535 | '0': 1536 | 'name': 'punctuation.definition.parameters.begin.bracket.round.java' 1537 | 'end': '\\)' 1538 | 'endCaptures': 1539 | '0': 1540 | 'name': 'punctuation.definition.parameters.end.bracket.round.java' 1541 | 'contentName': 'meta.catch.parameters.java' 1542 | 'patterns': [ 1543 | { 1544 | 'include': '#comments' 1545 | } 1546 | { 1547 | 'include': '#storage-modifiers' 1548 | } 1549 | { 1550 | 'begin': '[a-zA-Z$_][\\.a-zA-Z0-9$_]*' 1551 | 'beginCaptures': 1552 | '0': 1553 | 'name': 'storage.type.java' 1554 | 'end': '(\\|)|(?=\\))' 1555 | 'endCaptures': 1556 | '1': 1557 | 'name': 'punctuation.catch.separator.java' 1558 | 'patterns': [ 1559 | { 1560 | 'include': '#comments' 1561 | } 1562 | { 1563 | 'match': '\\w+' 1564 | 'captures': 1565 | '0': 1566 | 'name': 'variable.parameter.java' 1567 | } 1568 | ] 1569 | } 1570 | ] 1571 | } 1572 | { 1573 | 'begin': '{' 1574 | 'beginCaptures': 1575 | '0': 1576 | 'name': 'punctuation.section.catch.begin.bracket.curly.java' 1577 | 'end': '(?=})' 1578 | 'contentName': 'meta.catch.body.java' 1579 | 'patterns': [ 1580 | { 1581 | 'include': '#code' 1582 | } 1583 | ] 1584 | } 1585 | ] 1586 | } 1587 | # finally block 1588 | { 1589 | 'begin': '\\bfinally\\b' 1590 | 'beginCaptures': 1591 | '0': 1592 | 'name': 'keyword.control.finally.java' 1593 | 'end': '}' 1594 | 'endCaptures': 1595 | '0': 1596 | 'name': 'punctuation.section.finally.end.bracket.curly.java' 1597 | 'name': 'meta.finally.java' 1598 | 'patterns': [ 1599 | { 1600 | 'begin': '{' 1601 | 'beginCaptures': 1602 | '0': 1603 | 'name': 'punctuation.section.finally.begin.bracket.curly.java' 1604 | 'end': '(?=})' 1605 | 'contentName': 'meta.finally.body.java' 1606 | 'patterns': [ 1607 | { 1608 | 'include': '#code' 1609 | } 1610 | ] 1611 | } 1612 | ] 1613 | } 1614 | ] 1615 | 'variables': 1616 | 'begin': '''(?x) 1617 | (?= 1618 | \\b 1619 | ( 1620 | (void|boolean|byte|char|short|int|float|long|double) 1621 | | 1622 | (?>(\\w+\\.)*[A-Z_]+\\w*) # e.g. `javax.ws.rs.Response`, or `String` 1623 | ) 1624 | \\b 1625 | \\s* 1626 | ( 1627 | <[\\w<>,\\.?\\s\\[\\]]*> # e.g. `HashMap`, or `List` 1628 | )? 1629 | \\s* 1630 | ( 1631 | (\\[\\])* # int[][] 1632 | )? 1633 | \\s+ 1634 | [A-Za-z_$][\\w$]* # At least one identifier after space 1635 | ([\\w\\[\\],$][\\w\\[\\],\\s]*)? # possibly primitive array or additional identifiers 1636 | \\s*(=|:|;) 1637 | ) 1638 | ''' 1639 | 'end': '(?=\\=|:|;)' 1640 | 'name': 'meta.definition.variable.java' 1641 | 'patterns': [ 1642 | { 1643 | 'match': '([A-Za-z$_][\\w$]*)(?=\\s*(\\[\\])*\\s*(;|:|=|,))' 1644 | 'captures': 1645 | '1': 1646 | 'name': 'variable.other.definition.java' 1647 | } 1648 | { 1649 | 'include': '#all-types' 1650 | } 1651 | { 1652 | 'include': '#code' 1653 | } 1654 | ] 1655 | # Java 10 local variable type "var", should only be used inside the method body, 1656 | # see spec http://openjdk.java.net/jeps/286 1657 | 'variables-local': 1658 | # This is simplified version of `variables` pattern 1659 | 'begin': '(?=\\b(var)\\b\\s+[A-Za-z_$][\\w$]*\\s*(=|:|;))' 1660 | 'end': '(?=\\=|:|;)' 1661 | 'name': 'meta.definition.variable.local.java' 1662 | 'patterns': [ 1663 | { 1664 | 'match': '\\bvar\\b' 1665 | 'name': 'storage.type.local.java' 1666 | } 1667 | { 1668 | 'match': '([A-Za-z$_][\\w$]*)(?=\\s*(\\[\\])*\\s*(=|:|;))' 1669 | 'captures': 1670 | '1': 1671 | 'name': 'variable.other.definition.java' 1672 | } 1673 | { 1674 | 'include': '#code' 1675 | } 1676 | ] 1677 | -------------------------------------------------------------------------------- /grammars/javaproperties.cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'source.java-properties' 2 | 'name': 'Java Properties' 3 | 'fileTypes': [ 4 | 'properties' 5 | ] 6 | 'foldingStartMarker': '^[a-zA-Z0-9.-_]+=.*\\\n' 7 | 'foldingStopMarker': '^(.*(? "?", 61 | ternary_expression > ":" 62 | ''': 'keyword.control.ternary' 63 | 64 | '"instanceof"': 'keyword.operator.instanceof' 65 | '"="': 'keyword.operator.assignment' 66 | 67 | ''' 68 | "==", 69 | "!=", 70 | "<=", 71 | ">=", 72 | ">", 73 | "<" 74 | ''': 'keyword.operator.comparison' 75 | 76 | ''' 77 | "!", 78 | "&&", 79 | "||" 80 | ''': 'keyword.operator.logical' 81 | 82 | ''' 83 | "-", 84 | "+", 85 | "*", 86 | "/", 87 | "%", 88 | "-=", 89 | "+=", 90 | "*=", 91 | "/=", 92 | "%=", 93 | "++", 94 | "--" 95 | ''': 'keyword.operator.arithmetic' 96 | 97 | ''' 98 | "&", 99 | "|", 100 | "^", 101 | "~", 102 | "&=", 103 | "|=", 104 | "^=", 105 | "<<", 106 | ">>", 107 | ">>>", 108 | "<<=", 109 | ">>=", 110 | ">>>=" 111 | ''': 'keyword.operator.bitwise' 112 | 113 | '"."': 'punctuation.separator.period' 114 | '","': 'punctuation.separator.delimiter' 115 | '";"': 'punctuation.terminator.statement' 116 | '"["': 'punctuation.bracket.square' 117 | '"]"': 'punctuation.bracket.square' 118 | '"{"': 'punctuation.bracket.curly' 119 | '"}"': 'punctuation.bracket.curly' 120 | '"("': 'punctuation.bracket.round' 121 | '")"': 'punctuation.bracket.round' 122 | 123 | ''' 124 | this, 125 | super 126 | ''': 'variable.language' 127 | 128 | # Literals and constants 129 | 130 | 'null_literal': 'constant.language.null' 131 | 132 | ''' 133 | true, 134 | false 135 | ''': 'constant.boolean' 136 | 137 | ''' 138 | decimal_integer_literal, 139 | hex_integer_literal, 140 | octal_integer_literal, 141 | binary_integer_literal 142 | ''': 'constant.numeric' 143 | 144 | ''' 145 | decimal_floating_point_literal, 146 | hex_floating_point_literal 147 | ''': 'constant.numeric' 148 | 149 | 'character_literal': 'string.quoted.single' 150 | 'string_literal': 'string.quoted.double' 151 | 152 | # Primitive and simple types 153 | 154 | ''' 155 | void_type, 156 | integral_type, 157 | floating_point_type, 158 | boolean_type, 159 | type_identifier, 160 | type_parameter > identifier 161 | ''': 'storage.type' 162 | 163 | # Generic types 164 | 165 | ''' 166 | type_arguments > "<", 167 | type_arguments > ">", 168 | type_parameters > "<", 169 | type_parameters > ">" 170 | ''': 'punctuation.bracket.angle' 171 | 172 | 'type_arguments > wildcard > "?"': 'storage.type.generic.wildcard' 173 | 'type_arguments > wildcard > "extends"': "storage.modifier.extends" 174 | 'type_arguments > wildcard > super': "storage.modifier.super" 175 | # generic bounds in classes 176 | 'type_bound > "extends"': "storage.modifier.extends" 177 | 'type_bound > "&"': 'punctuation.separator.types' 178 | 179 | # Modifiers and keywords 180 | 181 | ''' 182 | "public", 183 | "protected", 184 | "private", 185 | "abstract", 186 | "static", 187 | "final", 188 | "strictfp", 189 | "default", 190 | "synchronized", 191 | "native", 192 | "transient", 193 | "volatile", 194 | "threadsafe" 195 | ''': 'storage.modifier' 196 | # "extends" keyword for classes and enums 197 | 'superclass > "extends"': 'storage.modifier.extends' 198 | # "extends" keyword for interfaces 199 | 'extends_interfaces > "extends"': 'storage.modifier.extends' 200 | 'super_interfaces > "implements"': 'storage.modifier.implements' 201 | 'static_initializer > "static"': 'storage.modifier' 202 | 203 | # Package and imports 204 | 205 | 'package_declaration': 'meta.package' 206 | 'package_declaration > "package"': 'keyword.other.package' 207 | 208 | 'import_declaration': 'meta.import' 209 | 'import_declaration > "import"': 'keyword.other.import' 210 | 'import_declaration > "static"': 'keyword.other.static' 211 | 'import_declaration > asterisk > "*"': 'variable.language.wildcard' 212 | 213 | # Expressions 214 | 215 | 'lambda_expression > "->"': 'storage.type.function.arrow' 216 | 217 | # Statements 218 | 219 | 'catch_type > "|"': 'punctuation.catch.separator' 220 | 221 | # Class declaration 222 | 223 | 'class_declaration > "class"': 'keyword.other.class' 224 | 'class_declaration > identifier': 'entity.name.type.class' 225 | 226 | 'class_declaration > class_body': 'meta.class.body' 227 | 228 | # Enum declaration 229 | 230 | 'enum_declaration > "enum"': 'keyword.other.enum' 231 | 'enum_declaration > identifier': 'entity.name.type.enum' 232 | 233 | 'enum_declaration > enum_body': 'meta.enum.body' 234 | 235 | 'enum_constant > identifier': 'constant.other.enum' 236 | 237 | # Interface declaration 238 | 239 | 'interface_declaration > "interface"': 'keyword.other.interface' 240 | 'interface_declaration > identifier': 'entity.name.type.interface' 241 | 242 | 'interface_declaration > interface_body': 'meta.interface.body' 243 | 244 | # annotated interface 245 | 'annotation_type_declaration > "@interface"': 'keyword.other.interface.annotated' 246 | 'annotation_type_declaration > identifier': 'entity.name.type.interface.annotated' 247 | 248 | 'annotation_type_declaration > annotation_type_body': 'meta.interface.annotated.body' 249 | 250 | 'annotation_type_element_declaration > identifier': 'entity.name.function' 251 | 252 | # Annotations 253 | 254 | 'marker_annotation': 'meta.declaration.annotation' 255 | 'marker_annotation > "@"': 'punctuation.definition.annotation' 256 | ''' 257 | marker_annotation > identifier, 258 | marker_annotation > scoped_identifier > identifier 259 | ''': 'storage.type.annotation' 260 | 261 | 'annotation': 'meta.declaration.annotation' 262 | 'annotation > "@"': 'punctuation.definition.annotation' 263 | ''' 264 | annotation > identifier, 265 | annotation > scoped_identifier > identifier 266 | ''': 'storage.type.annotation' 267 | 268 | 'element_value_pair > identifier': 'variable.other.annotation.element' 269 | 270 | # Methods 271 | 272 | 'method_declaration': 'meta.method' 273 | 'method_declaration > identifier': 'entity.name.function' 274 | 'method_declaration > block': 'meta.method.body' 275 | 276 | 'constructor_declaration': 'meta.constructor' 277 | 'constructor_declaration > identifier': 'entity.name.function' 278 | 'constructor_body': 'meta.constructor.body' 279 | 280 | 'throws > "throws"': 'storage.modifier.throws' 281 | 282 | 'spread_parameter > "..."': 'punctuation.definition.parameters.varargs' 283 | 284 | # Method access and reference 285 | 286 | 'method_invocation > method_invocation_name > identifier': 'entity.name.function' 287 | 288 | # Method reference 289 | 'method_reference > "::"': 'keyword.control.method' 290 | 291 | ''' 292 | method_reference > "new", 293 | method_reference > identifier:nth-child(2) 294 | ''': 'entity.name.function' 295 | 296 | ''' 297 | field_access > identifier, 298 | method_reference > identifier, 299 | method_invocation > identifier 300 | ''': [ 301 | {match: '^[A-Z][A-Z0-9_\\$]+$', scopes: 'constant.other'}, 302 | {match: '^[A-Z]', scopes: 'storage.type'} 303 | ] 304 | 'identifier': [ 305 | {match: '^[A-Z][A-Z0-9_\\$]+$', scopes: 'constant.other'} 306 | ] 307 | -------------------------------------------------------------------------------- /grammars/unified expression language (el).cson: -------------------------------------------------------------------------------- 1 | 'scopeName': 'source.java.el' 2 | 'patterns': [ 3 | { 4 | 'name': 'keyword.control.ternary.java.el' 5 | 'match': '\\?|(?<=\\s):' 6 | } 7 | { 8 | 'name': 'keyword.operator.comparison.java.el' 9 | 'match': '((==|!=|<=|>=|<|>)|\\b(eq|ne|le|ge|lt|gt)\\b)' 10 | } 11 | { 12 | 'name': 'keyword.operator.empty.java.el' 13 | 'match': '\\b(empty)\\b' 14 | } 15 | { 16 | 'name': 'keyword.operator.arithmetic.java.el' 17 | 'match': '(?:(\\-|\\+|\\*|\\/|%)|\\b(div|mod)\\b)' 18 | } 19 | { 20 | 'name': 'keyword.operator.logical.java.el' 21 | 'match': '(?:(!|&&|\\|\\|)|\\b(not|and|or)\\b)' 22 | } 23 | { 24 | 'name': 'namespace.java.el' 25 | 'match': '[a-zA-Z]+(:)' 26 | 'captures': 27 | '1': 28 | 'name': 'punctuation.separator.namespace.java.el' 29 | } 30 | { 31 | 'match': ',' 32 | 'name': 'meta.delimiter.java.el' 33 | } 34 | { 35 | 'match': '\\(|\\)' 36 | 'name': 'meta.brace.round.java.el' 37 | } 38 | { 39 | 'match': '\\[|\\]' 40 | 'name': 'meta.brace.square.java.el' 41 | } 42 | { 43 | 'name': 'constant.boolean.java.el' 44 | 'match': '\\b(true|false)\\b' 45 | } 46 | { 47 | 'name': 'constant.null.java.el' 48 | 'match': '\\bnull\\b' 49 | } 50 | { 51 | 'name': 'constant.numeric.java.el' 52 | 'match': '\\b([0-9]+\\.[0-9]+|[0-9]+)\\b' 53 | } 54 | { 55 | 'name': 'string.quoted.single.java.el' 56 | 'begin': '\'' 57 | 'beginCaptures': 58 | '0': 59 | 'name': 'punctuation.definition.string.begin.java.el' 60 | 'end': '\'' 61 | 'endCaptures': 62 | '0': 63 | 'name': 'punctuation.definition.string.end.java.el' 64 | 'patterns': [ 65 | { 66 | 'name': 'constant.character.escape.java.el' 67 | 'match': '\\\\.' 68 | } 69 | ] 70 | } 71 | { 72 | 'name': 'string.quoted.double.java.el' 73 | 'begin': '"' 74 | 'beginCaptures': 75 | '0': 76 | 'name': 'punctuation.definition.string.begin.java.el' 77 | 'end': '"' 78 | 'endCaptures': 79 | '0': 80 | 'name': 'punctuation.definition.string.end.java.el' 81 | 'patterns': [ 82 | { 83 | 'name': 'constant.character.escape.java.el' 84 | 'match': '\\\\.' 85 | } 86 | ] 87 | } 88 | ] 89 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-java", 3 | "version": "0.32.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "balanced-match": { 8 | "version": "1.0.0", 9 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 10 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 11 | "dev": true 12 | }, 13 | "brace-expansion": { 14 | "version": "1.1.11", 15 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 16 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 17 | "dev": true, 18 | "requires": { 19 | "balanced-match": "^1.0.0", 20 | "concat-map": "0.0.1" 21 | } 22 | }, 23 | "coffee-script": { 24 | "version": "1.11.1", 25 | "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz", 26 | "integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=", 27 | "dev": true 28 | }, 29 | "coffeelint": { 30 | "version": "1.16.2", 31 | "resolved": "https://registry.npmjs.org/coffeelint/-/coffeelint-1.16.2.tgz", 32 | "integrity": "sha512-6mzgOo4zb17WfdrSui/cSUEgQ0AQkW3gXDht+6lHkfkqGUtSYKwGdGcXsDfAyuScVzTlTtKdfwkAlJWfqul7zg==", 33 | "dev": true, 34 | "requires": { 35 | "coffee-script": "~1.11.0", 36 | "glob": "^7.0.6", 37 | "ignore": "^3.0.9", 38 | "optimist": "^0.6.1", 39 | "resolve": "^0.6.3", 40 | "strip-json-comments": "^1.0.2" 41 | } 42 | }, 43 | "concat-map": { 44 | "version": "0.0.1", 45 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 46 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 47 | "dev": true 48 | }, 49 | "fs.realpath": { 50 | "version": "1.0.0", 51 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 52 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 53 | "dev": true 54 | }, 55 | "glob": { 56 | "version": "7.1.6", 57 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 58 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 59 | "dev": true, 60 | "requires": { 61 | "fs.realpath": "^1.0.0", 62 | "inflight": "^1.0.4", 63 | "inherits": "2", 64 | "minimatch": "^3.0.4", 65 | "once": "^1.3.0", 66 | "path-is-absolute": "^1.0.0" 67 | } 68 | }, 69 | "ignore": { 70 | "version": "3.3.10", 71 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", 72 | "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", 73 | "dev": true 74 | }, 75 | "inflight": { 76 | "version": "1.0.6", 77 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 78 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 79 | "dev": true, 80 | "requires": { 81 | "once": "^1.3.0", 82 | "wrappy": "1" 83 | } 84 | }, 85 | "inherits": { 86 | "version": "2.0.4", 87 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 88 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 89 | "dev": true 90 | }, 91 | "minimatch": { 92 | "version": "3.0.4", 93 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 94 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 95 | "dev": true, 96 | "requires": { 97 | "brace-expansion": "^1.1.7" 98 | } 99 | }, 100 | "minimist": { 101 | "version": "0.0.10", 102 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", 103 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", 104 | "dev": true 105 | }, 106 | "nan": { 107 | "version": "2.14.1", 108 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", 109 | "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" 110 | }, 111 | "once": { 112 | "version": "1.4.0", 113 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 114 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 115 | "dev": true, 116 | "requires": { 117 | "wrappy": "1" 118 | } 119 | }, 120 | "optimist": { 121 | "version": "0.6.1", 122 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 123 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 124 | "dev": true, 125 | "requires": { 126 | "minimist": "~0.0.1", 127 | "wordwrap": "~0.0.2" 128 | } 129 | }, 130 | "path-is-absolute": { 131 | "version": "1.0.1", 132 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 133 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 134 | "dev": true 135 | }, 136 | "resolve": { 137 | "version": "0.6.3", 138 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", 139 | "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=", 140 | "dev": true 141 | }, 142 | "strip-json-comments": { 143 | "version": "1.0.4", 144 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", 145 | "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", 146 | "dev": true 147 | }, 148 | "tree-sitter-java-dev": { 149 | "version": "0.16.0-dev2", 150 | "resolved": "https://registry.npmjs.org/tree-sitter-java-dev/-/tree-sitter-java-dev-0.16.0-dev2.tgz", 151 | "integrity": "sha512-BilPJ2SwvRKMTeq2WZdvVX5HiMYTLSncJATkqWiPRGUl157FcBjY42mzm3M42/5QQybb1nDJjW0tAvVA5iEHmw==", 152 | "requires": { 153 | "nan": "^2.12.1" 154 | } 155 | }, 156 | "wordwrap": { 157 | "version": "0.0.3", 158 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 159 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 160 | "dev": true 161 | }, 162 | "wrappy": { 163 | "version": "1.0.2", 164 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 165 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 166 | "dev": true 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-java", 3 | "version": "0.32.1", 4 | "description": "Java language support in Atom", 5 | "engines": { 6 | "atom": "*", 7 | "node": "*" 8 | }, 9 | "homepage": "http://atom.github.io/language-java", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/atom/language-java.git" 13 | }, 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/atom/language-java/issues" 17 | }, 18 | "dependencies": { 19 | "tree-sitter-java-dev": "^0.16.0-dev2" 20 | }, 21 | "devDependencies": { 22 | "coffeelint": "^1.10.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /settings/language-java.cson: -------------------------------------------------------------------------------- 1 | '.source.java': 2 | 'editor': 3 | 'commentStart': '// ' 4 | 'foldEndPattern': '^\\s*(\\}|// \\}\\}\\}$)' 5 | 'increaseIndentPattern': '^.*\\{(\\}|[^}"\']*)$|^\\s*(public|private|protected):\\s*$' 6 | 'decreaseIndentPattern': '^(.*\\*/)?\\s*\\}|^\\s*(public|private|protected):\\s*$' 7 | '.text.html.jsp': 8 | 'editor': 9 | 'foldEndPattern': '\\*\\*/|^\\s*\\}' 10 | 'commentStart': '<%-- ' 11 | 'commentEnd': ' --%>' 12 | 'increaseIndentPattern': '^\\s*<(([^!/?]|%)(?!.+?([/%]>|))|[%!]--\\s*$)' 13 | 'decreaseIndentPattern': '^\\s*(]+>|-->|--%>)' 14 | '.text.junit-test-report': 15 | 'editor': 16 | 'foldEndPattern': '^\\s*(\\}|// \\}\\}\\}$)' 17 | '.source.java-properties': 18 | 'editor': 19 | 'commentStart': '# ' 20 | '.keyword.other.documentation.javadoc.java': 21 | 'editor': 22 | 'completions': [ 23 | 'author' 24 | 'deprecated' 25 | 'exception' 26 | 'link' 27 | 'param' 28 | 'return' 29 | 'see' 30 | 'serial' 31 | 'since' 32 | 'throws' 33 | 'version' 34 | ] 35 | -------------------------------------------------------------------------------- /snippets/language-java.cson: -------------------------------------------------------------------------------- 1 | '.source.java, .source.groovy': 2 | 'abstract': 3 | 'prefix': 'ab' 4 | 'body': 'abstract ' 5 | 'case': 6 | 'prefix': 'cs' 7 | 'body': 'case $1:\n\t$2\n$0' 8 | 'catch': 9 | 'prefix': 'ca' 10 | 'body': 'catch (${1:Exception} ${2:e}) {\n\t$0\n}' 11 | 'class': 12 | 'prefix': 'cl' 13 | 'body': 'class ${1:MyClass} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{\n\t$6\n}' 14 | 'else if': 15 | 'prefix': 'elif' 16 | 'body': 'else if ($1) {\n\t$0\n}' 17 | 'do while': 18 | 'prefix': 'dow' 19 | 'body': 'do {\n\t$1\n} while ($2);$0' 20 | 'else': 21 | 'prefix': 'el' 22 | 'body': 'else {\n\t$0\n}' 23 | 'final': 24 | 'prefix': 'fi' 25 | 'body': 'final ' 26 | 'finally': 27 | 'prefix': 'fy' 28 | 'body': 'finally {\n\t$0\n}' 29 | 'for': 30 | 'prefix': 'for' 31 | 'body': 'for ($1; $2; $3) {\n\t$0\n}' 32 | 'if': 33 | 'prefix': 'if' 34 | 'body': 'if ($1) {\n\t$0\n}' 35 | 'import': 36 | 'prefix': 'im' 37 | 'body': 'import ' 38 | 'interface': 39 | 'prefix': 'in' 40 | 'body': 'interface ${1:MyInterface} ${2:extends ${3:Parent} }{\n\t$0\n}' 41 | 'private': 42 | 'prefix': 'pr' 43 | 'body': 'private ' 44 | 'protected': 45 | 'prefix': 'po' 46 | 'body': 'protected ' 47 | 'public': 48 | 'prefix': 'pu' 49 | 'body': 'public ' 50 | 'return': 51 | 'prefix': 're' 52 | 'body': 'return ' 53 | 'serialVersionUID': 54 | 'prefix': 'se' 55 | 'body': 'private static final long serialVersionUID = ${1:42}l;$0' 56 | 'static': 57 | 'prefix': 'st' 58 | 'body': 'static ' 59 | 'switch': 60 | 'prefix': 'sw' 61 | 'body': 'switch ($1) {\n\t$0\n}' 62 | 'synchronized': 63 | 'prefix': 'sy' 64 | 'body': 'synchronized ' 65 | 'throw new': 66 | 'prefix': 'tn' 67 | 'body': 'throw new $0' 68 | 'throw': 69 | 'prefix': 'th' 70 | 'body': 'throw $0' 71 | 'try': 72 | 'prefix': 'tr' 73 | 'body': 'try {\n\t$0\n}' 74 | 'try-catch': 75 | 'prefix':'trc' 76 | 'body': 'try {\n\t$1\n} catch(${2:Exception} ${3:e}) {\n\t$4\n}' 77 | 'variable': 78 | 'prefix': 'v' 79 | 'body': '${1:String} ${2:var}${3: = ${0:null}};' 80 | '.source.java': 81 | 'break': 82 | 'prefix': 'br' 83 | 'body': 'break;\n' 84 | 'constant string': 85 | 'prefix': 'cos' 86 | 'body': 'public static final String ${1:var} = "$2";$0' 87 | 'constant': 88 | 'prefix': 'co' 89 | 'body': 'public static final ${1:String} ${2:var} = $3;$0' 90 | 'default': 91 | 'prefix': 'de' 92 | 'body': 'default:\n\t$0' 93 | 'for (each)': 94 | 'prefix': 'fore' 95 | 'body': 'for ($1 : $2) {\n\t$0\n}' 96 | 'import junit.framework.TestCase;': 97 | 'prefix': 'imt' 98 | 'body': 'import junit.framework.TestCase;\n$0' 99 | 'java.beans.': 100 | 'prefix': 'j.b' 101 | 'body': 'java.beans.' 102 | 'java.io.': 103 | 'prefix': 'j.i' 104 | 'body': 'java.io.' 105 | 'java.math.': 106 | 'prefix': 'j.m' 107 | 'body': 'java.math.' 108 | 'java.net.': 109 | 'prefix': 'j.n' 110 | 'body': 'java.net.' 111 | 'java.util.': 112 | 'prefix': 'j.u' 113 | 'body': 'java.util.' 114 | 'method (main)': 115 | 'prefix': 'main' 116 | 'body': 'public static void main(String[] args) {\n\t$0\n}' 117 | 'method': 118 | 'prefix': 'm' 119 | 'body': '${1:void} ${2:method}($3) ${4:throws $5 }{\n\t$0\n}\n' 120 | 'print': 121 | 'prefix': 'p' 122 | 'body': 'System.out.print($1);$0' 123 | 'println': 124 | 'prefix': 'pl' 125 | 'body': 'System.out.println($1);$0' 126 | 'test case': 127 | 'prefix': 'tc' 128 | 'body': 'public class ${1:MyTest} extends ${2:TestCase} {\n\t$0\n}' 129 | 'test': 130 | 'prefix': 't' 131 | 'body': 'public void test${1:Name}() throws Exception {\n\t$0\n}' 132 | 'while': 133 | 'prefix': 'wh' 134 | 'body': 'while ($1) {\n\t$0\n}' 135 | -------------------------------------------------------------------------------- /spec/tree-sitter-java-spec.coffee: -------------------------------------------------------------------------------- 1 | {TextEditor} = require 'atom' 2 | 3 | describe 'Tree-sitter based Java grammar', -> 4 | grammar = null 5 | editor = null 6 | buffer = null 7 | 8 | beforeEach -> 9 | atom.config.set('core.useTreeSitterParsers', true) 10 | 11 | waitsForPromise -> 12 | atom.packages.activatePackage('language-java') 13 | 14 | runs -> 15 | editor = new TextEditor() 16 | grammar = atom.grammars.grammarForScopeName('source.java') 17 | editor.setGrammar(grammar) 18 | buffer = editor.getBuffer() 19 | 20 | # Compatibility functions with TextMate grammar tests 21 | 22 | # Returns list of tokens as [{value: ..., scopes: [...]}, ...] 23 | getTokens = (buffer, row) -> 24 | line = buffer.lineForRow row 25 | tokens = [] 26 | 27 | iterator = buffer.getLanguageMode().buildHighlightIterator() 28 | start = {row: row, column: 0} 29 | scopes = iterator.seek(start, row) 30 | 31 | while true 32 | end = iterator.getPosition() 33 | 34 | if end.row > row 35 | end.row = row 36 | end.column = line.length 37 | 38 | if end.column > start.column 39 | tokens.push({ 40 | value: line.substring(start.column, end.column), 41 | scopes: buffer.getLanguageMode().grammar.scopeNameForScopeId(s) for s in scopes 42 | }) 43 | 44 | if end.column < line.length 45 | for num in iterator.getCloseScopeIds() 46 | item = scopes.pop() 47 | scopes.push(iterator.getOpenScopeIds()...) 48 | start = end 49 | iterator.moveToSuccessor() 50 | else 51 | break 52 | 53 | tokens 54 | 55 | tokenizeLine = (text) -> 56 | buffer.setText(text) 57 | getTokens(buffer, 0) 58 | 59 | tokenizeLines = (text) -> 60 | buffer.setText(text) 61 | lines = buffer.getLines() 62 | tokens = [] 63 | row = 0 64 | for _ in lines 65 | tokens.push(getTokens(buffer, row)) 66 | row += 1 67 | tokens 68 | 69 | printTokens = (tokens) -> 70 | console.log() 71 | for token, i in tokens 72 | for t, j in token 73 | scopes = ("'#{scope}'" for scope in t.scopes).join(", ") 74 | console.log("expect(tokens[#{i}][#{j}]).toEqual value: '#{t.value}', scopes: [#{scopes}]") 75 | console.log() 76 | 77 | # Unit tests 78 | 79 | it 'parses the grammar', -> 80 | expect(grammar).toBeTruthy() 81 | expect(grammar.scopeName).toBe 'source.java' 82 | 83 | it 'tokenizes punctuation', -> 84 | tokens = tokenizeLine 'int a, b, c;' 85 | 86 | expect(tokens[2]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 87 | expect(tokens[4]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 88 | expect(tokens[6]).toEqual value: ';', scopes: ['source.java', 'punctuation.terminator.statement'] 89 | 90 | tokens = tokenizeLine 'a.b.c();' 91 | 92 | expect(tokens[1]).toEqual value: '.', scopes: ['source.java', 'punctuation.separator.period'] 93 | expect(tokens[3]).toEqual value: '.', scopes: ['source.java', 'punctuation.separator.period'] 94 | expect(tokens[7]).toEqual value: ';', scopes: ['source.java', 'punctuation.terminator.statement'] 95 | 96 | tokens = tokenizeLine 'a . b' 97 | 98 | expect(tokens[2]).toEqual value: '.', scopes: ['source.java', 'punctuation.separator.period'] 99 | 100 | tokens = tokenizeLine 'new com.package.Clazz();' 101 | 102 | expect(tokens[3]).toEqual value: '.', scopes: ['source.java', 'punctuation.separator.period'] 103 | expect(tokens[5]).toEqual value: '.', scopes: ['source.java', 'punctuation.separator.period'] 104 | expect(tokens[9]).toEqual value: ';', scopes: ['source.java', 'punctuation.terminator.statement'] 105 | 106 | tokens = tokenizeLine 'class A implements B, C {}' 107 | 108 | expect(tokens[7]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 109 | 110 | it 'tokenizes comparison', -> 111 | tokens = tokenizeLines ''' 112 | a > b; 113 | a < b; 114 | a == b; 115 | a >= b; 116 | a <= b; 117 | a != b; 118 | ''' 119 | 120 | expect(tokens[0][1]).toEqual value: '>', scopes: ['source.java', 'keyword.operator.comparison'] 121 | expect(tokens[1][1]).toEqual value: '<', scopes: ['source.java', 'keyword.operator.comparison'] 122 | expect(tokens[2][1]).toEqual value: '==', scopes: ['source.java', 'keyword.operator.comparison'] 123 | expect(tokens[3][1]).toEqual value: '>=', scopes: ['source.java', 'keyword.operator.comparison'] 124 | expect(tokens[4][1]).toEqual value: '<=', scopes: ['source.java', 'keyword.operator.comparison'] 125 | expect(tokens[5][1]).toEqual value: '!=', scopes: ['source.java', 'keyword.operator.comparison'] 126 | 127 | it 'tokenizes logical', -> 128 | tokens = tokenizeLines ''' 129 | a && b; 130 | a || b; 131 | !a; 132 | ''' 133 | 134 | expect(tokens[0][1]).toEqual value: '&&', scopes: ['source.java', 'keyword.operator.logical'] 135 | expect(tokens[1][1]).toEqual value: '||', scopes: ['source.java', 'keyword.operator.logical'] 136 | expect(tokens[2][0]).toEqual value: '!', scopes: ['source.java', 'keyword.operator.logical'] 137 | 138 | it 'tokenizes arithmetic', -> 139 | tokens = tokenizeLines ''' 140 | a + b; 141 | a - b; 142 | a * b; 143 | a / b; 144 | a % b; 145 | a += b; 146 | a -= b; 147 | a *= b; 148 | a /= b; 149 | a %= b; 150 | a++; 151 | --a; 152 | ''' 153 | 154 | expect(tokens[0][1]).toEqual value: '+', scopes: ['source.java', 'keyword.operator.arithmetic'] 155 | expect(tokens[1][1]).toEqual value: '-', scopes: ['source.java', 'keyword.operator.arithmetic'] 156 | expect(tokens[2][1]).toEqual value: '*', scopes: ['source.java', 'keyword.operator.arithmetic'] 157 | expect(tokens[3][1]).toEqual value: '/', scopes: ['source.java', 'keyword.operator.arithmetic'] 158 | expect(tokens[4][1]).toEqual value: '%', scopes: ['source.java', 'keyword.operator.arithmetic'] 159 | expect(tokens[5][1]).toEqual value: '+=', scopes: ['source.java', 'keyword.operator.arithmetic'] 160 | expect(tokens[6][1]).toEqual value: '-=', scopes: ['source.java', 'keyword.operator.arithmetic'] 161 | expect(tokens[7][1]).toEqual value: '*=', scopes: ['source.java', 'keyword.operator.arithmetic'] 162 | expect(tokens[8][1]).toEqual value: '/=', scopes: ['source.java', 'keyword.operator.arithmetic'] 163 | expect(tokens[9][1]).toEqual value: '%=', scopes: ['source.java', 'keyword.operator.arithmetic'] 164 | expect(tokens[10][1]).toEqual value: '++', scopes: ['source.java', 'keyword.operator.arithmetic'] 165 | expect(tokens[11][0]).toEqual value: '--', scopes: ['source.java', 'keyword.operator.arithmetic'] 166 | 167 | it 'tokenizes bitwise', -> 168 | tokens = tokenizeLines ''' 169 | a & b; 170 | a | b; 171 | a ^ b; 172 | a >> b; 173 | a << b; 174 | a >>> b; 175 | a &= b; 176 | a |= b; 177 | a ^= b; 178 | a >>= b; 179 | a <<= b; 180 | a >>>= b; 181 | ~a; 182 | ''' 183 | 184 | expect(tokens[0][1]).toEqual value: '&', scopes: ['source.java', 'keyword.operator.bitwise'] 185 | expect(tokens[1][1]).toEqual value: '|', scopes: ['source.java', 'keyword.operator.bitwise'] 186 | expect(tokens[2][1]).toEqual value: '^', scopes: ['source.java', 'keyword.operator.bitwise'] 187 | expect(tokens[3][1]).toEqual value: '>>', scopes: ['source.java', 'keyword.operator.bitwise'] 188 | expect(tokens[4][1]).toEqual value: '<<', scopes: ['source.java', 'keyword.operator.bitwise'] 189 | expect(tokens[5][1]).toEqual value: '>>>', scopes: ['source.java', 'keyword.operator.bitwise'] 190 | expect(tokens[6][1]).toEqual value: '&=', scopes: ['source.java', 'keyword.operator.bitwise'] 191 | expect(tokens[7][1]).toEqual value: '|=', scopes: ['source.java', 'keyword.operator.bitwise'] 192 | expect(tokens[8][1]).toEqual value: '^=', scopes: ['source.java', 'keyword.operator.bitwise'] 193 | expect(tokens[9][1]).toEqual value: '>>=', scopes: ['source.java', 'keyword.operator.bitwise'] 194 | expect(tokens[10][1]).toEqual value: '<<=', scopes: ['source.java', 'keyword.operator.bitwise'] 195 | expect(tokens[11][1]).toEqual value: '>>>=', scopes: ['source.java', 'keyword.operator.bitwise'] 196 | expect(tokens[12][0]).toEqual value: '~', scopes: ['source.java', 'keyword.operator.bitwise'] 197 | 198 | it 'tokenizes brackets', -> 199 | tokens = tokenizeLine '{ (a + b) + c[d] }' 200 | 201 | expect(tokens[0]).toEqual value: '{', scopes: ['source.java', 'punctuation.bracket.curly'] 202 | expect(tokens[2]).toEqual value: '(', scopes: ['source.java', 'punctuation.bracket.round'] 203 | expect(tokens[6]).toEqual value: ')', scopes: ['source.java', 'punctuation.bracket.round'] 204 | expect(tokens[10]).toEqual value: '[', scopes: ['source.java', 'punctuation.bracket.square'] 205 | expect(tokens[12]).toEqual value: ']', scopes: ['source.java', 'punctuation.bracket.square'] 206 | expect(tokens[14]).toEqual value: '}', scopes: ['source.java', 'punctuation.bracket.curly'] 207 | 208 | it 'tokenizes literals', -> 209 | tokens = tokenizeLines ''' 210 | a = null; 211 | a = true; 212 | a = false; 213 | a = 123; 214 | a = 0x1a; 215 | a = 0b11010; 216 | a = 123L; 217 | a = 123l; 218 | a = 123.4; 219 | a = 123.4d; 220 | a = 1.234e2; 221 | a = 123.4f; 222 | a = 'a'; 223 | a = '\u0108' 224 | a = "abc"; 225 | ''' 226 | 227 | expect(tokens[0][3]).toEqual value: 'null', scopes: ['source.java', 'constant.language.null'] 228 | expect(tokens[1][3]).toEqual value: 'true', scopes: ['source.java', 'constant.boolean'] 229 | expect(tokens[2][3]).toEqual value: 'false', scopes: ['source.java', 'constant.boolean'] 230 | expect(tokens[3][3]).toEqual value: '123', scopes: ['source.java', 'constant.numeric'] 231 | expect(tokens[4][3]).toEqual value: '0x1a', scopes: ['source.java', 'constant.numeric'] 232 | expect(tokens[5][3]).toEqual value: '0b11010', scopes: ['source.java', 'constant.numeric'] 233 | expect(tokens[6][3]).toEqual value: '123L', scopes: ['source.java', 'constant.numeric'] 234 | expect(tokens[7][3]).toEqual value: '123l', scopes: ['source.java', 'constant.numeric'] 235 | expect(tokens[8][3]).toEqual value: '123.4', scopes: ['source.java', 'constant.numeric'] 236 | expect(tokens[9][3]).toEqual value: '123.4d', scopes: ['source.java', 'constant.numeric'] 237 | expect(tokens[10][3]).toEqual value: '1.234e2', scopes: ['source.java', 'constant.numeric'] 238 | expect(tokens[11][3]).toEqual value: '123.4f', scopes: ['source.java', 'constant.numeric'] 239 | expect(tokens[12][3]).toEqual value: '\'a\'', scopes: ['source.java', 'string.quoted.single'] 240 | expect(tokens[13][3]).toEqual value: '\'\u0108\'', scopes: ['source.java', 'string.quoted.single'] 241 | expect(tokens[14][3]).toEqual value: '\"abc\"', scopes: ['source.java', 'string.quoted.double'] 242 | 243 | it 'tokenizes constants', -> 244 | tokens = tokenizeLines ''' 245 | String CONSTANT_STR = "value"; 246 | int CONST0 = 0; 247 | int CONST_1 = 1; 248 | String A1_B2_C3 = "abc"; 249 | String A$_B$_C$ = "abc"; 250 | a = CONSTANT + obj.func(); 251 | b = conf.get(CONSTANT_ANOTHER); 252 | c = Integer.MAX_VALUE; 253 | d = A1_B2_C3; 254 | e = A1_B2_C$; 255 | f = Test.A1_B2_C3; 256 | ''' 257 | 258 | expect(tokens[0][2]).toEqual value: 'CONSTANT_STR', scopes: ['source.java', 'constant.other'] 259 | expect(tokens[1][2]).toEqual value: 'CONST0', scopes: ['source.java', 'constant.other'] 260 | expect(tokens[2][2]).toEqual value: 'CONST_1', scopes: ['source.java', 'constant.other'] 261 | expect(tokens[3][2]).toEqual value: 'A1_B2_C3', scopes: ['source.java', 'constant.other'] 262 | expect(tokens[4][2]).toEqual value: 'A$_B$_C$', scopes: ['source.java', 'constant.other'] 263 | expect(tokens[5][3]).toEqual value: 'CONSTANT', scopes: ['source.java', 'constant.other'] 264 | expect(tokens[6][6]).toEqual value: 'CONSTANT_ANOTHER', scopes: ['source.java', 'constant.other'] 265 | expect(tokens[7][5]).toEqual value: 'MAX_VALUE', scopes: ['source.java', 'constant.other'] 266 | expect(tokens[8][3]).toEqual value: 'A1_B2_C3', scopes: ['source.java', 'constant.other'] 267 | expect(tokens[9][3]).toEqual value: 'A1_B2_C$', scopes: ['source.java', 'constant.other'] 268 | expect(tokens[10][5]).toEqual value: 'A1_B2_C3', scopes: ['source.java', 'constant.other'] 269 | 270 | it 'tokenizes constants in switch statement', -> 271 | tokens = tokenizeLines ''' 272 | switch (value) { 273 | case CONST: break; 274 | case CONST_STR: break; 275 | case CONST0: break; 276 | case CONST_1: break; 277 | case C0_STR1_DEF2: break; 278 | case C$_STR$_DEF$: break; 279 | default: break; 280 | } 281 | ''' 282 | 283 | expect(tokens[1][3]).toEqual value: 'CONST', scopes: ['source.java', 'constant.other'] 284 | expect(tokens[2][3]).toEqual value: 'CONST_STR', scopes: ['source.java', 'constant.other'] 285 | expect(tokens[3][3]).toEqual value: 'CONST0', scopes: ['source.java', 'constant.other'] 286 | expect(tokens[4][3]).toEqual value: 'CONST_1', scopes: ['source.java', 'constant.other'] 287 | expect(tokens[5][3]).toEqual value: 'C0_STR1_DEF2', scopes: ['source.java', 'constant.other'] 288 | expect(tokens[6][3]).toEqual value: 'C$_STR$_DEF$', scopes: ['source.java', 'constant.other'] 289 | 290 | it 'tokenizes reserved keywords', -> 291 | tokens = tokenizeLine 'const value;' 292 | 293 | expect(tokens[0]).toEqual value: 'const', scopes: ['source.java', 'keyword.reserved'] 294 | 295 | tokens = tokenizeLine 'int a = 1; goto;' 296 | 297 | expect(tokens[7]).toEqual value: 'goto', scopes: ['source.java', 'keyword.reserved'] 298 | 299 | it 'tokenizes packages', -> 300 | tokens = tokenizeLine 'package com.test;' 301 | 302 | expect(tokens[0]).toEqual value: 'package', scopes: ['source.java', 'meta.package', 'keyword.other.package'] 303 | expect(tokens[1]).toEqual value: ' com', scopes: ['source.java', 'meta.package'] 304 | expect(tokens[2]).toEqual value: '.', scopes: ['source.java', 'meta.package', 'punctuation.separator.period'] 305 | expect(tokens[3]).toEqual value: 'test', scopes: ['source.java', 'meta.package'] 306 | expect(tokens[4]).toEqual value: ';', scopes: ['source.java', 'meta.package', 'punctuation.terminator.statement'] 307 | 308 | it 'tokenizes imports', -> 309 | tokens = tokenizeLine 'import com.package;' 310 | 311 | expect(tokens[0]).toEqual value: 'import', scopes: ['source.java', 'meta.import', 'keyword.other.import'] 312 | 313 | it 'tokenizes static imports', -> 314 | tokens = tokenizeLine 'import static com.package;' 315 | 316 | expect(tokens[0]).toEqual value: 'import', scopes: ['source.java', 'meta.import', 'keyword.other.import'] 317 | expect(tokens[2]).toEqual value: 'static', scopes: ['source.java', 'meta.import', 'keyword.other.static'] 318 | 319 | it 'tokenizes imports with asterisk', -> 320 | tokens = tokenizeLine 'import static com.package.*;' 321 | 322 | expect(tokens[0]).toEqual value: 'import', scopes: ['source.java', 'meta.import', 'keyword.other.import'] 323 | expect(tokens[2]).toEqual value: 'static', scopes: ['source.java', 'meta.import', 'keyword.other.static'] 324 | expect(tokens[7]).toEqual value: '*', scopes: ['source.java', 'meta.import', 'variable.language.wildcard'] 325 | 326 | it 'tokenizes static initializers', -> 327 | tokens = tokenizeLines ''' 328 | class A { 329 | private static int a = 0; 330 | 331 | static { 332 | a = 1; 333 | } 334 | } 335 | ''' 336 | 337 | expect(tokens[1][3]).toEqual value: 'static', scopes: ['source.java', 'meta.class.body', 'storage.modifier'] 338 | expect(tokens[3][1]).toEqual value: 'static', scopes: ['source.java', 'meta.class.body', 'storage.modifier'] 339 | 340 | it 'tokenizes synchronized blocks', -> 341 | tokens = tokenizeLines ''' 342 | class A { 343 | synchronized { 344 | func(); 345 | } 346 | } 347 | ''' 348 | 349 | expect(tokens[1][1]).toEqual value: 'synchronized', scopes: ['source.java', 'meta.class.body', 'storage.modifier'] 350 | 351 | it 'tokenizes instanceof', -> 352 | tokens = tokenizeLines ''' 353 | (a instanceof Tpe); 354 | (a instanceof tpe); 355 | (a instanceof tpTpe); 356 | (a instanceof tp.Tpe); 357 | if (a instanceof B) { } 358 | if (aaBb instanceof B) { } 359 | ''' 360 | 361 | expect(tokens[0][2]).toEqual value: 'instanceof', scopes: ['source.java', 'keyword.operator.instanceof'] 362 | expect(tokens[0][4]).toEqual value: 'Tpe', scopes: ['source.java', 'storage.type'] 363 | expect(tokens[1][2]).toEqual value: 'instanceof', scopes: ['source.java', 'keyword.operator.instanceof'] 364 | expect(tokens[1][4]).toEqual value: 'tpe', scopes: ['source.java', 'storage.type'] 365 | expect(tokens[2][2]).toEqual value: 'instanceof', scopes: ['source.java', 'keyword.operator.instanceof'] 366 | expect(tokens[2][4]).toEqual value: 'tpTpe', scopes: ['source.java', 'storage.type'] 367 | expect(tokens[3][2]).toEqual value: 'instanceof', scopes: ['source.java', 'keyword.operator.instanceof'] 368 | expect(tokens[3][4]).toEqual value: 'tp', scopes: ['source.java', 'storage.type'] 369 | expect(tokens[3][6]).toEqual value: 'Tpe', scopes: ['source.java', 'storage.type'] 370 | expect(tokens[4][4]).toEqual value: 'instanceof', scopes: ['source.java', 'keyword.operator.instanceof'] 371 | expect(tokens[5][4]).toEqual value: 'instanceof', scopes: ['source.java', 'keyword.operator.instanceof'] 372 | 373 | it 'tokenizes ternary', -> 374 | tokens = tokenizeLine '(a > b) ? a : b;' 375 | 376 | expect(tokens[6]).toEqual value: '?', scopes: ['source.java', 'keyword.control.ternary'] 377 | expect(tokens[8]).toEqual value: ':', scopes: ['source.java', 'keyword.control.ternary'] 378 | 379 | it 'tokenizes try-catch block with multiple exceptions', -> 380 | tokens = tokenizeLines ''' 381 | private void method() { 382 | try { 383 | // do something 384 | } catch (Exception1 | Exception2 err) { 385 | throw new Exception3(); 386 | } 387 | } 388 | ''' 389 | 390 | expect(tokens[1][1]).toEqual value: 'try', scopes: ['source.java', 'keyword.control'] 391 | expect(tokens[3][3]).toEqual value: 'catch', scopes: ['source.java', 'keyword.control'] 392 | expect(tokens[3][5]).toEqual value: '(', scopes: ['source.java', 'punctuation.bracket.round'] 393 | expect(tokens[3][6]).toEqual value: 'Exception1', scopes: ['source.java', 'storage.type'] 394 | expect(tokens[3][8]).toEqual value: '|', scopes: ['source.java', 'punctuation.catch.separator'] 395 | expect(tokens[3][10]).toEqual value: 'Exception2', scopes: ['source.java', 'storage.type'] 396 | expect(tokens[3][12]).toEqual value: ')', scopes: ['source.java', 'punctuation.bracket.round'] 397 | expect(tokens[4][1]).toEqual value: 'throw', scopes: ['source.java', 'keyword.control'] 398 | expect(tokens[4][3]).toEqual value: 'new', scopes: ['source.java', 'keyword.control'] 399 | expect(tokens[4][5]).toEqual value: 'Exception3', scopes: ['source.java', 'storage.type'] 400 | 401 | it 'tokenizes lambda expressions', -> 402 | tokens = tokenizeLine '(String s1) -> s1.length() - outer.length();' 403 | 404 | expect(tokens[5]).toEqual value: '->', scopes: ['source.java', 'storage.type.function.arrow'] 405 | 406 | it 'tokenizes spread parameters', -> 407 | tokens = tokenizeLine 'public void method(String... args);' 408 | 409 | expect(tokens[6]).toEqual value: '...', scopes: ['source.java', 'punctuation.definition.parameters.varargs'] 410 | 411 | tokens = tokenizeLine 'void func(int /* ... */ arg, int ... args);' 412 | 413 | expect(tokens[5]).toEqual value: '/* ... */', scopes: ['source.java', 'comment.block'] 414 | expect(tokens[11]).toEqual value: '...', scopes: ['source.java', 'punctuation.definition.parameters.varargs'] 415 | 416 | it 'tokenizes identifiers with `$`', -> 417 | tokens = tokenizeLines ''' 418 | class A$B { 419 | void func$() { 420 | $object.$property; 421 | $hello(); 422 | } 423 | } 424 | ''' 425 | 426 | expect(tokens[0][2]).toEqual value: 'A$B', scopes: ['source.java', 'entity.name.type.class'] 427 | expect(tokens[0][3]).toEqual value: ' ', scopes: ['source.java'] 428 | expect(tokens[0][4]).toEqual value: '{', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.curly'] 429 | expect(tokens[1][3]).toEqual value: 'func$', scopes: ['source.java', 'meta.class.body', 'meta.method', 'entity.name.function'] 430 | expect(tokens[2][1]).toEqual value: '$object', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body'] 431 | expect(tokens[2][3]).toEqual value: '$property', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body'] 432 | expect(tokens[3][1]).toEqual value: '$hello', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 433 | 434 | it 'tokenizes this and super', -> 435 | tokens = tokenizeLine 'this.x + super.x;' 436 | 437 | expect(tokens[0]).toEqual value: 'this', scopes: ['source.java', 'variable.language'] 438 | expect(tokens[5]).toEqual value: 'super', scopes: ['source.java', 'variable.language'] 439 | 440 | it 'tokenizes this and super in method invocations', -> 441 | tokens = tokenizeLines ''' 442 | class A { 443 | void func() { 444 | super.debug("debug"); 445 | this.debug("debug"); 446 | property.super.func("arg"); 447 | } 448 | } 449 | ''' 450 | 451 | expect(tokens[2][1]).toEqual value: 'super', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'variable.language'] 452 | expect(tokens[3][1]).toEqual value: 'this', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'variable.language'] 453 | expect(tokens[4][3]).toEqual value: 'super', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'variable.language'] 454 | 455 | it 'tokenizes comments', -> 456 | tokens = tokenizeLines ''' 457 | // comment 458 | 459 | /* 460 | comment 461 | */ 462 | ''' 463 | 464 | expect(tokens[0][0]).toEqual value: '// comment', scopes: ['source.java', 'comment.block'] 465 | expect(tokens[2][0]).toEqual value: '/*', scopes: ['source.java', 'comment.block'] 466 | expect(tokens[3][0]).toEqual value: ' comment', scopes: ['source.java', 'comment.block'] 467 | expect(tokens[4][0]).toEqual value: ' */', scopes: ['source.java', 'comment.block'] 468 | 469 | it 'tokenizes type definitions', -> 470 | tokens = tokenizeLines ''' 471 | class A { 472 | void method() { } 473 | boolean method() { } 474 | int method() { } 475 | long method() { } 476 | float method() { } 477 | double method() { } 478 | int[] method() { } 479 | T method() { } 480 | java.util.List method() { } 481 | } 482 | ''' 483 | 484 | expect(tokens[1][1]).toEqual value: 'void', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 485 | expect(tokens[2][1]).toEqual value: 'boolean', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 486 | expect(tokens[3][1]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 487 | expect(tokens[4][1]).toEqual value: 'long', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 488 | expect(tokens[5][1]).toEqual value: 'float', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 489 | expect(tokens[6][1]).toEqual value: 'double', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 490 | expect(tokens[7][1]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 491 | expect(tokens[8][1]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 492 | expect(tokens[9][1]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 493 | expect(tokens[9][3]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 494 | expect(tokens[9][5]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 495 | expect(tokens[9][7]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 496 | 497 | it 'tokenizes type casting', -> 498 | tokens = tokenizeLines ''' 499 | class A { 500 | A method() { 501 | return (A) a; 502 | } 503 | } 504 | ''' 505 | 506 | expect(tokens[2][1]).toEqual value: 'return', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control'] 507 | expect(tokens[2][3]).toEqual value: '(', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.round'] 508 | expect(tokens[2][4]).toEqual value: 'A', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 509 | expect(tokens[2][5]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.angle'] 510 | expect(tokens[2][6]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 511 | expect(tokens[2][7]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.angle'] 512 | expect(tokens[2][8]).toEqual value: ')', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.round'] 513 | 514 | it 'tokenizes class generic type definitions', -> 515 | tokens = tokenizeLines ''' 516 | class Test {} 517 | class Test> {} 518 | class Bound {} 519 | class Bound {} 520 | class Bound & B> {} 521 | class Test extends Common {} 522 | class Test {} 523 | class Test, S extends Conv> {} 524 | ''' 525 | 526 | expect(tokens[0][3]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 527 | expect(tokens[0][4]).toEqual value: 'K', scopes: ['source.java', 'storage.type'] 528 | expect(tokens[0][5]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 529 | expect(tokens[0][7]).toEqual value: 'V', scopes: ['source.java', 'storage.type'] 530 | expect(tokens[0][8]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 531 | 532 | expect(tokens[1][3]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 533 | expect(tokens[1][4]).toEqual value: 'A', scopes: ['source.java', 'storage.type'] 534 | expect(tokens[1][6]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 535 | expect(tokens[1][8]).toEqual value: 'java', scopes: ['source.java', 'storage.type'] 536 | expect(tokens[1][10]).toEqual value: 'util', scopes: ['source.java', 'storage.type'] 537 | expect(tokens[1][12]).toEqual value: 'List', scopes: ['source.java', 'storage.type'] 538 | expect(tokens[1][13]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 539 | expect(tokens[1][14]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 540 | expect(tokens[1][15]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 541 | expect(tokens[1][16]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 542 | 543 | expect(tokens[2][3]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 544 | expect(tokens[2][4]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 545 | expect(tokens[2][6]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 546 | expect(tokens[2][8]).toEqual value: 'A', scopes: ['source.java', 'storage.type'] 547 | expect(tokens[2][10]).toEqual value: '&', scopes: ['source.java', 'punctuation.separator.types'] 548 | expect(tokens[2][12]).toEqual value: 'B', scopes: ['source.java', 'storage.type'] 549 | expect(tokens[2][13]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 550 | 551 | expect(tokens[3][3]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 552 | expect(tokens[3][4]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 553 | expect(tokens[3][6]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 554 | expect(tokens[3][8]).toEqual value: 'java', scopes: ['source.java', 'storage.type'] 555 | expect(tokens[3][10]).toEqual value: 'lang', scopes: ['source.java', 'storage.type'] 556 | expect(tokens[3][12]).toEqual value: 'A', scopes: ['source.java', 'storage.type'] 557 | expect(tokens[3][14]).toEqual value: '&', scopes: ['source.java', 'punctuation.separator.types'] 558 | expect(tokens[3][16]).toEqual value: 'java', scopes: ['source.java', 'storage.type'] 559 | expect(tokens[3][18]).toEqual value: 'lang', scopes: ['source.java', 'storage.type'] 560 | expect(tokens[3][20]).toEqual value: 'B', scopes: ['source.java', 'storage.type'] 561 | expect(tokens[3][21]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 562 | 563 | expect(tokens[4][4]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 564 | expect(tokens[4][5]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 565 | expect(tokens[4][7]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 566 | expect(tokens[4][9]).toEqual value: 'A', scopes: ['source.java', 'storage.type'] 567 | expect(tokens[4][10]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 568 | expect(tokens[4][11]).toEqual value: '?', scopes: ['source.java', 'storage.type.generic.wildcard'] 569 | expect(tokens[4][13]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 570 | expect(tokens[4][15]).toEqual value: 'D', scopes: ['source.java', 'storage.type'] 571 | expect(tokens[4][16]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 572 | expect(tokens[4][18]).toEqual value: '&', scopes: ['source.java', 'punctuation.separator.types'] 573 | expect(tokens[4][20]).toEqual value: 'B', scopes: ['source.java', 'storage.type'] 574 | expect(tokens[4][21]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 575 | 576 | expect(tokens[5][3]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 577 | expect(tokens[5][4]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 578 | expect(tokens[5][5]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 579 | expect(tokens[5][7]).toEqual value: 'S', scopes: ['source.java', 'storage.type'] 580 | expect(tokens[5][8]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 581 | expect(tokens[5][10]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 582 | expect(tokens[5][12]).toEqual value: 'Common', scopes: ['source.java', 'storage.type'] 583 | expect(tokens[5][13]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 584 | expect(tokens[5][14]).toEqual value: '?', scopes: ['source.java', 'storage.type.generic.wildcard'] 585 | expect(tokens[5][16]).toEqual value: 'super', scopes: ['source.java', 'storage.modifier.super'] 586 | expect(tokens[5][18]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 587 | expect(tokens[5][19]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 588 | 589 | expect(tokens[6][3]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 590 | expect(tokens[6][4]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 591 | expect(tokens[6][6]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 592 | expect(tokens[6][8]).toEqual value: 'A', scopes: ['source.java', 'storage.type'] 593 | expect(tokens[6][10]).toEqual value: '&', scopes: ['source.java', 'punctuation.separator.types'] 594 | expect(tokens[6][12]).toEqual value: 'B', scopes: ['source.java', 'storage.type'] 595 | expect(tokens[6][13]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 596 | expect(tokens[6][15]).toEqual value: 'String', scopes: ['source.java', 'storage.type'] 597 | expect(tokens[6][16]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 598 | expect(tokens[6][18]).toEqual value: 'Integer', scopes: ['source.java', 'storage.type'] 599 | expect(tokens[6][19]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 600 | 601 | expect(tokens[7][3]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 602 | expect(tokens[7][4]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 603 | expect(tokens[7][6]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 604 | expect(tokens[7][8]).toEqual value: 'Conv', scopes: ['source.java', 'storage.type'] 605 | expect(tokens[7][9]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 606 | expect(tokens[7][10]).toEqual value: 'S', scopes: ['source.java', 'storage.type'] 607 | expect(tokens[7][11]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 608 | expect(tokens[7][12]).toEqual value: ',', scopes: ['source.java', 'punctuation.separator.delimiter'] 609 | expect(tokens[7][14]).toEqual value: 'S', scopes: ['source.java', 'storage.type'] 610 | expect(tokens[7][16]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 611 | expect(tokens[7][18]).toEqual value: 'Conv', scopes: ['source.java', 'storage.type'] 612 | expect(tokens[7][19]).toEqual value: '<', scopes: ['source.java', 'punctuation.bracket.angle'] 613 | expect(tokens[7][20]).toEqual value: 'T', scopes: ['source.java', 'storage.type'] 614 | expect(tokens[7][21]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 615 | expect(tokens[7][22]).toEqual value: '>', scopes: ['source.java', 'punctuation.bracket.angle'] 616 | 617 | it 'tokenizes generic type definitions', -> 618 | tokens = tokenizeLines ''' 619 | abstract class Generics { 620 | HashMap map = new HashMap<>(); 621 | CodeMap codemap; 622 | C(Map> m) {} 623 | Map method() {} 624 | Set> set1; 625 | Set> set2; 626 | 627 | List func(); 628 | java.util.List func(); 629 | List<> func(); 630 | java.util.List> func(); 631 | java.util.List func(); 632 | java.util.List func(); 633 | T getAnnotation(Class annotationType); 634 | } 635 | ''' 636 | 637 | expect(tokens[1][1]).toEqual value: 'HashMap', scopes: ['source.java', 'meta.class.body', 'storage.type'] 638 | expect(tokens[1][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 639 | expect(tokens[1][3]).toEqual value: 'Integer', scopes: ['source.java', 'meta.class.body', 'storage.type'] 640 | expect(tokens[1][4]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.delimiter'] 641 | expect(tokens[1][6]).toEqual value: 'String', scopes: ['source.java', 'meta.class.body', 'storage.type'] 642 | expect(tokens[1][7]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 643 | expect(tokens[1][13]).toEqual value: 'HashMap', scopes: ['source.java', 'meta.class.body', 'storage.type'] 644 | expect(tokens[1][14]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 645 | expect(tokens[1][15]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 646 | 647 | expect(tokens[2][1]).toEqual value: 'CodeMap', scopes: ['source.java', 'meta.class.body', 'storage.type'] 648 | expect(tokens[2][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 649 | expect(tokens[2][3]).toEqual value: 'String', scopes: ['source.java', 'meta.class.body', 'storage.type'] 650 | expect(tokens[2][4]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.delimiter'] 651 | expect(tokens[2][6]).toEqual value: '?', scopes: ['source.java', 'meta.class.body', 'storage.type.generic.wildcard'] 652 | expect(tokens[2][8]).toEqual value: 'extends', scopes: ['source.java', 'meta.class.body', 'storage.modifier.extends'] 653 | expect(tokens[2][10]).toEqual value: 'ArrayList', scopes: ['source.java', 'meta.class.body', 'storage.type'] 654 | expect(tokens[2][11]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 655 | 656 | expect(tokens[3][3]).toEqual value: 'Map', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.type'] 657 | expect(tokens[3][4]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'punctuation.bracket.angle'] 658 | expect(tokens[3][5]).toEqual value: '?', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.type.generic.wildcard'] 659 | expect(tokens[3][6]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'punctuation.separator.delimiter'] 660 | expect(tokens[3][8]).toEqual value: '?', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.type.generic.wildcard'] 661 | expect(tokens[3][10]).toEqual value: 'extends', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.modifier.extends'] 662 | expect(tokens[3][12]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.type'] 663 | expect(tokens[3][13]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'punctuation.bracket.angle'] 664 | expect(tokens[3][14]).toEqual value: '?', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.type.generic.wildcard'] 665 | expect(tokens[3][15]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'punctuation.bracket.angle'] 666 | expect(tokens[3][16]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'punctuation.bracket.angle'] 667 | 668 | expect(tokens[4][1]).toEqual value: 'Map', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 669 | expect(tokens[4][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 670 | expect(tokens[4][3]).toEqual value: 'Integer', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 671 | expect(tokens[4][4]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.delimiter'] 672 | expect(tokens[4][6]).toEqual value: 'String', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 673 | expect(tokens[4][7]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 674 | 675 | expect(tokens[5][1]).toEqual value: 'Set', scopes: ['source.java', 'meta.class.body', 'storage.type'] 676 | expect(tokens[5][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 677 | expect(tokens[5][3]).toEqual value: 'Map', scopes: ['source.java', 'meta.class.body', 'storage.type'] 678 | expect(tokens[5][4]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.period'] 679 | expect(tokens[5][5]).toEqual value: 'Entry', scopes: ['source.java', 'meta.class.body', 'storage.type'] 680 | expect(tokens[5][6]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 681 | expect(tokens[5][7]).toEqual value: 'K', scopes: ['source.java', 'meta.class.body', 'storage.type'] 682 | expect(tokens[5][8]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.delimiter'] 683 | expect(tokens[5][10]).toEqual value: 'V', scopes: ['source.java', 'meta.class.body', 'storage.type'] 684 | expect(tokens[5][11]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 685 | expect(tokens[5][12]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 686 | 687 | expect(tokens[6][1]).toEqual value: 'Set', scopes: ['source.java', 'meta.class.body', 'storage.type'] 688 | expect(tokens[6][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 689 | expect(tokens[6][3]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'storage.type'] 690 | expect(tokens[6][4]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.period'] 691 | expect(tokens[6][5]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'storage.type'] 692 | expect(tokens[6][6]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.period'] 693 | expect(tokens[6][7]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'storage.type'] 694 | expect(tokens[6][8]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 695 | expect(tokens[6][9]).toEqual value: 'K', scopes: ['source.java', 'meta.class.body', 'storage.type'] 696 | expect(tokens[6][10]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 697 | expect(tokens[6][11]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 698 | 699 | expect(tokens[8][1]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 700 | expect(tokens[8][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 701 | expect(tokens[8][3]).toEqual value: 'A', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 702 | expect(tokens[8][4]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.delimiter'] 703 | expect(tokens[8][6]).toEqual value: 'B', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 704 | expect(tokens[8][7]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.delimiter'] 705 | expect(tokens[8][9]).toEqual value: 'C', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 706 | expect(tokens[8][10]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 707 | 708 | expect(tokens[9][1]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 709 | expect(tokens[9][2]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 710 | expect(tokens[9][3]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 711 | expect(tokens[9][4]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 712 | expect(tokens[9][5]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 713 | expect(tokens[9][6]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 714 | expect(tokens[9][7]).toEqual value: 'Integer', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 715 | expect(tokens[9][8]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 716 | 717 | expect(tokens[10][1]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 718 | expect(tokens[10][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 719 | expect(tokens[10][3]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 720 | 721 | expect(tokens[11][1]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 722 | expect(tokens[11][2]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 723 | expect(tokens[11][3]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 724 | expect(tokens[11][4]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 725 | expect(tokens[11][5]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 726 | expect(tokens[11][6]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 727 | expect(tokens[11][7]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 728 | expect(tokens[11][8]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 729 | expect(tokens[11][9]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 730 | expect(tokens[11][10]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 731 | expect(tokens[11][11]).toEqual value: 'Map', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 732 | expect(tokens[11][12]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 733 | expect(tokens[11][13]).toEqual value: 'Integer', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 734 | expect(tokens[11][14]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.delimiter'] 735 | expect(tokens[11][16]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 736 | expect(tokens[11][17]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 737 | expect(tokens[11][18]).toEqual value: 'lang', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 738 | expect(tokens[11][19]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 739 | expect(tokens[11][20]).toEqual value: 'String', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 740 | expect(tokens[11][21]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 741 | expect(tokens[11][22]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 742 | 743 | expect(tokens[12][1]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 744 | expect(tokens[12][2]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 745 | expect(tokens[12][3]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 746 | expect(tokens[12][4]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 747 | expect(tokens[12][5]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 748 | expect(tokens[12][6]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 749 | expect(tokens[12][7]).toEqual value: '?', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type.generic.wildcard'] 750 | expect(tokens[12][9]).toEqual value: 'extends', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier.extends'] 751 | expect(tokens[12][11]).toEqual value: 'Integer', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 752 | expect(tokens[12][12]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 753 | 754 | expect(tokens[13][1]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 755 | expect(tokens[13][2]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 756 | expect(tokens[13][4]).toEqual value: 'extends', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier.extends'] 757 | expect(tokens[13][6]).toEqual value: 'Integer', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 758 | expect(tokens[13][7]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 759 | expect(tokens[13][9]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 760 | expect(tokens[13][10]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 761 | expect(tokens[13][11]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 762 | expect(tokens[13][12]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.period'] 763 | expect(tokens[13][13]).toEqual value: 'List', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 764 | expect(tokens[13][14]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 765 | expect(tokens[13][15]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 766 | expect(tokens[13][16]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 767 | 768 | expect(tokens[14][1]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 769 | expect(tokens[14][2]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 770 | expect(tokens[14][4]).toEqual value: 'extends', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier.extends'] 771 | expect(tokens[14][6]).toEqual value: 'Annotation', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 772 | expect(tokens[14][7]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 773 | expect(tokens[14][9]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 774 | expect(tokens[14][14]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 775 | expect(tokens[14][15]).toEqual value: 'T', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 776 | expect(tokens[14][16]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.angle'] 777 | 778 | it 'tokenizes generics without mixing with bitwise or comparison operators', -> 779 | tokens = tokenizeLines ''' 780 | class A { 781 | void func1() { 782 | t = M << 12; 783 | } 784 | 785 | void func2() { 786 | if (A < a) { 787 | a = A; 788 | } 789 | ArrayList list; 790 | list = new ArrayList(); 791 | 792 | if (A < a) { } 793 | 794 | if (A < a && b < a) { 795 | b = a; 796 | } 797 | } 798 | } 799 | ''' 800 | 801 | expect(tokens[2][4]).toEqual value: '<<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.operator.bitwise'] 802 | expect(tokens[6][1]).toEqual value: 'if', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control'] 803 | expect(tokens[6][5]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.operator.comparison'] 804 | expect(tokens[9][1]).toEqual value: 'ArrayList', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 805 | expect(tokens[9][2]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.angle'] 806 | expect(tokens[9][3]).toEqual value: 'A', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 807 | expect(tokens[9][4]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.angle'] 808 | expect(tokens[10][4]).toEqual value: 'new', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control'] 809 | expect(tokens[10][6]).toEqual value: 'ArrayList', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 810 | expect(tokens[10][7]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.angle'] 811 | expect(tokens[10][8]).toEqual value: 'A', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 812 | expect(tokens[10][9]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.angle'] 813 | expect(tokens[12][1]).toEqual value: 'if', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control'] 814 | expect(tokens[12][5]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.operator.comparison'] 815 | expect(tokens[14][1]).toEqual value: 'if', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control'] 816 | expect(tokens[14][5]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.operator.comparison'] 817 | expect(tokens[14][7]).toEqual value: '&&', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.operator.logical'] 818 | expect(tokens[14][9]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.operator.comparison'] 819 | 820 | it 'tokenizes types and class names with underscore', -> 821 | tokens = tokenizeLines ''' 822 | class _Class { 823 | static _String var1; 824 | static _abc._abc._Class var2; 825 | static _abc._abc._Generic<_String> var3; 826 | } 827 | ''' 828 | 829 | expect(tokens[0][2]).toEqual value: '_Class', scopes: ['source.java', 'entity.name.type.class'] 830 | expect(tokens[1][3]).toEqual value: '_String', scopes: ['source.java', 'meta.class.body', 'storage.type'] 831 | expect(tokens[2][3]).toEqual value: '_abc', scopes: ['source.java', 'meta.class.body', 'storage.type'] 832 | expect(tokens[2][4]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.period'] 833 | expect(tokens[2][5]).toEqual value: '_abc', scopes: ['source.java', 'meta.class.body', 'storage.type'] 834 | expect(tokens[2][6]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.period'] 835 | expect(tokens[2][7]).toEqual value: '_Class', scopes: ['source.java', 'meta.class.body', 'storage.type'] 836 | expect(tokens[3][3]).toEqual value: '_abc', scopes: ['source.java', 'meta.class.body', 'storage.type'] 837 | expect(tokens[3][4]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.period'] 838 | expect(tokens[3][5]).toEqual value: '_abc', scopes: ['source.java', 'meta.class.body', 'storage.type'] 839 | expect(tokens[3][6]).toEqual value: '.', scopes: ['source.java', 'meta.class.body', 'punctuation.separator.period'] 840 | expect(tokens[3][7]).toEqual value: '_Generic', scopes: ['source.java', 'meta.class.body', 'storage.type'] 841 | expect(tokens[3][8]).toEqual value: '<', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 842 | expect(tokens[3][9]).toEqual value: '_String', scopes: ['source.java', 'meta.class.body', 'storage.type'] 843 | expect(tokens[3][10]).toEqual value: '>', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.angle'] 844 | 845 | it 'tokenizes classes', -> 846 | tokens = tokenizeLine 'public abstract static class A { }' 847 | 848 | expect(tokens[0]).toEqual value: 'public', scopes: ['source.java', 'storage.modifier'] 849 | expect(tokens[2]).toEqual value: 'abstract', scopes: ['source.java', 'storage.modifier'] 850 | expect(tokens[4]).toEqual value: 'static', scopes: ['source.java', 'storage.modifier'] 851 | expect(tokens[6]).toEqual value: 'class', scopes: ['source.java', 'keyword.other.class'] 852 | expect(tokens[8]).toEqual value: 'A', scopes: ['source.java', 'entity.name.type.class'] 853 | expect(tokens[10]).toEqual value: '{', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.curly'] 854 | expect(tokens[12]).toEqual value: '}', scopes: ['source.java', 'meta.class.body', 'punctuation.bracket.curly'] 855 | 856 | tokens = tokenizeLine 'class A extends B implements C, D { }' 857 | 858 | expect(tokens[0]).toEqual value: 'class', scopes: ['source.java', 'keyword.other.class'] 859 | expect(tokens[2]).toEqual value: 'A', scopes: ['source.java', 'entity.name.type.class'] 860 | expect(tokens[4]).toEqual value: 'extends', scopes: ['source.java', 'storage.modifier.extends'] 861 | expect(tokens[6]).toEqual value: 'B', scopes: ['source.java', 'storage.type'] 862 | expect(tokens[8]).toEqual value: 'implements', scopes: ['source.java', 'storage.modifier.implements'] 863 | expect(tokens[10]).toEqual value: 'C', scopes: ['source.java', 'storage.type'] 864 | expect(tokens[13]).toEqual value: 'D', scopes: ['source.java', 'storage.type'] 865 | 866 | it 'tokenizes interfaces', -> 867 | tokens = tokenizeLine 'public interface A { }' 868 | 869 | expect(tokens[0]).toEqual value: 'public', scopes: ['source.java', 'storage.modifier'] 870 | expect(tokens[2]).toEqual value: 'interface', scopes: ['source.java', 'keyword.other.interface'] 871 | expect(tokens[4]).toEqual value: 'A', scopes: ['source.java', 'entity.name.type.interface'] 872 | expect(tokens[6]).toEqual value: '{', scopes: ['source.java', 'meta.interface.body', 'punctuation.bracket.curly'] 873 | expect(tokens[8]).toEqual value: '}', scopes: ['source.java', 'meta.interface.body', 'punctuation.bracket.curly'] 874 | 875 | it 'tokenizes annotated interfaces', -> 876 | tokens = tokenizeLines ''' 877 | public @interface A { 878 | String method() default "abc"; 879 | } 880 | ''' 881 | 882 | expect(tokens[0][0]).toEqual value: 'public', scopes: ['source.java', 'storage.modifier'] 883 | expect(tokens[0][2]).toEqual value: '@interface', scopes: ['source.java', 'keyword.other.interface.annotated'] 884 | expect(tokens[0][4]).toEqual value: 'A', scopes: ['source.java', 'entity.name.type.interface.annotated'] 885 | expect(tokens[0][6]).toEqual value: '{', scopes: ['source.java', 'meta.interface.annotated.body', 'punctuation.bracket.curly'] 886 | expect(tokens[1][1]).toEqual value: 'String', scopes: ['source.java', 'meta.interface.annotated.body', 'storage.type'] 887 | expect(tokens[1][3]).toEqual value: 'method', scopes: ['source.java', 'meta.interface.annotated.body', 'entity.name.function'] 888 | expect(tokens[1][7]).toEqual value: 'default', scopes: ['source.java', 'meta.interface.annotated.body', 'keyword.control'] 889 | expect(tokens[1][9]).toEqual value: '\"abc\"', scopes: ['source.java', 'meta.interface.annotated.body', 'string.quoted.double'] 890 | expect(tokens[2][0]).toEqual value: '}', scopes: ['source.java', 'meta.interface.annotated.body', 'punctuation.bracket.curly'] 891 | 892 | it 'tokenizes enums', -> 893 | tokens = tokenizeLines ''' 894 | public enum A implements B { 895 | CONSTANT1, 896 | CONSTANT2, 897 | Constant3, 898 | constant4 899 | } 900 | ''' 901 | 902 | expect(tokens[0][0]).toEqual value: 'public', scopes: ['source.java', 'storage.modifier'] 903 | expect(tokens[0][2]).toEqual value: 'enum', scopes: ['source.java', 'keyword.other.enum'] 904 | expect(tokens[0][4]).toEqual value: 'A', scopes: ['source.java', 'entity.name.type.enum'] 905 | expect(tokens[0][6]).toEqual value: 'implements', scopes: ['source.java', 'storage.modifier.implements'] 906 | expect(tokens[0][8]).toEqual value: 'B', scopes: ['source.java', 'storage.type'] 907 | expect(tokens[0][10]).toEqual value: '{', scopes: ['source.java', 'meta.enum.body', 'punctuation.bracket.curly'] 908 | expect(tokens[1][1]).toEqual value: 'CONSTANT1', scopes: ['source.java', 'meta.enum.body', 'constant.other.enum'] 909 | expect(tokens[2][1]).toEqual value: 'CONSTANT2', scopes: ['source.java', 'meta.enum.body', 'constant.other.enum'] 910 | expect(tokens[3][1]).toEqual value: 'Constant3', scopes: ['source.java', 'meta.enum.body', 'constant.other.enum'] 911 | expect(tokens[4][1]).toEqual value: 'constant4', scopes: ['source.java', 'meta.enum.body', 'constant.other.enum'] 912 | expect(tokens[5][0]).toEqual value: '}', scopes: ['source.java', 'meta.enum.body', 'punctuation.bracket.curly'] 913 | 914 | it 'tokenizes enums with modifiers', -> 915 | tokens = tokenizeLines ''' 916 | public enum Test { } 917 | private enum Test { } 918 | protected enum Test { } 919 | ''' 920 | 921 | expect(tokens[0][0]).toEqual value: 'public', scopes: ['source.java', 'storage.modifier'] 922 | expect(tokens[0][2]).toEqual value: 'enum', scopes: ['source.java', 'keyword.other.enum'] 923 | expect(tokens[0][4]).toEqual value: 'Test', scopes: ['source.java', 'entity.name.type.enum'] 924 | expect(tokens[1][0]).toEqual value: 'private', scopes: ['source.java', 'storage.modifier'] 925 | expect(tokens[1][2]).toEqual value: 'enum', scopes: ['source.java', 'keyword.other.enum'] 926 | expect(tokens[1][4]).toEqual value: 'Test', scopes: ['source.java', 'entity.name.type.enum'] 927 | expect(tokens[2][0]).toEqual value: 'protected', scopes: ['source.java', 'storage.modifier'] 928 | expect(tokens[2][2]).toEqual value: 'enum', scopes: ['source.java', 'keyword.other.enum'] 929 | expect(tokens[2][4]).toEqual value: 'Test', scopes: ['source.java', 'entity.name.type.enum'] 930 | 931 | it 'tokenizes annotations', -> 932 | tokens = tokenizeLines ''' 933 | @Annotation1 934 | @Annotation2() 935 | @Annotation3("value") 936 | @Annotation4(key = "value") 937 | @Test.Annotation5 938 | @Test.Annotation6() 939 | class A { } 940 | ''' 941 | 942 | expect(tokens[0][0]).toEqual value: '@', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.definition.annotation'] 943 | expect(tokens[0][1]).toEqual value: 'Annotation1', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 944 | 945 | expect(tokens[1][0]).toEqual value: '@', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.definition.annotation'] 946 | expect(tokens[1][1]).toEqual value: 'Annotation2', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 947 | expect(tokens[1][2]).toEqual value: '(', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 948 | expect(tokens[1][3]).toEqual value: ')', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 949 | 950 | expect(tokens[2][0]).toEqual value: '@', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.definition.annotation'] 951 | expect(tokens[2][1]).toEqual value: 'Annotation3', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 952 | expect(tokens[2][2]).toEqual value: '(', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 953 | expect(tokens[2][3]).toEqual value: '\"value\"', scopes: ['source.java', 'meta.declaration.annotation', 'string.quoted.double'] 954 | expect(tokens[2][4]).toEqual value: ')', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 955 | 956 | expect(tokens[3][0]).toEqual value: '@', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.definition.annotation'] 957 | expect(tokens[3][1]).toEqual value: 'Annotation4', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 958 | expect(tokens[3][2]).toEqual value: '(', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 959 | expect(tokens[3][3]).toEqual value: 'key', scopes: ['source.java', 'meta.declaration.annotation', 'variable.other.annotation.element'] 960 | expect(tokens[3][5]).toEqual value: '=', scopes: ['source.java', 'meta.declaration.annotation', 'keyword.operator.assignment'] 961 | expect(tokens[3][7]).toEqual value: '\"value\"', scopes: ['source.java', 'meta.declaration.annotation', 'string.quoted.double'] 962 | expect(tokens[3][8]).toEqual value: ')', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 963 | 964 | expect(tokens[4][0]).toEqual value: '@', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.definition.annotation'] 965 | expect(tokens[4][1]).toEqual value: 'Test', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 966 | expect(tokens[4][2]).toEqual value: '.', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.separator.period'] 967 | expect(tokens[4][3]).toEqual value: 'Annotation5', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 968 | 969 | expect(tokens[5][0]).toEqual value: '@', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.definition.annotation'] 970 | expect(tokens[5][1]).toEqual value: 'Test', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 971 | expect(tokens[5][2]).toEqual value: '.', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.separator.period'] 972 | expect(tokens[5][3]).toEqual value: 'Annotation6', scopes: ['source.java', 'meta.declaration.annotation', 'storage.type.annotation'] 973 | expect(tokens[5][4]).toEqual value: '(', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 974 | expect(tokens[5][5]).toEqual value: ')', scopes: ['source.java', 'meta.declaration.annotation', 'punctuation.bracket.round'] 975 | 976 | it 'tokenizes constructor declarations', -> 977 | tokens = tokenizeLines ''' 978 | class A { 979 | public A() throws Exception { 980 | super(); 981 | this.a = 1; 982 | } 983 | } 984 | ''' 985 | 986 | expect(tokens[1][1]).toEqual value: 'public', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.modifier'] 987 | expect(tokens[1][3]).toEqual value: 'A', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'entity.name.function'] 988 | expect(tokens[1][4]).toEqual value: '(', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'punctuation.bracket.round'] 989 | expect(tokens[1][5]).toEqual value: ')', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'punctuation.bracket.round'] 990 | expect(tokens[1][7]).toEqual value: 'throws', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.modifier.throws'] 991 | expect(tokens[1][9]).toEqual value: 'Exception', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'storage.type'] 992 | expect(tokens[1][11]).toEqual value: '{', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'meta.constructor.body', 'punctuation.bracket.curly'] 993 | expect(tokens[2][1]).toEqual value: 'super', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'meta.constructor.body', 'variable.language'] 994 | expect(tokens[2][2]).toEqual value: '(', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'meta.constructor.body', 'punctuation.bracket.round'] 995 | expect(tokens[2][3]).toEqual value: ')', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'meta.constructor.body', 'punctuation.bracket.round'] 996 | expect(tokens[2][4]).toEqual value: ';', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'meta.constructor.body', 'punctuation.terminator.statement'] 997 | expect(tokens[3][1]).toEqual value: 'this', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'meta.constructor.body', 'variable.language'] 998 | expect(tokens[4][1]).toEqual value: '}', scopes: ['source.java', 'meta.class.body', 'meta.constructor', 'meta.constructor.body', 'punctuation.bracket.curly'] 999 | 1000 | it 'tokenizes method declarations', -> 1001 | tokens = tokenizeLines ''' 1002 | class A { 1003 | public int[] func(int size) throws Exception { 1004 | return null; 1005 | } 1006 | 1007 | public int FUNC() { 1008 | return 1; 1009 | } 1010 | 1011 | public int func2(final int finalScore, final int scorefinal) { 1012 | return finalScore; 1013 | } 1014 | } 1015 | ''' 1016 | 1017 | expect(tokens[1][1]).toEqual value: 'public', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier'] 1018 | expect(tokens[1][3]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 1019 | expect(tokens[1][4]).toEqual value: '[', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.square'] 1020 | expect(tokens[1][5]).toEqual value: ']', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.square'] 1021 | expect(tokens[1][7]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'entity.name.function'] 1022 | expect(tokens[1][8]).toEqual value: '(', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.round'] 1023 | expect(tokens[1][9]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 1024 | expect(tokens[1][11]).toEqual value: ')', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.round'] 1025 | expect(tokens[1][13]).toEqual value: 'throws', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier.throws'] 1026 | expect(tokens[1][15]).toEqual value: 'Exception', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 1027 | expect(tokens[1][17]).toEqual value: '{', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.curly'] 1028 | expect(tokens[2][1]).toEqual value: 'return', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control'] 1029 | expect(tokens[2][3]).toEqual value: 'null', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'constant.language.null'] 1030 | expect(tokens[2][4]).toEqual value: ';', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.terminator.statement'] 1031 | expect(tokens[3][1]).toEqual value: '}', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.curly'] 1032 | 1033 | expect(tokens[5][1]).toEqual value: 'public', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier'] 1034 | expect(tokens[5][3]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 1035 | expect(tokens[5][5]).toEqual value: 'FUNC', scopes: ['source.java', 'meta.class.body', 'meta.method', 'entity.name.function'] 1036 | expect(tokens[5][6]).toEqual value: '(', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.round'] 1037 | expect(tokens[5][7]).toEqual value: ')', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.round'] 1038 | expect(tokens[5][9]).toEqual value: '{', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.curly'] 1039 | expect(tokens[7][1]).toEqual value: '}', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.curly'] 1040 | 1041 | expect(tokens[9][1]).toEqual value: 'public', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier'] 1042 | expect(tokens[9][3]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 1043 | expect(tokens[9][5]).toEqual value: 'func2', scopes: ['source.java', 'meta.class.body', 'meta.method', 'entity.name.function'] 1044 | expect(tokens[9][6]).toEqual value: '(', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.round'] 1045 | expect(tokens[9][7]).toEqual value: 'final', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier'] 1046 | expect(tokens[9][9]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 1047 | expect(tokens[9][11]).toEqual value: ',', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.separator.delimiter'] 1048 | expect(tokens[9][13]).toEqual value: 'final', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.modifier'] 1049 | expect(tokens[9][15]).toEqual value: 'int', scopes: ['source.java', 'meta.class.body', 'meta.method', 'storage.type'] 1050 | expect(tokens[9][17]).toEqual value: ')', scopes: ['source.java', 'meta.class.body', 'meta.method', 'punctuation.bracket.round'] 1051 | expect(tokens[9][19]).toEqual value: '{', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.curly'] 1052 | expect(tokens[11][1]).toEqual value: '}', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'punctuation.bracket.curly'] 1053 | 1054 | it 'tokenizes method invocations', -> 1055 | tokens = tokenizeLines ''' 1056 | class A { 1057 | void func() { 1058 | func("arg"); 1059 | obj.func("arg"); 1060 | obj.prop1.prop2.func(); 1061 | obj.prop1.func().prop2.func(); 1062 | super.func("arg"); 1063 | super.prop1.func("arg"); 1064 | this.func("arg"); 1065 | this.prop1.func("arg"); 1066 | this.prop1.prop2.func("arg"); 1067 | this.prop1.func().func("arg"); 1068 | property.super.func("arg"); 1069 | } 1070 | } 1071 | ''' 1072 | 1073 | expect(tokens[2][1]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1074 | expect(tokens[3][3]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1075 | expect(tokens[4][7]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1076 | expect(tokens[5][5]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1077 | expect(tokens[5][11]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1078 | expect(tokens[6][3]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1079 | expect(tokens[7][5]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1080 | expect(tokens[8][3]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1081 | expect(tokens[9][5]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1082 | expect(tokens[10][7]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1083 | expect(tokens[11][5]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1084 | expect(tokens[11][9]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1085 | expect(tokens[12][5]).toEqual value: 'func', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1086 | 1087 | it 'tokenizes method references', -> 1088 | tokens = tokenizeLines ''' 1089 | class A { 1090 | void func() { 1091 | Arrays.sort(rosterAsArray, Person::compareByAge); 1092 | call(Person::new); 1093 | call(java.util.ArrayList::new); 1094 | call(com.test.Util::create); 1095 | call(super::new); 1096 | call(testObject::method); 1097 | } 1098 | } 1099 | ''' 1100 | 1101 | expect(tokens[2][8]).toEqual value: 'Person', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1102 | expect(tokens[2][9]).toEqual value: '::', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control.method'] 1103 | expect(tokens[2][10]).toEqual value: 'compareByAge', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1104 | expect(tokens[3][3]).toEqual value: 'Person', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1105 | expect(tokens[3][4]).toEqual value: '::', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control.method'] 1106 | expect(tokens[3][5]).toEqual value: 'new', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1107 | expect(tokens[4][3]).toEqual value: 'java', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1108 | expect(tokens[4][5]).toEqual value: 'util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1109 | expect(tokens[4][7]).toEqual value: 'ArrayList', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1110 | expect(tokens[4][9]).toEqual value: 'String', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1111 | expect(tokens[4][11]).toEqual value: '::', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control.method'] 1112 | expect(tokens[4][12]).toEqual value: 'new', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1113 | # We cannot parse "com.test.Util" correctly in this example 1114 | # TODO: fix parsing of "com.test.Util::create" 1115 | expect(tokens[5][7]).toEqual value: 'Util', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1116 | expect(tokens[5][8]).toEqual value: '::', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control.method'] 1117 | expect(tokens[5][9]).toEqual value: 'create', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1118 | 1119 | expect(tokens[6][3]).toEqual value: 'super', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'variable.language'] 1120 | expect(tokens[6][4]).toEqual value: '::', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control.method'] 1121 | expect(tokens[6][5]).toEqual value: 'new', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1122 | # testObject is not scoped as "storage.type" 1123 | expect(tokens[7][3]).toEqual value: 'testObject', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body'] 1124 | expect(tokens[7][4]).toEqual value: '::', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'keyword.control.method'] 1125 | expect(tokens[7][5]).toEqual value: 'method', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'entity.name.function'] 1126 | 1127 | it 'tokenizes field access', -> 1128 | tokens = tokenizeLines ''' 1129 | class A { 1130 | void func() { 1131 | var1 = Test.class; 1132 | var2 = com.test.Test.class; 1133 | var5 = Test.staticProperty; 1134 | System.out.println("test"); 1135 | Arrays.sort(array); 1136 | } 1137 | } 1138 | ''' 1139 | 1140 | expect(tokens[2][4]).toEqual value: 'Test', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1141 | # TODO: it would be good to fix the scope for "com.test" component of the class name 1142 | expect(tokens[3][3]).toEqual value: ' com', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body'] 1143 | expect(tokens[3][5]).toEqual value: 'test', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body'] 1144 | expect(tokens[3][7]).toEqual value: 'Test', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1145 | expect(tokens[4][4]).toEqual value: 'Test', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1146 | expect(tokens[5][1]).toEqual value: 'System', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1147 | expect(tokens[6][1]).toEqual value: 'Arrays', scopes: ['source.java', 'meta.class.body', 'meta.method', 'meta.method.body', 'storage.type'] 1148 | -------------------------------------------------------------------------------- /spec/unified-el-spec.coffee: -------------------------------------------------------------------------------- 1 | describe 'Unified expression language grammar', -> 2 | grammar = null 3 | 4 | beforeEach -> 5 | atom.config.set('core.useTreeSitterParsers', false) 6 | waitsForPromise -> 7 | atom.packages.activatePackage('language-java') 8 | 9 | runs -> 10 | grammar = atom.grammars.grammarForScopeName('source.java.el') 11 | 12 | it 'parses the grammar', -> 13 | expect(grammar).toBeTruthy() 14 | expect(grammar.scopeName).toBe 'source.java.el' 15 | 16 | describe 'operators', -> 17 | it 'tokenizes the ternary operator', -> 18 | {tokens} = grammar.tokenizeLine 'true ? 0 : 1' 19 | 20 | expect(tokens[2]).toEqual value: '?', scopes: ['source.java.el', 'keyword.control.ternary.java.el'] 21 | expect(tokens[6]).toEqual value: ':', scopes: ['source.java.el', 'keyword.control.ternary.java.el'] 22 | 23 | it 'parses the comparison operator `==`', -> 24 | {tokens} = grammar.tokenizeLine '1 == 1' 25 | expect(tokens[2]).toEqual value: '==', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 26 | 27 | it 'parses the comparison operator `!=`', -> 28 | {tokens} = grammar.tokenizeLine '1 != 1' 29 | expect(tokens[2]).toEqual value: '!=', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 30 | 31 | it 'parses the comparison operator `<=`', -> 32 | {tokens} = grammar.tokenizeLine '1 <= 1' 33 | expect(tokens[2]).toEqual value: '<=', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 34 | 35 | it 'parses the comparison operator `>=`', -> 36 | {tokens} = grammar.tokenizeLine '1 >= 1' 37 | expect(tokens[2]).toEqual value: '>=', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 38 | 39 | it 'parses the comparison operator `<`', -> 40 | {tokens} = grammar.tokenizeLine '1 < 1' 41 | expect(tokens[2]).toEqual value: '<', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 42 | 43 | it 'parses the comparison operator `>`', -> 44 | {tokens} = grammar.tokenizeLine '1 > 1' 45 | expect(tokens[2]).toEqual value: '>', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 46 | 47 | it 'parses the comparison operator `eq`', -> 48 | {tokens} = grammar.tokenizeLine '1 eq 1' 49 | expect(tokens[2]).toEqual value: 'eq', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 50 | 51 | it 'parses the comparison operator `ne`', -> 52 | {tokens} = grammar.tokenizeLine '1 ne 1' 53 | expect(tokens[2]).toEqual value: 'ne', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 54 | 55 | it 'parses the comparison operator `le`', -> 56 | {tokens} = grammar.tokenizeLine '1 le 1' 57 | expect(tokens[2]).toEqual value: 'le', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 58 | 59 | it 'parses the comparison operator `gt`', -> 60 | {tokens} = grammar.tokenizeLine '1 gt 1' 61 | expect(tokens[2]).toEqual value: 'gt', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 62 | 63 | it 'parses the comparison operator `lt`', -> 64 | {tokens} = grammar.tokenizeLine '1 lt 1' 65 | expect(tokens[2]).toEqual value: 'lt', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 66 | 67 | it 'parses the comparison operator `gt`', -> 68 | {tokens} = grammar.tokenizeLine '1 gt 1' 69 | expect(tokens[2]).toEqual value: 'gt', scopes: ['source.java.el', 'keyword.operator.comparison.java.el'] 70 | 71 | it 'parses the empty operators', -> 72 | {tokens} = grammar.tokenizeLine 'empty foo' 73 | expect(tokens[0]).toEqual value: 'empty', scopes: ['source.java.el', 'keyword.operator.empty.java.el'] 74 | 75 | it 'parses the arithmetic operator `-`', -> 76 | {tokens} = grammar.tokenizeLine '1 - 1' 77 | expect(tokens[2]).toEqual value: '-', scopes: ['source.java.el', 'keyword.operator.arithmetic.java.el'] 78 | 79 | it 'parses the arithmetic operator `+`', -> 80 | {tokens} = grammar.tokenizeLine '1 + 1' 81 | expect(tokens[2]).toEqual value: '+', scopes: ['source.java.el', 'keyword.operator.arithmetic.java.el'] 82 | 83 | it 'parses the arithmetic operator `*`', -> 84 | {tokens} = grammar.tokenizeLine '1 * 1' 85 | expect(tokens[2]).toEqual value: '*', scopes: ['source.java.el', 'keyword.operator.arithmetic.java.el'] 86 | 87 | it 'parses the arithmetic operator `/`', -> 88 | {tokens} = grammar.tokenizeLine '1 / 1' 89 | expect(tokens[2]).toEqual value: '/', scopes: ['source.java.el', 'keyword.operator.arithmetic.java.el'] 90 | 91 | it 'parses the arithmetic operator `%`', -> 92 | {tokens} = grammar.tokenizeLine '1 % 1' 93 | expect(tokens[2]).toEqual value: '%', scopes: ['source.java.el', 'keyword.operator.arithmetic.java.el'] 94 | 95 | it 'parses the arithmetic operator `div`', -> 96 | {tokens} = grammar.tokenizeLine '1 div 1' 97 | expect(tokens[2]).toEqual value: 'div', scopes: ['source.java.el', 'keyword.operator.arithmetic.java.el'] 98 | 99 | it 'parses the arithmetic operator `mod`', -> 100 | {tokens} = grammar.tokenizeLine '1 mod 1' 101 | expect(tokens[2]).toEqual value: 'mod', scopes: ['source.java.el', 'keyword.operator.arithmetic.java.el'] 102 | 103 | it 'parses the logical operator `!`', -> 104 | {tokens} = grammar.tokenizeLine '!foo' 105 | expect(tokens[0]).toEqual value: '!', scopes: ['source.java.el', 'keyword.operator.logical.java.el'] 106 | 107 | it 'parses the logical operator `&&`', -> 108 | {tokens} = grammar.tokenizeLine '1 && 1' 109 | expect(tokens[2]).toEqual value: '&&', scopes: ['source.java.el', 'keyword.operator.logical.java.el'] 110 | 111 | it 'parses the logical operator `||`', -> 112 | {tokens} = grammar.tokenizeLine '1 || 1' 113 | expect(tokens[2]).toEqual value: '||', scopes: ['source.java.el', 'keyword.operator.logical.java.el'] 114 | 115 | it 'parses the logical operator `not`', -> 116 | {tokens} = grammar.tokenizeLine '1 not 1' 117 | expect(tokens[2]).toEqual value: 'not', scopes: ['source.java.el', 'keyword.operator.logical.java.el'] 118 | 119 | it 'parses the logical operator `and`', -> 120 | {tokens} = grammar.tokenizeLine '1 and 1' 121 | expect(tokens[2]).toEqual value: 'and', scopes: ['source.java.el', 'keyword.operator.logical.java.el'] 122 | 123 | it 'parses the logical operator `or`', -> 124 | {tokens} = grammar.tokenizeLine '1 or 1' 125 | expect(tokens[2]).toEqual value: 'or', scopes: ['source.java.el', 'keyword.operator.logical.java.el'] 126 | 127 | describe 'literals', -> 128 | it 'parses boolean literals', -> 129 | {tokens} = grammar.tokenizeLine 'true' 130 | expect(tokens[0]).toEqual value: 'true', scopes: ['source.java.el', 'constant.boolean.java.el'] 131 | 132 | {tokens} = grammar.tokenizeLine 'false' 133 | expect(tokens[0]).toEqual value: 'false', scopes: ['source.java.el', 'constant.boolean.java.el'] 134 | 135 | it 'parses the null literal', -> 136 | {tokens} = grammar.tokenizeLine 'null' 137 | 138 | it 'parses numeric literals', -> 139 | {tokens} = grammar.tokenizeLine '0' 140 | expect(tokens[0]).toEqual value: '0', scopes: ['source.java.el', 'constant.numeric.java.el'] 141 | 142 | {tokens} = grammar.tokenizeLine '9804' 143 | expect(tokens[0]).toEqual value: '9804', scopes: ['source.java.el', 'constant.numeric.java.el'] 144 | 145 | {tokens} = grammar.tokenizeLine '0.54' 146 | expect(tokens[0]).toEqual value: '0.54', scopes: ['source.java.el', 'constant.numeric.java.el'] 147 | 148 | {tokens} = grammar.tokenizeLine '13.12' 149 | expect(tokens[0]).toEqual value: '13.12', scopes: ['source.java.el', 'constant.numeric.java.el'] 150 | 151 | it 'tokenizes single quoted string literals', -> 152 | {tokens} = grammar.tokenizeLine "'foo\\n bar \\\'baz'" 153 | expect(tokens[0]).toEqual value: "'", scopes: ['source.java.el', 'string.quoted.single.java.el', 'punctuation.definition.string.begin.java.el'] 154 | expect(tokens[1]).toEqual value: 'foo', scopes: ['source.java.el', 'string.quoted.single.java.el'] 155 | expect(tokens[2]).toEqual value: '\\n', scopes: ['source.java.el', 'string.quoted.single.java.el', 'constant.character.escape.java.el'] 156 | expect(tokens[3]).toEqual value: ' bar ', scopes: ['source.java.el', 'string.quoted.single.java.el'] 157 | expect(tokens[4]).toEqual value: '\\\'', scopes: ['source.java.el', 'string.quoted.single.java.el', 'constant.character.escape.java.el'] 158 | expect(tokens[5]).toEqual value: 'baz', scopes: ['source.java.el', 'string.quoted.single.java.el'] 159 | expect(tokens[6]).toEqual value: "'", scopes: ['source.java.el', 'string.quoted.single.java.el', 'punctuation.definition.string.end.java.el'] 160 | 161 | it 'tokenizes double quoted string literals', -> 162 | {tokens} = grammar.tokenizeLine '"foo\\n bar \\\"baz"' 163 | expect(tokens[0]).toEqual value: '"', scopes: ['source.java.el', 'string.quoted.double.java.el', 'punctuation.definition.string.begin.java.el'] 164 | expect(tokens[1]).toEqual value: 'foo', scopes: ['source.java.el', 'string.quoted.double.java.el'] 165 | expect(tokens[2]).toEqual value: '\\n', scopes: ['source.java.el', 'string.quoted.double.java.el', 'constant.character.escape.java.el'] 166 | expect(tokens[3]).toEqual value: ' bar ', scopes: ['source.java.el', 'string.quoted.double.java.el'] 167 | expect(tokens[4]).toEqual value: '\\\"', scopes: ['source.java.el', 'string.quoted.double.java.el', 'constant.character.escape.java.el'] 168 | expect(tokens[5]).toEqual value: 'baz', scopes: ['source.java.el', 'string.quoted.double.java.el'] 169 | expect(tokens[6]).toEqual value: '"', scopes: ['source.java.el', 'string.quoted.double.java.el', 'punctuation.definition.string.end.java.el'] 170 | 171 | it 'tokenizes function calls', -> 172 | {tokens} = grammar.tokenizeLine 'fn:split(foo, bar)' 173 | 174 | expect(tokens[0]).toEqual value: 'fn', scopes: ['source.java.el', 'namespace.java.el'] 175 | expect(tokens[1]).toEqual value: ':', scopes: ['source.java.el', 'namespace.java.el', 'punctuation.separator.namespace.java.el'] 176 | expect(tokens[2]).toEqual value: 'split', scopes: ['source.java.el'] 177 | expect(tokens[3]).toEqual value: '(', scopes: ['source.java.el', 'meta.brace.round.java.el'] 178 | expect(tokens[4]).toEqual value: 'foo', scopes: ['source.java.el'] 179 | expect(tokens[5]).toEqual value: ',', scopes: ['source.java.el', 'meta.delimiter.java.el'] 180 | expect(tokens[6]).toEqual value: ' bar', scopes: ['source.java.el'] 181 | expect(tokens[7]).toEqual value: ')', scopes: ['source.java.el', 'meta.brace.round.java.el'] 182 | 183 | it 'tokenizes a computed property access', -> 184 | {tokens} = grammar.tokenizeLine 'foo[0]' 185 | 186 | expect(tokens[0]).toEqual value: 'foo', scopes: ['source.java.el'] 187 | expect(tokens[1]).toEqual value: '[', scopes: ['source.java.el', 'meta.brace.square.java.el'] 188 | expect(tokens[2]).toEqual value: '0', scopes: ['source.java.el', 'constant.numeric.java.el'] 189 | expect(tokens[3]).toEqual value: ']', scopes: ['source.java.el', 'meta.brace.square.java.el'] 190 | --------------------------------------------------------------------------------