├── spec ├── fixtures │ ├── dira │ │ └── dira.1 │ │ │ └── dira.2 │ │ │ ├── .babelrc │ │ │ ├── good.js │ │ │ ├── react.js │ │ │ ├── react.jsx │ │ │ ├── bad.js │ │ │ └── ignored.js │ ├── projectRoot │ │ ├── test.js │ │ ├── src │ │ │ ├── a.min.js │ │ │ ├── test.es │ │ │ ├── test.es6 │ │ │ ├── test.js │ │ │ ├── test.jsx │ │ │ └── test.babel │ │ └── .languagebabel │ ├── dirb │ │ └── good.js │ └── grammar │ │ ├── babel-sublime │ │ ├── js-template-strings.js │ │ ├── js-class.js │ │ ├── jsx-features.jsx │ │ ├── js-symbols.js │ │ ├── jsx-text.jsx │ │ ├── jsx-attributes.jsx │ │ └── jsx-full-react-class.jsx │ │ ├── misc.js │ │ └── declare.js ├── default-config.coffee ├── grammar-spec.coffee └── transpile-spec.coffee ├── .gitignore ├── .travis.yml ├── .gitattributes ├── README.md ├── settings └── language-babel.json ├── LICENSE.md ├── package.json ├── styles └── language-babel.less ├── lib ├── config.coffee ├── main.coffee ├── transpiler-task.coffee ├── auto-complete-jsx.coffee ├── completions-jsx.coffee └── transpiler.coffee ├── coffeelint.json ├── grammars └── Babel Regex.json └── CHANGELOG.md /spec/fixtures/dira/dira.1/dira.2/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/test.js: -------------------------------------------------------------------------------- 1 | let x = "simple test"; -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/src/a.min.js: -------------------------------------------------------------------------------- 1 | let x="simple test" 2 | -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/src/test.es: -------------------------------------------------------------------------------- 1 | let x="simple test" 2 | -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/src/test.es6: -------------------------------------------------------------------------------- 1 | let x="simple test" 2 | -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/src/test.js: -------------------------------------------------------------------------------- 1 | let x="simple test" 2 | -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/src/test.jsx: -------------------------------------------------------------------------------- 1 | let x="simple test" 2 | -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/src/test.babel: -------------------------------------------------------------------------------- 1 | let x="simple test" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | npm-debug.log 3 | node_modules 4 | babel-source 5 | babel-target 6 | thumbs.db 7 | /testJs/ 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | 3 | notifications: 4 | email: 5 | on_success: never 6 | on_failure: change 7 | 8 | script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh' 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # language-babel 2 | 3 | This fork exists only for the purpose of locking the version to `v2.22.0` in [Linguist](https://github.com/github/linguist). 4 | For syntax highlighting in Atom, you should use [gandm/language-babel](https://github.com/gandm/language-babel). 5 | 6 | The last versions of language-babel are incompatible with GitHub's regular expression engine (PCRE vs. Oniguruma for Atom). 7 | For more context, see [github/linguist#3044](https://github.com/github/linguist/issues/3044). 8 | -------------------------------------------------------------------------------- /settings/language-babel.json: -------------------------------------------------------------------------------- 1 | { 2 | ".source.js.jsx": { 3 | "editor": { 4 | "commentStart": "// ", 5 | "foldEndPattern": "^\\s*\\}|^\\s*\\]|^\\s*\\)", 6 | "increaseIndentPattern": "{[^}\"']*$|\\[[^\\]\"']*$|\\([^)\"']*$", 7 | "decreaseIndentPattern": "^\\s*(\\s*/[*].*[*]/\\s*)*[}\\])]", 8 | "nonWordCharacters": "/\\()\"':,.;<>~!@#%^&*|+=[]{}`?-…" 9 | } 10 | }, 11 | ".meta.tag.jsx": { 12 | "editor": { 13 | "commentStart": "{/*", 14 | "commentEnd": "*/}" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spec/default-config.coffee: -------------------------------------------------------------------------------- 1 | # these are defaults for the spec tests not necessarily the package defaults 2 | module.exports = 3 | # package control settings 4 | allowLocalOverride: false 5 | babelMapsAddUrl: true 6 | babelMapsPath: '' 7 | babelSourcePath: '' 8 | babelTranspilePath: '' 9 | createMap: false 10 | createTargetDirectories: false 11 | createTranspiledCode: true 12 | disableWhenNoBabelrcFileInPath: false 13 | suppressSourcePathMessages: false 14 | suppressTranspileOnSaveMessages: false 15 | transpileOnSave: true 16 | autoIndentJSX: true 17 | -------------------------------------------------------------------------------- /spec/fixtures/projectRoot/.languagebabel: -------------------------------------------------------------------------------- 1 | { 2 | "babelMapsPath": "", 3 | "babelMapsAddUrl": false, 4 | "babelSourcePath": "src", 5 | "babelTranspilePath": "", 6 | "createMap": false, 7 | "createTargetDirectories": true, 8 | "createTranspiledCode": true, 9 | "disableWhenNoBabelrcFileInPath": false, 10 | "projectRoot": true, 11 | "suppressSourcePathMessages": true, 12 | "suppressTranspileOnSaveMessages": true, 13 | "transpileOnSave": true 14 | } 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Graham Clark 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 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-babel", 3 | "main": "./lib/main", 4 | "version": "2.22.0", 5 | "description": "Babel JavaScript ES201x, React JSX & Flow Grammar & Transpiler", 6 | "keywords": [ 7 | "es6", 8 | "es7", 9 | "react", 10 | "jsx", 11 | "flow", 12 | "javascript" 13 | ], 14 | "activationCommands": [], 15 | "repository": "https://github.com/gandm/language-babel", 16 | "license": "MIT", 17 | "engines": { 18 | "atom": "^1.0.0" 19 | }, 20 | "providedServices": { 21 | "autocomplete.provider": { 22 | "versions": { 23 | "2.0.0": "JSXCompleteProvider" 24 | } 25 | }, 26 | "preview.provider": { 27 | "versions": { 28 | "0.1.0": "provide" 29 | } 30 | } 31 | }, 32 | "dependencies": { 33 | "babel-core": "^6.7.6", 34 | "fs-plus": "^2.8.2", 35 | "fuzzaldrin": "^2.1.0", 36 | "jjv": "^1.0.2", 37 | "js-yaml": "^3.6.0", 38 | "path-is-inside": "^1.0.1", 39 | "strip-json-comments": "^2.0.1" 40 | }, 41 | "devDependencies": { 42 | "atom-grammar-test": "<1.0.0", 43 | "chai": "^3.0.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /spec/fixtures/dira/dira.1/dira.2/good.js: -------------------------------------------------------------------------------- 1 | var QuadraticCalculator = React.createClass({ 2 | getInitialState: function() { 3 | console.log("test") 4 | return { 5 | a: 1, 6 | b: 3, 7 | c: -4 8 | }; 9 | }, 10 | 11 | /** 12 | * This function will be re-bound in render multiple times. Each .bind() will 13 | * create a new function that calls this with the appropriate key as well as 14 | * the event. The key is the key in the state object that the value should be 15 | * mapped from. 16 | */ 17 | handleInputChange: function(key, event) { 18 | var partialState = {}; 19 | partialState[key] = parseFloat(event.target.value); 20 | this.setState(partialState); 21 | }, 22 | 23 | render: function() { 24 | var a = this.state.a; 25 | var b = this.state.b; 26 | var c = this.state.c; 27 | var root = Math.sqrt(Math.pow(b, 2) - 4 * a * c); 28 | var denominator = 2 * a; 29 | var x1 = (-b + root) / denominator; 30 | var x2 = (-b - root) / denominator; 31 | return true; 32 | } 33 | }); 34 | 35 | React.render( 36 | document.getElementById('container') 37 | ); 38 | -------------------------------------------------------------------------------- /spec/fixtures/dira/dira.1/dira.2/react.js: -------------------------------------------------------------------------------- 1 | var QuadraticCalculator = React.createClass({ 2 | getInitialState: function () { 3 | console.log("test"); 4 | return { 5 | a: 1, 6 | b: 3, 7 | c: -4 8 | }; 9 | }, 10 | 11 | /** 12 | * This function will be re-bound in render multiple times. Each .bind() will 13 | * create a new function that calls this with the appropriate key as well as 14 | * the event. The key is the key in the state object that the value should be 15 | * mapped from. 16 | */ 17 | handleInputChange: function (key, event) { 18 | var partialState = {}; 19 | partialState[key] = parseFloat(event.target.value); 20 | this.setState(partialState); 21 | }, 22 | 23 | render: function () { 24 | var a = this.state.a; 25 | var b = this.state.b; 26 | var c = this.state.c; 27 | var root = Math.sqrt(Math.pow(b, 2) - 4 * a * c); 28 | var denominator = 2 * a; 29 | var x1 = (-b + root) / denominator; 30 | var x2 = (-b - root) / denominator; 31 | return; 32 | false; 33 | } 34 | }); 35 | 36 | React.render(document.getElementById('container')); 37 | -------------------------------------------------------------------------------- /spec/fixtures/dira/dira.1/dira.2/react.jsx: -------------------------------------------------------------------------------- 1 | var QuadraticCalculator = React.createClass({ 2 | getInitialState: function() { 3 | console.log("test") 4 | return { 5 | a: 1, 6 | b: 3, 7 | c: -4 8 | }; 9 | }, 10 | 11 | /** 12 | * This function will be re-bound in render multiple times. Each .bind() will 13 | * create a new function that calls this with the appropriate key as well as 14 | * the event. The key is the key in the state object that the value should be 15 | * mapped from. 16 | */ 17 | handleInputChange: function(key, event) { 18 | var partialState = {}; 19 | partialState[key] = parseFloat(event.target.value); 20 | this.setState(partialState); 21 | }, 22 | 23 | render: function() { 24 | var a = this.state.a; 25 | var b = this.state.b; 26 | var c = this.state.c; 27 | var root = Math.sqrt(Math.pow(b, 2) - 4 * a * c); 28 | var denominator = 2 * a; 29 | var x1 = (-b + root) / denominator; 30 | var x2 = (-b - root) / denominator; 31 | return 32 | false; 33 | } 34 | }); 35 | 36 | React.render( 37 | document.getElementById('container') 38 | ); 39 | -------------------------------------------------------------------------------- /spec/fixtures/dira/dira.1/dira.2/bad.js: -------------------------------------------------------------------------------- 1 | var QuadraticCalculator = React.createClass({ 2 | getInitialState: function() { 3 | console.log("test") 4 | return { 5 | a: 1, 6 | b: 3, 7 | c: -4 8 | }; 9 | }, 10 | 11 | /** 12 | * This function will be re-bound in render multiple times. Each .bind() will 13 | * create a new function that calls this with the appropriate key as well as 14 | * the event. The key is the key in the state object that the value should be 15 | * mapped from. 16 | */ 17 | handleInputChange: function(key, event) { 18 | var partialState = {}; 19 | partialState[key] = parseFloat(event.target.value); 20 | this.setState(partialState); 21 | }, 22 | 23 | render: function() { 24 | var a = this.state.a; 25 | var b = this.state.b; 26 | var c = this.state.c; 27 | var root = Math.sqrt(Math.pow(b, 2) - 4 * a * c); 28 | var denominator = 2 * a; 29 | var x1 = (-b + root) / denominator; 30 | var x2 = (-b - root) / denominator; 31 | return { // ill formed object 32 | }); 33 | 34 | React.render( 35 | document.getElementById('container') 36 | ); 37 | 38 | this is an error 39 | -------------------------------------------------------------------------------- /spec/fixtures/dirb/good.js: -------------------------------------------------------------------------------- 1 | var QuadraticCalculator = React.createClass({ 2 | getInitialState: function() { 3 | console.log("test") 4 | return { 5 | a: 1, 6 | b: 3, 7 | c: -4 8 | }; 9 | }, 10 | 11 | /** 12 | * This function will be re-bound in render multiple times. Each .bind() will 13 | * create a new function that calls this with the appropriate key as well as 14 | * the event. The key is the key in the state object that the value should be 15 | * mapped from. 16 | */ 17 | handleInputChange: function(key, event) { 18 | var partialState = {}; 19 | partialState[key] = parseFloat(event.target.value); 20 | this.setState(partialState); 21 | }, 22 | 23 | render: function() { 24 | var a = this.state.a; 25 | var b = this.state.b; 26 | var c = this.state.c; 27 | var root = Math.sqrt(Math.pow(b, 2) - 4 * a * c); 28 | var denominator = 2 * a; 29 | var x1 = (-b + root) / denominator; 30 | var x2 = (-b - root) / denominator; 31 | return ( 32 |
33 | 34 | ax2 + bx + c = 0 35 | 36 |

Solve for x:

37 |

38 | 41 |
42 | 45 |
46 | 49 |
50 | x: {x1}, {x2} 51 |

52 |
53 | ); 54 | } 55 | }); 56 | 57 | React.render( 58 | , 59 | document.getElementById('container') 60 | ); 61 | -------------------------------------------------------------------------------- /spec/fixtures/dira/dira.1/dira.2/ignored.js: -------------------------------------------------------------------------------- 1 | var QuadraticCalculator = React.createClass({ 2 | getInitialState: function() { 3 | console.log("test") 4 | return { 5 | a: 1, 6 | b: 3, 7 | c: -4 8 | }; 9 | }, 10 | 11 | /** 12 | * This function will be re-bound in render multiple times. Each .bind() will 13 | * create a new function that calls this with the appropriate key as well as 14 | * the event. The key is the key in the state object that the value should be 15 | * mapped from. 16 | */ 17 | handleInputChange: function(key, event) { 18 | var partialState = {}; 19 | partialState[key] = parseFloat(event.target.value); 20 | this.setState(partialState); 21 | }, 22 | 23 | render: function() { 24 | var a = this.state.a; 25 | var b = this.state.b; 26 | var c = this.state.c; 27 | var root = Math.sqrt(Math.pow(b, 2) - 4 * a * c); 28 | var denominator = 2 * a; 29 | var x1 = (-b + root) / denominator; 30 | var x2 = (-b - root) / denominator; 31 | return ( 32 |
33 | 34 | ax2 + bx + c = 0 35 | 36 |

Solve for x:

37 |

38 | 41 |
42 | 45 |
46 | 49 |
50 | x: {x1}, {x2} 51 |

52 |
53 | ); 54 | } 55 | }); 56 | 57 | React.render( 58 | , 59 | document.getElementById('container') 60 | ); 61 | -------------------------------------------------------------------------------- /spec/grammar-spec.coffee: -------------------------------------------------------------------------------- 1 | path = require 'path' 2 | grammarTest = require 'atom-grammar-test' 3 | 4 | describe 'Grammar', -> 5 | beforeEach -> 6 | waitsForPromise -> 7 | atom.packages.activatePackage('language-babel') 8 | waitsForPromise -> 9 | atom.packages.activatePackage('language-todo') 10 | waitsForPromise -> 11 | atom.packages.activatePackage('language-hyperlink') 12 | 13 | # babel-sublime test files 14 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/flow.js') 15 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-class.js') 16 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-functions.js') 17 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-symbols.js') 18 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-template-strings.js') 19 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-attributes.jsx') 20 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-es6.jsx') 21 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-features.jsx') 22 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-full-react-class.jsx') 23 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-text.jsx') 24 | 25 | # flow declaration file 26 | grammarTest path.join(__dirname, 'fixtures/grammar/declare.js') 27 | 28 | # grammar test large files 29 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/browser-polyfill.js') 30 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/jquery-2.1.4.js') 31 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/bundle.js') 32 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/jquery-2.1.4.min.js') 33 | 34 | # # es2015 check 35 | grammarTest path.join(__dirname, 'fixtures/grammar/everythingJs/es2015-module.js') 36 | 37 | # todo,jsdoc,... 38 | grammarTest path.join(__dirname, 'fixtures/grammar/doc-keywords.js') 39 | 40 | # issues raised 41 | grammarTest path.join(__dirname, 'fixtures/grammar/issues.js') 42 | 43 | # misc Tests 44 | grammarTest path.join(__dirname, 'fixtures/grammar/misc.js') 45 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/babel-sublime/js-template-strings.js: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | // nested template strings 3 | var node = Relay.QL` 4 | node(123) { 5 | ${Relay.QL` 6 | User { 7 | address { 8 | ${fragment}, 9 | }, 10 | } 11 | `} 12 | } 13 | `; 14 | 15 | var node = Relay.QL` node(123) {${Relay.QL` User { address { ${fragment},}, }` } }`; 16 | // <- storage.type.js 17 | // <- storage.type.js 18 | //^ storage.type.js 19 | // ^^^^ ^^^^^^^^ variable.other.readwrite.js 20 | // ^ keyword.operator.assignment.js 21 | // ^^^^^^^^ ^^^^^^^^ meta.property.class.js 22 | // ^^^^^ ^^^^^ variable.other.class.js 23 | // ^ ^ keyword.operator.accessor.js 24 | // ^^ ^^ variable.other.property.static.js 25 | // ^ ^^^^^^^^^ ^^^^^^^^^^^^ ^^^^ ^ ^^^^^^^ ^ ^^^^^^^^^^^^^^ ^^ ^ ^^ string.quasi.js 26 | // ^ ^ punctuation.definition.quasi.begin.js 27 | // ^ ^^^^^^^^^ ^^^^^^^^^^^^ ^^^^ ^ ^^^^^^^ ^ ^^^^^^^^^^^^^^ ^^ ^ ^^ string.quoted.template.js 28 | // ^^^^^^^^^^^ ^^^^ ^ ^^^^^^^ ^ ^^^^^^^^^^^^^^ ^^ ^ entity.quasi.element.js 29 | // ^^ ^^ punctuation.quasi.element.begin.js 30 | // ^ ^ punctuation.quasi.element.end.js 31 | // ^ ^ punctuation.definition.quasi.end.js 32 | // ^ punctuation.terminator.statement.js 33 | 34 | // >> only:source.js.jsx 35 | -------------------------------------------------------------------------------- /styles/language-babel.less: -------------------------------------------------------------------------------- 1 | // You can provide styles for the language-babel package here. 2 | 3 | @import "ui-variables"; 4 | 5 | // Config ----------------------------------- 6 | @syntax-hue: 220; 7 | @syntax-saturation: 24%; 8 | @syntax-brightness: 20%; 9 | 10 | // Base colors ----------------------------------- 11 | @syntax-base-accent-color: hsl(@syntax-hue, 100%, 66% ); 12 | @syntax-base-background-color: hsv(@syntax-hue, @syntax-saturation, @syntax-brightness); 13 | @syntax-base-text-color: @light-gray; 14 | @syntax-base-guide-color: fade(@syntax-base-text-color, 15%); 15 | 16 | 17 | // Colors: Mix Base16 Tomorrow with Theme hue ----------------------------------- 18 | @syntax-mix-base: hsl(@syntax-hue, 100%, 66%); 19 | @syntax-mix-grey: 12%; 20 | @syntax-mix-color: 0%; 21 | 22 | @very-light-gray: mix( @syntax-mix-base, hsl(0,0%,84%), @syntax-mix-grey); 23 | @light-gray: mix( @syntax-mix-base, hsl(0,0%,72%), @syntax-mix-grey); 24 | @gray: mix( @syntax-mix-base, hsl(0,0%,54%), @syntax-mix-grey); 25 | @dark-gray: mix( @syntax-mix-base, hsl(0,0%,36%), @syntax-mix-grey); 26 | @very-dark-gray: mix( @syntax-mix-base, hsl(0,0%,18%), @syntax-mix-grey); 27 | 28 | @cyan: mix( @syntax-mix-base, #57B6C2, @syntax-mix-color); 29 | @blue: mix( @syntax-mix-base, #61AEEF, @syntax-mix-color); 30 | @purple: mix( @syntax-mix-base, #C679DD, @syntax-mix-color); 31 | @green: mix( @syntax-mix-base, #97C378, @syntax-mix-color); 32 | @red: mix( @syntax-mix-base, #DF6A73, @syntax-mix-color); 33 | @dark-red: mix( @syntax-mix-base, #BE4F44, @syntax-mix-color); 34 | @orange: mix( @syntax-mix-base, #D29B67, @syntax-mix-color); 35 | @light-orange: mix( @syntax-mix-base, #E5C17C, @syntax-mix-color); 36 | @bright-orange: mix( @syntax-mix-base, #FF8000, @syntax-mix-color); 37 | 38 | atom-text-editor::shadow { 39 | .source.js.jsx { 40 | .jsx { 41 | .entity { 42 | &.other { 43 | &.attribute-name { 44 | font-style: italic // color: @cyan; 45 | } 46 | } 47 | } 48 | .constant.character.entity { 49 | font-style: italic 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/config.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | allowLocalOverride: 3 | description: 'Allow .languagebabel files to overide the settings below. Useful for project based configurations.' 4 | type: 'boolean' 5 | default: false 6 | order: 30 7 | transpileOnSave: 8 | description: 'Check source code validity on file save. Use "Create Transpiled Code" option below to save file.' 9 | type: 'boolean' 10 | default: false 11 | order: 40 12 | createTranspiledCode: 13 | description: 'Save transpiled code to Babel Transpile Path below.' 14 | type: 'boolean' 15 | default: false 16 | order: 50 17 | disableWhenNoBabelrcFileInPath: 18 | description: 'Suppress transpile when no .babelrc file is in source file path.' 19 | type: 'boolean' 20 | default: true 21 | order: 60 22 | suppressTranspileOnSaveMessages: 23 | description: 'Suppress non-error notification messages on each save.' 24 | type: 'boolean' 25 | default: true 26 | order: 70 27 | suppressSourcePathMessages: 28 | description: 'Suppress messages about file not being inside Babel Source Path.' 29 | type: 'boolean' 30 | default: true 31 | order: 75 32 | createMap: 33 | description: 'Create separate map file.' 34 | type: 'boolean' 35 | default: false 36 | order: 80 37 | babelMapsAddUrl: 38 | description: 'Append map file name to transpiled output if "Create separate map file" is set.' 39 | type: 'boolean' 40 | default: true 41 | order: 90 42 | babelSourcePath: 43 | description: 'Babel Source Root based on Project root.' 44 | type: 'string' 45 | default: '' 46 | order: 100 47 | babelTranspilePath: 48 | description: 'Babel Transpile Root based on Project root.' 49 | type: 'string' 50 | default: '' 51 | order: 120 52 | babelMapsPath: 53 | description: 'Babel Maps Root based on Project root.' 54 | type: 'string' 55 | default: '' 56 | order: 130 57 | createTargetDirectories: 58 | description: 'Create transpile output target directories.' 59 | type: 'boolean' 60 | default: true 61 | order: 140 62 | autoIndentJSX: 63 | title: 'Auto Indent JSX' 64 | description: 'Auto Indent JSX using default or eslintrc rules' 65 | type: 'boolean' 66 | default: false 67 | order: 160 68 | -------------------------------------------------------------------------------- /lib/main.coffee: -------------------------------------------------------------------------------- 1 | {CompositeDisposable} = require 'atom' 2 | autoCompleteJSX = require './auto-complete-jsx' 3 | AutoIndent = require './auto-indent' 4 | 5 | INTERFILESAVETIME = 1000 6 | LB = 'language-babel' 7 | 8 | module.exports = 9 | config: require './config' 10 | 11 | activate: (state) -> 12 | @transpiler ?= new (require './transpiler') 13 | # track any file save events and transpile if babel 14 | @disposable = new CompositeDisposable 15 | @textEditors = {} 16 | @fileSaveTimes = {} 17 | 18 | @disposable.add atom.project.onDidChangePaths => 19 | @transpiler.stopUnusedTasks() 20 | 21 | @disposable.add atom.workspace.observeTextEditors (textEditor) => 22 | @textEditors[textEditor.id] = new CompositeDisposable 23 | 24 | @textEditors[textEditor.id].add textEditor.observeGrammar (grammar) => 25 | # Instantiate indentor for language-babel files 26 | if textEditor.getGrammar().packageName is LB 27 | if atom.config.get(LB).autoIndentJSX 28 | @textEditors[textEditor.id].autoIndent = new AutoIndent(textEditor) 29 | else 30 | @textEditors[textEditor.id]?.autoIndent?.destroy() 31 | delete @textEditors[textEditor.id]?.autoIndent? 32 | 33 | @textEditors[textEditor.id].add textEditor.onDidSave (event) => 34 | if textEditor.getGrammar().packageName is LB 35 | filePath = textEditor.getPath() 36 | lastSaveTime = @fileSaveTimes[filePath] ? 0 37 | @fileSaveTimes[filePath] = Date.now() 38 | if (lastSaveTime < (@fileSaveTimes[filePath] - INTERFILESAVETIME)) 39 | @transpiler.transpile(filePath, textEditor) 40 | 41 | @textEditors[textEditor.id].add textEditor.onDidDestroy () => 42 | @textEditors[textEditor.id]?.autoIndent?.destroy() 43 | delete @textEditors[textEditor.id]?.autoIndent? 44 | filePath = textEditor.getPath() 45 | if @fileSaveTimes[filePath]? then delete @fileSaveTimes[filePath] 46 | @textEditors[textEditor.id].dispose() 47 | delete @textEditors[textEditor.id] 48 | 49 | 50 | deactivate: -> 51 | @disposable.dispose() 52 | for id, disposeable of @textEditors 53 | if @textEditors[id].autoIndent? 54 | @textEditors[id].autoIndent.destroy() 55 | delete @textEditors[id].autoIndent 56 | disposeable.dispose() 57 | @transpiler.stopAllTranspilerTask() 58 | @transpiler.disposables.dispose() 59 | 60 | JSXCompleteProvider: -> 61 | autoCompleteJSX 62 | 63 | provide:-> 64 | @transpiler 65 | -------------------------------------------------------------------------------- /coffeelint.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrow_spacing": { 3 | "level": "ignore" 4 | }, 5 | "braces_spacing": { 6 | "level": "ignore", 7 | "spaces": 0, 8 | "empty_object_spaces": 0 9 | }, 10 | "camel_case_classes": { 11 | "level": "error" 12 | }, 13 | "coffeescript_error": { 14 | "level": "error" 15 | }, 16 | "colon_assignment_spacing": { 17 | "level": "ignore", 18 | "spacing": { 19 | "left": 0, 20 | "right": 0 21 | } 22 | }, 23 | "cyclomatic_complexity": { 24 | "level": "ignore", 25 | "value": 10 26 | }, 27 | "duplicate_key": { 28 | "level": "error" 29 | }, 30 | "empty_constructor_needs_parens": { 31 | "level": "ignore" 32 | }, 33 | "ensure_comprehensions": { 34 | "level": "warn" 35 | }, 36 | "eol_last": { 37 | "level": "ignore" 38 | }, 39 | "indentation": { 40 | "value": 2, 41 | "level": "error" 42 | }, 43 | "line_endings": { 44 | "level": "ignore", 45 | "value": "unix" 46 | }, 47 | "max_line_length": { 48 | "value": 200, 49 | "level": "warn", 50 | "limitComments": true 51 | }, 52 | "missing_fat_arrows": { 53 | "level": "ignore", 54 | "is_strict": false 55 | }, 56 | "newlines_after_classes": { 57 | "value": 3, 58 | "level": "ignore" 59 | }, 60 | "no_backticks": { 61 | "level": "error" 62 | }, 63 | "no_debugger": { 64 | "level": "warn", 65 | "console": false 66 | }, 67 | "no_empty_functions": { 68 | "level": "ignore" 69 | }, 70 | "no_empty_param_list": { 71 | "level": "ignore" 72 | }, 73 | "no_implicit_braces": { 74 | "level": "ignore", 75 | "strict": true 76 | }, 77 | "no_implicit_parens": { 78 | "level": "ignore", 79 | "strict": true 80 | }, 81 | "no_interpolation_in_single_quotes": { 82 | "level": "ignore" 83 | }, 84 | "no_nested_string_interpolation": { 85 | "level": "warn" 86 | }, 87 | "no_plusplus": { 88 | "level": "ignore" 89 | }, 90 | "no_private_function_fat_arrows": { 91 | "level": "warn" 92 | }, 93 | "no_stand_alone_at": { 94 | "level": "ignore" 95 | }, 96 | "no_tabs": { 97 | "level": "error" 98 | }, 99 | "no_this": { 100 | "level": "ignore" 101 | }, 102 | "no_throwing_strings": { 103 | "level": "error" 104 | }, 105 | "no_trailing_semicolons": { 106 | "level": "error" 107 | }, 108 | "no_trailing_whitespace": { 109 | "level": "ignore", 110 | "allowed_in_comments": false, 111 | "allowed_in_empty_lines": true 112 | }, 113 | "no_unnecessary_double_quotes": { 114 | "level": "ignore" 115 | }, 116 | "no_unnecessary_fat_arrows": { 117 | "level": "warn" 118 | }, 119 | "non_empty_constructor_needs_parens": { 120 | "level": "ignore" 121 | }, 122 | "prefer_english_operator": { 123 | "level": "ignore", 124 | "doubleNotLevel": "ignore" 125 | }, 126 | "space_operators": { 127 | "level": "ignore" 128 | }, 129 | "spacing_after_comma": { 130 | "level": "ignore" 131 | }, 132 | "transform_messes_up_line_numbers": { 133 | "level": "warn" 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/transpiler-task.coffee: -------------------------------------------------------------------------------- 1 | # language-babel transpiles run here. 2 | # This runs as a separate task so that transpiles can have their own environment. 3 | module.exports = (projectPath) -> 4 | path = require 'path' 5 | callback = @async() #async task 6 | process.chdir(projectPath) 7 | # require babel-core package for this project 8 | projectBabelCore = path.normalize( path.join( projectPath, '/node_modules/babel-core')) 9 | try 10 | babel = require projectBabelCore 11 | catch 12 | # babel core version not found revert to the global 13 | projectBabelCore = '../node_modules/babel-core' 14 | babel = require projectBabelCore 15 | 16 | babelCoreUsed = "Using babel-core at\n#{require.resolve projectBabelCore}" 17 | 18 | process.on 'message', (mObj) -> 19 | if mObj.command is 'transpile' 20 | try 21 | babel.transformFile mObj.pathTo.sourceFile, mObj.babelOptions, (err,result) => 22 | # fiddly formating a return 23 | msgRet = {} 24 | msgRet.reqId = mObj.reqId # send back to reqId 25 | if err 26 | msgRet.err = {} 27 | if err.loc then msgRet.err.loc = err.loc 28 | if err.codeFrame 29 | msgRet.err.codeFrame = err.codeFrame 30 | else msgRet.err.codeFrame = "" 31 | msgRet.err.message = err.message 32 | if result 33 | msgRet.result = result 34 | msgRet.result.ast = null; # ast seems to create a JSON circular ref on emit 35 | msgRet.babelVersion = babel.version 36 | msgRet.babelCoreUsed = babelCoreUsed 37 | emit "transpile:#{mObj.reqId}", msgRet 38 | # if this file transpilation isn't in a Atom project folder then term this task 39 | # as this is normally an Ad-hoc file transpile. 40 | if not mObj.pathTo.sourceFileInProject 41 | callback() 42 | catch err 43 | msgRet = {} 44 | msgRet.reqId = mObj.reqId # send back to reqId 45 | msgRet.err = {} 46 | msgRet.err.message = err.message 47 | msgRet.err.stack = err.stack 48 | msgRet.babelCoreUsed = babelCoreUsed 49 | emit "transpile:#{mObj.reqId}", msgRet 50 | callback() 51 | 52 | # used for preview 53 | if mObj.command is 'transpileCode' 54 | try 55 | msgRet = babel.transform mObj.code, mObj.babelOptions 56 | # fiddly formating a return 57 | msgRet.babelVersion = babel.version 58 | msgRet.babelCoreUsed = babelCoreUsed 59 | emit "transpile:#{mObj.reqId}", msgRet 60 | # if this file transpilation isn't in a Atom project folder then term this task 61 | # as this is normally an Ad-hoc file transpile. 62 | if not mObj.pathTo.sourceFileInProject 63 | callback() 64 | catch err 65 | msgRet = {} 66 | msgRet.reqId = mObj.reqId # send back to reqId 67 | msgRet.err = {} 68 | msgRet.err.message = err.message 69 | msgRet.err.stack = err.stack 70 | msgRet.babelVersion = babel.version 71 | msgRet.babelCoreUsed = babelCoreUsed 72 | emit "transpile:#{mObj.reqId}", msgRet 73 | callback() 74 | 75 | #stop issued stop process 76 | if mObj.command is 'stop' 77 | callback() 78 | -------------------------------------------------------------------------------- /grammars/Babel Regex.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Regular Expressions (Babel)", 3 | "scopeName": "source.regexp.babel", 4 | "fileTypes": [ 5 | "re" 6 | ], 7 | "patterns": [ 8 | { "include": "#anchor"}, 9 | { "include": "#backref"}, 10 | { "include": "#quantifier"}, 11 | { "include": "#operator"}, 12 | { "include": "#group-assertion"}, 13 | { "include": "#group-definition"}, 14 | { "include": "#character-class-definition" }, 15 | { "include": "#character-class" } 16 | ], 17 | "repository": { 18 | "character-class-definition": { 19 | "patterns": [{ 20 | "name": "constant.other.character-class.set.regexp", 21 | "begin": "(\\[)(\\^)?", 22 | "end": "(\\])", 23 | "beginCaptures": { 24 | "1": { "name": "punctuation.definition.character-class.regexp" }, 25 | "2": { "name": "keyword.operator.negation.regexp" } 26 | }, 27 | "endCaptures": { 28 | "1": { 29 | "name": "punctuation.definition.character-class.regexp" 30 | } 31 | }, 32 | "patterns": 33 | [ 34 | { 35 | "name": "constant.other.character-class.range.regexp", 36 | "match": "((\\\\[wWsSdD]|\\.)|(\\\\([trnvf0]|c[A-Z]|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u\\{[\\da-fA-F]+\\}|.)|([^\\]\\s])))(\\-)((\\\\[wWsSdD]|\\.)|(\\\\([trnvf0]|c[A-Z]|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u\\{[\\da-fA-F]+\\}|.)|([^\\]\\s])))", 37 | "captures": 38 | { 39 | "2": { "name": "constant.character.escape.backslash.regexp" }, 40 | "3": { "name": "constant.character.escape.backslash.regexp" }, 41 | "5": { "name": "constant.character.regexp" }, 42 | "6": { "name": "punctuation.definition.range.regexp" }, 43 | "8": { "name": "constant.character.escape.backslash.regexp" }, 44 | "9": { "name": "constant.character.escape.backslash.regexp" }, 45 | "11": { "name": "constant.character.regexp" } 46 | } 47 | }, 48 | { "include": "#character-class" } 49 | ] 50 | }] 51 | }, 52 | "group-assertion": { 53 | "patterns": [{ 54 | "begin": "(\\()((\\?=)|(\\?!))", 55 | "end": "(\\))", 56 | "name": "meta.group.assertion.regexp", 57 | "endCaptures": { 58 | "1": { 59 | "name": "punctuation.definition.group.regexp" 60 | } 61 | }, 62 | "beginCaptures": { 63 | "1": { "name": "punctuation.definition.group.regexp" }, 64 | "2": { "name": "punctuation.definition.group.assertion.regexp" }, 65 | "3": { "name": "meta.assertion.look-ahead.regexp" }, 66 | "4": { "name": "meta.assertion.negative-look-ahead.regexp" } 67 | }, 68 | "patterns": [{ 69 | "include": "$self" 70 | }] 71 | }] 72 | }, 73 | "anchor": { 74 | "patterns": [{ 75 | "name": "keyword.control.anchor.regexp", 76 | "match": "\\\\[bB]|\\^|\\$" 77 | }] 78 | }, 79 | "operator": { 80 | "patterns": [{ 81 | "name": "keyword.operator.or.regexp", 82 | "match": "\\|" 83 | }] 84 | }, 85 | "group-definition": { 86 | "patterns": [{ 87 | "begin": "(\\()((\\?:))?", 88 | "end": "(\\))", 89 | "name": "meta.group.regexp", 90 | "endCaptures": { 91 | "1": { "name": "punctuation.definition.group.regexp" } 92 | }, 93 | "beginCaptures": { 94 | "1": { "name": "punctuation.definition.group.regexp" }, 95 | "3": { "name": "punctuation.definition.group.capture.regexp" }, 96 | "5": { "name": "punctuation.definition.group.capture.regexp" }, 97 | "6": { "name": "punctuation.definition.group.no-capture.regexp" } 98 | }, 99 | "patterns": [{ 100 | "include": "$self" 101 | }] 102 | }] 103 | }, 104 | "quantifier": { 105 | "patterns": [{ 106 | "name": "keyword.operator.quantifier.regexp", 107 | "match": "(\\?|\\*\\??|\\+\\??)|\\{(\\d+,\\d+|\\d+,|\\d+)\\}" 108 | }] 109 | }, 110 | "backref": { 111 | "patterns": [{ 112 | "name": "keyword.other.back-reference.regexp", 113 | "match": "\\\\[1-9][0-9]*" 114 | }] 115 | }, 116 | "character-class": { 117 | "patterns": [{ 118 | "name": "constant.character.escape.backslash.regexp", 119 | "match": "\\\\[wWsSdD]" 120 | }, { 121 | "match": "(\\\\([trnvf0\\\\]|c[A-Z]|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u\\{[\\da-fA-F]+\\}|.))", 122 | "captures": { 123 | "1": { "name": "constant.character.escape.backslash.regexp" } 124 | } 125 | }] 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /lib/auto-complete-jsx.coffee: -------------------------------------------------------------------------------- 1 | {Range, Point} = require "atom" 2 | {filter, score} = require "fuzzaldrin" 3 | 4 | # tags we are interested in are marked by the grammar 5 | JSXSTARTTAGEND = 0 6 | JSXENDTAGSTART = 1 7 | JSXTAG = 2 8 | JSXATTRIBUTE = 3 9 | # regex to search for tag open/close tag and close tag 10 | JSXREGEXP = /(?:(<)|(<\/))([$_A-Za-z](?:[$._:\-a-zA-Z0-9])*)|(?:(\/>)|(>))/g 11 | TAGREGEXP = /<([$_a-zA-Z][$._:\-a-zA-Z0-9]*)(\s|\/>|>)/g 12 | COMPLETIONS = require "./completions-jsx" 13 | REACTURL = "http://facebook.github.io/react/docs/tags-and-attributes.html" 14 | 15 | module.exports = 16 | selector: ".meta.tag.jsx" 17 | inclusionPriority: 10000 18 | excludeLowerPriority: false 19 | 20 | 21 | getSuggestions: (opts) -> 22 | {editor, bufferPosition, scopeDescriptor, prefix} = opts 23 | return if editor.getGrammar().packageName isnt "language-babel" 24 | 25 | jsxTag = @getTriggerTag editor, bufferPosition 26 | return if not jsxTag? 27 | 28 | # build autocomplete list 29 | suggestions = [] 30 | 31 | if jsxTag is JSXSTARTTAGEND 32 | startOfJSX = @getStartOfJSX editor, bufferPosition 33 | jsxRange = new Range(startOfJSX, bufferPosition) 34 | tagNameStack = @buildTagStack(editor, jsxRange) 35 | while ( tagName = tagNameStack.pop())? 36 | suggestions.push 37 | snippet: "$1" 38 | type: "tag" 39 | description: "language-babel tag closer" 40 | 41 | else if jsxTag is JSXENDTAGSTART 42 | startOfJSX = @getStartOfJSX editor, bufferPosition 43 | jsxRange = new Range(startOfJSX, bufferPosition) 44 | tagNameStack = @buildTagStack(editor, jsxRange) 45 | while ( tagName = tagNameStack.pop())? 46 | suggestions.push 47 | snippet: "#{tagName}>" 48 | type: "tag" 49 | description: "language-babel tag closer" 50 | 51 | else if jsxTag is JSXTAG 52 | return if not /^[a-z]/g.exec(prefix) 53 | htmlElements = filter(COMPLETIONS.htmlElements, prefix, {key: "name"}) 54 | for htmlElement in htmlElements 55 | if score(htmlElement.name, prefix) < 0.07 then continue 56 | suggestions.push 57 | snippet: htmlElement.name 58 | type: "tag" 59 | description: "language-babel JSX supported elements" 60 | descriptionMoreURL: REACTURL 61 | 62 | else if jsxTag is JSXATTRIBUTE 63 | tagName = @getThisTagName editor, bufferPosition 64 | return if not tagName? 65 | for elementObj in COMPLETIONS.htmlElements 66 | if elementObj.name is tagName then break 67 | elementObj.attributes = elementObj.attributes.concat COMPLETIONS.globalAttributes 68 | elementObj.attributes = elementObj.attributes.concat COMPLETIONS.events 69 | filteredAttributes = filter(elementObj.attributes, prefix, {key: "name"}) 70 | for attribute in filteredAttributes 71 | if score(attribute.name, prefix) < 0.07 then continue 72 | suggestions.push 73 | snippet: attribute.name 74 | type: "attribute" 75 | rightLabel: "<#{tagName}>" 76 | description: "language-babel JSXsupported attributes/events" 77 | descriptionMoreURL: REACTURL 78 | 79 | else return 80 | suggestions 81 | 82 | # get tagname for this attribute 83 | getThisTagName: ( editor, bufferPosition) -> 84 | row = bufferPosition.row 85 | column = null 86 | while row >= 0 87 | rowText = editor.lineTextForBufferRow(row) 88 | if not column? 89 | rowText = rowText.substr 0, column = bufferPosition.column 90 | matches = [] 91 | while (( match = TAGREGEXP.exec(rowText)) isnt null ) 92 | # save this match if it a valid tag 93 | scopes = editor.scopeDescriptorForBufferPosition([row, match.index+1]).getScopesArray() 94 | if "entity.name.tag.open.jsx" in scopes then matches.push match[1] 95 | # return the tag that is the last one found 96 | if matches 97 | return matches.pop() 98 | else row-- 99 | 100 | 101 | getTriggerTag: (editor, bufferPosition) -> 102 | # JSX tag scopes we are interested in may already closed once typed 103 | # so we have to backtrack by one char to see if they were typed 104 | column = bufferPosition.column-1 105 | if column >= 0 106 | scopes = editor.scopeDescriptorForBufferPosition([bufferPosition.row, column]).getScopesArray() 107 | if "entity.other.attribute-name.jsx" in scopes then return JSXATTRIBUTE 108 | if "entity.name.tag.open.jsx" in scopes then return JSXTAG 109 | if "JSXStartTagEnd" in scopes then return JSXSTARTTAGEND 110 | if "JSXEndTagStart" in scopes then return JSXENDTAGSTART 111 | 112 | 113 | # find beggining of JSX in buffer and return Point 114 | getStartOfJSX: (editor, bufferPosition) -> 115 | row = bufferPosition.row 116 | # find previous start of row that has no jsx tag 117 | while row >= 0 118 | break if "meta.tag.jsx" not in editor.scopeDescriptorForBufferPosition([row, 0]).getScopesArray() 119 | row-- 120 | if row < 0 then row = 0 121 | # maybe jsx appaears later in row 122 | columnLen = editor.lineTextForBufferRow(row).length 123 | column = 0 124 | while column < columnLen 125 | break if "meta.tag.jsx" in editor.scopeDescriptorForBufferPosition([row, column]).getScopesArray() 126 | column++ 127 | # adjust row column if jsx not in this row at all 128 | if column is columnLen 129 | row++ 130 | column = 0 131 | new Point(row, column) 132 | 133 | # build stack of tagnames opened but not closed in Range 134 | buildTagStack: (editor, range) -> 135 | tagNameStack = [] 136 | row = range.start.row 137 | while row <= range.end.row 138 | line = editor.lineTextForBufferRow row 139 | while (( match = JSXREGEXP.exec(line)) isnt null ) 140 | matchColumn = match.index 141 | matchPointStart = new Point(row, matchColumn) 142 | matchPointEnd = new Point(row, matchColumn + match[0].length - 1) 143 | matchRange = new Range(matchPointStart, matchPointEnd) 144 | if range.intersectsWith(matchRange) 145 | scopes = editor.scopeDescriptorForBufferPosition([row, match.index]).getScopesArray() 146 | continue if "punctuation.definition.tag.jsx" not in scopes 147 | #check capture groups 148 | if match[1]? # tags starting 155 | tagNameStack.pop() 156 | row++ 157 | tagNameStack 158 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/babel-sublime/js-class.js: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | 3 | class MyClass { 4 | // <- meta.class.js storage.type.class.js 5 | // <- meta.class.js storage.type.class.js 6 | //^^^ meta.class.js 7 | //^^^ storage.type.class.js 8 | // ^^^^^^^ entity.name.class.js 9 | // ^ punctuation.section.class.begin.js 10 | regularMethod() {} 11 | //^^^^^^^^^^^^^^^ ^^ meta.class.body.js 12 | //^^^^^^^^^^^^^^^ meta.function.method.js 13 | //^^^^^^^^^^^^^ entity.name.function.method.js 14 | // ^ punctuation.definition.parameters.begin.js 15 | // ^ punctuation.definition.parameters.end.js 16 | // ^^ meta.brace.curly.js 17 | *generatorMethod() {} 18 | //^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 19 | //^^^^^^^^^^^^^^^^^^ meta.function.method.js 20 | //^ keyword.generator.asterisk.js 21 | // ^^^^^^^^^^^^^^^ entity.name.function.method.js 22 | // ^ punctuation.definition.parameters.begin.js 23 | // ^ punctuation.definition.parameters.end.js 24 | // ^^ meta.brace.curly.js 25 | static staticRegularMethod() {} 26 | //^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 27 | //^^^^^^ storage.modifier.js 28 | // ^^^^^^^^^^^^^^^^^^^^^ meta.function.method.js 29 | // ^^^^^^^^^^^^^^^^^^^ entity.name.function.method.js 30 | // ^ punctuation.definition.parameters.begin.js 31 | // ^ punctuation.definition.parameters.end.js 32 | // ^^ meta.brace.curly.js 33 | static get staticGetterMethod() {} 34 | //^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 35 | //^^^^^^ storage.modifier.js 36 | // ^^^ ^^^^^^^^^^^^^^^^^^^^ meta.accessor.js 37 | // ^^^ storage.type.accessor.js 38 | // ^^^^^^^^^^^^^^^^^^ entity.name.accessor.js 39 | // ^ punctuation.definition.parameters.begin.js 40 | // ^ punctuation.definition.parameters.end.js 41 | // ^^ meta.brace.curly.js 42 | static set staticSetterMethod(arg) {} 43 | //^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 44 | //^^^^^^ storage.modifier.js 45 | // ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ meta.accessor.js 46 | // ^^^ storage.type.accessor.js 47 | // ^^^^^^^^^^^^^^^^^^ entity.name.accessor.js 48 | // ^ punctuation.definition.parameters.begin.js 49 | // ^^^ variable.other.readwrite.js 50 | // ^ punctuation.definition.parameters.end.js 51 | // ^^ meta.brace.curly.js 52 | static *staticGeneratorMethod() {} 53 | //^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 54 | //^^^^^^ storage.modifier.js 55 | // ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.method.js 56 | // ^ keyword.generator.asterisk.js 57 | // ^^^^^^^^^^^^^^^^^^^^^ entity.name.function.method.js 58 | // ^ punctuation.definition.parameters.begin.js 59 | // ^ punctuation.definition.parameters.end.js 60 | // ^^ meta.brace.curly.js 61 | static async staticAsyncMethod() {} 62 | //^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 63 | //^^^^^^ storage.modifier.js 64 | // ^^^^^ ^^^^^^^^^^^^^^^^^^^ meta.function.method.js 65 | // ^^^^^ storage.type.js 66 | // ^^^^^^^^^^^^^^^^^ entity.name.function.method.js 67 | // ^ punctuation.definition.parameters.begin.js 68 | // ^ punctuation.definition.parameters.end.js 69 | // ^^ meta.brace.curly.js 70 | async asyncMethod() {} 71 | //^^^^^ ^^^^^^^^^^^^^ ^^ meta.class.body.js 72 | //^^^^^ ^^^^^^^^^^^^^ meta.function.method.js 73 | //^^^^^ storage.type.js 74 | // ^^^^^^^^^^^ entity.name.function.method.js 75 | // ^ punctuation.definition.parameters.begin.js 76 | // ^ punctuation.definition.parameters.end.js 77 | // ^^ meta.brace.curly.js 78 | [computedMethod()]() {} 79 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 80 | //^^^^^^^^^^^^^^^^^^^^ meta.function.method.js 81 | //^ ^ meta.brace.square.js 82 | // ^^^^^^^^^^^^^^^^ meta.function-call.without-arguments.js 83 | // ^^^^^^^^^^^^^^ entity.name.function.js 84 | // ^^ meta.brace.round.js 85 | // ^ punctuation.definition.parameters.begin.js 86 | // ^ punctuation.definition.parameters.end.js 87 | // ^^ meta.brace.curly.js 88 | ["computedString"]() {} 89 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 90 | //^^^^^^^^^^^^^^^^^^^^ meta.function.method.js 91 | //^ ^ meta.brace.square.js 92 | // ^^^^^^^^^^^^^^^^ string.quoted.double.js 93 | // ^ punctuation.definition.string.begin.js 94 | // ^ punctuation.definition.string.end.js 95 | // ^ punctuation.definition.parameters.begin.js 96 | // ^ punctuation.definition.parameters.end.js 97 | // ^^ meta.brace.curly.js 98 | ["computed" + "String"]() {} 99 | //^^^^^^^^^^^ ^ ^^^^^^^^^^^ ^^ meta.class.body.js 100 | //^^^^^^^^^^^ ^ ^^^^^^^^^^^ meta.function.method.js 101 | //^ ^ meta.brace.square.js 102 | // ^^^^^^^^^^ ^^^^^^^^ string.quoted.double.js 103 | // ^ ^ punctuation.definition.string.begin.js 104 | // ^ ^ punctuation.definition.string.end.js 105 | // ^ keyword.operator.arithmetic.js 106 | // ^ punctuation.definition.parameters.begin.js 107 | // ^ punctuation.definition.parameters.end.js 108 | // ^^ meta.brace.curly.js 109 | *[Symbol.iterator]() {} 110 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 111 | //^^^^^^^^^^^^^^^^^^^^ meta.function.method.js 112 | //^ keyword.generator.asterisk.js 113 | // ^ ^ meta.brace.square.js 114 | // ^^^^^^^^^^^^^^^ meta.property.class.js 115 | // ^^^^^^ variable.other.class.js 116 | // ^ keyword.operator.accessor.js 117 | // ^^^^^^^^ variable.other.property.static.js 118 | // ^ punctuation.definition.parameters.begin.js 119 | // ^ punctuation.definition.parameters.end.js 120 | // ^^ meta.brace.curly.js 121 | } 122 | // <- punctuation.section.class.end.js 123 | 124 | 125 | // >> only:(source.js.jsx) 126 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/babel-sublime/jsx-features.jsx: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | 3 | // tight greater-/less-than operations. 4 | 5 | for (var i=1; i 87 | // <- meta.tag.jsx punctuation.definition.tag.jsx 88 | // <- meta.tag.jsx entity.name.tag.open.jsx 89 | //^^ ^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 90 | // ^ punctuation.definition.tag.jsx 91 | //^^ entity.name.tag.open.jsx 92 | // ^^ ^^^^^^^ ^^ comment.block.js 93 | // ^^ ^^ punctuation.definition.comment.js 94 | // ^^^^^^^ entity.other.attribute-name.jsx 95 | // ^ keyword.operator.assignment.jsx 96 | // ^^^^^^^^^^^^^^ meta.embedded.expression.js 97 | // ^ punctuation.section.embedded.begin.jsx 98 | // ^^^^ variable.language.this.js 99 | // ^ keyword.operator.accessor.js 100 | // ^^^^^^^ meta.property.object.js 101 | // ^^^^^^^ variable.other.property.js 102 | // ^ punctuation.section.embedded.end.jsx 103 | // ^ JSXStartTagEnd 104 | 105 | //^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.tag.jsx 106 | //^ ^^ punctuation.definition.tag.jsx 107 | // ^^^^^^^^^^^^^^^^^^^^^^ entity.name.tag.open.jsx 108 | 133 | // ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 134 | // ^^^^^^^^^ entity.other.attribute-name.jsx 135 | // ^ keyword.operator.assignment.jsx 136 | // ^^^^^^^^^^^^^^ string.quoted.single.js 137 | // ^ punctuation.definition.string.begin.jsx 138 | // ^ punctuation.definition.string.end.jsx 139 | // ^ punctuation.definition.tag.jsx 140 | // ^ JSXStartTagEnd 141 | 142 | //^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 143 | //^^ ^ punctuation.definition.tag.jsx 144 | //^^ JSXEndTagStart 145 | // ^^^^^^^^^^^^^^^^^ entity.name.tag.close.jsx 146 | 147 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 148 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 149 | //^^^^ meta.tag.jsx 150 | // ^ punctuation.definition.tag.jsx 151 | //^^^ entity.name.tag.close.jsx 152 | 153 | // >> only:source.js.jsx 154 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/misc.js: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | 3 | // class fields, statics and methods 4 | class SomeClass { 5 | myProperty: string = 'some value' 6 | //^^^^^^^^^^^ ^^^^^^ ^ ^^^^^ ^^^^^^ meta.class.body.js 7 | //^^^^^^^^^^ variable.other.readwrite.js 8 | // ^ punctuation.type.flowtype 9 | // ^^^^^^ support.type.builtin.primitive.flowtype 10 | // ^ keyword.operator.assignment.js 11 | // ^^^^^ ^^^^^^ string.quoted.single.js 12 | // ^ punctuation.definition.string.begin.js 13 | // ^ punctuation.definition.string.end.js 14 | xxx: number = 1 15 | //^^^^ ^^^^^^ ^ ^ meta.class.body.js 16 | //^^^ variable.other.readwrite.js 17 | // ^ punctuation.type.flowtype 18 | // ^^^^^^ support.type.builtin.primitive.flowtype 19 | // ^ keyword.operator.assignment.js 20 | // ^ constant.numeric.js 21 | declare = "aaaa" 22 | //^^^^^^^ ^ ^^^^^^ meta.class.body.js 23 | //^^^^^^^ variable.other.readwrite.js 24 | // ^ keyword.operator.assignment.js 25 | // ^^^^^^ string.quoted.double.js 26 | // ^ punctuation.definition.string.begin.js 27 | // ^ punctuation.definition.string.end.js 28 | static anamedVar 29 | //^^^^^^ ^^^^^^^^^ meta.class.body.js 30 | //^^^^^^ storage.modifier.js 31 | // ^^^^^^^^^ variable.other.readwrite.js 32 | anotherVar 33 | //^^^^^^^^^^ meta.class.body.js 34 | //^^^^^^^^^^ variable.other.readwrite.js 35 | [a]() {} 36 | //^^^^^ ^^ meta.class.body.js 37 | //^^^^^ meta.function.method.js 38 | //^ ^ meta.brace.square.js 39 | // ^ variable.other.readwrite.js 40 | // ^ punctuation.definition.parameters.begin.js 41 | // ^ punctuation.definition.parameters.end.js 42 | // ^^ meta.brace.curly.js 43 | 'aaa'() {} 44 | //^^^^^^^ ^^ meta.class.body.js 45 | //^^^^^^^ meta.function.method.js 46 | //^^^^^ entity.name.function.method.js 47 | // ^ punctuation.definition.parameters.begin.js 48 | // ^ punctuation.definition.parameters.end.js 49 | // ^^ meta.brace.curly.js 50 | type: (a)=>string = function() { return ('any' + ' ' + 'expression'); } 51 | //^^^^^ ^^^^^^^^^^^ ^ ^^^^^^^^^^ ^ ^^^^^^ ^^^^^^ ^ ^ ^ ^ ^^^^^^^^^^^^^^ ^ meta.class.body.js 52 | //^^^^ ^^^^^^^^ storage.type.function.js 53 | // ^ punctuation.type.flowtype 54 | // ^ ^ punctuation.definition.parameters.begin.js 55 | // ^ variable.other.readwrite.js 56 | // ^ ^ punctuation.definition.parameters.end.js 57 | // ^^ storage.type.function.arrow.js 58 | // ^^^^^^ support.type.builtin.primitive.flowtype 59 | // ^ keyword.operator.assignment.js 60 | // ^^^^^^^^^^ meta.function.js 61 | // ^ ^ meta.brace.curly.js 62 | // ^^^^^^ keyword.control.flow.js 63 | // ^ ^ meta.brace.round.js 64 | // ^^^^^ ^ ^ ^^^^^^^^^^^^ string.quoted.single.js 65 | // ^ ^ ^ punctuation.definition.string.begin.js 66 | // ^ ^ ^ punctuation.definition.string.end.js 67 | // ^ ^ keyword.operator.arithmetic.js 68 | // ^ punctuation.terminator.statement.js 69 | } 70 | 71 | // labels with function calls 72 | const foo = { 73 | bar: baz() 74 | //^^^^ constant.other.object.key.js 75 | //^^^ string.unquoted.js 76 | // ^ punctuation.separator.key-value.js 77 | // ^^^^^ meta.function-call.without-arguments.js 78 | // ^^^ entity.name.function.js 79 | // ^^ meta.brace.round.js 80 | }; 81 | 82 | // $JSXIntrinsics is special and magic. 83 | // This declares the types a `span` 84 | type $JSXIntrinsics = { 85 | span: JSXHelper<{id: string, class: string}> }; 86 | //^^^^ variable.other.readwrite.js 87 | // ^ ^ ^ punctuation.type.flowtype 88 | // ^^^^^^^^^ support.type.class.flowtype 89 | // ^ ^ punctutation.flowtype 90 | // ^ meta.brace.round.open.flowtype 91 | // ^^ ^^^^^ variable.other.property.flowtype 92 | // ^^^^^^ ^^^^^^ support.type.builtin.primitive.flowtype 93 | // ^ meta.delimiter.comma.js 94 | // ^ meta.brace.round.close.flowtype 95 | // ^ meta.brace.curly.js 96 | // ^ punctuation.object.end.flowtype 97 | 98 | 99 | // Some JSX 100 | 101 |
102 | // <- meta.tag.jsx punctuation.definition.tag.jsx 103 | // <- meta.tag.jsx entity.name.tag.open.jsx 104 | //^^^ meta.tag.jsx 105 | // ^ punctuation.definition.tag.jsx 106 | //^^ entity.name.tag.open.jsx 107 | // ^ JSXStartTagEnd 108 |
109 | //^^^^ ^^ meta.tag.jsx 110 | //^ ^^ punctuation.definition.tag.jsx 111 | // ^^^ entity.name.tag.open.jsx 112 |

