├── 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 |
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 |
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#{tagName}>"
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 in jsx terminating children
508 |
509 | #### 0.4.3
510 | - patched JSX detecting attribute names with trailing invalid chars
511 |
512 | #### 0.4.2
513 | - patched minor grammar, add package keywords
514 |
515 | #### 0.4.0
516 | - stable enough to add .js as supported file types.
517 | - added new screen shots of source.
518 |
519 | #### 0.3.9
520 | - added settings file to auto indent and outdent
521 |
522 | #### 0.3.8
523 | - constant numeric not scoping. error moving babel-sublime regex to language-babel
524 | - forms Sound.play = arg => { } 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 |
--------------------------------------------------------------------------------