113 | //^^^^^^^^^ meta.tag.jsx 114 | //^ ^^^ ^ punctuation.definition.tag.jsx 115 | // ^^ entity.name.tag.open.jsx 116 | // ^ JSXStartTagEnd 117 | // ^^ JSXEndTagStart 118 | // ^^ entity.name.tag.close.jsx 119 | 120 | //^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 121 | //^ ^^^ ^ punctuation.definition.tag.jsx 122 | // ^^^^^^^^^ entity.name.tag.open.jsx 123 | // ^^^^^^^^^ support.class.component.open.jsx 124 | // ^ JSXStartTagEnd 125 | // ^^ JSXEndTagStart 126 | // ^^^^^^^^^ entity.name.tag.close.jsx 127 | // ^^^^^^^^^ support.class.component.close.jsx 128 | 129 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 130 | //^ ^^^ ^ punctuation.definition.tag.jsx 131 | // ^^^^^^^^^^^^^^ entity.name.tag.open.jsx 132 | // ^^^^^^^^^^^^^^ support.class.component.open.jsx 133 | // ^ JSXStartTagEnd 134 | // ^^ JSXEndTagStart 135 | // ^^^^^^^^^^^^^^ entity.name.tag.close.jsx 136 | // ^^^^^^^^^^^^^^ support.class.component.close.jsx 137 | 138 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 139 | //^ ^^^ ^ punctuation.definition.tag.jsx 140 | // ^^^^^^^^^^^^^^^^^^^ entity.name.tag.open.jsx 141 | // ^^^^^^^^^^^^^^^^^^^ support.class.component.open.jsx 142 | // ^ JSXStartTagEnd 143 | // ^^ JSXEndTagStart 144 | // ^^^^^^^^^^^^^^^^^^^ entity.name.tag.close.jsx 145 | // ^^^^^^^^^^^^^^^^^^^ support.class.component.close.jsx 146 | 147 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 148 | //^ ^^^ ^ punctuation.definition.tag.jsx 149 | // ^^^^^^^^^^^^^^ entity.name.tag.open.jsx 150 | // ^^^^^^^^^^^^^^ support.class.component.open.jsx 151 | // ^ JSXStartTagEnd 152 | // ^^ JSXEndTagStart 153 | // ^^^^^^^^^^^^^^ entity.name.tag.close.jsx 154 | // ^^^^^^^^^^^^^^ support.class.component.close.jsx 155 |
156 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 157 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 158 | //^^^^ meta.tag.jsx 159 | // ^ punctuation.definition.tag.jsx 160 | //^^^ entity.name.tag.close.jsx 161 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/declare.js: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | 3 | declare module 'a-unique-module-name' { 4 | declare interface Stack {} 5 | //^^^^^^^ ^^^^^^^^^ ^^^^^^^^ ^^ meta.class.body.js 6 | //^^^^^^^ keyword.other.declare.flowtype 7 | // ^^^^^^^^^ keyword.other.interface.flowtype 8 | // ^^^^^ support.type.class.interface.js 9 | // ^ ^ punctutation.flowtype 10 | // ^ support.type.class.flowtype 11 | // ^ punctuation.section.class.begin.js 12 | // ^ punctuation.section.class.end.js 13 | declare class Response extends A mixins A,B {} 14 | //^^^^^^^ ^^^^^ ^^^^^^^^ ^^^^^^^ ^ ^^^^^^ ^^^ ^^ meta.class.body.js 15 | //^^^^^^^ keyword.other.declare.flowtype 16 | // ^^^^^ storage.type.class.flowtype 17 | // ^^^^^^^^ ^ ^ ^ entity.name.class.js 18 | // ^^^^^^^ ^^^^^^ meta.class.extends.js 19 | // ^^^^^^^ ^^^^^^ storage.type.extends.js 20 | // ^ punctuation.section.class.begin.js 21 | // ^ punctuation.section.class.end.js 22 | declare module.exports: () => Function; 23 | //^^^^^^^ ^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^ meta.class.body.js 24 | //^^^^^^^ keyword.other.declare.flowtype 25 | // ^^^^^^ ^^^^^^^ storage.type.module.flowtype 26 | // ^ keyword.operator.accessor.flowtype 27 | // ^ punctuation.type.flowtype 28 | // ^ punctuation.definition.parameters.begin.js 29 | // ^ punctuation.definition.parameters.end.js 30 | // ^^ storage.type.function.arrow.js 31 | // ^^^^^^^^ support.type.builtin.class.flowtype 32 | // ^ punctuation.terminator.statement.js 33 | declare type NextFunction = (error?: Object) => void 34 | //^^^^^^^ ^^^^ ^^^^^^^^^^^^ ^ ^^^^^^^^ ^^^^^^^ ^^ ^^^^ meta.class.body.js 35 | //^^^^^^^ keyword.other.declare.flowtype 36 | // ^^^^ keyword.other.typedef.flowtype 37 | // ^^^^^^^^^^^^ support.type.class.flowtype 38 | // ^ punctuation.definition.parameters.begin.js 39 | // ^^^^^ variable.other.readwrite.js 40 | // ^ keyword.operator.optional.parameter.flowtype 41 | // ^ punctuation.type.flowtype 42 | // ^^^^^^ support.type.builtin.class.flowtype 43 | // ^ punctuation.definition.parameters.end.js 44 | // ^^^^ support.type.builtin.primitive.flowtype 45 | } 46 | // <- meta.class.body.js 47 | 48 | interface Iterator { 49 | // <- keyword.other.interface.flowtype 50 | // <- keyword.other.interface.flowtype 51 | //^^^^^^^ keyword.other.interface.flowtype 52 | // ^^^^^^^^ support.type.class.interface.js 53 | // ^ ^ punctutation.flowtype 54 | // ^ support.type.class.flowtype 55 | // ^ punctuation.section.class.begin.js 56 | next(): IteratorResult 57 | // ^^^^^^^ ^^^^^^^^^^^^^^^^^ meta.class.body.js 58 | // ^^^^^^^ ^^^^^^^^^^^^^^^^^ meta.function.method.js 59 | // ^^^^ entity.name.function.method.js 60 | // ^ punctuation.definition.parameters.begin.js 61 | // ^ punctuation.definition.parameters.end.js 62 | // ^ punctuation.type.flowtype 63 | // ^^^^^^^^^^^^^^ ^ support.type.class.flowtype 64 | // ^ ^ punctutation.flowtype 65 | iterator(): Iterator 66 | // ^^^^^^^^^^^ ^^^^^^^^^^^ meta.class.body.js 67 | // ^^^^^^^^^^^ ^^^^^^^^^^^ meta.function.method.js 68 | // ^^^^^^^^ entity.name.function.method.js 69 | // ^ punctuation.definition.parameters.begin.js 70 | // ^ punctuation.definition.parameters.end.js 71 | // ^ punctuation.type.flowtype 72 | // ^^^^^^^^ ^ support.type.class.flowtype 73 | // ^ ^ punctutation.flowtype 74 | } 75 | // <- punctuation.section.class.end.js 76 | 77 | declare var NaN: number 78 | // <- keyword.other.declare.flowtype 79 | // <- keyword.other.declare.flowtype 80 | //^^^^^ keyword.other.declare.flowtype 81 | // ^^^ storage.type.js 82 | // ^^^ variable.other.readwrite.js 83 | // ^ punctuation.type.flowtype 84 | // ^^^^^^ support.type.builtin.primitive.flowtype 85 | 86 | declare var module: { 87 | // <- keyword.other.declare.flowtype 88 | // <- keyword.other.declare.flowtype 89 | //^^^^^ keyword.other.declare.flowtype 90 | // ^^^ storage.type.js 91 | // ^^^^^^ variable.other.readwrite.js 92 | // ^ punctuation.type.flowtype 93 | // ^ meta.brace.round.open.flowtype 94 | exports: any; 95 | // ^^^^^^^ variable.other.property.flowtype 96 | // ^ punctuation.type.flowtype 97 | // ^^^ support.type.builtin.primitive.flowtype 98 | require(id: string): any; 99 | // ^^^^^^^^^^^ ^^^^^^^ meta.function-call.with-arguments.js 100 | // ^^^^^^^ entity.name.function.js 101 | // ^ ^ meta.brace.round.js 102 | // ^^ ^^^^^^ variable.other.readwrite.js 103 | // ^ punctuation.type.flowtype 104 | // ^^^ support.type.builtin.primitive.flowtype 105 | id: string; 106 | // ^^ variable.other.property.flowtype 107 | // ^ punctuation.type.flowtype 108 | // ^^^^^^ support.type.builtin.primitive.flowtype 109 | filename: string; 110 | // ^^^^^^^^ variable.other.property.flowtype 111 | // ^ punctuation.type.flowtype 112 | // ^^^^^^ support.type.builtin.primitive.flowtype 113 | loaded: boolean; 114 | // ^^^^^^ variable.other.property.flowtype 115 | // ^ punctuation.type.flowtype 116 | // ^^^^^^^ support.type.builtin.primitive.flowtype 117 | parent: any; 118 | // ^^^^^^ variable.other.property.flowtype 119 | // ^ punctuation.type.flowtype 120 | // ^^^ support.type.builtin.primitive.flowtype 121 | children: Array; 122 | // ^^^^^^^^ variable.other.property.flowtype 123 | // ^ punctuation.type.flowtype 124 | // ^^^^^ support.type.builtin.class.flowtype 125 | // ^ ^ punctuation.flowtype 126 | // ^^^ support.type.builtin.primitive.flowtype 127 | }; 128 | // <- meta.brace.round.close.flowtype 129 | // <- punctuation.terminator.statement.js 130 | 131 | declare class Blob { 132 | // <- keyword.other.declare.flowtype 133 | // <- keyword.other.declare.flowtype 134 | //^^^^^ keyword.other.declare.flowtype 135 | // ^^^^^ storage.type.class.flowtype 136 | // ^^^^ entity.name.class.js 137 | // ^ punctuation.section.class.begin.js 138 | constructor(blobParts?: Array, options?: { 139 | // ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^ meta.class.body.js 140 | // ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^ meta.function.method.js 141 | // ^^^^^^^^^^^ entity.name.function.method.js 142 | // ^ punctuation.definition.parameters.begin.js 143 | // ^^^^^^^^^ ^^^^^^^ variable.other.readwrite.js 144 | // ^ ^ keyword.operator.optional.parameter.flowtype 145 | // ^ ^ punctuation.type.flowtype 146 | // ^^^^^ support.type.builtin.class.flowtype 147 | // ^ ^ punctuation.flowtype 148 | // ^^^ support.type.builtin.primitive.flowtype 149 | // ^ meta.delimiter.comma.js 150 | // ^ meta.brace.round.open.flowtype 151 | type?: string 152 | // ^^^^^^ ^^^^^^ meta.class.body.js 153 | // ^^^^^^ ^^^^^^ meta.function.method.js 154 | // ^^^^ variable.other.property.flowtype 155 | // ^ keyword.operator.optional.parameter.flowtype 156 | // ^ punctuation.type.flowtype 157 | // ^^^^^^ support.type.builtin.primitive.flowtype 158 | endings?: string 159 | // ^^^^^^^^^ ^^^^^^ meta.class.body.js 160 | // ^^^^^^^^^ ^^^^^^ meta.function.method.js 161 | // ^^^^^^^ variable.other.property.flowtype 162 | // ^ keyword.operator.optional.parameter.flowtype 163 | // ^ punctuation.type.flowtype 164 | // ^^^^^^ support.type.builtin.primitive.flowtype 165 | }): void 166 | // ^^^ ^^^^ meta.class.body.js 167 | // ^^^ ^^^^ meta.function.method.js 168 | // ^ meta.brace.round.close.flowtype 169 | // ^ punctuation.definition.parameters.end.js 170 | // ^ punctuation.type.flowtype 171 | // ^^^^ support.type.builtin.primitive.flowtype 172 | type: string 173 | // ^^^^^ ^^^^^^ meta.class.body.js 174 | // ^^^^ variable.other.readwrite.js 175 | // ^ punctuation.type.flowtype 176 | // ^^^^^^ support.type.builtin.primitive.flowtype 177 | size: number 178 | // ^^^^^ ^^^^^^ meta.class.body.js 179 | // ^^^^ variable.other.readwrite.js 180 | // ^ punctuation.type.flowtype 181 | // ^^^^^^ support.type.builtin.primitive.flowtype 182 | slice(start?: number, end?: number, contentType?: string): Blob 183 | // ^^^^^^^^^^^^^ ^^^^^^^ ^^^^^ ^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^ ^^^^ meta.class.body.js 184 | // ^^^^^^^^^^^^^ ^^^^^^^ ^^^^^ ^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^ ^^^^ meta.function.method.js 185 | // ^^^^^ entity.name.function.method.js 186 | // ^ punctuation.definition.parameters.begin.js 187 | // ^^^^^ ^^^ ^^^^^^^^^^^ variable.other.readwrite.js 188 | // ^ ^ ^ keyword.operator.optional.parameter.flowtype 189 | // ^ ^ ^ ^ punctuation.type.flowtype 190 | // ^^^^^^ ^^^^^^ ^^^^^^ support.type.builtin.primitive.flowtype 191 | // ^ ^ meta.delimiter.comma.js 192 | // ^ punctuation.definition.parameters.end.js 193 | // ^^^^ support.type.class.flowtype 194 | } 195 | // <- punctuation.section.class.end.js 196 | 197 | type CanvasImageSource = HTMLImageElement | number & string 198 | // <- keyword.other.typedef.flowtype 199 | // <- keyword.other.typedef.flowtype 200 | //^^ keyword.other.typedef.flowtype 201 | // ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ support.type.class.flowtype 202 | // ^ kewyword.operator.union.flowtype 203 | // ^^^^^^ ^^^^^^ support.type.builtin.primitive.flowtype 204 | // ^ kewyword.operator.intersection.flowtype 205 | 206 | type child_process$execOpts = { 207 | // <- keyword.other.typedef.flowtype 208 | // <- keyword.other.typedef.flowtype 209 | //^^ keyword.other.typedef.flowtype 210 | // ^^^^^^^^^^^^^^^^^^^^^^ support.type.primitive.flowtype 211 | // ^ meta.brace.curly.js 212 | cwd?: string 213 | //^^^ variable.other.readwrite.js 214 | // ^ keyword.operator.optional.parameter.flowtype 215 | // ^ punctuation.type.flowtype 216 | // ^^^^^^ support.type.builtin.primitive.flowtype 217 | env?: Object 218 | //^^^ variable.other.readwrite.js 219 | // ^ keyword.operator.optional.parameter.flowtype 220 | // ^ punctuation.type.flowtype 221 | // ^^^^^^ support.type.builtin.class.flowtype 222 | }; 223 | // <- meta.brace.curly.js 224 | // <- punctuation.object.end.flowtype 225 | 226 | type ReactClass = _ReactClass 227 | // <- keyword.other.typedef.flowtype 228 | // <- keyword.other.typedef.flowtype 229 | //^^ keyword.other.typedef.flowtype 230 | // ^^^^^^^^^^ ^ ^ ^ ^^^^^^^^^^^ ^ ^ ^ support.type.class.flowtype 231 | // ^ ^ ^ ^ punctutation.flowtype 232 | // ^ ^ ^ ^ ^ meta.delimiter.comma.js 233 | // ^ kewyword.operator.existential.flowtype 234 | 235 | declare function require(id: string): any; 236 | // <- keyword.other.declare.flowtype 237 | // <- keyword.other.declare.flowtype 238 | //^^^^^ keyword.other.declare.flowtype 239 | // ^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^ ^^^ meta.function.js 240 | // ^^^^^^^^ storage.type.function.js 241 | // ^^^^^^^ entity.name.function.js 242 | // ^ punctuation.definition.parameters.begin.js 243 | // ^^ variable.other.readwrite.js 244 | // ^ ^ punctuation.type.flowtype 245 | // ^^^^^^ ^^^ support.type.builtin.primitive.flowtype 246 | // ^ punctuation.definition.parameters.end.js 247 | // ^ punctuation.terminator.statement.js 248 | 249 | // >> only:(source.js.jsx) 250 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/babel-sublime/js-symbols.js: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | 3 | A = function() {} 4 | // <- meta.function.js entity.name.function.js 5 | //^ ^^^^^^^^^^ meta.function.js 6 | //^ keyword.operator.assignment.js 7 | // ^^^^^^^^ storage.type.function.js 8 | // ^ punctuation.definition.parameters.begin.js 9 | // ^ punctuation.definition.parameters.end.js 10 | // ^^ meta.brace.curly.js 11 | B = function(z) {} 12 | // <- meta.function.js entity.name.function.js 13 | //^ ^^^^^^^^^^^ meta.function.js 14 | //^ keyword.operator.assignment.js 15 | // ^^^^^^^^ storage.type.function.js 16 | // ^ punctuation.definition.parameters.begin.js 17 | // ^ variable.other.readwrite.js 18 | // ^ punctuation.definition.parameters.end.js 19 | // ^^ meta.brace.curly.js 20 | C = function c() {} 21 | // <- meta.function.js entity.name.function.js 22 | //^ ^^^^^^^^ ^^^ meta.function.js 23 | // ^ entity.name.function.js 24 | //^ keyword.operator.assignment.js 25 | // ^^^^^^^^ storage.type.function.js 26 | // ^ punctuation.definition.parameters.begin.js 27 | // ^ punctuation.definition.parameters.end.js 28 | // ^^ meta.brace.curly.js 29 | D = function d(z) {} 30 | // <- meta.function.js entity.name.function.js 31 | //^ ^^^^^^^^ ^^^^ meta.function.js 32 | // ^ entity.name.function.js 33 | //^ keyword.operator.assignment.js 34 | // ^^^^^^^^ storage.type.function.js 35 | // ^ punctuation.definition.parameters.begin.js 36 | // ^ variable.other.readwrite.js 37 | // ^ punctuation.definition.parameters.end.js 38 | // ^^ meta.brace.curly.js 39 | E = () => {} 40 | // <- meta.function.arrow.js entity.name.function.js 41 | //^ ^^ ^^ meta.function.arrow.js 42 | //^ keyword.operator.assignment.js 43 | // ^ punctuation.definition.parameters.begin.js 44 | // ^ punctuation.definition.parameters.end.js 45 | // ^^ storage.type.function.arrow.js 46 | // ^^ meta.brace.curly.js 47 | F = (z) => {} 48 | // <- meta.function.arrow.js entity.name.function.js 49 | //^ ^^^ ^^ meta.function.arrow.js 50 | //^ keyword.operator.assignment.js 51 | // ^ punctuation.definition.parameters.begin.js 52 | // ^ variable.other.readwrite.js 53 | // ^ punctuation.definition.parameters.end.js 54 | // ^^ storage.type.function.arrow.js 55 | // ^^ meta.brace.curly.js 56 | G = z => {} 57 | // <- meta.function.arrow.js entity.name.function.js 58 | //^ ^ ^^ meta.function.arrow.js 59 | //^ keyword.operator.assignment.js 60 | // ^ variable.other.readwrite.js 61 | // ^^ storage.type.function.arrow.js 62 | // ^^ meta.brace.curly.js 63 | function() {} 64 | // <- meta.function.js storage.type.function.js 65 | // <- meta.function.js storage.type.function.js 66 | //^^^^^^^^ meta.function.js 67 | //^^^^^^ storage.type.function.js 68 | // ^ punctuation.definition.parameters.begin.js 69 | // ^ punctuation.definition.parameters.end.js 70 | // ^^ meta.brace.curly.js 71 | function(z) {} 72 | // <- meta.function.js storage.type.function.js 73 | // <- meta.function.js storage.type.function.js 74 | //^^^^^^^^^ meta.function.js 75 | //^^^^^^ storage.type.function.js 76 | // ^ punctuation.definition.parameters.begin.js 77 | // ^ variable.other.readwrite.js 78 | // ^ punctuation.definition.parameters.end.js 79 | // ^^ meta.brace.curly.js 80 | function H() {} 81 | // <- meta.function.js storage.type.function.js 82 | // <- meta.function.js storage.type.function.js 83 | //^^^^^^ ^^^ meta.function.js 84 | //^^^^^^ storage.type.function.js 85 | // ^ entity.name.function.js 86 | // ^ punctuation.definition.parameters.begin.js 87 | // ^ punctuation.definition.parameters.end.js 88 | // ^^ meta.brace.curly.js 89 | function I(z) {} 90 | // <- meta.function.js storage.type.function.js 91 | // <- meta.function.js storage.type.function.js 92 | //^^^^^^ ^^^^ meta.function.js 93 | //^^^^^^ storage.type.function.js 94 | // ^ entity.name.function.js 95 | // ^ punctuation.definition.parameters.begin.js 96 | // ^ variable.other.readwrite.js 97 | // ^ punctuation.definition.parameters.end.js 98 | // ^^ meta.brace.curly.js 99 | () => {} 100 | // <- meta.function.arrow.js punctuation.definition.parameters.begin.js 101 | // <- meta.function.arrow.js punctuation.definition.parameters.end.js 102 | // ^^ meta.function.arrow.js 103 | // ^^ storage.type.function.arrow.js 104 | // ^^ meta.brace.curly.js 105 | (z) => {} 106 | // <- meta.function.arrow.js punctuation.definition.parameters.begin.js 107 | // <- meta.function.arrow.js variable.other.readwrite.js 108 | //^ ^^ meta.function.arrow.js 109 | //^ punctuation.definition.parameters.end.js 110 | // ^^ storage.type.function.arrow.js 111 | // ^^ meta.brace.curly.js 112 | J.prototype.j = () => {} 113 | // <- meta.prototype.function.arrow.js entity.name.class.js 114 | // <- meta.prototype.function.arrow.js keyword.operator.accessor.js 115 | //^^^^^^^^^^^ ^ ^^ ^^ meta.prototype.function.arrow.js 116 | // ^ keyword.operator.accessor.js 117 | //^^^^^^^^^ variable.language.prototype.js 118 | // ^ entity.name.function.js 119 | // ^ keyword.operator.assignment.js 120 | // ^ punctuation.definition.parameters.begin.js 121 | // ^ punctuation.definition.parameters.end.js 122 | // ^^ storage.type.function.arrow.js 123 | // ^^ meta.brace.curly.js 124 | K.prototype.k = (z) => {} 125 | // <- meta.prototype.function.arrow.js entity.name.class.js 126 | // <- meta.prototype.function.arrow.js keyword.operator.accessor.js 127 | //^^^^^^^^^^^ ^ ^^^ ^^ meta.prototype.function.arrow.js 128 | // ^ keyword.operator.accessor.js 129 | //^^^^^^^^^ variable.language.prototype.js 130 | // ^ entity.name.function.js 131 | // ^ keyword.operator.assignment.js 132 | // ^ punctuation.definition.parameters.begin.js 133 | // ^ variable.other.readwrite.js 134 | // ^ punctuation.definition.parameters.end.js 135 | // ^^ storage.type.function.arrow.js 136 | // ^^ meta.brace.curly.js 137 | L.prototype.l = z => {} 138 | // <- meta.prototype.function.arrow.js entity.name.class.js 139 | // <- meta.prototype.function.arrow.js keyword.operator.accessor.js 140 | //^^^^^^^^^^^ ^ ^ ^^ meta.prototype.function.arrow.js 141 | // ^ keyword.operator.accessor.js 142 | //^^^^^^^^^ variable.language.prototype.js 143 | // ^ entity.name.function.js 144 | // ^ keyword.operator.assignment.js 145 | // ^ variable.other.readwrite.js 146 | // ^^ storage.type.function.arrow.js 147 | // ^^ meta.brace.curly.js 148 | M.prototype.m = function() {} 149 | // <- meta.prototype.function.js entity.name.class.js 150 | // <- meta.prototype.function.js keyword.operator.accessor.js 151 | //^^^^^^^^^^^ ^ ^^^^^^^^^^ meta.prototype.function.js 152 | // ^ keyword.operator.accessor.js 153 | //^^^^^^^^^ variable.language.prototype.js 154 | // ^ entity.name.function.js 155 | // ^ keyword.operator.assignment.js 156 | // ^^^^^^^^ storage.type.function.js 157 | // ^ punctuation.definition.parameters.begin.js 158 | // ^ punctuation.definition.parameters.end.js 159 | // ^^ meta.brace.curly.js 160 | N.prototype.n = function(z) {} 161 | // <- meta.prototype.function.js entity.name.class.js 162 | // <- meta.prototype.function.js keyword.operator.accessor.js 163 | //^^^^^^^^^^^ ^ ^^^^^^^^^^^ meta.prototype.function.js 164 | // ^ keyword.operator.accessor.js 165 | //^^^^^^^^^ variable.language.prototype.js 166 | // ^ entity.name.function.js 167 | // ^ keyword.operator.assignment.js 168 | // ^^^^^^^^ storage.type.function.js 169 | // ^ punctuation.definition.parameters.begin.js 170 | // ^ variable.other.readwrite.js 171 | // ^ punctuation.definition.parameters.end.js 172 | // ^^ meta.brace.curly.js 173 | O.prototype.o = function oo() {} 174 | // <- meta.prototype.function.js entity.name.class.js 175 | // <- meta.prototype.function.js keyword.operator.accessor.js 176 | //^^^^^^^^^^^ ^ ^^^^^^^^ ^^^^ meta.prototype.function.js 177 | // ^ keyword.operator.accessor.js 178 | //^^^^^^^^^ variable.language.prototype.js 179 | // ^ ^^ entity.name.function.js 180 | // ^ keyword.operator.assignment.js 181 | // ^^^^^^^^ storage.type.function.js 182 | // ^ punctuation.definition.parameters.begin.js 183 | // ^ punctuation.definition.parameters.end.js 184 | // ^^ meta.brace.curly.js 185 | P.prototype.p = function pp(z) {} 186 | // <- meta.prototype.function.js entity.name.class.js 187 | // <- meta.prototype.function.js keyword.operator.accessor.js 188 | //^^^^^^^^^^^ ^ ^^^^^^^^ ^^^^^ meta.prototype.function.js 189 | // ^ keyword.operator.accessor.js 190 | //^^^^^^^^^ variable.language.prototype.js 191 | // ^ ^^ entity.name.function.js 192 | // ^ keyword.operator.assignment.js 193 | // ^^^^^^^^ storage.type.function.js 194 | // ^ punctuation.definition.parameters.begin.js 195 | // ^ variable.other.readwrite.js 196 | // ^ punctuation.definition.parameters.end.js 197 | // ^^ meta.brace.curly.js 198 | Q.q = () => {} 199 | // <- meta.function.static.arrow.js entity.name.class.js 200 | // <- meta.function.static.arrow.js keyword.operator.accessor.js 201 | //^ ^ ^^ ^^ meta.function.static.arrow.js 202 | //^ entity.name.function.js 203 | // ^ keyword.operator.assignment.js 204 | // ^ punctuation.definition.parameters.begin.js 205 | // ^ punctuation.definition.parameters.end.js 206 | // ^^ storage.type.function.arrow.js 207 | // ^^ meta.brace.curly.js 208 | R.r = (z) => {} 209 | // <- meta.function.static.arrow.js entity.name.class.js 210 | // <- meta.function.static.arrow.js keyword.operator.accessor.js 211 | //^ ^ ^^^ ^^ meta.function.static.arrow.js 212 | //^ entity.name.function.js 213 | // ^ keyword.operator.assignment.js 214 | // ^ punctuation.definition.parameters.begin.js 215 | // ^ variable.other.readwrite.js 216 | // ^ punctuation.definition.parameters.end.js 217 | // ^^ storage.type.function.arrow.js 218 | // ^^ meta.brace.curly.js 219 | S.s = z => {} 220 | // <- meta.function.static.arrow.js entity.name.class.js 221 | // <- meta.function.static.arrow.js keyword.operator.accessor.js 222 | //^ ^ ^ ^^ meta.function.static.arrow.js 223 | //^ entity.name.function.js 224 | // ^ keyword.operator.assignment.js 225 | // ^ variable.other.readwrite.js 226 | // ^^ storage.type.function.arrow.js 227 | // ^^ meta.brace.curly.js 228 | T.t = function() {} 229 | // <- meta.function.static.js entity.name.class.js 230 | // <- meta.function.static.js keyword.operator.accessor.js 231 | //^ ^ ^^^^^^^^^^ meta.function.static.js 232 | //^ entity.name.function.js 233 | // ^ keyword.operator.assignment.js 234 | // ^^^^^^^^ storage.type.function.js 235 | // ^ punctuation.definition.parameters.begin.js 236 | // ^ punctuation.definition.parameters.end.js 237 | // ^^ meta.brace.curly.js 238 | U.u = function(z) {} 239 | // <- meta.function.static.js entity.name.class.js 240 | // <- meta.function.static.js keyword.operator.accessor.js 241 | //^ ^ ^^^^^^^^^^^ meta.function.static.js 242 | //^ entity.name.function.js 243 | // ^ keyword.operator.assignment.js 244 | // ^^^^^^^^ storage.type.function.js 245 | // ^ punctuation.definition.parameters.begin.js 246 | // ^ variable.other.readwrite.js 247 | // ^ punctuation.definition.parameters.end.js 248 | // ^^ meta.brace.curly.js 249 | V.v = function vv() {} 250 | // <- meta.function.static.js entity.name.class.js 251 | // <- meta.function.static.js keyword.operator.accessor.js 252 | //^ ^ ^^^^^^^^ ^^^^ meta.function.static.js 253 | //^ ^^ entity.name.function.js 254 | // ^ keyword.operator.assignment.js 255 | // ^^^^^^^^ storage.type.function.js 256 | // ^ punctuation.definition.parameters.begin.js 257 | // ^ punctuation.definition.parameters.end.js 258 | // ^^ meta.brace.curly.js 259 | W.w = function ww(z) {} 260 | // <- meta.function.static.js entity.name.class.js 261 | // <- meta.function.static.js keyword.operator.accessor.js 262 | //^ ^ ^^^^^^^^ ^^^^^ meta.function.static.js 263 | //^ ^^ entity.name.function.js 264 | // ^ keyword.operator.assignment.js 265 | // ^^^^^^^^ storage.type.function.js 266 | // ^ punctuation.definition.parameters.begin.js 267 | // ^ variable.other.readwrite.js 268 | // ^ punctuation.definition.parameters.end.js 269 | // ^^ meta.brace.curly.js 270 | 271 | class X extends XX {} 272 | // <- meta.class.js storage.type.class.js 273 | // <- meta.class.js storage.type.class.js 274 | //^^^ meta.class.js 275 | //^^^ storage.type.class.js 276 | // ^ ^^ entity.name.class.js 277 | // ^^^^^^^ meta.class.extends.js 278 | // ^^^^^^^ storage.type.extends.js 279 | // ^ punctuation.section.class.begin.js 280 | // ^ punctuation.section.class.end.js 281 | class Y {} 282 | // <- meta.class.js storage.type.class.js 283 | // <- meta.class.js storage.type.class.js 284 | //^^^ meta.class.js 285 | //^^^ storage.type.class.js 286 | // ^ entity.name.class.js 287 | // ^ punctuation.section.class.begin.js 288 | // ^ punctuation.section.class.end.js 289 | 290 | 291 | // >> only:(source.js.jsx) 292 | -------------------------------------------------------------------------------- /lib/completions-jsx.coffee: -------------------------------------------------------------------------------- 1 | module.exports = 2 | 3 | events: [ 4 | { name: 'onCopy' } 5 | { name: 'onCut' } 6 | { name: 'onPaste' } 7 | { name: 'onCompositionEnd' } 8 | { name: 'onCompositionStart' } 9 | { name: 'onCompositionUpdate' } 10 | { name: 'onKeyDown' } 11 | { name: 'onKeyPress' } 12 | { name: 'onKeyUp' } 13 | { name: 'onFocus' } 14 | { name: 'onBlur' } 15 | { name: 'onChange' } 16 | { name: 'onInput' } 17 | { name: 'onSubmit' } 18 | { name: 'onClick' } 19 | { name: 'onContextMenu' } 20 | { name: 'onDoubleClick' } 21 | { name: 'onDrag' } 22 | { name: 'onDragEnd' } 23 | { name: 'onDragEnter' } 24 | { name: 'onDragExit' } 25 | { name: 'onDragLeave' } 26 | { name: 'onDragOver' } 27 | { name: 'onDragStart' } 28 | { name: 'onDrop' } 29 | { name: 'onMouseDown' } 30 | { name: 'onMouseEnter' } 31 | { name: 'onMouseLeave' } 32 | { name: 'onMouseMove' } 33 | { name: 'onMouseOut' } 34 | { name: 'onMouseOver' } 35 | { name: 'onMouseUp' } 36 | { name: 'onSelect' } 37 | { name: 'onTouchCancel' } 38 | { name: 'onTouchEnd' } 39 | { name: 'onTouchMove' } 40 | { name: 'onTouchStart' } 41 | { name: 'onScroll' } 42 | { name: 'onWheel' } 43 | { name: 'onAbort' } 44 | { name: 'onCanPlay' } 45 | { name: 'onCanPlayThrough' } 46 | { name: 'onDurationChange' } 47 | { name: 'onEmptied' } 48 | { name: 'onEncrypted' } 49 | { name: 'onEnded' } 50 | { name: 'onError' } 51 | { name: 'onLoadedData' } 52 | { name: 'onLoadedMetadata' } 53 | { name: 'onLoadStart' } 54 | { name: 'onPause' } 55 | { name: 'onPlay' } 56 | { name: 'onPlaying' } 57 | { name: 'onProgress' } 58 | { name: 'onRateChange' } 59 | { name: 'onSeeked' } 60 | { name: 'onSeeking' } 61 | { name: 'onStalled' } 62 | { name: 'onSuspend' } 63 | { name: 'onTimeUpdate' } 64 | { name: 'onVolumeChange' } 65 | { name: 'onWaiting' } 66 | ] 67 | 68 | globalAttributes: [ 69 | { name: 'className'} 70 | { name: 'class'} 71 | { name: 'id'} 72 | { name: 'itemProp'} 73 | { name: 'itemScope'} 74 | { name: 'itemType'} 75 | { name: 'itemID'} 76 | { name: 'dangerouslySetInnerHTML'} 77 | { name: 'data-'} 78 | { name: 'aria-'} 79 | ] 80 | 81 | htmlElements: [ 82 | { name: 'a' 83 | attributes: [ 84 | { name: 'href'} 85 | { name: 'target'} 86 | { name: 'download'} 87 | { name: 'rel'} 88 | { name: 'hrefLang'} 89 | { name: 'type'} 90 | ]} 91 | { name: 'abbr' 92 | attributes: []} 93 | { name: 'address' 94 | attributes: []} 95 | { name: 'area' 96 | attributes: [ 97 | { name: 'alt'} 98 | { name: 'coords'} 99 | { name: 'href'} 100 | { name: 'hrefLang'} 101 | { name: 'media'} 102 | { name: 'rel'} 103 | { name: 'shape'} 104 | { name: 'target'} 105 | { name: 'type'} 106 | ]} 107 | { name: 'article' 108 | attributes: []} 109 | { name: 'aside' 110 | attributes: []} 111 | { name: 'audio' 112 | attributes: [ 113 | { name: 'autoPlay'} 114 | { name: 'controls'} 115 | { name: 'crossOrigin'} 116 | { name: 'loop'} 117 | { name: 'mediaGroup'} 118 | { name: 'muted'} 119 | { name: 'preload'} 120 | { name: 'src'} 121 | ]} 122 | { name: 'b' 123 | attributes: []} 124 | { name: 'base' 125 | attributes: [ 126 | { name: 'href'} 127 | { name: 'target'} 128 | ]} 129 | { name: 'bdi' 130 | attributes: []} 131 | { name: 'bdo' 132 | attributes: []} 133 | { name: 'big' 134 | attributes: []} 135 | { name: 'blockquote' 136 | attributes: []} 137 | { name: 'body' 138 | attributes: []} 139 | { name: 'br' 140 | attributes: []} 141 | { name: 'button' 142 | attributes: [ 143 | { name: 'autoFocus'} 144 | { name: 'disabled'} 145 | { name: 'form'} 146 | { name: 'formAction'} 147 | { name: 'formEncType'} 148 | { name: 'formMethod'} 149 | { name: 'formNoValidate'} 150 | { name: 'formTarget'} 151 | { name: 'name'} 152 | { name: 'type'} 153 | { name: 'value'} 154 | ]} 155 | { name: 'canvas' 156 | attributes: [ 157 | { name: 'height'} 158 | { name: 'width'} 159 | ]} 160 | { name: 'caption' 161 | attributes: []} 162 | { name: 'cite' 163 | attributes: []} 164 | { name: 'code' 165 | attributes: []} 166 | { name: 'col' 167 | attributes: [ 168 | { name: 'span'} 169 | ]} 170 | { name: 'colgroup' 171 | attributes: [ 172 | { name: 'span'} 173 | ]} 174 | { name: 'data' 175 | attributes: []} 176 | { name: 'datalist' 177 | attributes: []} 178 | { name: 'dd' 179 | attributes: []} 180 | { name: 'del' 181 | attributes: [ 182 | { name: 'dateTime'} 183 | ]} 184 | { name: 'details' 185 | attributes: [ 186 | { name: 'open'} 187 | ]} 188 | { name: 'dfn' 189 | attributes: [ 190 | { name: 'open'} 191 | ]} 192 | { name: 'dialog' 193 | attributes: []} 194 | { name: 'div' 195 | attributes: []} 196 | { name: 'dl' 197 | attributes: []} 198 | { name: 'dt' 199 | attributes: []} 200 | { name: 'em' 201 | attributes: []} 202 | { name: 'embed' 203 | attributes: [ 204 | { name: 'height'} 205 | { name: 'src'} 206 | { name: 'type'} 207 | { name: 'width'} 208 | ]} 209 | { name: 'fieldset' 210 | attributes: [ 211 | { name: 'disabled'} 212 | { name: 'form'} 213 | { name: 'name'} 214 | ]} 215 | { name: 'figcaption' 216 | attributes: []} 217 | { name: 'figure' 218 | attributes: []} 219 | { name: 'footer' 220 | attributes: []} 221 | { name: 'form' 222 | attributes: [ 223 | { name: 'acceptCharset'} 224 | { name: 'action'} 225 | { name: 'autoComplete'} 226 | { name: 'encType'} 227 | { name: 'method'} 228 | { name: 'name'} 229 | { name: 'noValidate'} 230 | { name: 'target'} 231 | ]} 232 | { name: 'h1' 233 | attributes: []} 234 | { name: 'h2' 235 | attributes: []} 236 | { name: 'h3' 237 | attributes: []} 238 | { name: 'h4' 239 | attributes: []} 240 | { name: 'h5' 241 | attributes: []} 242 | { name: 'h6' 243 | attributes: []} 244 | { name: 'head' 245 | attributes: []} 246 | { name: 'header' 247 | attributes: []} 248 | { name: 'hr' 249 | attributes: []} 250 | { name: 'html' 251 | attributes: [ 252 | { name: 'manifest'} 253 | { name: 'lang'} 254 | ]} 255 | { name: 'i' 256 | attributes: []} 257 | { name: 'iframe' 258 | attributes: [ 259 | { name: 'height'} 260 | { name: 'name'} 261 | { name: 'sandbox'} 262 | { name: 'seamless'} 263 | { name: 'src'} 264 | { name: 'srcDoc'} 265 | { name: 'width'} 266 | ]} 267 | { name: 'img' 268 | attributes: [ 269 | { name: 'alt'} 270 | { name: 'height'} 271 | { name: 'src'} 272 | { name: 'usemap'} 273 | { name: 'width'} 274 | ]} 275 | { name: 'input' 276 | attributes: [ 277 | { name: 'accept'} 278 | { name: 'alt'} 279 | { name: 'autoComplete'} 280 | { name: 'autoFocus'} 281 | { name: 'checked'} 282 | { name: 'disabled'} 283 | { name: 'form'} 284 | { name: 'formAction'} 285 | { name: 'formEncType'} 286 | { name: 'formMethod'} 287 | { name: 'formNoValidate'} 288 | { name: 'formTarget'} 289 | { name: 'height'} 290 | { name: 'list'} 291 | { name: 'max'} 292 | { name: 'maxLength'} 293 | { name: 'min'} 294 | { name: 'multiple'} 295 | { name: 'name'} 296 | { name: 'pattern'} 297 | { name: 'placeholder'} 298 | { name: 'readOnly'} 299 | { name: 'required'} 300 | { name: 'size'} 301 | { name: 'src'} 302 | { name: 'step'} 303 | { name: 'type'} 304 | { name: 'value'} 305 | { name: 'width'} 306 | ]} 307 | { name: 'ins' 308 | attributes: [ 309 | { name: 'dateTime'} 310 | ]} 311 | { name: 'kbd' 312 | attributes: []} 313 | { name: 'keygen' 314 | attributes: [ 315 | { name: 'autoFocus'} 316 | { name: 'challenge'} 317 | { name: 'disabled'} 318 | { name: 'form'} 319 | { name: 'keyType'} 320 | { name: 'name'} 321 | ]} 322 | { name: 'label' 323 | attributes: [ 324 | { name: 'htmlFor'} 325 | { name: 'form'} 326 | ]} 327 | { name: 'legend' 328 | attributes: [ 329 | { name: 'value'} 330 | ]} 331 | { name: 'li' 332 | attributes: []} 333 | { name: 'link' 334 | attributes: [ 335 | { name: 'disabled'} 336 | { name: 'href'} 337 | { name: 'hrefLang'} 338 | { name: 'media'} 339 | { name: 'rel'} 340 | { name: 'sizes'} 341 | { name: 'type'} 342 | ]} 343 | { name: 'main' 344 | attributes: []} 345 | { name: 'map' 346 | attributes: [ 347 | { name: 'name'} 348 | ]} 349 | { name: 'mark' 350 | attributes: []} 351 | { name: 'menu' 352 | attributes: [ 353 | { name: 'label'} 354 | { name: 'type'} 355 | ]} 356 | { name: 'menuitem' 357 | attributes: []} 358 | { name: 'meta' 359 | attributes: [ 360 | { name: 'charset'} 361 | { name: 'content'} 362 | { name: 'httpEquiv'} 363 | { name: 'name'} 364 | ]} 365 | { name: 'meter' 366 | attributes: []} 367 | { name: 'nav' 368 | attributes: []} 369 | { name: 'noscript' 370 | attributes: []} 371 | { name: 'object' 372 | attributes: [ 373 | { name: 'data'} 374 | { name: 'form'} 375 | { name: 'height'} 376 | { name: 'name'} 377 | { name: 'type'} 378 | { name: 'usemap'} 379 | { name: 'width'} 380 | ]} 381 | { name: 'ol' 382 | attributes: [ 383 | { name: 'start'} 384 | { name: 'type'} 385 | ]} 386 | { name: 'optgroup' 387 | attributes: [ 388 | { name: 'disabled'} 389 | { name: 'label'} 390 | ]} 391 | { name: 'option' 392 | attributes: [ 393 | { name: 'disabled'} 394 | { name: 'label'} 395 | { name: 'selected'} 396 | { name: 'value'} 397 | ]} 398 | { name: 'output' 399 | attributes: [ 400 | { name: 'htmlFor'} 401 | { name: 'form'} 402 | { name: 'name'} 403 | ]} 404 | { name: 'p' 405 | attributes: []} 406 | { name: 'param' 407 | attributes: [ 408 | { name: 'name'} 409 | { name: 'value'} 410 | ]} 411 | { name: 'picture' 412 | attributes: []} 413 | { name: 'pre' 414 | attributes: []} 415 | { name: 'progress' 416 | attributes: [ 417 | { name: 'form'} 418 | { name: 'max'} 419 | { name: 'value'} 420 | ]} 421 | { name: 'q' 422 | attributes: []} 423 | { name: 'rp' 424 | attributes: []} 425 | { name: 'rt' 426 | attributes: []} 427 | { name: 'ruby' 428 | attributes: []} 429 | { name: 's' 430 | attributes: []} 431 | { name: 'samp' 432 | attributes: []} 433 | { name: 'script' 434 | attributes: [ 435 | { name: 'async'} 436 | { name: 'charSet'} 437 | { name: 'defer'} 438 | { name: 'src'} 439 | { name: 'type'} 440 | ]} 441 | { name: 'section' 442 | attributes: []} 443 | { name: 'select' 444 | attributes: [ 445 | { name: 'autoFocus'} 446 | { name: 'disabled'} 447 | { name: 'form'} 448 | { name: 'multiple'} 449 | { name: 'name'} 450 | { name: 'required'} 451 | { name: 'size'} 452 | ]} 453 | { name: 'small' 454 | attributes: []} 455 | { name: 'source' 456 | attributes: [ 457 | { name: 'media'} 458 | { name: 'src'} 459 | { name: 'type'} 460 | ]} 461 | { name: 'span' 462 | attributes: []} 463 | { name: 'strong' 464 | attributes: []} 465 | { name: 'style' 466 | attributes: [ 467 | { name: 'disabled'} 468 | { name: 'media'} 469 | { name: 'scoped'} 470 | { name: 'type'} 471 | ]} 472 | { name: 'sub' 473 | attributes: []} 474 | { name: 'summary' 475 | attributes: []} 476 | { name: 'sup' 477 | attributes: []} 478 | { name: 'table' 479 | attributes: []} 480 | { name: 'tbody' 481 | attributes: []} 482 | { name: 'td' 483 | attributes: [ 484 | { name: 'colSpan'} 485 | { name: 'headers'} 486 | { name: 'rowSpan'} 487 | ]} 488 | { name: 'textarea' 489 | attributes: [ 490 | { name: 'autoFocus'} 491 | { name: 'cols'} 492 | { name: 'disabled'} 493 | { name: 'form'} 494 | { name: 'label'} 495 | { name: 'maxLength'} 496 | { name: 'name'} 497 | { name: 'placeholder'} 498 | { name: 'readonly'} 499 | { name: 'required'} 500 | { name: 'rows'} 501 | { name: 'wrap'} 502 | ]} 503 | { name: 'tfoot' 504 | attributes: []} 505 | { name: 'th' 506 | attributes: [ 507 | { name: 'colSpan'} 508 | { name: 'headers'} 509 | { name: 'rowSpan'} 510 | { name: 'scope'} 511 | ]} 512 | { name: 'thead' 513 | attributes: []} 514 | { name: 'time' 515 | attributes: [ 516 | { name: 'dateTime'} 517 | ]} 518 | { name: 'title' 519 | attributes: []} 520 | { name: 'tr' 521 | attributes: []} 522 | { name: 'track' 523 | attributes: [ 524 | { name: 'default'} 525 | { name: 'label'} 526 | { name: 'src'} 527 | ]} 528 | { name: 'u' 529 | attributes: []} 530 | { name: 'ul' 531 | attributes: []} 532 | { name: 'var' 533 | attributes: []} 534 | { name: 'video' 535 | attributes: [ 536 | { name: 'autoPlay'} 537 | { name: 'controls'} 538 | { name: 'height'} 539 | { name: 'loop'} 540 | { name: 'mediaGroup'} 541 | { name: 'muted'} 542 | { name: 'poster'} 543 | { name: 'preload'} 544 | { name: 'src'} 545 | { name: 'width'} 546 | ]} 547 | { name: 'wbr' 548 | attributes: []} 549 | # svg elements 550 | { name: 'circle' 551 | attributes: [ 552 | { name: 'cx'} 553 | { name: 'cy'} 554 | { name: 'r'} 555 | { name: 'stroke'} 556 | { name: 'strokeWidth'} 557 | { name: 'fill'} 558 | ]} 559 | { name: 'clipPath' 560 | attributes: [ 561 | { name: 'clipPath'} 562 | ]} 563 | { name: 'defs' 564 | attributes: []} 565 | { name: 'ellipse' 566 | attributes: [ 567 | { name: 'cx'} 568 | { name: 'cy'} 569 | { name: 'rx'} 570 | { name: 'ry'} 571 | ]} 572 | { name: 'g' 573 | attributes: [ 574 | { name: 'fill'} 575 | { name: 'opacity'} 576 | ]} 577 | { name: 'line' 578 | attributes: [ 579 | { name: 'x1'} 580 | { name: 'x2'} 581 | { name: 'y1'} 582 | { name: 'y2'} 583 | ]} 584 | { name: 'linearGradient' 585 | attributes: [ 586 | { name: 'x1'} 587 | { name: 'x2'} 588 | { name: 'y1'} 589 | { name: 'y2'} 590 | { name: 'spreadMethod'} 591 | { name: 'xlinkHref'} 592 | ]} 593 | { name: 'mask' 594 | attributes: [ 595 | { name: 'mashUnits'} 596 | { name: 'x'} 597 | { name: 'y'} 598 | { name: 'width'} 599 | { name: 'height'} 600 | ]} 601 | { name: 'path' 602 | attributes: [ 603 | { name: 'd'} 604 | { name: 'transform'} 605 | ]} 606 | { name: 'pattern' 607 | attributes: [ 608 | { name: 'patternContentUnits'} 609 | { name: 'x'} 610 | { name: 'y'} 611 | { name: 'width'} 612 | { name: 'height'} 613 | { name: 'viewBox'} 614 | { name: 'xlinkHref'} 615 | ]} 616 | { name: 'polygon' 617 | attributes: [ 618 | { name: 'points'} 619 | ]} 620 | { name: 'polyline' 621 | attributes: [ 622 | { name: 'points'} 623 | ]} 624 | { name: 'radialGradient' 625 | attributes: [ 626 | { name: 'gradientUnits'} 627 | { name: 'gradientTransform'} 628 | { name: 'cx'} 629 | { name: 'cy'} 630 | { name: 'r'} 631 | { name: 'fx'} 632 | { name: 'fy'} 633 | { name: 'spreadMethod'} 634 | { name: 'xlinkHref'} 635 | ]} 636 | { name: 'rect' 637 | attributes: [ 638 | { name: 'x'} 639 | { name: 'y'} 640 | { name: 'rx'} 641 | { name: 'ry'} 642 | { name: 'width'} 643 | { name: 'height'} 644 | ]} 645 | { name: 'stop' 646 | attributes: [ 647 | { name: 'offset'} 648 | { name: 'stopColor'} 649 | { name: 'stopOpacity'} 650 | ]} 651 | { name: 'svg' 652 | attributes: [ 653 | { name: 'x'} 654 | { name: 'y'} 655 | { name: 'width'} 656 | { name: 'height'} 657 | { name: 'viewBox'} 658 | { name: 'preserveAspectRatio'} 659 | { name: 'zoomAndPan'} 660 | ]} 661 | { name: 'text' 662 | attributes: [ 663 | { name: 'x'} 664 | { name: 'y'} 665 | { name: 'dx'} 666 | { name: 'dy'} 667 | { name: 'rotate'} 668 | { name: 'textLength'} 669 | { name: 'lengthAdjust'} 670 | ]} 671 | { name: 'tspan' 672 | attributes: [ 673 | { name: 'x'} 674 | { name: 'y'} 675 | { name: 'dx'} 676 | { name: 'dy'} 677 | { name: 'rotate'} 678 | { name: 'textLength'} 679 | { name: 'lengthAdjust'} 680 | { name: 'xlinkHref'} 681 | ]} 682 | ] 683 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/babel-sublime/jsx-text.jsx: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 |
3 | // <- meta.tag.jsx punctuation.definition.tag.jsx 4 | // <- meta.tag.jsx entity.name.tag.open.jsx 5 | //^^^ meta.tag.jsx 6 | // ^ punctuation.definition.tag.jsx 7 | //^^ entity.name.tag.open.jsx 8 | // ^ JSXStartTagEnd 9 | {'it\'s with text inside'} 10 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx 11 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js 12 | //^ punctuation.section.embedded.begin.jsx 13 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js 14 | // ^ punctuation.definition.string.begin.jsx 15 | // ^ punctuation.definition.string.end.jsx 16 | // ^ punctuation.section.embedded.end.jsx 17 |
18 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 19 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 20 | //^^^^ meta.tag.jsx 21 | // ^ punctuation.definition.tag.jsx 22 | //^^^ entity.name.tag.close.jsx 23 | 24 |
{'it\'s with text inside'}
25 | // <- meta.tag.jsx punctuation.definition.tag.jsx 26 | // <- meta.tag.jsx entity.name.tag.open.jsx 27 | //^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^^^ meta.tag.jsx 28 | // ^ ^^ ^ punctuation.definition.tag.jsx 29 | //^^ entity.name.tag.open.jsx 30 | // ^ JSXStartTagEnd 31 | // ^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js 32 | // ^ punctuation.section.embedded.begin.jsx 33 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js 34 | // ^ punctuation.definition.string.begin.jsx 35 | // ^ punctuation.definition.string.end.jsx 36 | // ^ punctuation.section.embedded.end.jsx 37 | // ^^ JSXEndTagStart 38 | // ^^^ entity.name.tag.close.jsx 39 | 40 |
46 | //^^^^^^^^ meta.tag.jsx 47 | //^^^^ entity.other.attribute-name.jsx 48 | // ^ keyword.operator.assignment.jsx 49 | // ^^ string.quoted.single.js 50 | // ^ punctuation.definition.string.begin.jsx 51 | // ^ punctuation.definition.string.end.jsx 52 | // ^ punctuation.definition.tag.jsx 53 | // ^ JSXStartTagEnd 54 | {'it\'s with text inside'} 55 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx 56 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js 57 | //^ punctuation.section.embedded.begin.jsx 58 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js 59 | // ^ punctuation.definition.string.begin.jsx 60 | // ^ punctuation.definition.string.end.jsx 61 | // ^ punctuation.section.embedded.end.jsx 62 |
63 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 64 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 65 | //^^^^ meta.tag.jsx 66 | // ^ punctuation.definition.tag.jsx 67 | //^^^ entity.name.tag.close.jsx 68 | 69 |
{'it\'s with text inside'}
70 | // <- meta.tag.jsx punctuation.definition.tag.jsx 71 | // <- meta.tag.jsx entity.name.tag.open.jsx 72 | //^^ ^^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^^^ meta.tag.jsx 73 | // ^ ^^ ^ punctuation.definition.tag.jsx 74 | //^^ entity.name.tag.open.jsx 75 | // ^^^^ entity.other.attribute-name.jsx 76 | // ^ keyword.operator.assignment.jsx 77 | // ^^ string.quoted.double.js 78 | // ^ ^ punctuation.definition.string.begin.jsx 79 | // ^ ^ punctuation.definition.string.end.jsx 80 | // ^ JSXStartTagEnd 81 | // ^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js 82 | // ^ punctuation.section.embedded.begin.jsx 83 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js 84 | // ^ punctuation.section.embedded.end.jsx 85 | // ^^ JSXEndTagStart 86 | // ^^^ entity.name.tag.close.jsx 87 |
93 | //^^^^^^^^ meta.tag.jsx 94 | //^^^^ entity.other.attribute-name.jsx 95 | // ^ keyword.operator.assignment.jsx 96 | // ^^ string.quoted.double.js 97 | // ^ punctuation.definition.string.begin.jsx 98 | // ^ punctuation.definition.string.end.jsx 99 | // ^ punctuation.definition.tag.jsx 100 | // ^ JSXStartTagEnd 101 | {"it's with text inside"} 102 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx 103 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js 104 | //^ punctuation.section.embedded.begin.jsx 105 | // ^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.double.js 106 | // ^ punctuation.definition.string.begin.jsx 107 | // ^ punctuation.definition.string.end.jsx 108 | // ^ punctuation.section.embedded.end.jsx 109 |
110 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 111 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 112 | //^^^^ meta.tag.jsx 113 | // ^ punctuation.definition.tag.jsx 114 | //^^^ entity.name.tag.close.jsx 115 | 116 |
{"it's with text inside"}
117 | // <- meta.tag.jsx punctuation.definition.tag.jsx 118 | // <- meta.tag.jsx entity.name.tag.open.jsx 119 | //^^ ^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^^^ meta.tag.jsx 120 | // ^ ^^ ^ punctuation.definition.tag.jsx 121 | //^^ entity.name.tag.open.jsx 122 | // ^^^^ entity.other.attribute-name.jsx 123 | // ^ keyword.operator.assignment.jsx 124 | // ^^ ^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js 125 | // ^ ^ punctuation.section.embedded.begin.jsx 126 | // ^ ^ punctuation.section.embedded.end.jsx 127 | // ^ JSXStartTagEnd 128 | // ^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.double.js 129 | // ^ punctuation.definition.string.begin.jsx 130 | // ^ punctuation.definition.string.end.jsx 131 | // ^^ JSXEndTagStart 132 | // ^^^ entity.name.tag.close.jsx 133 |
139 | //^^^^^^^^ meta.tag.jsx 140 | //^^^^ entity.other.attribute-name.jsx 141 | // ^ keyword.operator.assignment.jsx 142 | // ^^ meta.embedded.expression.js 143 | // ^ punctuation.section.embedded.begin.jsx 144 | // ^ punctuation.section.embedded.end.jsx 145 | // ^ punctuation.definition.tag.jsx 146 | // ^ JSXStartTagEnd 147 | {"it's with text inside"} 148 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx 149 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js 150 | //^ punctuation.section.embedded.begin.jsx 151 | // ^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.double.js 152 | // ^ punctuation.definition.string.begin.jsx 153 | // ^ punctuation.definition.string.end.jsx 154 | // ^ punctuation.section.embedded.end.jsx 155 |
156 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 157 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 158 | //^^^^ meta.tag.jsx 159 | // ^ punctuation.definition.tag.jsx 160 | //^^^ entity.name.tag.close.jsx 161 | 162 |
163 | // <- meta.tag.jsx punctuation.definition.tag.jsx 164 | // <- meta.tag.jsx entity.name.tag.open.jsx 165 | //^^^ meta.tag.jsx 166 | // ^ punctuation.definition.tag.jsx 167 | //^^ entity.name.tag.open.jsx 168 | // ^ JSXStartTagEnd 169 | it's with text inside 170 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx 171 |
172 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 173 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 174 | //^^^^ meta.tag.jsx 175 | // ^ punctuation.definition.tag.jsx 176 | //^^^ entity.name.tag.close.jsx 177 | 178 |
it's with text inside
179 | // <- meta.tag.jsx punctuation.definition.tag.jsx 180 | // <- meta.tag.jsx entity.name.tag.open.jsx 181 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx 182 | // ^ ^^ ^ punctuation.definition.tag.jsx 183 | //^^ entity.name.tag.open.jsx 184 | // ^ JSXStartTagEnd 185 | // ^^ JSXEndTagStart 186 | // ^^^ entity.name.tag.close.jsx 187 | 188 |
194 | //^^^^^^^^ meta.tag.jsx 195 | //^^^^ entity.other.attribute-name.jsx 196 | // ^ keyword.operator.assignment.jsx 197 | // ^^ string.quoted.single.js 198 | // ^ punctuation.definition.string.begin.jsx 199 | // ^ punctuation.definition.string.end.jsx 200 | // ^ punctuation.definition.tag.jsx 201 | // ^ JSXStartTagEnd 202 | it's with text inside 203 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx 204 |
205 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 206 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 207 | //^^^^ meta.tag.jsx 208 | // ^ punctuation.definition.tag.jsx 209 | //^^^ entity.name.tag.close.jsx 210 | 211 |
it's with text inside
212 | // <- meta.tag.jsx punctuation.definition.tag.jsx 213 | // <- meta.tag.jsx entity.name.tag.open.jsx 214 | //^^ ^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx 215 | // ^ ^^ ^ punctuation.definition.tag.jsx 216 | //^^ entity.name.tag.open.jsx 217 | // ^^^^ entity.other.attribute-name.jsx 218 | // ^ keyword.operator.assignment.jsx 219 | // ^^ string.quoted.double.js 220 | // ^ punctuation.definition.string.begin.jsx 221 | // ^ punctuation.definition.string.end.jsx 222 | // ^ JSXStartTagEnd 223 | // ^^ JSXEndTagStart 224 | // ^^^ entity.name.tag.close.jsx 225 |
231 | //^^^^^^^^ meta.tag.jsx 232 | //^^^^ entity.other.attribute-name.jsx 233 | // ^ keyword.operator.assignment.jsx 234 | // ^^ string.quoted.double.js 235 | // ^ punctuation.definition.string.begin.jsx 236 | // ^ punctuation.definition.string.end.jsx 237 | // ^ punctuation.definition.tag.jsx 238 | // ^ JSXStartTagEnd 239 | it's with text inside 240 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx 241 |
242 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 243 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 244 | //^^^^ meta.tag.jsx 245 | // ^ punctuation.definition.tag.jsx 246 | //^^^ entity.name.tag.close.jsx 247 | 248 |
it's with text inside
249 | // <- meta.tag.jsx punctuation.definition.tag.jsx 250 | // <- meta.tag.jsx entity.name.tag.open.jsx 251 | //^^ ^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx 252 | // ^ ^^ ^ punctuation.definition.tag.jsx 253 | //^^ entity.name.tag.open.jsx 254 | // ^^^^ entity.other.attribute-name.jsx 255 | // ^ keyword.operator.assignment.jsx 256 | // ^^ meta.embedded.expression.js 257 | // ^ punctuation.section.embedded.begin.jsx 258 | // ^ punctuation.section.embedded.end.jsx 259 | // ^ JSXStartTagEnd 260 | // ^^ JSXEndTagStart 261 | // ^^^ entity.name.tag.close.jsx 262 |
268 | //^^^^^^^^ meta.tag.jsx 269 | //^^^^ entity.other.attribute-name.jsx 270 | // ^ keyword.operator.assignment.jsx 271 | // ^^ meta.embedded.expression.js 272 | // ^ punctuation.section.embedded.begin.jsx 273 | // ^ punctuation.section.embedded.end.jsx 274 | // ^ punctuation.definition.tag.jsx 275 | // ^ JSXStartTagEnd 276 | it's with text inside 277 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx 278 |
279 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 280 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 281 | //^^^^ meta.tag.jsx 282 | // ^ punctuation.definition.tag.jsx 283 | //^^^ entity.name.tag.close.jsx 284 | 285 |
it's with text inside
286 | // <- meta.tag.jsx punctuation.definition.tag.jsx 287 | // <- meta.tag.jsx entity.name.tag.open.jsx 288 | //^^ ^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx 289 | // ^ ^^ ^ punctuation.definition.tag.jsx 290 | //^^ entity.name.tag.open.jsx 291 | // ^^^^ entity.other.attribute-name.jsx 292 | // ^ JSXStartTagEnd 293 | // ^^ JSXEndTagStart 294 | // ^^^ entity.name.tag.close.jsx 295 | 296 |
it's with text inside
302 | //^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx 303 | //^ ^^ ^ punctuation.definition.tag.jsx 304 | //^ JSXStartTagEnd 305 | // ^^ JSXEndTagStart 306 | // ^^^ entity.name.tag.close.jsx 307 | 308 |
it's with text inside
321 | //^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx 322 | //^ ^^ ^ punctuation.definition.tag.jsx 323 | //^ JSXStartTagEnd 324 | // ^^ JSXEndTagStart 325 | // ^^^ entity.name.tag.close.jsx 326 | 327 | // >> only:source.js.jsx 328 | -------------------------------------------------------------------------------- /spec/transpile-spec.coffee: -------------------------------------------------------------------------------- 1 | chai = require '../node_modules/chai' 2 | expect = chai.expect 3 | fs = require 'fs-plus' 4 | path = require 'path' 5 | defaultConfig = require './default-config' 6 | grammarTest = require 'atom-grammar-test' 7 | 8 | LB = 'language-babel' 9 | # we use atom setPaths in this spec. setPaths checks if directories exist 10 | # thus:- setPaths(['/root/Project1']) may find /root but not /root/Project1 11 | # and sets the proj dir as /root rather than /root/Project1. If /root/Project1 12 | # were no found, atom sets the directory to the full name. 13 | # We need some prefix directory faux names for posix and windows to ensure 14 | # we always get a project name we set 15 | PU = '/dir199a99231' # unlikely directory name UNIX 16 | PW = 'C:\\dir199a99231' # unlikely directory name windows 17 | 18 | describe 'language-babel', -> 19 | lb = null 20 | config = {} 21 | beforeEach -> 22 | waitsForPromise -> 23 | atom.packages.activatePackage(LB) 24 | config = JSON.parse JSON.stringify defaultConfig 25 | 26 | runs -> 27 | lb = atom.packages.getActivePackage(LB).mainModule.transpiler 28 | # ---------------------------------------------------------------------------- 29 | describe 'Reading real config', -> 30 | it 'should read all possible configuration keys', -> 31 | realConfig = lb.getConfig() 32 | expect(realConfig).to.contain.all.keys key for key, value of config 33 | # ---------------------------------------------------------------------------- 34 | describe ':getPaths', -> 35 | 36 | if not process.platform.match /^win/ 37 | it 'returns paths for a named sourcefile with default config', -> 38 | atom.project.setPaths([PU+'/Project1', PU+'/Project2']) 39 | 40 | ret = lb.getPaths(PU+'/Project1/source/dira/fauxfile.js',config) 41 | 42 | expect(ret.sourceFile).to.equal(PU+'/Project1/source/dira/fauxfile.js') 43 | expect(ret.sourceFileDir).to.equal(PU+'/Project1/source/dira') 44 | expect(ret.mapFile).to.equal(PU+'/Project1/source/dira/fauxfile.js.map') 45 | expect(ret.transpiledFile).to.equal(PU+'/Project1/source/dira/fauxfile.js') 46 | expect(ret.sourceRoot).to.equal(PU+'/Project1') 47 | expect(ret.projectPath).to.equal(PU+'/Project1') 48 | 49 | it 'returns paths config with target & source paths set', -> 50 | atom.project.setPaths([PU+'/Project1', PU+'/Project2']) 51 | config.babelSourcePath = '/source' # with dir prefix 52 | config.babelMapsPath ='mapspath' # and without 53 | config.babelTranspilePath = '/transpath' 54 | 55 | ret = lb.getPaths(PU+'/Project1/source/dira/fauxfile.js',config) 56 | 57 | expect(ret.sourceFile).to.equal(PU+'/Project1/source/dira/fauxfile.js') 58 | expect(ret.sourceFileDir).to.equal(PU+'/Project1/source/dira') 59 | expect(ret.mapFile).to.equal(PU+'/Project1/mapspath/dira/fauxfile.js.map') 60 | expect(ret.transpiledFile).to.equal(PU+'/Project1/transpath/dira/fauxfile.js') 61 | expect(ret.sourceRoot).to.equal(PU+'/Project1/source') 62 | expect(ret.projectPath).to.equal(PU+'/Project1') 63 | 64 | it 'returns correct paths with project in root directory', -> 65 | atom.project.setPaths(['/']) 66 | config.babelSourcePath = 'source' 67 | config.babelMapsPath ='mapspath' 68 | config.babelTranspilePath = 'transpath' 69 | 70 | ret = lb.getPaths('/source/dira/fauxfile.js',config) 71 | 72 | expect(ret.sourceFile).to.equal('/source/dira/fauxfile.js') 73 | expect(ret.sourceFileDir).to.equal('/source/dira') 74 | expect(ret.mapFile).to.equal('/mapspath/dira/fauxfile.js.map') 75 | expect(ret.transpiledFile).to.equal('/transpath/dira/fauxfile.js') 76 | expect(ret.sourceRoot).to.equal('/source') 77 | expect(ret.projectPath).to.equal('/') 78 | 79 | if process.platform.match /^win/ 80 | it 'returns paths for a named sourcefile with default config', -> 81 | atom.project.setPaths([PW+'\\Project1', PW+'\\Project2']) 82 | 83 | ret = lb.getPaths(PW+'\\Project1\\source\\dira\\fauxfile.js',config) 84 | 85 | expect(ret.sourceFile).to.equal(PW+'\\Project1\\source\\dira\\fauxfile.js') 86 | expect(ret.sourceFileDir).to.equal(PW+'\\Project1\\source\\dira') 87 | expect(ret.mapFile).to.equal(PW+'\\Project1\\source\\dira\\fauxfile.js.map') 88 | expect(ret.transpiledFile).to.equal(PW+'\\Project1\\source\\dira\\fauxfile.js') 89 | expect(ret.sourceRoot).to.equal(PW+'\\Project1') 90 | expect(ret.projectPath).to.equal(PW+'\\Project1') 91 | 92 | it 'returns paths config with target & source paths set', -> 93 | atom.project.setPaths([PW+'\\Project1', PW+'\\Project2']) 94 | config.babelSourcePath = '\\source' # with dir prefix 95 | config.babelMapsPath ='mapspath' # and without 96 | config.babelTranspilePath = '\\transpath' 97 | 98 | ret = lb.getPaths(PW+'\\Project1\\source\\dira\\fauxfile.js',config) 99 | 100 | expect(ret.sourceFile).to.equal(PW+'\\Project1\\source\\dira\\fauxfile.js') 101 | expect(ret.sourceFileDir).to.equal(PW+'\\Project1\\source\\dira') 102 | expect(ret.mapFile).to.equal(PW+'\\Project1\\mapspath\\dira\\fauxfile.js.map') 103 | expect(ret.transpiledFile).to.equal(PW+'\\Project1\\transpath\\dira\\fauxfile.js') 104 | expect(ret.sourceRoot).to.equal(PW+'\\Project1\\source') 105 | expect(ret.projectPath).to.equal(PW+'\\Project1') 106 | 107 | it 'returns correct paths with project in root directory', -> 108 | atom.project.setPaths(['C:\\']) 109 | config.babelSourcePath = 'source' 110 | config.babelMapsPath ='mapspath' 111 | config.babelTranspilePath = 'transpath' 112 | 113 | ret = lb.getPaths('C:\\source\\dira\\fauxfile.js',config) 114 | 115 | expect(ret.sourceFile).to.equal('C:\\source\\dira\\fauxfile.js') 116 | expect(ret.sourceFileDir).to.equal('C:\\source\\dira') 117 | expect(ret.mapFile).to.equal('C:\\mapspath\\dira\\fauxfile.js.map') 118 | expect(ret.transpiledFile).to.equal('C:\\transpath\\dira\\fauxfile.js') 119 | expect(ret.sourceRoot).to.equal('C:\\source') 120 | expect(ret.projectPath).to.equal('C:\\') 121 | # ---------------------------------------------------------------------------- 122 | describe ':transpile', -> 123 | notificationSpy = null 124 | notification = null 125 | writeFileStub = null 126 | writeFileName = null 127 | 128 | beforeEach -> 129 | notificationSpy = jasmine.createSpy 'notificationSpy' 130 | notification = atom.notifications.onDidAddNotification notificationSpy 131 | writeFileName = null 132 | writeFileStub = spyOn(fs,'writeFileSync').andCallFake (path)-> 133 | writeFileName = path 134 | afterEach -> 135 | notification.dispose() 136 | 137 | describe 'when transpileOnSave is false', -> 138 | it 'does nothing', -> 139 | config.transpileOnSave = false 140 | 141 | spyOn(lb, 'getConfig').andCallFake -> config 142 | lb.transpile('somefilename') 143 | expect(notificationSpy.callCount).to.equal(0) 144 | expect(writeFileStub.callCount).to.equal(0) 145 | 146 | describe 'When a source file is outside the "babelSourcePath" & suppress msgs false', -> 147 | it 'notifies sourcefile is not inside sourcepath', -> 148 | atom.project.setPaths([__dirname]) 149 | config.babelSourcePath = 'fixtures' 150 | config.babelTranspilePath = 'fixtures' 151 | config.babelMapsPath = 'fixtures' 152 | 153 | spyOn(lb, 'getConfig').andCallFake -> config 154 | lb.transpile(__dirname+'/fake.js') 155 | expect(notificationSpy.callCount).to.equal(1) 156 | msg = notificationSpy.calls[0].args[0].message # first call, first arg 157 | type = notificationSpy.calls[0].args[0].type 158 | expect(msg).to.match(/^LB: Babel file is not inside/) 159 | expect(writeFileStub.callCount).to.equal(0) 160 | 161 | describe 'When a source file is outside the "babelSourcePath" & suppress msgs true', -> 162 | it 'exects no notifications', -> 163 | atom.project.setPaths([__dirname]) 164 | config.babelSourcePath = 'fixtures' 165 | config.babelTranspilePath = 'fixtures' 166 | config.babelMapsPath = 'fixtures' 167 | config.suppressSourcePathMessages = true 168 | 169 | spyOn(lb, 'getConfig').andCallFake -> config 170 | lb.transpile(__dirname+'/fake.js') 171 | expect(notificationSpy.callCount).to.equal(0) 172 | expect(writeFileStub.callCount).to.equal(0) 173 | 174 | describe 'When a js files is transpiled and gets an error', -> 175 | it 'it issues a notification error message', -> 176 | atom.project.setPaths([__dirname]) 177 | config.babelSourcePath = 'fixtures' 178 | config.babelTranspilePath = 'fixtures' 179 | config.babelMapsPath = 'fixtures' 180 | 181 | spyOn(lb, 'getConfig').andCallFake ->config 182 | lb.transpile(path.resolve(__dirname, 'fixtures/dira/dira.1/dira.2/bad.js')) 183 | #may take a while for the transpiler to run and call home 184 | waitsFor -> 185 | notificationSpy.callCount 186 | runs -> 187 | expect(notificationSpy.callCount).to.equal(1) 188 | msg = notificationSpy.calls[0].args[0].message 189 | expect(msg).to.match(/^LB: Babel.*Transpiler Error/) 190 | expect(writeFileStub.callCount).to.equal(0) 191 | 192 | describe 'When a js file saved but no output is set', -> 193 | it 'calls the transpiler but doesnt save output', -> 194 | atom.project.setPaths([__dirname]) 195 | config.babelSourcePath = 'fixtures' 196 | config.babelTranspilePath = 'fixtures' 197 | config.babelMapsPath = 'fixtures' 198 | config.createTranspiledCode = false 199 | 200 | spyOn(lb, 'getConfig').andCallFake ->config 201 | lb.transpile(path.resolve(__dirname, 'fixtures/dira/dira.1/dira.2/react.jsx')) 202 | #may take a while for the transpiler to run and call home 203 | waitsFor -> 204 | notificationSpy.callCount > 1 205 | runs -> 206 | expect(notificationSpy.callCount).to.equal(2) 207 | msg = notificationSpy.calls[0].args[0].message 208 | expect(msg).to.match(/^LB: Babel.*Transpiler Success/) 209 | msg = notificationSpy.calls[1].args[0].message 210 | expect(msg).to.match(/^LB: No transpiled output configured/) 211 | expect(writeFileStub.callCount).to.equal(0) 212 | 213 | 214 | describe 'When a js file saved but no transpile path is set', -> 215 | it 'calls the transpiler and transpiles OK but doesnt save and issues msg', -> 216 | atom.project.setPaths([__dirname]) 217 | config.babelSourcePath = 'fixtures' 218 | config.babelTranspilePath = 'fixtures' 219 | config.babelMapsPath = 'fixtures' 220 | 221 | spyOn(lb, 'getConfig').andCallFake ->config 222 | lb.transpile(path.resolve(__dirname, 'fixtures/dira/dira.1/dira.2/good.js')) 223 | #may take a while for the transpiler to run and call home 224 | waitsFor -> 225 | notificationSpy.callCount > 1 226 | runs -> 227 | expect(notificationSpy.callCount).to.equal(2) 228 | msg = notificationSpy.calls[0].args[0].message # first call, first arg 229 | expect(msg).to.match(/^LB: Babel.*Transpiler Success/) 230 | msg = notificationSpy.calls[1].args[0].message 231 | expect(msg).to.match(/^LB: Transpiled file would overwrite source file/) 232 | expect(writeFileStub.callCount).to.equal(0) 233 | 234 | describe 'When a jsx file saved,transpile path is set, source maps enabled', -> 235 | it 'calls the transpiler and transpiles OK, saves as .js and issues msg', -> 236 | atom.project.setPaths([__dirname]) 237 | config.babelSourcePath = 'fixtures' 238 | config.babelTranspilePath = 'fixtures-transpiled' 239 | config.babelMapsPath = 'fixtures-maps' 240 | config.createMap = true 241 | 242 | spyOn(lb, 'getConfig').andCallFake ->config 243 | lb.transpile(path.resolve(__dirname, 'fixtures/dira/dira.1/dira.2/react.jsx')) 244 | #may take a while for the transpiler to run and call home 245 | waitsFor -> 246 | writeFileStub.callCount 247 | runs -> 248 | expect(notificationSpy.callCount).to.equal(1) 249 | msg = notificationSpy.calls[0].args[0].message # first call, first arg 250 | expect(msg).to.match(/^LB: Babel.*Transpiler Success/) 251 | expect(writeFileStub.callCount).to.equal(2) 252 | savedFilename = writeFileStub.calls[0].args[0] 253 | expectedFileName = path.resolve(__dirname, 'fixtures-transpiled/dira/dira.1/dira.2/react.js') 254 | expect(savedFilename).to.equal(expectedFileName) 255 | savedFilename = writeFileStub.calls[1].args[0] 256 | expectedFileName = path.resolve(__dirname, 'fixtures-maps/dira/dira.1/dira.2/react.js.map') 257 | expect(savedFilename).to.equal(expectedFileName) 258 | 259 | describe 'When a jsx file saved,transpile path is set, source maps enabled, success suppressed', -> 260 | it 'calls the transpiler and transpiles OK, saves as .js and issues msg', -> 261 | atom.project.setPaths([__dirname]) 262 | config.babelSourcePath = 'fixtures' 263 | config.babelTranspilePath = 'fixtures-transpiled' 264 | config.babelMapsPath = 'fixtures-maps' 265 | config.createMap = true 266 | config.suppressTranspileOnSaveMessages = true 267 | 268 | spyOn(lb, 'getConfig').andCallFake ->config 269 | lb.transpile(path.resolve(__dirname, 'fixtures/dira/dira.1/dira.2/react.jsx')) 270 | #may take a while for the transpiler to run and call home 271 | waitsFor -> 272 | writeFileStub.callCount 273 | runs -> 274 | expect(notificationSpy.callCount).to.equal(0) 275 | expect(writeFileStub.callCount).to.equal(2) 276 | savedFilename = writeFileStub.calls[0].args[0] 277 | expectedFileName = path.resolve(__dirname, 'fixtures-transpiled/dira/dira.1/dira.2/react.js') 278 | expect(savedFilename).to.equal(expectedFileName) 279 | savedFilename = writeFileStub.calls[1].args[0] 280 | expectedFileName = path.resolve(__dirname, 'fixtures-maps/dira/dira.1/dira.2/react.js.map') 281 | expect(savedFilename).to.equal(expectedFileName) 282 | 283 | describe 'When a js file saved , babelrc in path and flag disableWhenNoBabelrcFileInPath is set', -> 284 | it 'calls the transpiler', -> 285 | atom.project.setPaths([__dirname]) 286 | config.babelSourcePath = 'fixtures' 287 | config.babelTranspilePath = 'fixtures' 288 | config.babelMapsPath = 'fixtures' 289 | config.createTranspiledCode = false 290 | config.disableWhenNoBabelrcFileInPath = true 291 | 292 | spyOn(lb, 'getConfig').andCallFake ->config 293 | lb.transpile(path.resolve(__dirname, 'fixtures/dira/dira.1/dira.2/good.js')) 294 | #may take a while for the transpiler to run and call home 295 | waitsFor -> 296 | notificationSpy.callCount 297 | runs -> 298 | expect(notificationSpy.callCount).to.equal(2) 299 | msg = notificationSpy.calls[0].args[0].message 300 | expect(msg).to.match(/^LB: Babel.*Transpiler Success/) 301 | msg = notificationSpy.calls[1].args[0].message 302 | expect(msg).to.match(/^LB: No transpiled output configured/) 303 | expect(writeFileStub.callCount).to.equal(0) 304 | 305 | describe 'When a js file saved , babelrc in not in path and flag disableWhenNoBabelrcFileInPath is set', -> 306 | it 'does nothing', -> 307 | atom.project.setPaths([__dirname]) 308 | config.babelSourcePath = 'fixtures' 309 | config.babelTranspilePath = 'fixtures' 310 | config.babelMapsPath = 'fixtures' 311 | config.createTranspiledCode = false 312 | config.disableWhenNoBabelrcFileInPath = true 313 | 314 | spyOn(lb, 'getConfig').andCallFake ->config 315 | lb.transpile(path.resolve(__dirname, 'fixtures/dirb/good.js')) 316 | expect(notificationSpy.callCount).to.equal(0) 317 | expect(writeFileStub.callCount).to.equal(0) 318 | 319 | describe 'When a js file saved in a nested project', -> 320 | it 'creates a file in the correct location based upon .languagebabel', -> 321 | atom.project.setPaths([__dirname]) 322 | config.allowLocalOverride = true 323 | 324 | spyOn(lb, 'getConfig').andCallFake -> config 325 | sourceFile = path.resolve(__dirname, 'fixtures/projectRoot/src/test.js') 326 | targetFile = path.resolve(__dirname, 'fixtures/projectRoot/test.js') 327 | lb.transpile(sourceFile) 328 | waitsFor -> 329 | writeFileStub.callCount 330 | runs -> 331 | expect(writeFileName).to.equal(targetFile) 332 | 333 | describe 'When a directory is compiled', -> 334 | it 'transpiles the js,jsx,es,es6,babel files but ignores minified files', -> 335 | atom.project.setPaths([__dirname]) 336 | config.allowLocalOverride = true 337 | 338 | spyOn(lb, 'getConfig').andCallFake -> config 339 | sourceDir = path.resolve(__dirname, 'fixtures/projectRoot/src/') 340 | lb.transpileDirectory(sourceDir) 341 | waitsFor -> 342 | writeFileStub.callCount >= 5 343 | runs -> 344 | expect(writeFileStub.callCount).to.equal(5) 345 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### 2.22.0 2 | - Flow declare support for: 3 | - class extends and mixins keywords 4 | - module.exports: type keywords 5 | - declare type and declare interface 6 | - module names that may be quoted. 7 | 8 | ### 2.21.1 9 | - Allow flowtyped arrow function returns to have intersection (&) and array ([]) notation. 10 | 11 | ### 2.21.0 12 | - Allow $ chars to be treated as a word character by Atoms work skip keyboard shortcuts 13 | - Simplify Regex for trivial arrow functions with no argument parens. 14 | 15 | ### 2.20.10 16 | - Fix flow declare class methods named static being parsed as storage modifiers. 17 | - Fix flow declare class methods with no name being parsed incorrectly. 18 | 19 | ### 2.20.9 20 | - Fix class properties with flow keyword names - type, declare & interface being ignored. 21 | - Fix class property issues when used with ASI and flow. 22 | 23 | ### 2.20.8 24 | - Fix handling of let/var/const creation of arrow functions. [Fixes #181](https://github.com/gandm/language-babel/issues/181) 25 | - Fix function labels not allowing all possible characters. [Fixes #184](https://github.com/gandm/language-babel/issues/184) 26 | 27 | ### 2.20.7 28 | - Fix bad destructuring scopes in grammar. 29 | 30 | ### 2.20.6 31 | - Object literal prop:func-call mistakenly treated as prop:method-call. 32 | 33 | ### 2.20.5 34 | - Change JSX tag autocomplete snippet to only have a single anchor. [Fixes #180](https://github.com/gandm/language-babel/issues/180) 35 | 36 | ### 2.20.4 37 | - Fix Flow $JSXIntrinsics properties object being ignored in grammar. 38 | 39 | ### 2.20.3 40 | - Fix incorrect handling of case statement used as a return flow type [Fixes #179](https://github.com/gandm/language-babel/issues/179) 41 | 42 | ### 2.20.2 43 | - Refactored grammar regex reverted in 2.20.1 44 | 45 | ### 2.20.1 46 | - Revert small commit 47 | 48 | ### 2.20.0 49 | - Improve Flow and ASI support. 50 | 51 | ### 2.19.4 52 | - Regression JSX ignoring '-' chars as being valid in custom element names. 53 | 54 | ### 2.19.3 55 | - Added more cases as per 2.19.2 for function/arrow labels. 56 | 57 | ### 2.19.2 58 | - Parsing some ternaries as key/value arrow constants, 59 | 60 | ### 2.19.1 61 | - Incorrect JSX Start regex 62 | 63 | ### 2.19.0 64 | - Modified grammar scopes to highlight JSX components as classes. [Enhancement Request #173](https://github.com/gandm/language-babel/issues/173) 65 | 66 | ### 2.18.7 67 | - Add close brace and close array as let, var and const terminators. 68 | 69 | ### 2.18.6 70 | - Fix keys & values named type & declare being highlighted as js keywords. [Fixes #172 ](https://github.com/gandm/language-babel/issues/172) 71 | - Scope flow variant polymorph operators <+T,-V> 72 | 73 | ### 2.18.5 74 | - Grammar incorrectly parsed a returned object literal. [Fixes #171](https://github.com/gandm/language-babel/issues/171) 75 | 76 | ### 2.18.4 77 | - Make literal-object grammar recursive to fix nested object methods. 78 | 79 | ### 2.18.3 80 | - Improve detection of object literals. [Fixes #170](https://github.com/gandm/language-babel/issues/170) 81 | 82 | ### 2.18.2 83 | - Fix function call td.function() being interpreted as a function definition. [Fixes #169](https://github.com/gandm/language-babel/issues) 84 | 85 | ### 2.18.1 86 | - Incorrect scope for arrow function async keyword inside object literal. [Fixes](https://github.com/gandm/language-babel/issues/168) 87 | 88 | ### 2.18.0 89 | - Allow flow syntax to be used within files that use ASI. 90 | - Use two forms of scoping for interpolated strings. [Fixes](https://github.com/gandm/language-babel/issues/167) 91 | 92 | ### 2.17.3 93 | - [Fixes #166](https://github.com/gandm/language-babel/issues/166) Grammar for `async`, `get` and `set` on shorthand object functions 94 | 95 | ### 2.17.2 96 | - [Fixes #164](https://github.com/gandm/language-babel/issues/164) flow comment syntax breaks highlighting 97 | 98 | ### 2.17.1 99 | - Fix regression: single line comment not including language-todo 100 | - Fix export default in grammar 101 | 102 | #### 2.17.0 103 | - Add file tree `Babel Transpile` context menu. [Enhancement Request #160](https://github.com/gandm/language-babel/issues/160) 104 | - Add `.es` as grammar detected file type. 105 | - Grammar support for RegEx `u` flags. 106 | - Fix to allow uppercase literals in 0X,0E,0B,0O expressions. 107 | - Scope arrow symbol `=>` when unparsed. See [Issue #149](https://github.com/gandm/language-babel/issues/149) 108 | 109 | #### 2.16.0 110 | - Refactor ::indentRow 111 | 112 | #### 2.15.8 113 | - Fix autoIndentJSX for Ternary expressions and other issues. 114 | 115 | #### 2.15.7 116 | - Fix autoIndentJSX for first tag of embedded expression. 117 | - Fix positioning on new JSX line. 118 | 119 | #### 2.15.6 120 | - Remove scopes for nodejs support variables. [Fixes issue #152](https://github.com/gandm/language-babel/issues/152) 121 | - Fixed more JSX indenting issues. 122 | 123 | #### 2.15.5 124 | - Fix colon in case missing scope [Fixes #145](https://github.com/gandm/language-babel/issues/145) 125 | - Fix move/paste JSX blocks not auto-indenting. [Fixes #150](https://github.com/gandm/language-babel/issues/150) 126 | - Add [atom-grammar-test](https://github.com/kevinastone/atom-grammar-test) package as grammar spec handler. 127 | 128 | #### 2.15.4 129 | - Fix #144 130 | - Improve Auto indent JSX for embedded components within tags. 131 | 132 | #### 2.15.3 133 | - Fix auto indent when JSX at end of file. 134 | 135 | #### 2.15.2 136 | - Fix JSX auto indenting for multiple cursors. 137 | 138 | #### 2.15.1 139 | - Missing a check for the auto indent toggle - Doesn't turn off indenting. 140 | 141 | #### 2.15.0 142 | - Improve auto-indenting and formatting of JSX to allow for embedded expressions. 143 | - Remove monkey patching as not required. 144 | 145 | #### 2.14.1 146 | - Fix specs 147 | 148 | #### 2.14.0 149 | - Auto Indent JSX is now turned off by default as it is still experimental. 150 | 151 | #### 2.13.0 152 | - Support namespaced JSX components. 153 | - Add readme information about the toggle comments feature inside JSX blocks. 154 | 155 | #### 2.12.2 156 | - Fixes #138 Adds scope to semi-colon class property terminator. 157 | 158 | #### 2.12.1 159 | - Fixes #137 Division with no spaces incorrectly scoped. e.g. var x = 1/123 160 | 161 | #### 2.12.0 162 | - Babel transpiled code can be viewed in real-time in the editor. Requires the [source-preview](https://atom.io/packages/source-preview) package ^v.4.0. 163 | 164 | #### 2.11.3 165 | - Improve Fix for 2.11.2 166 | - Improve cursor positioning after JSX new line insertion. 167 | 168 | #### 2.11.2 169 | - Fix Non JSX trailing JSX insertion point was being indented. Fixes #136 170 | - Remove JSON5 dependency. 171 | 172 | #### 2.11.1 173 | - Inadvertently removed JSON5! 174 | 175 | #### 2.11.0 176 | - Support .eslintrc YAML files 177 | 178 | #### 2.10.0 179 | - Change Atom's toggle comments to use `{/* */}` when inside JSX blocks. 180 | 181 | #### 2.9.5 182 | - Improved indenting 183 | 184 | #### 2.9.4 185 | - Fixes #132 186 | 187 | #### 2.9.3 188 | - Improve .eslintrc parsing 189 | 190 | #### 2.9.2 191 | - Fixes #130 .eslintrc has no rules property. 192 | 193 | #### 2.9.1 194 | - Fixes #126. 195 | 196 | #### 2.9.0 197 | - Use JSON5 to parse .eslintrc 198 | 199 | #### 2.8.3 200 | - incorrect filename reference when notifying a user about invalid JSON in .eslintrc 201 | 202 | #### 2.8.2 203 | - Minor change 204 | 205 | #### 2.8.1 206 | - Minor change 207 | 208 | #### 2.8.0 209 | - Initial release of JSX auto formatting. 210 | 211 | #### 2.7.4 212 | - Small fixes to grammar as per issues #123 and #125 213 | 214 | #### 2.7.3 215 | - Fix Scope on $ variables - PR #121 216 | 217 | #### 2.7.2 218 | - Fix 2.7.1 grammar! 219 | 220 | #### 2.7.1 221 | - Add scope to commas - Fixes 119 222 | - Minor changes to JSX Autocomplete 223 | 224 | #### 2.7.0 225 | - Added auto completion of React JSX start/end tags + HTML tag names & attributes 226 | 227 | #### 2.6.3 228 | - Added more flow builtin types. 229 | - Fixes #118. Typo in scopename. 230 | 231 | #### 2.6.2 232 | - Fixes 2.6.1 precedence! 233 | 234 | #### 2.6.1 235 | - Fix issues when same file is displayed (split) into two or more panes. 236 | 237 | #### 2.6.0 238 | - Add `.flow` as a supported file type. See http://flowtype.org/blog/2015/12/01/Version-0.19.0.html#declaration-files 239 | 240 | #### 2.5.4 241 | - Fix babel error column position row indexed from 1 but column indexed from 0 242 | 243 | #### 2.5.3 244 | - Added PID info when task goes missing for no recorded reason! 245 | 246 | #### 2.5.2 247 | - Transpiler task goes missing so recover it. Issue #110 Maybe related to https://github.com/atom/atom/issues/9663 248 | 249 | #### 2.5.1 250 | - Check that Babel returns a valid line/column for an error. 251 | 252 | #### 2.5.0 253 | - Trap transpiler task stack traces. 254 | 255 | #### 2.4.1 256 | - Remove console.log! 257 | 258 | #### 2.4.0 259 | - Add new property `projectRoot` to ``.languagebabel` to allow for nested projects. 260 | 261 | #### 2.3.1 262 | - Fixes #106 - prefixed whitespace before number scoped as part of it. 263 | 264 | #### 2.3.0 265 | - Modified how sub tasks are closed. 266 | - Fixed issue for handling babel's ignored property. 267 | - Added info about the example project which shows some `.languagebabel` configs. 268 | 269 | #### 2.2.0 270 | - The package now supports mixed Babel V5 & Babel V6 projects. 271 | 272 | #### 2.1.0 273 | - Fix memory leak issues 274 | - Fix for growing listener pool 275 | - Fix for Atom issue never deleting memory for dismissed notifications 276 | 277 | #### 2.0.2 278 | - babel-core and chai as dependencies not Dev. 279 | 280 | #### 2.0.1 281 | - Whoops!!! Missing files. 282 | 283 | #### 2.0.0 284 | - Babel V6 support is now provided for Project based development. 285 | 286 | #### 1.0.0 287 | - Babel V6 is now supported with additional options for plugins and presets. See README. 288 | - Babel V5 support is removed together with options to configure stages, whitelists, etc. 289 | - Minor fixes in grammar. 290 | 291 | #### 0.15.13 292 | - Fix for some < equality operators being seen as JSX. 293 | 294 | #### 0.15.12 295 | - Avoid parsing lines over 1000 chars long. No point as it's a performance hit and ATOM has a token limit. 296 | 297 | #### 0.15.11 298 | - Fix function call expressions. 299 | 300 | #### 0.15.10 301 | - Fixes fat arrows being passed as function arguments. 302 | 303 | #### 0.15.9 304 | - Fixes #95 - toggle-quotes not working. 305 | 306 | #### 0.15.8 307 | - Add scopes for esc chars in template strings. 308 | - Fix for #93. 309 | 310 | #### 0.15.7 311 | - Fix ternaries as in issue #91 312 | 313 | #### 0.15.6 314 | - Fix for Issue #60. 315 | - Fix for ES7 decorators. 316 | 317 | #### 0.15.5 318 | - Fix methods that have array/string forms. 319 | 320 | #### 0.15.4 321 | - Removed lodash dependency & lazy load jjv. 322 | 323 | #### 0.15.3 324 | - Fixes #86 JSX Attribute names not scoped when terminated by > or /> 325 | 326 | #### 0.15.2 327 | - Various non critical PR's 328 | - Change perceived package load time for language-babel. 329 | 330 | #### 0.15.1 331 | - Support flowtype class mixins and multiple inheritance via interface extends 332 | - Various fixes. 333 | 334 | #### 0.15.0 335 | - Added a new option `Allow Local Override` to enable the `.languagebabel` option. 336 | - Various other fixes in grammar. 337 | - Workaround to fix issues on Nuclide Remote Filesystems causing endless loop. 338 | 339 | #### 0.14.0 340 | - BREAKING: `Transpile On Save` is now disabled by default. Please re-enable if required. [See Issue 64](https://github.com/gandm/language-babel/issues/64) 341 | - Local configuration of language-babel options via JSON configuration files - `.languagebabel` is now supported. Please [README](https://github.com/gandm/language-babel/blob/master/README.md) [See Issue 51](https://github.com/gandm/language-babel/issues/51) 342 | 343 | #### 0.13.6 344 | - Small fixes in ternary handling 345 | - Fixes #63 346 | 347 | #### 0.13.5 348 | - Changed scopenames for vars in func defs and calls to use variable... 349 | 350 | #### 0.13.4 351 | - Fixes #61 Regression - Class not in first column no scoped. 352 | 353 | #### 0.13.3 354 | - Fix issues with parens/braces not terminating scope. 355 | - Fix optional flowtype params and maybe type handling. 356 | - Change scope when 'constructor', 'super' and 'self' used as method names. 357 | 358 | #### 0.13.2 359 | - Fixes #57. Highlighting breaks down. 360 | - Remove generators from arrow functions 361 | - Ternary/Typecast detection 362 | 363 | #### 0.13.1 364 | - Fixes #55 missing scope on JSX self closing tags. 365 | 366 | #### 0.13.0 367 | - Add jsduck documentation keywords. 368 | - Fixes #53 ternary operator being parsed as flow type. 369 | 370 | #### 0.12.0 371 | - PR #50 Add simple JSDoc grammar. 372 | - Scope fixes. 373 | 374 | #### 0.11.11 375 | - Fixes #49 incorrect handling of escapes within strings. 376 | 377 | #### 0.11.10 378 | - Add flow typecast support as per [flowtype blog](http://flowtype.org/blog/2015/02/18/Typecasts.html) 379 | 380 | #### 0.11.9 381 | - Various Fixes. 382 | 383 | #### 0.11.8 384 | - Fix & symbol being treated as expression termination. 385 | 386 | #### 0.11.7 387 | - Various Fixes 388 | - Adds flow type support for let, var and const. Read [limitations](https://github.com/gandm/language-babel/issues/46) 389 | 390 | #### 0.11.6 391 | - Fixes #45 obj literal with key of type inferred as flow type keyword. 392 | - Revert to V10 scope name for function arg parens. 393 | 394 | #### 0.11.5 395 | - Improvements to polymorphic type function & arrow function parsing. 396 | 397 | #### 0.11.4 398 | - README fix to Issue #42 399 | - Various changes to flow type support. 400 | - Fix embedded escape back quote in Quasi Literal. 401 | - Change some scopes to affect colours. 402 | 403 | #### 0.11.3 404 | - fixed polymorphs for functions. 405 | 406 | #### 0.11.2 407 | - fix scopes for quoted literal-arrow-function-labels 408 | 409 | #### 0.11.1 410 | - fix arrow functions 411 | 412 | #### 0.11.0 413 | - Initial support for Facebook flow. 414 | 415 | #### 0.10.5 416 | - Fixes #36 - Clarify grammar name to match standard and atom-preview package. 417 | - Fixes #37 Comment not calling TODO injectioin grammar 418 | 419 | #### 0.10.4 420 | - Fixes #27 scope on ArrowFunctions 421 | - Checks for no map returned 422 | 423 | #### 0.10.3 424 | - Fix various grammar issues reported/PR's 425 | - bump babel-core version in dependencies. 426 | 427 | #### 0.10.2 428 | - PR to add additional module options for Babel #22 429 | - PR Removed label scope from "constant.other.object.key.js" grammar. #20 430 | 431 | #### 0.10.1 432 | - Not checking for result.ignored flag correctly. fixes #21 433 | 434 | #### 0.10.0 435 | - Clear transpile error messages automatically on next save. closes #16 436 | 437 | #### 0.9.1 438 | - Bad deprecation code looses config settings 439 | 440 | #### 0.9.0 441 | - Added new flag `disableWhenNoBabelrcFileInPath` to stop transpiles in absence of `.babelrc` fixes #15 442 | - Corrected misspelling of suppress - about time! 443 | 444 | #### 0.8.1 445 | - extend suppress message flag to include no output config'd messages 446 | 447 | #### 0.8.0 448 | - Removed Internal Scanner 449 | 450 | #### 0.7.4 451 | - Future deprecation of internal scanner. 452 | 453 | #### 0.7.3 454 | - Use Chai ^3.0.0 455 | - Fixes #10 - jsx tag punctuation incorrect 456 | 457 | #### 0.7.2 458 | - Added dependency badge and small changes to readme. 459 | 460 | #### 0.7.1 461 | - Fix bug where project is in root directory 462 | - Add new screen Image 463 | 464 | #### 0.7.0 465 | - Errors that return row,column cause editor to jump to that position 466 | - Added option button to see babel options. Use internal Scanner for most benefit. 467 | - Added option to suppress transpile success messages 468 | - Added specs 469 | - Use Atom's fs-plus as replacement for nodes fs 470 | - Removed dependency on mkdirp as fs-plus uses it anyway 471 | 472 | #### 0.6.2 473 | - Reverted change as per issue 7 474 | 475 | #### 0.6.1 476 | - Changes to readme 477 | - Cosmetic changes to transpiler 478 | - Added back case and default indentation as per issue 7 479 | 480 | #### 0.6.0 481 | - Changes to augment handling of `.babelrc` files 482 | 483 | #### 0.5.6 484 | - Applied pull request 485 | - Added babel-core version used in notification dialogs 486 | 487 | #### 0.5.5 488 | - Fix scope Indent 489 | 490 | #### 0.5.4 491 | - Fix scope styling 492 | 493 | #### 0.5.3 494 | - Fix linter-eslint not working. 495 | 496 | #### 0.5.2 497 | - Fixes Issue 4. Symbol view not working. 498 | 499 | #### 0.5.1 500 | - Correct readme 501 | 502 | #### 0.5.0 503 | - New suppress source message option. 504 | - Use Cases added to readme. 505 | 506 | #### 0.4.4 507 | - patch not detecting { } not scoping. error moving babel-sublime regex to language-babel 525 | 526 | #### 0.3.7 527 | - Modified JSX spread attribute handling 528 | - Added trap for bad entity name 529 | - Added style for JSX attribute names to be italic 530 | 531 | #### 0.3.6 532 | - closes https://github.com/gandm/language-babel/issues/2 533 | - closes https://github.com/gandm/language-babel/issues/3 534 | 535 | #### 0.3.5 536 | - Permanent removal of invalid element name highlighting 537 | 538 | #### 0.3.4 539 | - Grammar Changes 540 | - Disabled invalid JSX invalid element name highlight. Firing on < operator erroneously. 541 | 542 | #### 0.3.3 543 | - Grammar Changes 544 | - Removed pure JSX syntax checking to remove options for namespaced names as per React JSX 545 | 546 | #### 0.1.0 547 | - Intital Releases 548 | -------------------------------------------------------------------------------- /lib/transpiler.coffee: -------------------------------------------------------------------------------- 1 | {Task, CompositeDisposable } = require 'atom' 2 | fs = require 'fs-plus' 3 | path = require 'path' 4 | pathIsInside = require '../node_modules/path-is-inside' 5 | 6 | # setup JSON Schema to parse .languagebabel configs 7 | languagebabelSchema = { 8 | type: 'object', 9 | properties: { 10 | babelMapsPath: { type: 'string' }, 11 | babelMapsAddUrl: { type: 'boolean' }, 12 | babelSourcePath: { type: 'string' }, 13 | babelTranspilePath: { type: 'string' }, 14 | createMap: { type: 'boolean' }, 15 | createTargetDirectories: { type: 'boolean' }, 16 | createTranspiledCode: { type: 'boolean' }, 17 | disableWhenNoBabelrcFileInPath: { type: 'boolean' }, 18 | projectRoot: { type: 'boolean' }, 19 | suppressSourcePathMessages: { type: 'boolean' }, 20 | suppressTranspileOnSaveMessages: { type: 'boolean' }, 21 | transpileOnSave: { type: 'boolean' } 22 | }, 23 | additionalProperties: false 24 | } 25 | 26 | class Transpiler 27 | 28 | fromGrammarName: 'Babel ES6 JavaScript' 29 | fromScopeName: 'source.js.jsx' 30 | toScopeName: 'source.js.jsx' 31 | 32 | constructor: -> 33 | @reqId = 0 34 | @babelTranspilerTasks = {} 35 | @babelTransformerPath = require.resolve './transpiler-task' 36 | @transpileErrorNotifications = {} 37 | @deprecateConfig() 38 | @disposables = new CompositeDisposable() 39 | if @getConfig().transpileOnSave or @getConfig().allowLocalOverride 40 | @disposables.add atom.contextMenu.add { 41 | '.tree-view .directory > .header > .name': [ 42 | {label: 'Babel Transpile', command: 'language-babel:transpile-directory'} 43 | {'type': 'separator'} 44 | ] 45 | } 46 | @disposables.add atom.commands.add '.tree-view .directory > .header > .name', 'language-babel:transpile-directory', @commandTranspileDirectory 47 | 48 | # method used by source-preview to see transpiled code 49 | transform: (code, {filePath, sourceMap}) -> 50 | config = @getConfig() 51 | pathTo = @getPaths filePath, config 52 | # create babel transformer tasks - one per project as needed 53 | @createTask pathTo.projectPath 54 | babelOptions = 55 | filename: filePath 56 | sourceMaps: sourceMap ? false 57 | ast: false 58 | # ok now transpile in the task and wait on the result 59 | if @babelTranspilerTasks[pathTo.projectPath] 60 | reqId = @reqId++ 61 | msgObject = 62 | reqId: reqId 63 | command: 'transpileCode' 64 | pathTo: pathTo 65 | code: code 66 | babelOptions: babelOptions 67 | 68 | new Promise (resolve, reject ) => 69 | # transpile in task 70 | try 71 | @babelTranspilerTasks[pathTo.projectPath].send(msgObject) 72 | catch err 73 | delete @babelTranspilerTasks[pathTo.projectPath] 74 | reject("Error #{err} sending to transpile task with PID #{@babelTranspilerTasks[pathTo.projectPath].childProcess.pid}") 75 | # get result from task for this reqId 76 | @babelTranspilerTasks[pathTo.projectPath].once "transpile:#{reqId}", (msgRet) => 77 | if msgRet.err? 78 | reject("Babel v#{msgRet.babelVersion}\n#{msgRet.err.message}\n#{msgRet.babelCoreUsed}") 79 | else 80 | msgRet.sourceMap = msgRet.map 81 | resolve(msgRet) 82 | 83 | # called by command 84 | commandTranspileDirectory: ({target}) => 85 | @transpileDirectory target.dataset.path 86 | 87 | # transpile all files in a directory 88 | transpileDirectory: (directory) -> 89 | fs.readdir directory, (err,files) => 90 | if not err? 91 | files.map (file) => 92 | return if /\.min\.[a-z]+$/.test file # no minimized files 93 | if /\.(js|jsx|es|es6|babel)$/.test file # only js 94 | @transpile file, null, @getConfigAndPathTo path.join(directory, file) 95 | 96 | # transpile sourceFile edited by the optional textEditor 97 | transpile: (sourceFile, textEditor, configAndPathTo) -> 98 | # get config 99 | if configAndPathTo? 100 | { config, pathTo } = configAndPathTo 101 | else 102 | {config, pathTo } = @getConfigAndPathTo(sourceFile) 103 | 104 | return if config.transpileOnSave isnt true 105 | 106 | if config.disableWhenNoBabelrcFileInPath 107 | if not @isBabelrcInPath pathTo.sourceFileDir 108 | return 109 | 110 | if not pathIsInside(pathTo.sourceFile, pathTo.sourceRoot) 111 | if not config.suppressSourcePathMessages 112 | atom.notifications.addWarning 'LB: Babel file is not inside the "Babel Source Path" directory.', 113 | dismissable: false 114 | detail: "No transpiled code output for file \n#{pathTo.sourceFile} 115 | \n\nTo suppress these 'invalid source path' 116 | messages use language-babel package settings" 117 | return 118 | 119 | babelOptions = @getBabelOptions config 120 | 121 | @cleanNotifications(pathTo) 122 | 123 | # create babel transformer tasks - one per project as needed 124 | @createTask pathTo.projectPath 125 | 126 | # ok now transpile in the task and wait on the result 127 | if @babelTranspilerTasks[pathTo.projectPath] 128 | reqId = @reqId++ 129 | msgObject = 130 | reqId: reqId 131 | command: 'transpile' 132 | pathTo: pathTo 133 | babelOptions: babelOptions 134 | 135 | # transpile in task 136 | try 137 | @babelTranspilerTasks[pathTo.projectPath].send(msgObject) 138 | catch err 139 | console.log "Error #{err} sending to transpile task with PID #{@babelTranspilerTasks[pathTo.projectPath].childProcess.pid}" 140 | delete @babelTranspilerTasks[pathTo.projectPath] 141 | @createTask pathTo.projectPath 142 | console.log "Restarted transpile task with PID #{@babelTranspilerTasks[pathTo.projectPath].childProcess.pid}" 143 | @babelTranspilerTasks[pathTo.projectPath].send(msgObject) 144 | 145 | # get result from task for this reqId 146 | @babelTranspilerTasks[pathTo.projectPath].once "transpile:#{reqId}", (msgRet) => 147 | # .ignored is returned when .babelrc ignore/only flags are used 148 | if msgRet.result?.ignored then return 149 | if msgRet.err 150 | if msgRet.err.stack 151 | @transpileErrorNotifications[pathTo.sourceFile] = 152 | atom.notifications.addError "LB: Babel Transpiler Error", 153 | dismissable: true 154 | detail: "#{msgRet.err.message}\n \n#{msgRet.babelCoreUsed}\n \n#{msgRet.err.stack}" 155 | else 156 | @transpileErrorNotifications[pathTo.sourceFile] = 157 | atom.notifications.addError "LB: Babel v#{msgRet.babelVersion} Transpiler Error", 158 | dismissable: true 159 | detail: "#{msgRet.err.message}\n \n#{msgRet.babelCoreUsed}\n \n#{msgRet.err.codeFrame}" 160 | # if we have a line/col syntax error jump to the position 161 | if msgRet.err.loc?.line? and textEditor? 162 | textEditor.setCursorBufferPosition [msgRet.err.loc.line-1, msgRet.err.loc.column] 163 | else 164 | if not config.suppressTranspileOnSaveMessages 165 | atom.notifications.addInfo "LB: Babel v#{msgRet.babelVersion} Transpiler Success", 166 | detail: "#{pathTo.sourceFile}\n \n#{msgRet.babelCoreUsed}" 167 | 168 | if not config.createTranspiledCode 169 | if not config.suppressTranspileOnSaveMessages 170 | atom.notifications.addInfo 'LB: No transpiled output configured' 171 | return 172 | if pathTo.sourceFile is pathTo.transpiledFile 173 | atom.notifications.addWarning 'LB: Transpiled file would overwrite source file. Aborted!', 174 | dismissable: true 175 | detail: pathTo.sourceFile 176 | return 177 | 178 | # write code and maps 179 | if config.createTargetDirectories 180 | fs.makeTreeSync( path.parse( pathTo.transpiledFile).dir) 181 | 182 | # add source map url to code if file isn't ignored 183 | if config.babelMapsAddUrl 184 | msgRet.result.code = msgRet.result.code + '\n' + '//# sourceMappingURL='+pathTo.mapFile 185 | 186 | fs.writeFileSync pathTo.transpiledFile, msgRet.result.code 187 | 188 | # write source map if returned and if asked 189 | if config.createMap and msgRet.result.map?.version 190 | if config.createTargetDirectories 191 | fs.makeTreeSync(path.parse(pathTo.mapFile).dir) 192 | mapJson = 193 | version: msgRet.result.map.version 194 | sources: pathTo.sourceFile 195 | file: pathTo.transpiledFile 196 | sourceRoot: '' 197 | names: msgRet.result.map.names 198 | mappings: msgRet.result.map.mappings 199 | xssiProtection = ')]}\n' 200 | fs.writeFileSync pathTo.mapFile, 201 | xssiProtection + JSON.stringify mapJson, null, ' ' 202 | 203 | # clean notification messages 204 | cleanNotifications: (pathTo) -> 205 | # auto dismiss previous transpile error notifications for this source file 206 | if @transpileErrorNotifications[pathTo.sourceFile]? 207 | @transpileErrorNotifications[pathTo.sourceFile].dismiss() 208 | delete @transpileErrorNotifications[pathTo.sourceFile] 209 | # remove any user dismissed notification object references 210 | for sf, n of @transpileErrorNotifications 211 | if n.dismissed 212 | delete @transpileErrorNotifications[sf] 213 | # FIX for atom notifications. dismissed noftifications via whatever means 214 | # are never actually removed from memory. I consider this a memory leak 215 | # See https://github.com/atom/atom/issues/8614 so remove any dismissed 216 | # notification objects prefixed with a message prefix of LB: from memory 217 | i = atom.notifications.notifications.length - 1 218 | while i >= 0 219 | if atom.notifications.notifications[i].dismissed and 220 | atom.notifications.notifications[i].message.substring(0,3) is "LB:" 221 | atom.notifications.notifications.splice i, 1 222 | i-- 223 | 224 | # create babel transformer tasks - one per project as needed 225 | createTask: (projectPath) -> 226 | @babelTranspilerTasks[projectPath] ?= 227 | Task.once @babelTransformerPath, projectPath, => 228 | # task ended 229 | delete @babelTranspilerTasks[projectPath] 230 | 231 | # modifies config options for changed or deprecated configs 232 | deprecateConfig: -> 233 | if atom.config.get('language-babel.supressTranspileOnSaveMessages')? 234 | atom.config.set 'language-babel.suppressTranspileOnSaveMessages', 235 | atom.config.get('language-babel.supressTranspileOnSaveMessages') 236 | if atom.config.get('language-babel.supressSourcePathMessages')? 237 | atom.config.set 'language-babel.suppressSourcePathMessages', 238 | atom.config.get('language-babel.supressSourcePathMessages') 239 | atom.config.unset('language-babel.supressTranspileOnSaveMessages') 240 | atom.config.unset('language-babel.supressSourcePathMessages') 241 | atom.config.unset('language-babel.useInternalScanner') 242 | atom.config.unset('language-babel.stopAtProjectDirectory') 243 | # remove babel V5 options 244 | atom.config.unset('language-babel.babelStage') 245 | atom.config.unset('language-babel.externalHelpers') 246 | atom.config.unset('language-babel.moduleLoader') 247 | atom.config.unset('language-babel.blacklistTransformers') 248 | atom.config.unset('language-babel.whitelistTransformers') 249 | atom.config.unset('language-babel.looseTransformers') 250 | atom.config.unset('language-babel.optionalTransformers') 251 | atom.config.unset('language-babel.plugins') 252 | atom.config.unset('language-babel.presets') 253 | # remove old name indent options 254 | atom.config.unset('language-babel.formatJSX') 255 | 256 | # calculate babel options based upon package config, babelrc files and 257 | # whether internalScanner is used. 258 | getBabelOptions: (config)-> 259 | # set transpiler options from package configuration. 260 | babelOptions = 261 | sourceMaps: config.createMap 262 | code: true 263 | 264 | #get configuration and paths 265 | getConfigAndPathTo: (sourceFile) -> 266 | config = @getConfig() 267 | pathTo = @getPaths sourceFile, config 268 | 269 | if config.allowLocalOverride 270 | if not @jsonSchema? 271 | @jsonSchema = (require '../node_modules/jjv')() # use jjv as it runs without CSP issues 272 | @jsonSchema.addSchema 'localConfig', languagebabelSchema 273 | localConfig = @getLocalConfig pathTo.sourceFileDir, pathTo.projectPath, {} 274 | # merge local configs with global. local wins 275 | @merge config, localConfig 276 | # recalc paths 277 | pathTo = @getPaths sourceFile, config 278 | return { config, pathTo } 279 | 280 | # get global configuration for language-babel 281 | getConfig: -> atom.config.get('language-babel') 282 | 283 | # check for prescence of a .languagebabel file path fromDir toDir 284 | # read, validate and overwrite config as required 285 | # toDir is normally the implicit Atom project folders root but we 286 | # will stop of a projectRoot true is found as well 287 | getLocalConfig: (fromDir, toDir, localConfig) -> 288 | # get local path overides 289 | localConfigFile = '.languagebabel' 290 | languageBabelCfgFile = path.join fromDir, localConfigFile 291 | if fs.existsSync languageBabelCfgFile 292 | fileContent= fs.readFileSync languageBabelCfgFile, 'utf8' 293 | try 294 | jsonContent = JSON.parse fileContent 295 | catch err 296 | atom.notifications.addError "LB: #{localConfigFile} #{err.message}", 297 | dismissable: true 298 | detail: "File = #{languageBabelCfgFile}\n\n#{fileContent}" 299 | return 300 | 301 | schemaErrors = @jsonSchema.validate 'localConfig', jsonContent 302 | if schemaErrors 303 | atom.notifications.addError "LB: #{localConfigFile} configuration error", 304 | dismissable: true 305 | detail: "File = #{languageBabelCfgFile}\n\n#{fileContent}" 306 | else 307 | # merge local config. config closest sourceFile wins 308 | # apart from projectRoot which wins on true 309 | isProjectRoot = jsonContent.projectRoot 310 | @merge jsonContent, localConfig 311 | if isProjectRoot then jsonContent.projectRootDir = fromDir 312 | localConfig = jsonContent 313 | if fromDir isnt toDir 314 | # stop infinite recursion https://github.com/gandm/language-babel/issues/66 315 | if fromDir == path.dirname(fromDir) then return localConfig 316 | # check projectRoot property and end recursion if true 317 | if isProjectRoot then return localConfig 318 | return @getLocalConfig path.dirname(fromDir), toDir, localConfig 319 | else return localConfig 320 | 321 | # calculate absoulte paths of babel source, target js and maps files 322 | # based upon the project directory containing the source 323 | # and the roots of source, transpile path and maps paths defined in config 324 | getPaths: (sourceFile, config) -> 325 | projectContainingSource = atom.project.relativizePath sourceFile 326 | # Is the sourceFile located inside an Atom project folder? 327 | if projectContainingSource[0] is null 328 | sourceFileInProject = false 329 | else sourceFileInProject = true 330 | # determines the project root dir from .languagebabel or from Atom 331 | # if a project is in the root directory of atom passes back a null for 332 | # the project path if the file isn't in a project folder 333 | # so make the root dir that source file the project 334 | if config.projectRootDir? 335 | absProjectPath = path.normalize(config.projectRootDir) 336 | else if projectContainingSource[0] is null 337 | absProjectPath = path.parse(sourceFile).root 338 | else 339 | absProjectPath = path.normalize(projectContainingSource[0]) 340 | relSourcePath = path.normalize(config.babelSourcePath) 341 | relTranspilePath = path.normalize(config.babelTranspilePath) 342 | relMapsPath = path.normalize(config.babelMapsPath) 343 | 344 | absSourceRoot = path.join(absProjectPath , relSourcePath) 345 | absTranspileRoot = path.join(absProjectPath , relTranspilePath) 346 | absMapsRoot = path.join(absProjectPath , relMapsPath) 347 | 348 | parsedSourceFile = path.parse(sourceFile) 349 | relSourceRootToSourceFile = path.relative(absSourceRoot, parsedSourceFile.dir) 350 | absTranspiledFile = path.join(absTranspileRoot, relSourceRootToSourceFile , parsedSourceFile.name + '.js') 351 | absMapFile = path.join(absMapsRoot, relSourceRootToSourceFile , parsedSourceFile.name + '.js.map') 352 | 353 | sourceFileInProject: sourceFileInProject 354 | sourceFile: sourceFile 355 | sourceFileDir: parsedSourceFile.dir 356 | mapFile: absMapFile 357 | transpiledFile: absTranspiledFile 358 | sourceRoot: absSourceRoot 359 | projectPath: absProjectPath 360 | 361 | # check for prescence of a .babelrc file path fromDir to root 362 | isBabelrcInPath: (fromDir) -> 363 | # enviromnents used in babelrc 364 | babelrc = '.babelrc' 365 | babelrcFile = path.join fromDir, babelrc 366 | if fs.existsSync babelrcFile 367 | return true 368 | if fromDir != path.dirname(fromDir) 369 | return @isBabelrcInPath path.dirname(fromDir) 370 | else return false 371 | 372 | # simple merge of objects 373 | merge: (targetObj, sourceObj) -> 374 | for prop, val of sourceObj 375 | targetObj[prop] = val 376 | 377 | # stop transpiler task 378 | stopTranspilerTask: (projectPath) -> 379 | msgObject = 380 | command: 'stop' 381 | @babelTranspilerTasks[projectPath].send(msgObject) 382 | 383 | # stop all transpiler tasks 384 | stopAllTranspilerTask: () -> 385 | for projectPath, v of @babelTranspilerTasks 386 | @stopTranspilerTask(projectPath) 387 | 388 | # stop unsued transpiler tasks if its path isn't present in a current 389 | # Atom project folder 390 | stopUnusedTasks: () -> 391 | atomProjectPaths = atom.project.getPaths() 392 | for projectTaskPath,v of @babelTranspilerTasks 393 | isTaskInCurrentProject = false 394 | for atomProjectPath in atomProjectPaths 395 | if pathIsInside(projectTaskPath, atomProjectPath) 396 | isTaskInCurrentProject = true 397 | break 398 | if not isTaskInCurrentProject then @stopTranspilerTask(projectTaskPath) 399 | 400 | module.exports = Transpiler 401 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/babel-sublime/jsx-attributes.jsx: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | // 3 | // GOOD JSX followed by this JSX spec 4 | // 5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
this.setState({})} /> 17 |
18 |
19 |
21 |
24 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 | // <- meta.tag.jsx punctuation.definition.tag.jsx 40 | // <- meta.tag.jsx entity.name.tag.open.jsx 41 | //^^ ^^^^^^^^^ ^^^^ meta.tag.jsx 42 | // ^ punctuation.definition.tag.jsx 43 | //^^ entity.name.tag.open.jsx 44 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 45 | // ^ JSXStartTagEnd 46 |
47 | //^^^^ ^^^^^^^^ ^^^^^^^^^ ^^^^^^^^ ^^^^ meta.tag.jsx 48 | //^ ^ punctuation.definition.tag.jsx 49 | // ^^^ entity.name.tag.open.jsx 50 | // ^^^^^^^^ ^^^^^^^^ comment.block.js 51 | // ^^ ^^ ^^ ^^ punctuation.definition.comment.js 52 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 53 | // ^ JSXStartTagEnd 54 |
55 | // ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ meta.tag.jsx 56 | // ^ ^ punctuation.definition.tag.jsx 57 | // ^^^ entity.name.tag.open.jsx 58 | // ^^^^^^^^ ^^^^^^^^ comment.block.js 59 | // ^^ ^^ ^^ ^^ punctuation.definition.comment.js 60 | // ^^^ entity.other.attribute-name.jsx 61 | // ^ JSXStartTagEnd 62 |
76 | // ^^ meta.tag.jsx 77 | // ^^ punctuation.definition.tag.jsx 78 |
79 | // ^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^ meta.tag.jsx 80 | // ^ ^ punctuation.definition.tag.jsx 81 | // ^^^ entity.name.tag.open.jsx 82 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 83 | // ^ keyword.operator.assignment.jsx 84 | // ^^^^^^^^^ string.quoted.single.js 85 | // ^ punctuation.definition.string.begin.jsx 86 | // ^ punctuation.definition.string.end.jsx 87 | // ^ JSXStartTagEnd 88 |
89 | // ^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^ meta.tag.jsx 90 | // ^ ^ punctuation.definition.tag.jsx 91 | // ^^^ entity.name.tag.open.jsx 92 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 93 | // ^ ^ keyword.operator.assignment.jsx 94 | // ^^^^^^^^^ string.quoted.single.js 95 | // ^ punctuation.definition.string.begin.jsx 96 | // ^ punctuation.definition.string.end.jsx 97 | // ^^^ meta.embedded.expression.js 98 | // ^ punctuation.section.embedded.begin.jsx 99 | // ^ constant.numeric.js 100 | // ^ punctuation.section.embedded.end.jsx 101 | // ^ JSXStartTagEnd 102 |
103 | // ^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^ meta.tag.jsx 104 | // ^ ^^ punctuation.definition.tag.jsx 105 | // ^^^ entity.name.tag.open.jsx 106 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 107 | // ^ ^ keyword.operator.assignment.jsx 108 | // ^^^^^^^^^ string.quoted.single.js 109 | // ^ punctuation.definition.string.begin.jsx 110 | // ^ punctuation.definition.string.end.jsx 111 | // ^^^ meta.embedded.expression.js 112 | // ^ punctuation.section.embedded.begin.jsx 113 | // ^ constant.numeric.js 114 | // ^ punctuation.section.embedded.end.jsx 115 |
116 | // ^^^^ ^^^^^^^^^ ^ ^^^^^^^^^ ^^^^^^^ ^^ meta.tag.jsx 117 | // ^ ^^ punctuation.definition.tag.jsx 118 | // ^^^ entity.name.tag.open.jsx 119 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 120 | // ^ ^ keyword.operator.assignment.jsx 121 | // ^^^^^^^^^ string.quoted.single.js 122 | // ^ punctuation.definition.string.begin.jsx 123 | // ^ punctuation.definition.string.end.jsx 124 | // ^^^ meta.embedded.expression.js 125 | // ^ punctuation.section.embedded.begin.jsx 126 | // ^ constant.numeric.js 127 | // ^ punctuation.section.embedded.end.jsx 128 |
this.setState({})} /> 129 | // ^^^^ ^^^^^^^^^ ^ ^^^^^^^^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^ ^^ meta.tag.jsx 130 | // ^ ^^ punctuation.definition.tag.jsx 131 | // ^^^ entity.name.tag.open.jsx 132 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 133 | // ^ ^ keyword.operator.assignment.jsx 134 | // ^^^^^^^^^ string.quoted.single.js 135 | // ^ punctuation.definition.string.begin.jsx 136 | // ^ punctuation.definition.string.end.jsx 137 | // ^^^ ^^ ^^^^^^^^^^^^^^^^^^ meta.embedded.expression.js 138 | // ^ punctuation.section.embedded.begin.jsx 139 | // ^^ ^^ meta.function.arrow.js 140 | // ^ punctuation.definition.parameters.begin.js 141 | // ^ punctuation.definition.parameters.end.js 142 | // ^^ storage.type.function.arrow.js 143 | // ^^^^ variable.language.this.js 144 | // ^ keyword.operator.accessor.js 145 | // ^^^^^^^^ meta.function-call.method.with-arguments.js 146 | // ^^^^^^^^ entity.name.function.js 147 | // ^ ^ meta.brace.round.js 148 | // ^^ meta.brace.curly.js 149 | // ^ punctuation.section.embedded.end.jsx 150 |
151 | // ^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^^^ ^^ meta.tag.jsx 152 | // ^ ^^ punctuation.definition.tag.jsx 153 | // ^^^ entity.name.tag.open.jsx 154 | // ^^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 155 | // ^ keyword.operator.assignment.jsx 156 | // ^^^^^^^^^ string.quoted.single.js 157 | // ^ punctuation.definition.string.begin.jsx 158 | // ^ punctuation.definition.string.end.jsx 159 |
160 | // ^^^^ ^^^^^^^^^^ ^^^^^^^^^ ^^^ ^ ^^ ^^ meta.tag.jsx 161 | // ^ ^^ punctuation.definition.tag.jsx 162 | // ^^^ entity.name.tag.open.jsx 163 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 164 | // ^ ^ keyword.operator.assignment.jsx 165 | // ^^^^^^^^^ ^^ string.quoted.single.js 166 | // ^ ^ punctuation.definition.string.begin.jsx 167 | // ^ ^ punctuation.definition.string.end.jsx 168 |
178 | // ^^^^^^^ ^^ meta.tag.jsx 179 | // ^^^ entity.other.attribute-name.jsx 180 | // ^ keyword.operator.assignment.jsx 181 | // ^^^ meta.embedded.expression.js 182 | // ^ punctuation.section.embedded.begin.jsx 183 | // ^ constant.numeric.js 184 | // ^ punctuation.section.embedded.end.jsx 185 | // ^^ punctuation.definition.tag.jsx 186 |
198 | // ^^^^^^^ ^^ meta.tag.jsx 199 | // ^^^ entity.other.attribute-name.jsx 200 | // ^ keyword.operator.assignment.jsx 201 | // ^^^ meta.embedded.expression.js 202 | // ^ punctuation.section.embedded.begin.jsx 203 | // ^ constant.numeric.js 204 | // ^ punctuation.section.embedded.end.jsx 205 | // ^^ punctuation.definition.tag.jsx 206 |
212 | // ^ ^^^^^^^^^ ^^^^^^^ ^^ meta.tag.jsx 213 | // ^ ^ keyword.operator.assignment.jsx 214 | // ^^^^^^^^^ string.quoted.single.js 215 | // ^ punctuation.definition.string.begin.jsx 216 | // ^ punctuation.definition.string.end.jsx 217 | // ^^^ entity.other.attribute-name.jsx 218 | // ^^^ meta.embedded.expression.js 219 | // ^ punctuation.section.embedded.begin.jsx 220 | // ^ constant.numeric.js 221 | // ^ punctuation.section.embedded.end.jsx 222 | // ^^ punctuation.definition.tag.jsx 223 |
232 | // ^^^^^^^^^ ^^^^^^^ ^^ meta.tag.jsx 233 | // ^^^^^^^^^ string.quoted.single.js 234 | // ^ punctuation.definition.string.begin.jsx 235 | // ^ punctuation.definition.string.end.jsx 236 | // ^^^ entity.other.attribute-name.jsx 237 | // ^ keyword.operator.assignment.jsx 238 | // ^^^ meta.embedded.expression.js 239 | // ^ punctuation.section.embedded.begin.jsx 240 | // ^ constant.numeric.js 241 | // ^ punctuation.section.embedded.end.jsx 242 | // ^^ punctuation.definition.tag.jsx 243 |
244 | // ^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^ ^^ meta.tag.jsx 245 | // ^ ^^ punctuation.definition.tag.jsx 246 | // ^^^ entity.name.tag.open.jsx 247 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 248 | // ^^^^^^^^ comment.block.js 249 | // ^^ ^^ punctuation.definition.comment.js 250 | // ^ keyword.operator.assignment.jsx 251 | // ^^^^^^^^^ string.quoted.single.js 252 | // ^ punctuation.definition.string.begin.jsx 253 | // ^ punctuation.definition.string.end.jsx 254 |
255 | // ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^ meta.tag.jsx 256 | // ^ ^^ punctuation.definition.tag.jsx 257 | // ^^^ entity.name.tag.open.jsx 258 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 259 | // ^ keyword.operator.assignment.jsx 260 | // ^^^^^^^^ comment.block.js 261 | // ^^ ^^ punctuation.definition.comment.js 262 | // ^^^^^^^^^ string.quoted.single.js 263 | // ^ punctuation.definition.string.begin.jsx 264 | // ^ punctuation.definition.string.end.jsx 265 |
266 | // ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^ meta.tag.jsx 267 | // ^ ^^ punctuation.definition.tag.jsx 268 | // ^^^ entity.name.tag.open.jsx 269 | // ^^^^^^^^^ ^^^ entity.other.attribute-name.jsx 270 | // ^^^^^^^^ ^^^^^^^^ comment.block.js 271 | // ^^ ^^ ^^ ^^ punctuation.definition.comment.js 272 | // ^ keyword.operator.assignment.jsx 273 | // ^^^^^^^^^ string.quoted.single.js 274 | // ^ punctuation.definition.string.begin.jsx 275 | // ^ punctuation.definition.string.end.jsx 276 |
277 | // ^^^^^^ meta.tag.jsx 278 | // ^^ ^ punctuation.definition.tag.jsx 279 | // ^^ JSXEndTagStart 280 | // ^^^ entity.name.tag.close.jsx 281 |
282 | // ^^^^^^ meta.tag.jsx 283 | // ^^ ^ punctuation.definition.tag.jsx 284 | // ^^ JSXEndTagStart 285 | // ^^^ entity.name.tag.close.jsx 286 |
287 | // ^^^^^^ meta.tag.jsx 288 | // ^^ ^ punctuation.definition.tag.jsx 289 | // ^^ JSXEndTagStart 290 | // ^^^ entity.name.tag.close.jsx 291 |
292 | //^^^^^^ meta.tag.jsx 293 | //^^ ^ punctuation.definition.tag.jsx 294 | //^^ JSXEndTagStart 295 | // ^^^ entity.name.tag.close.jsx 296 |
297 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 298 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXEndTagStart 299 | //^^^^ meta.tag.jsx 300 | // ^ punctuation.definition.tag.jsx 301 | //^^^ entity.name.tag.close.jsx 302 | 303 | // >> only:source.js.jsx 304 | -------------------------------------------------------------------------------- /spec/fixtures/grammar/babel-sublime/jsx-full-react-class.jsx: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.js.jsx" 2 | 3 | import React from 'react'; 4 | // <- keyword.control.module.js 5 | // <- keyword.control.module.js 6 | //^^^^ keyword.control.module.js 7 | // ^^^^^ variable.other.readwrite.js 8 | // ^^^^ keyword.control.module.reference.js 9 | // ^^^^^^^ string.quoted.single.js 10 | // ^ punctuation.definition.string.begin.js 11 | // ^ punctuation.definition.string.end.js 12 | // ^ punctuation.terminator.statement.js 13 | import { InputsMixin } from './Forms'; 14 | // <- keyword.control.module.js 15 | // <- keyword.control.module.js 16 | //^^^^ keyword.control.module.js 17 | // ^ ^ meta.brace.curly.js 18 | // ^^^^^^^^^^^ variable.other.readwrite.js 19 | // ^^^^ keyword.control.module.reference.js 20 | // ^^^^^^^^^ string.quoted.single.js 21 | // ^ punctuation.definition.string.begin.js 22 | // ^ punctuation.definition.string.end.js 23 | // ^ punctuation.terminator.statement.js 24 | 25 | export default React.createClass({ 26 | // <- keyword.control.module.js 27 | // <- keyword.control.module.js 28 | //^^^^ ^^^^^^^ keyword.control.module.js 29 | // ^^^^^^^^^^^^^^^^^ meta.function-call.static.with-arguments.js 30 | // ^^^^^ variable.other.class.js 31 | // ^ keyword.operator.accessor.js 32 | // ^^^^^^^^^^^ entity.name.function.js 33 | // ^ meta.brace.round.js 34 | // ^ meta.brace.curly.js 35 | 36 | mixins: [InputsMixin], 37 | //^^^^^^^ constant.other.object.key.js 38 | //^^^^^^ string.unquoted.js 39 | // ^ punctuation.separator.key-value.js 40 | // ^ ^ meta.brace.square.js 41 | // ^^^^^^^^^^^ variable.other.readwrite.js 42 | // ^ meta.delimiter.comma.js 43 | 44 | submit() { 45 | //^^^^^^^^ meta.function.method.js 46 | //^^^^^^ entity.name.function.method.js 47 | // ^ punctuation.definition.parameters.begin.js 48 | // ^ punctuation.definition.parameters.end.js 49 | // ^ meta.brace.curly.js 50 | var {email, question} = this.state; 51 | // ^^^ ^^^^^^^ ^^^^^^^^^ ^ ^^^^^^^^^^^ meta.function-call.static.with-arguments.js 52 | // ^^^ storage.type.js 53 | // ^ ^ meta.brace.curly.js 54 | // ^^^^^ ^^^^^^^^ variable.other.readwrite.js 55 | // ^ meta.delimiter.comma.js 56 | // ^ keyword.operator.assignment.js 57 | // ^^^^ variable.language.this.js 58 | // ^ keyword.operator.accessor.js 59 | // ^^^^^ meta.property.object.js 60 | // ^^^^^ variable.other.property.js 61 | // ^ punctuation.terminator.statement.js 62 | request 63 | // ^^^^^^^ variable.other.readwrite.js 64 | .post(`${API_BASE}/askform`) 65 | // ^ keyword.operator.accessor.js 66 | // ^^^^ meta.function-call.method.with-arguments.js 67 | // ^^^^ entity.name.function.js 68 | // ^ ^ meta.brace.round.js 69 | // ^^^^^^^^^^^^^^^^^^^^^ string.quasi.js 70 | // ^ punctuation.definition.quasi.begin.js 71 | // ^^^^^^^^^^^^^^^^^^^^^ string.quoted.template.js 72 | // ^^^^^^^^^^^ entity.quasi.element.js 73 | // ^^ punctuation.quasi.element.begin.js 74 | // ^^^^^^^^ variable.other.constant.js 75 | // ^ punctuation.quasi.element.end.js 76 | // ^ punctuation.definition.quasi.end.js 77 | .send({email, question}) 78 | // ^ keyword.operator.accessor.js 79 | // ^^^^ meta.function-call.method.with-arguments.js 80 | // ^^^^ entity.name.function.js 81 | // ^ ^ meta.brace.round.js 82 | // ^ ^ meta.brace.curly.js 83 | // ^^^^^ ^^^^^^^^ variable.other.readwrite.js 84 | // ^ meta.delimiter.comma.js 85 | .end((err, res) => 86 | // ^ keyword.operator.accessor.js 87 | // ^^^ meta.function-call.method.with-arguments.js 88 | // ^^^ entity.name.function.js 89 | // ^ meta.brace.round.js 90 | // ^^^^^ ^^^^ ^^ meta.function.arrow.js 91 | // ^ punctuation.definition.parameters.begin.js 92 | // ^^^ ^^^ variable.other.readwrite.js 93 | // ^ meta.delimiter.comma.js 94 | // ^ punctuation.definition.parameters.end.js 95 | // ^^ storage.type.function.arrow.js 96 | this.setState({isValid: !err})); 97 | // ^^^^ variable.language.this.js 98 | // ^ keyword.operator.accessor.js 99 | // ^^^^^^^^ meta.function-call.method.with-arguments.js 100 | // ^^^^^^^^ entity.name.function.js 101 | // ^ ^^ meta.brace.round.js 102 | // ^ ^ meta.brace.curly.js 103 | // ^^^^^^^^ constant.other.object.key.js 104 | // ^^^^^^^ string.unquoted.js 105 | // ^ punctuation.separator.key-value.js 106 | // ^ keyword.operator.logical.js 107 | // ^^^ variable.other.readwrite.js 108 | // ^ punctuation.terminator.statement.js 109 | }, 110 | //^ meta.brace.curly.js 111 | // ^ meta.delimiter.comma.js 112 | 113 | render() { 114 | //^^^^^^^^ meta.function.method.js 115 | //^^^^^^ entity.name.function.method.js 116 | // ^ punctuation.definition.parameters.begin.js 117 | // ^ punctuation.definition.parameters.end.js 118 | // ^ meta.brace.curly.js 119 | var {email} = this.state; 120 | // ^^^ ^^^^^^^ ^ ^^^^^^^^^^^ meta.function-call.static.with-arguments.js 121 | // ^^^ storage.type.js 122 | // ^ ^ meta.brace.curly.js 123 | // ^^^^^ variable.other.readwrite.js 124 | // ^ keyword.operator.assignment.js 125 | // ^^^^ variable.language.this.js 126 | // ^ keyword.operator.accessor.js 127 | // ^^^^^ meta.property.object.js 128 | // ^^^^^ variable.other.property.js 129 | // ^ punctuation.terminator.statement.js 130 | return ( 131 | // ^^^^^^ keyword.control.flow.js 132 | // ^ meta.brace.round.js 133 |
134 | // ^^^^ ^^^^^^^^^^^^^^^^ meta.tag.jsx 135 | // ^ ^ punctuation.definition.tag.jsx 136 | // ^^^ entity.name.tag.open.jsx 137 | // ^^^^^^^^^^^^^^^ meta.embedded.expression.js 138 | // ^ punctuation.section.embedded.begin.jsx 139 | // ^^^ keyword.operator.spread.jsx 140 | // ^^^^ variable.language.this.js 141 | // ^ keyword.operator.accessor.js 142 | // ^^^^^ meta.property.object.js 143 | // ^^^^^ variable.other.property.js 144 | // ^ punctuation.section.embedded.end.jsx 145 | // ^ JSXStartTagEnd 146 | 181 | // ^^^^^^^^ ^^ meta.tag.jsx 182 | // ^^^^^^^^ entity.other.attribute-name.jsx 183 | // ^^ punctuation.definition.tag.jsx 184 |
185 | // ^^^^^^ meta.tag.jsx 186 | // ^^ ^ punctuation.definition.tag.jsx 187 | // ^^ JSXEndTagStart 188 | // ^^^ entity.name.tag.close.jsx 189 | ); 190 | // ^ meta.brace.round.js 191 | // ^ punctuation.terminator.statement.js 192 | } 193 | //^ meta.brace.curly.js 194 | }); 195 | // <- meta.brace.curly.js 196 | // <- meta.brace.round.js 197 | //^ punctuation.terminator.statement.js 198 | 199 | // With ES7+ Property Initializers 200 | // <- comment.line.double-slash.js punctuation.definition.comment.js 201 | // <- comment.line.double-slash.js punctuation.definition.comment.js 202 | // ^^^^ ^^^^ ^^^^^^^^ ^^^^^^^^^^^^ comment.line.double-slash.js 203 | 204 | export class Counter extends React.Component { 205 | // <- keyword.control.module.js 206 | // <- keyword.control.module.js 207 | //^^^^ keyword.control.module.js 208 | // ^^^^^ meta.class.js 209 | // ^^^^^ storage.type.class.js 210 | // ^^^^^^^ ^^^^^ entity.name.class.js 211 | // ^^^^^^^ meta.class.extends.js 212 | // ^^^^^^^ storage.type.extends.js 213 | // ^ keyword.operator.accessor.js 214 | // ^^^^^^^^^ meta.property.object.js 215 | // ^^^^^^^^^ variable.other.property.js 216 | // ^ punctuation.section.class.begin.js 217 | static propTypes = { initialCount: React.PropTypes.number }; 218 | //^^^^^^ ^^^^^^^^^ ^ ^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 219 | //^^^^^^ storage.modifier.js 220 | // ^^^^^^^^^ variable.other.readwrite.js 221 | // ^ keyword.operator.assignment.js 222 | // ^ ^ meta.brace.curly.js 223 | // ^^^^^^^^^^^^^ constant.other.object.key.js 224 | // ^^^^^^^^^^^^ string.unquoted.js 225 | // ^ punctuation.separator.key-value.js 226 | // ^^^^^^^^^^^^^^^ meta.property.class.js 227 | // ^^^^^ variable.other.class.js 228 | // ^ ^ keyword.operator.accessor.js 229 | // ^^^^^^^^^ variable.other.property.static.js 230 | // ^^^^^^ meta.property.object.js 231 | // ^^^^^^ variable.other.property.js 232 | // ^ punctuation.terminator.statement.js 233 | static defaultProps = { initialCount: 0 }; 234 | //^^^^^^ ^^^^^^^^^^^^ ^ ^ ^^^^^^^^^^^^^ ^ ^^ meta.class.body.js 235 | //^^^^^^ storage.modifier.js 236 | // ^^^^^^^^^^^^ variable.other.readwrite.js 237 | // ^ keyword.operator.assignment.js 238 | // ^ ^ meta.brace.curly.js 239 | // ^^^^^^^^^^^^^ constant.other.object.key.js 240 | // ^^^^^^^^^^^^ string.unquoted.js 241 | // ^ punctuation.separator.key-value.js 242 | // ^ constant.numeric.js 243 | // ^ punctuation.terminator.statement.js 244 | static childContextTypes = () => { 245 | //^^^^^^ ^^^^^^^^^^^^^^^^^ ^ ^^ ^^ ^ meta.class.body.js 246 | //^^^^^^ storage.modifier.js 247 | // ^^^^^^^^^^^^^^^^^ ^ ^^ ^^ meta.function.arrow.js 248 | // ^^^^^^^^^^^^^^^^^ entity.name.function.js 249 | // ^ keyword.operator.assignment.js 250 | // ^ punctuation.definition.parameters.begin.js 251 | // ^ punctuation.definition.parameters.end.js 252 | // ^^ storage.type.function.arrow.js 253 | // ^ meta.brace.curly.js 254 | return { 255 | // ^^^^^^ ^ meta.class.body.js 256 | // ^^^^^^ keyword.control.flow.js 257 | // ^ meta.brace.curly.js 258 | app: React.PropTypes.instanceOf(App).isRequired 259 | // ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.body.js 260 | // ^^^^ constant.other.object.key.js 261 | // ^^^ string.unquoted.js 262 | // ^ punctuation.separator.key-value.js 263 | // ^^^^^^^^^^^^^^^ meta.property.class.js 264 | // ^^^^^ variable.other.class.js 265 | // ^ ^ ^ keyword.operator.accessor.js 266 | // ^^^^^^^^^ variable.other.property.static.js 267 | // ^^^^^^^^^^ meta.function-call.method.with-arguments.js 268 | // ^^^^^^^^^^ entity.name.function.js 269 | // ^ ^ meta.brace.round.js 270 | // ^^^ variable.other.readwrite.js 271 | // ^^^^^^^^^^ meta.property.object.js 272 | // ^^^^^^^^^^ variable.other.property.js 273 | } 274 | // ^ meta.class.body.js 275 | // ^ meta.brace.curly.js 276 | }; 277 | //^^ meta.class.body.js 278 | //^ meta.brace.curly.js 279 | // ^ punctuation.terminator.statement.js 280 | getChildContext = makeGetChildContext(); 281 | //^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^ meta.class.body.js 282 | //^^^^^^^^^^^^^^^ variable.other.readwrite.js 283 | // ^ keyword.operator.assignment.js 284 | // ^^^^^^^^^^^^^^^^^^^^^ meta.function-call.without-arguments.js 285 | // ^^^^^^^^^^^^^^^^^^^ entity.name.function.js 286 | // ^^ meta.brace.round.js 287 | // ^ punctuation.terminator.statement.js 288 | state = { count: this.props.initialCount }; 289 | //^^^^^ ^ ^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js 290 | //^^^^^ variable.other.readwrite.js 291 | // ^ keyword.operator.assignment.js 292 | // ^ ^ meta.brace.curly.js 293 | // ^^^^^^ constant.other.object.key.js 294 | // ^^^^^ string.unquoted.js 295 | // ^ punctuation.separator.key-value.js 296 | // ^^^^ variable.language.this.js 297 | // ^ ^ keyword.operator.accessor.js 298 | // ^^^^^ ^^^^^^^^^^^^ meta.property.object.js 299 | // ^^^^^ ^^^^^^^^^^^^ variable.other.property.js 300 | // ^ punctuation.terminator.statement.js 301 | tick() { 302 | //^^^^^^ ^ meta.class.body.js 303 | //^^^^^^ meta.function.method.js 304 | //^^^^ entity.name.function.method.js 305 | // ^ punctuation.definition.parameters.begin.js 306 | // ^ punctuation.definition.parameters.end.js 307 | // ^ meta.brace.curly.js 308 | this.setState({ count: this.state.count + 1 }); 309 | // ^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^^^^^^^ ^ ^ ^^^ meta.class.body.js 310 | // ^^^^ ^^^^ variable.language.this.js 311 | // ^ ^ ^ keyword.operator.accessor.js 312 | // ^^^^^^^^ meta.function-call.method.with-arguments.js 313 | // ^^^^^^^^ entity.name.function.js 314 | // ^ ^ meta.brace.round.js 315 | // ^ ^ meta.brace.curly.js 316 | // ^^^^^^ constant.other.object.key.js 317 | // ^^^^^ string.unquoted.js 318 | // ^ punctuation.separator.key-value.js 319 | // ^^^^^ ^^^^^ meta.property.object.js 320 | // ^^^^^ ^^^^^ variable.other.property.js 321 | // ^ keyword.operator.arithmetic.js 322 | // ^ constant.numeric.js 323 | // ^ punctuation.terminator.statement.js 324 | } 325 | //^ meta.class.body.js 326 | //^ meta.brace.curly.js 327 | render() { 328 | //^^^^^^^^ ^ meta.class.body.js 329 | //^^^^^^^^ meta.function.method.js 330 | //^^^^^^ entity.name.function.method.js 331 | // ^ punctuation.definition.parameters.begin.js 332 | // ^ punctuation.definition.parameters.end.js 333 | // ^ meta.brace.curly.js 334 | return ( 335 | // ^^^^^^ ^ meta.class.body.js 336 | // ^^^^^^ keyword.control.flow.js 337 | // ^ meta.brace.round.js 338 |
339 | // ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.body.js 340 | // ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx 341 | // ^ ^ punctuation.definition.tag.jsx 342 | // ^^^ entity.name.tag.open.jsx 343 | // ^^^^^^^ entity.other.attribute-name.jsx 344 | // ^ keyword.operator.assignment.jsx 345 | // ^^^^^^^^^^^^^^^^^^^^^^ meta.embedded.expression.js 346 | // ^ punctuation.section.embedded.begin.jsx 347 | // ^^^^ ^^^^ variable.language.this.js 348 | // ^ ^ keyword.operator.accessor.js 349 | // ^^^^ meta.property.object.js 350 | // ^^^^ variable.other.property.js 351 | // ^^^^ meta.function-call.method.with-arguments.js 352 | // ^^^^ entity.name.function.js 353 | // ^ ^ meta.brace.round.js 354 | // ^ punctuation.section.embedded.end.jsx 355 | // ^ JSXStartTagEnd 356 | Clicks: {this.state.count} 357 | // ^^^^^^^ ^^^^^^^^^^^^^^^^^^ meta.class.body.js 358 | // ^^^^^^^ ^^^^^^^^^^^^^^^^^^ meta.tag.jsx 359 | // ^^^^^^^^^^^^^^^^^^ meta.embedded.expression.js 360 | // ^ punctuation.section.embedded.begin.jsx 361 | // ^^^^ variable.language.this.js 362 | // ^ ^ keyword.operator.accessor.js 363 | // ^^^^^ ^^^^^ meta.property.object.js 364 | // ^^^^^ ^^^^^ variable.other.property.js 365 | // ^ punctuation.section.embedded.end.jsx 366 |
367 | // ^^^^^^ meta.class.body.js 368 | // ^^^^^^ meta.tag.jsx 369 | // ^^ ^ punctuation.definition.tag.jsx 370 | // ^^ JSXEndTagStart 371 | // ^^^ entity.name.tag.close.jsx 372 | ); 373 | // ^^ meta.class.body.js 374 | // ^ meta.brace.round.js 375 | // ^ punctuation.terminator.statement.js 376 | } 377 | //^ meta.class.body.js 378 | //^ meta.brace.curly.js 379 | } 380 | // <- punctuation.section.class.end.js 381 | 382 | 383 | // >> only:(source.js.jsx) 384 | --------------------------------------------------------------------------------