├── .eslintignore
├── 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
│ ├── grammar
│ │ ├── babel-sublime
│ │ │ ├── js-template-strings.js
│ │ │ ├── js-class.js
│ │ │ ├── jsx-features.jsx
│ │ │ ├── js-symbols.js
│ │ │ └── jsx-text.jsx
│ │ ├── flow-predicates.js
│ │ ├── css.js
│ │ ├── private-fields.js
│ │ └── declare.js
│ └── dirb
│ │ └── good.js
├── .eslintrc
├── default-config.js
├── grammar-spec.coffee
├── create-tag-grammar-spec.js
└── auto-indent-spec.coffee
├── .gitignore
├── grammars
├── Embedded Babel Language.json
├── ttl-26d12b471f2035277d061587e2033f31d73aaf261c3f4b1e48d5e0c0ad2087f8.json
└── Babel Regex.json
├── src
├── .babelrc
├── .languagebabel
└── create-ttl-grammar.js
├── .eslintrc
├── .gitattributes
├── appveyor.yml
├── .travis.yml
├── LICENSE.md
├── settings
└── language-babel.json
├── lib
├── auto-complete-emmet-css.js
├── transpiler-task.coffee
├── did-insert-text.coffee
├── main.coffee
├── auto-complete-jsx.coffee
├── auto-complete-styled-components.coffee
└── completions-jsx.coffee
├── styles
└── language-babel.less
├── coffeelint.json
└── package.json
/.eslintignore:
--------------------------------------------------------------------------------
1 | lib/
2 | spec/fixtures
3 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/spec/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "atomtest": true,
4 | "jasmine": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | npm-debug.log
3 | node_modules
4 | babel-source
5 | babel-target
6 | thumbs.db
7 | /testJs/
8 | package-lock.json
9 |
--------------------------------------------------------------------------------
/grammars/Embedded Babel Language.json:
--------------------------------------------------------------------------------
1 | {
2 | "scopeName": "source.embedded.js.jsx",
3 | "injectionSelector": "source.embedded.jsx",
4 | "patterns": [
5 | {
6 | "include": "source.js.jsx"
7 | }
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/src/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "node5"
4 | ],
5 | "plugins": [
6 | "transform-class-properties",
7 | "syntax-class-properties",
8 | "transform-decorators-legacy"
9 | ],
10 | "sourceMaps": "inline"
11 | }
12 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "eslint:recommended",
4 | "env": {
5 | "browser": true,
6 | "node": true,
7 | "es6": true
8 | },
9 | "rules": {
10 | "indent": ["error", 2],
11 | "semi": ["error", "always"]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/grammars/ttl-26d12b471f2035277d061587e2033f31d73aaf261c3f4b1e48d5e0c0ad2087f8.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "language-babel-extension",
3 | "comment": "Auto generated Tag Extensions for language-babel",
4 | "comment": "Please do not edit this file directly",
5 | "scopeName": "languagebabel.ttlextension",
6 | "fileTypes": [],
7 | "patterns": [
8 |
9 | ]
10 | }
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/spec/default-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | allowLocalOverride: false,
3 | babelMapsAddUrl: true,
4 | babelMapsPath: "",
5 | babelSourcePath: "",
6 | babelTranspilePath: "",
7 | createMap: false,
8 | createTargetDirectories: false,
9 | createTranspiledCode: true,
10 | disableWhenNoBabelrcFileInPath: false,
11 | keepFileExtension: false,
12 | suppressSourcePathMessages: false,
13 | suppressTranspileOnSaveMessages: false,
14 | transpileOnSave: true,
15 | autoIndentJSX: true
16 | };
17 |
--------------------------------------------------------------------------------
/src/.languagebabel:
--------------------------------------------------------------------------------
1 | {
2 | "babelSourcePath": "src",
3 | "babelMapsAddUrl": false,
4 | "babelTranspilePath": "lib",
5 | "createMap": false,
6 | "createTranspiledCode": true,
7 | "disableWhenNoBabelrcFileInPath": true,
8 | "projectRoot": false,
9 | "suppressSourcePathMessages": true,
10 | "suppressTranspileOnSaveMessages": false,
11 | "transpileOnSave": true
12 | }
13 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: "{build}"
2 |
3 | platform: x64
4 |
5 | branches:
6 | only:
7 | - master
8 |
9 | clone_depth: 10
10 |
11 | skip_tags: true
12 |
13 | environment:
14 | APM_TEST_PACKAGES:
15 |
16 | matrix:
17 | - ATOM_CHANNEL: stable
18 | - ATOM_CHANNEL: beta
19 |
20 | install:
21 | - ps: Install-Product node 5
22 |
23 | build_script:
24 | - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/atom/ci/master/build-package.ps1'))
25 |
26 | test: off
27 | deploy: off
28 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | notifications:
2 | email:
3 | on_success: never
4 | on_failure: change
5 |
6 | script: 'curl -s https://raw.githubusercontent.com/atom/ci/master/build-package.sh | sh'
7 |
8 | git:
9 | depth: 10
10 |
11 | sudo: false
12 |
13 | matrix:
14 | include:
15 | - os: osx
16 | env: ATOM_CHANNEL=stable
17 | # - os: linux
18 | # dist: trusty
19 | # env: ATOM_CHANNEL=stable
20 | - os: osx
21 | env: ATOM_CHANNEL=beta
22 | # - os: linux
23 | # dist: trusty
24 | # env: ATOM_CHANNEL=beta
25 |
26 | branches:
27 | only:
28 | - master
29 |
30 | addons:
31 | apt:
32 | packages:
33 | - libstdc++6
34 |
--------------------------------------------------------------------------------
/spec/fixtures/grammar/babel-sublime/js-template-strings.js:
--------------------------------------------------------------------------------
1 | // SYNTAX TEST "source.js.jsx"
2 |
3 | return `another template ${aa}`
4 | // <- keyword.control.flow.js
5 | // <- keyword.control.flow.js
6 | //^^^^ keyword.control.flow.js
7 | // ^^^^^^^^ ^^^^^^^^ ^^^^^^ string.quasi.js
8 | // ^ punctuation.definition.quasi.begin.js
9 | // ^^^^^^^^ ^^^^^^^^ ^^^^^^ string.quoted.template.js
10 | // ^^^^^ entity.quasi.element.js
11 | // ^^ punctuation.quasi.element.begin.js
12 | // ^^ variable.other.readwrite.js
13 | // ^ punctuation.quasi.element.end.js
14 | // ^ punctuation.definition.quasi.end.js
15 |
16 | // >> only:source.js.jsx
17 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/settings/language-babel.json:
--------------------------------------------------------------------------------
1 | {
2 | ".source.js.jsx": {
3 | "editor": {
4 | "commentStart": "// ",
5 | "foldEndPattern": "^\\s*\\}|^\\s*\\]|^\\s*\\)",
6 | "increaseIndentPattern": "{[^}\"']*$|\\[[^\\]\"']*$|\\([^)\"']*$|^\\s*<[a-zA-Z][^/]*$|^\\s*>$",
7 | "decreaseIndentPattern": "^\\s*(\\s*/[*].*[*]/\\s*)*[}\\])]|^\\s*(|/>)",
8 | "nonWordCharacters": "/\\()\"':,.;<>~!@#%^&*|+=[]{}`?-…"
9 | }
10 | },
11 | ".source.inside-js.css.styled": {
12 | "editor": {
13 | "commentStart": "${'' /* ",
14 | "commentEnd": " */}"
15 | }
16 | },
17 | ".entity.quasi.element.js": {
18 | "editor": {
19 | "commentStart": "// "
20 | },
21 | "autocomplete": {
22 | "symbols": {
23 | "": {
24 | "selector": ".source",
25 | "typePriority": 1
26 | }
27 | }
28 | }
29 | },
30 | ".meta.tag.jsx": {
31 | "editor": {
32 | "commentStart": "{/* ",
33 | "commentEnd": " */}",
34 | "increaseIndentPattern": "{[^}\"']*$|\\[[^\\]\"']*$|\\([^)\"']*$|<[a-zA-Z][^/]*$|^\\s*>$",
35 | "decreaseIndentPattern": "^\\s*(\\s*/[*].*[*]/\\s*)*[}\\])]|^\\s*(|/>)"
36 | }
37 | },
38 | ".JSXAttrs": {
39 | "editor": {
40 | "commentStart": "// "
41 | }
42 | },
43 | ".JSXNested": {
44 | "editor": {
45 | "commentStart": "{/* ",
46 | "commentEnd": " */}"
47 | }
48 | },
49 | ".graphql": {
50 | "editor": {
51 | "commentStart": "# "
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/auto-complete-emmet-css.js:
--------------------------------------------------------------------------------
1 | /*global atom*/
2 | "use babel";
3 |
4 | module.exports = {
5 | selector: '.source.inside-js.css.styled, .source.css.styled',
6 | disableForSelector:
7 | '.source.inside-js.css.styled .comment, .source.inside-js.css.styled .string, .source.inside-js.css.styled .entity.quasi.element.js, .source.css.styled .comment, .source.css.styled .string, .source.css.styled .entity.quasi.element.js',
8 |
9 | filterSuggestions: false,
10 | inclusionPriority: 10000,
11 | excludeLowerPriority: false,
12 | suggestionPriority: 100,
13 |
14 | getSuggestions({editor, bufferPosition}) {
15 | if (atom.config.get('language-babel.emmetCSSAutocomplete')) {
16 | const prefix = this.getPrefix(editor, bufferPosition);
17 | return this.emmetSuggestion(prefix);
18 | }
19 | return null;
20 | },
21 |
22 | getPrefix(editor, bufferPosition) {
23 | const regex = /(^|;)(?:\s*)([\w\s0-9+-:@!#]+)$/g;
24 | const line = editor.getTextInRange([
25 | [bufferPosition.row, 0],
26 | bufferPosition
27 | ]);
28 | const match = regex.exec(line);
29 | return match ? match[2] : '';
30 | },
31 |
32 | emmetSuggestion(prefix) {
33 | const completion = [];
34 | try {
35 | // Expensive dependency: use a lazy require.
36 | const {expand} = require('@emmetio/expand-abbreviation');
37 | const emmetAbbreviation = expand(prefix, {
38 | syntax: 'css',
39 | field: (index, placeholder) =>
40 | `\${${index}${placeholder ? ':' + placeholder : ''}}`
41 | });
42 | const emmetDisplayText =
43 | emmetAbbreviation.length > 28
44 | ? emmetAbbreviation.substr(0, 25) + '...'
45 | : emmetAbbreviation;
46 | completion.push({
47 | type: 'snippet',
48 | snippet: emmetAbbreviation,
49 | displayText: emmetDisplayText,
50 | leftLabel: 'emmet',
51 | description: 'language-babel emmet',
52 | descriptionMoreURL: 'https://docs.emmet.io/cheat-sheet/',
53 | replacementPrefix: prefix
54 | });
55 | } catch (err) {
56 | }
57 | return completion;
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/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 | waitsForPromise ->
13 | atom.packages.activatePackage('language-mustache')
14 | waitsForPromise ->
15 | atom.packages.activatePackage('language-html')
16 |
17 | # test private class fields and methods
18 | grammarTest path.join(__dirname, 'fixtures/grammar/private-fields.js')
19 |
20 | # babel-sublime test files
21 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/flow.js')
22 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-class.js')
23 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-functions.js')
24 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-symbols.js')
25 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/js-template-strings.js')
26 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-attributes.jsx')
27 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-es6.jsx')
28 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-features.jsx')
29 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-full-react-class.jsx')
30 | grammarTest path.join(__dirname, 'fixtures/grammar/babel-sublime/jsx-text.jsx')
31 |
32 | # flow declaration file
33 | grammarTest path.join(__dirname, 'fixtures/grammar/declare.js')
34 |
35 | # grammar test large files
36 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/browser-polyfill.js')
37 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/jquery-2.1.4.js')
38 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/bundle.js')
39 | grammarTest path.join(__dirname, 'fixtures/grammar/large files/jquery-2.1.4.min.js')
40 |
41 | # # es2015 check
42 | grammarTest path.join(__dirname, 'fixtures/grammar/everythingJs/es2015-module.js')
43 |
44 | # todo,jsdoc,...
45 | grammarTest path.join(__dirname, 'fixtures/grammar/doc-keywords.js')
46 |
47 | # flow predicates...
48 | grammarTest path.join(__dirname, 'fixtures/grammar/flow-predicates.js')
49 |
50 | # issues raised
51 | grammarTest path.join(__dirname, 'fixtures/grammar/issues.js')
52 |
53 | # misc Tests
54 | grammarTest path.join(__dirname, 'fixtures/grammar/misc.js')
55 | grammarTest path.join(__dirname, 'fixtures/grammar/es6module.js')
56 |
57 | # graphql test
58 | grammarTest path.join(__dirname, 'fixtures/grammar/graphql.js')
59 |
--------------------------------------------------------------------------------
/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 {
39 | .syntax--source.syntax--js.syntax--jsx {
40 | .syntax--graphql {
41 | .syntax--alias {
42 | font-style: italic
43 | }
44 | .syntax--support.syntax--type.syntax--builtin {
45 | -webkit-filter: brightness(80%);
46 | }
47 | }
48 | .syntax--jsx {
49 | .syntax--entity {
50 | &.syntax--other {
51 | &.syntax--attribute-name {
52 | font-style: italic // color: @cyan;
53 | }
54 | }
55 | }
56 | .syntax--constant.syntax--character.syntax--entity {
57 | font-style: italic
58 | }
59 | }
60 | }
61 | .syntax--constant.syntax--numeric.syntax--bigint {
62 | font-style: italic
63 | }
64 | .syntax--source.syntax--css.syntax--styled {
65 | .syntax--support.syntax--type.syntax--property-name.syntax--unknown {
66 | -webkit-filter: brightness(75%);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/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 | fs = require 'fs-plus'
2 | path = require 'path'
3 |
4 | # recurse directories to root looking for babel core
5 | # or provide our own
6 | requireBabelCore = (dir) ->
7 | if dir != path.dirname(dir)
8 | if babelCore = resolveBabelCore(dir) then return babelCore
9 | else return requireBabelCore(path.dirname(dir))
10 | return resolveBabelCore('..') # return language-babel's copy of babel-core
11 |
12 | # resolve a babel core in the dir
13 | resolveBabelCore = (dir) ->
14 | try
15 | projectBabelCore = path.normalize( path.join( dir, '/node_modules/@babel/core'))
16 | babel = require projectBabelCore
17 | catch
18 | try
19 | projectBabelCore = path.normalize( path.join( dir, '/node_modules/babel-core'))
20 | babel = require projectBabelCore
21 | catch
22 | return false
23 | 'babel': babel
24 | 'projectBabelCore': projectBabelCore
25 |
26 | # language-babel transpiles run here.
27 | # This runs as a separate task so that transpiles can have their own environment.
28 | module.exports = (projectPath) ->
29 | callback = @async() #async task
30 | process.chdir(projectPath)
31 |
32 | { babel, projectBabelCore } = requireBabelCore(projectPath)
33 | babelCoreUsed = "Using babel-core at\n#{require.resolve projectBabelCore}"
34 |
35 | process.on 'message', (mObj) ->
36 | if mObj.command is 'transpile'
37 | try
38 | babel.transformFile mObj.pathTo.sourceFile, mObj.babelOptions, (err,result) =>
39 | # fiddly formating a return
40 | msgRet = {}
41 | msgRet.reqId = mObj.reqId # send back to reqId
42 | if err
43 | msgRet.err = {}
44 | if err.loc then msgRet.err.loc = err.loc
45 | if err.codeFrame
46 | msgRet.err.codeFrame = err.codeFrame
47 | else msgRet.err.codeFrame = ""
48 | msgRet.err.message = err.message
49 | if result
50 | msgRet.result = result
51 | msgRet.result.ast = null; # ast seems to create a JSON circular ref on emit
52 | msgRet.babelVersion = babel.version
53 | msgRet.babelCoreUsed = babelCoreUsed
54 | emit "transpile:#{mObj.reqId}", msgRet
55 | # if this file transpilation isn't in a Atom project folder then term this task
56 | # as this is normally an Ad-hoc file transpile.
57 | if not mObj.pathTo.sourceFileInProject
58 | callback()
59 | catch err
60 | msgRet = {}
61 | msgRet.reqId = mObj.reqId # send back to reqId
62 | msgRet.err = {}
63 | msgRet.err.message = err.message
64 | msgRet.err.stack = err.stack
65 | msgRet.babelCoreUsed = babelCoreUsed
66 | emit "transpile:#{mObj.reqId}", msgRet
67 | callback()
68 |
69 | # used for preview
70 | if mObj.command is 'transpileCode'
71 | try
72 | msgRet = babel.transform mObj.code, mObj.babelOptions
73 | # fiddly formating a return
74 | msgRet.babelVersion = babel.version
75 | msgRet.babelCoreUsed = babelCoreUsed
76 | emit "transpile:#{mObj.reqId}", msgRet
77 | # if this file transpilation isn't in a Atom project folder then term this task
78 | # as this is normally an Ad-hoc file transpile.
79 | if not mObj.pathTo.sourceFileInProject
80 | callback()
81 | catch err
82 | msgRet = {}
83 | msgRet.reqId = mObj.reqId # send back to reqId
84 | msgRet.err = {}
85 | msgRet.err.message = err.message
86 | msgRet.err.stack = err.stack
87 | msgRet.babelVersion = babel.version
88 | msgRet.babelCoreUsed = babelCoreUsed
89 | emit "transpile:#{mObj.reqId}", msgRet
90 | callback()
91 |
92 | #stop issued stop process
93 | if mObj.command is 'stop'
94 | callback()
95 |
--------------------------------------------------------------------------------
/spec/fixtures/grammar/flow-predicates.js:
--------------------------------------------------------------------------------
1 | // SYNTAX TEST "source.js.jsx"
2 |
3 | // Predicates
4 |
5 | declare function f(x: mixed): boolean %checks (x !== null);
6 | // <- keyword.other.declare.flowtype
7 | // <- keyword.other.declare.flowtype
8 | //^^^^^ keyword.other.declare.flowtype
9 | // ^^^^^^^^ ^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^ ^^^ ^^^^^ meta.function.js
10 | // ^^^^^^^^ storage.type.function.js
11 | // ^ entity.name.function.js
12 | // ^ punctuation.definition.parameters.begin.js
13 | // ^ ^ ^ ^ meta.brace.round.js
14 | // ^^ ^^^^^ meta.function.parameters.js
15 | // ^ ^ variable.other.readwrite.js
16 | // ^ ^ punctuation.type.flowtype
17 | // ^^^^^ ^^^^^^^ support.type.builtin.primitive.flowtype
18 | // ^ punctuation.definition.parameters.end.js
19 | // ^^^^^^^ entity.name.function.predicate.flowtype
20 | // ^^^ keyword.operator.comparison.js
21 | // ^^^^ constant.language.null.js
22 | // ^ punctuation.terminator.statement.js
23 | function f7(x: mixed): %checks { return x !== null }
24 | // <- meta.function.js storage.type.function.js
25 | // <- meta.function.js storage.type.function.js
26 | //^^^^^^ ^^^^^ ^^^^^^^ ^^^^^^^ ^ ^^^^^^ ^ ^^^ ^^^^ ^ meta.function.js
27 | //^^^^^^ storage.type.function.js
28 | // ^^ entity.name.function.js
29 | // ^ punctuation.definition.parameters.begin.js
30 | // ^ ^ meta.brace.round.js
31 | // ^^ ^^^^^ meta.function.parameters.js
32 | // ^ ^ variable.other.readwrite.js
33 | // ^ ^ punctuation.type.flowtype
34 | // ^^^^^ support.type.builtin.primitive.flowtype
35 | // ^ punctuation.definition.parameters.end.js
36 | // ^^^^^^^ entity.name.function.predicate.flowtype
37 | // ^ ^ meta.brace.curly.js
38 | // ^^^^^^ keyword.control.flow.js
39 | // ^^^ keyword.operator.comparison.js
40 | // ^^^^ constant.language.null.js
41 | var a1 = (x: mixed): %checks => x !== null
42 | // <- storage.type.js
43 | // <- storage.type.js
44 | //^ storage.type.js
45 | // ^^ ^ ^^^ ^^^^^^^ ^^^^^^^ ^^ meta.function.arrow.js
46 | // ^^ entity.name.function.js
47 | // ^ keyword.operator.assignment.js
48 | // ^ punctuation.definition.parameters.begin.js
49 | // ^ ^ meta.brace.round.js
50 | // ^^ ^^^^^ meta.function.parameters.js
51 | // ^ ^ variable.other.readwrite.js
52 | // ^ ^ punctuation.type.flowtype
53 | // ^^^^^ support.type.builtin.primitive.flowtype
54 | // ^ punctuation.definition.parameters.end.js
55 | // ^^^^^^^ entity.name.function.predicate.flowtype
56 | // ^^ storage.type.function.arrow.js
57 | // ^^^ keyword.operator.comparison.js
58 | // ^^^^ constant.language.null.js
59 |
60 |
61 | // >> only:(source.js.jsx)
62 |
--------------------------------------------------------------------------------
/lib/did-insert-text.coffee:
--------------------------------------------------------------------------------
1 | module.exports =
2 | class DidInsertText
3 | constructor: (@editor) ->
4 | @adviseBefore(@editor, 'insertText', @insertText)
5 |
6 | # patched TextEditor::insertText
7 | insertText: (text, options) =>
8 | return true if @editor.hasMultipleCursors() # for time being
9 |
10 | if ( text is "\n")
11 | if !@insertNewlineBetweenJSXTags() then return false
12 | if !@insertNewlineAfterBacktick() then return false
13 | else if ( text is "`")
14 | if !@insertBackTick() then return false
15 | true
16 |
17 | # check bracket-matcher package config to determine backtick insertion
18 | bracketMatcherBackticks: () ->
19 | return atom.packages.isPackageActive("bracket-matcher") and
20 | atom.config.get("bracket-matcher.autocompleteBrackets") and
21 | "``" in atom.config.get("bracket-matcher.autocompleteCharacters")
22 |
23 | # if a newLine is entered between a JSX tag open and close marked_ _
24 | # then add another newLine and reposition cursor
25 | insertNewlineBetweenJSXTags: () ->
26 | cursorBufferPosition = @editor.getCursorBufferPosition()
27 | return true unless cursorBufferPosition.column > 0
28 | return true unless 'JSXEndTagStart' is @editor.scopeDescriptorForBufferPosition(cursorBufferPosition).getScopesArray().slice(-1).toString()
29 | cursorBufferPosition.column--
30 | return true unless 'JSXStartTagEnd' is @editor.scopeDescriptorForBufferPosition(cursorBufferPosition).getScopesArray().slice(-1).toString()
31 | indentLength = @editor.indentationForBufferRow(cursorBufferPosition.row)
32 | @editor.insertText("\n\n")
33 | @editor.setIndentationForBufferRow cursorBufferPosition.row+1, indentLength+1, { preserveLeadingWhitespace: false }
34 | @editor.setIndentationForBufferRow cursorBufferPosition.row+2, indentLength, { preserveLeadingWhitespace: false }
35 | @editor.moveUp()
36 | @editor.moveToEndOfLine()
37 | false
38 |
39 | # if a newline is entered after the opening backtick
40 | # indent cursor and add a closing backtick
41 | insertNewlineAfterBacktick: () ->
42 | cursorBufferPosition = @editor.getCursorBufferPosition()
43 | return true unless cursorBufferPosition.column > 0
44 | betweenBackTicks = 'punctuation.definition.quasi.end.js' is @editor.scopeDescriptorForBufferPosition(cursorBufferPosition).getScopesArray().slice(-1).toString()
45 | cursorBufferPosition.column--
46 | return true unless 'punctuation.definition.quasi.begin.js' is @editor.scopeDescriptorForBufferPosition(cursorBufferPosition).getScopesArray().slice(-1).toString()
47 | indentLength = @editor.indentationForBufferRow(cursorBufferPosition.row)
48 | return true unless @bracketMatcherBackticks()
49 | if (betweenBackTicks)
50 | @editor.insertText("\n\n")
51 | @editor.setIndentationForBufferRow cursorBufferPosition.row+1, indentLength+1, { preserveLeadingWhitespace: false }
52 | @editor.setIndentationForBufferRow cursorBufferPosition.row+2, indentLength, { preserveLeadingWhitespace: false }
53 | @editor.moveUp()
54 | @editor.moveToEndOfLine()
55 | else
56 | @editor.insertText("\n\t")
57 | @editor.setIndentationForBufferRow cursorBufferPosition.row+1, indentLength+1, { preserveLeadingWhitespace: false }
58 | false
59 |
60 | # the atom bracket matcher doesn't currently ( v1.15) add a closing backtick when the opening
61 | # backtick appears after a word character as is the case in a tagname`` sequence
62 | # this remedies that
63 | insertBackTick: () ->
64 | return true unless @bracketMatcherBackticks()
65 | cursorBufferPosition = @editor.getCursorBufferPosition()
66 | return true if 'punctuation.definition.quasi.begin.js' is @editor.scopeDescriptorForBufferPosition(cursorBufferPosition).getScopesArray().slice(-1).toString()
67 | selectedText = @editor.getSelectedText()
68 | cursorPosition = @editor.getCursorBufferPosition()
69 | @editor.insertText("`" + selectedText + "`")
70 | @editor.setCursorBufferPosition(cursorPosition)
71 | @editor.moveRight()
72 | false
73 |
74 |
75 | # from https://github.com/atom/underscore-plus/blob/master/src/underscore-plus.coffee
76 | adviseBefore: (object, methodName, advice) ->
77 | original = object[methodName]
78 | object[methodName] = (args...) ->
79 | unless advice.apply(this, args) == false
80 | original.apply(this, args)
81 |
--------------------------------------------------------------------------------
/grammars/Babel Regex.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Regular Expressions (Babel)",
3 | "scopeName": "source.regexp.babel",
4 | "fileTypes": [],
5 | "patterns": [
6 | { "include": "#anchor"},
7 | { "include": "#backref"},
8 | { "include": "#quantifier"},
9 | { "include": "#operator"},
10 | { "include": "#group-assertion"},
11 | { "include": "#group-definition"},
12 | { "include": "#character-class-definition" },
13 | { "include": "#character-class" }
14 | ],
15 | "repository": {
16 | "character-class-definition": {
17 | "patterns": [{
18 | "name": "constant.other.character-class.set.regexp",
19 | "begin": "(\\[)(\\^)?",
20 | "end": "(\\])",
21 | "beginCaptures": {
22 | "1": { "name": "punctuation.definition.character-class.regexp" },
23 | "2": { "name": "keyword.operator.negation.regexp" }
24 | },
25 | "endCaptures": {
26 | "1": {
27 | "name": "punctuation.definition.character-class.regexp"
28 | }
29 | },
30 | "patterns":
31 | [
32 | {
33 | "name": "constant.other.character-class.range.regexp",
34 | "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])))",
35 | "captures":
36 | {
37 | "2": { "name": "constant.character.escape.backslash.regexp" },
38 | "3": { "name": "constant.character.escape.backslash.regexp" },
39 | "5": { "name": "constant.character.regexp" },
40 | "6": { "name": "punctuation.definition.range.regexp" },
41 | "8": { "name": "constant.character.escape.backslash.regexp" },
42 | "9": { "name": "constant.character.escape.backslash.regexp" },
43 | "11": { "name": "constant.character.regexp" }
44 | }
45 | },
46 | { "include": "#character-class" }
47 | ]
48 | }]
49 | },
50 | "group-assertion": {
51 | "patterns": [{
52 | "begin": "(\\()((\\?=)|(\\?!))",
53 | "end": "(\\))",
54 | "name": "meta.group.assertion.regexp",
55 | "endCaptures": {
56 | "1": {
57 | "name": "punctuation.definition.group.regexp"
58 | }
59 | },
60 | "beginCaptures": {
61 | "1": { "name": "punctuation.definition.group.regexp" },
62 | "2": { "name": "punctuation.definition.group.assertion.regexp" },
63 | "3": { "name": "meta.assertion.look-ahead.regexp" },
64 | "4": { "name": "meta.assertion.negative-look-ahead.regexp" }
65 | },
66 | "patterns": [{
67 | "include": "$self"
68 | }]
69 | }]
70 | },
71 | "anchor": {
72 | "patterns": [{
73 | "name": "keyword.control.anchor.regexp",
74 | "match": "\\\\[bB]|\\^|\\$"
75 | }]
76 | },
77 | "operator": {
78 | "patterns": [{
79 | "name": "keyword.operator.or.regexp",
80 | "match": "\\|"
81 | }]
82 | },
83 | "group-definition": {
84 | "patterns": [{
85 | "begin": "(\\()((\\?:))?",
86 | "end": "(\\))",
87 | "name": "meta.group.regexp",
88 | "endCaptures": {
89 | "1": { "name": "punctuation.definition.group.regexp" }
90 | },
91 | "beginCaptures": {
92 | "1": { "name": "punctuation.definition.group.regexp" },
93 | "3": { "name": "punctuation.definition.group.capture.regexp" },
94 | "5": { "name": "punctuation.definition.group.capture.regexp" },
95 | "6": { "name": "punctuation.definition.group.no-capture.regexp" }
96 | },
97 | "patterns": [{
98 | "include": "$self"
99 | }]
100 | }]
101 | },
102 | "quantifier": {
103 | "patterns": [{
104 | "name": "keyword.operator.quantifier.regexp",
105 | "match": "(\\?|\\*\\??|\\+\\??)|\\{(\\d+,\\d+|\\d+,|\\d+)\\}"
106 | }]
107 | },
108 | "backref": {
109 | "patterns": [{
110 | "name": "keyword.other.back-reference.regexp",
111 | "match": "\\\\[1-9][0-9]*"
112 | }]
113 | },
114 | "character-class": {
115 | "patterns": [{
116 | "name": "constant.character.escape.backslash.regexp",
117 | "match": "\\\\[wWsSdD]"
118 | }, {
119 | "match": "(\\\\([trnvf0\\\\]|c[A-Z]|x[\\da-fA-F]{2}|u[\\da-fA-F]{4}|u\\{[\\da-fA-F]+\\}|.))",
120 | "captures": {
121 | "1": { "name": "constant.character.escape.backslash.regexp" }
122 | }
123 | }]
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "language-babel",
3 | "main": "./lib/main",
4 | "version": "2.85.0",
5 | "description": "JavaScript ES201x, React JSX, Flow and GraphQL Grammar. Babel Transpiler",
6 | "keywords": [
7 | "react",
8 | "flow",
9 | "graphql",
10 | "es6",
11 | "jsx",
12 | "javascript",
13 | "es7",
14 | "esnext",
15 | "es2015",
16 | "es2016",
17 | "es2017",
18 | "relay",
19 | "apollo"
20 | ],
21 | "activationCommands": [],
22 | "repository": "https://github.com/gandm/language-babel",
23 | "license": "MIT",
24 | "engines": {
25 | "atom": "^1.15.0"
26 | },
27 | "providedServices": {
28 | "autocomplete.provider": {
29 | "versions": {
30 | "2.0.0": "autoCompleteProvider"
31 | }
32 | },
33 | "preview.provider": {
34 | "versions": {
35 | "0.1.0": "provide"
36 | }
37 | }
38 | },
39 | "dependencies": {
40 | "@emmetio/expand-abbreviation": "^0.5.8",
41 | "babel-core": "^6.26.0",
42 | "fs-plus": "^3.0.0",
43 | "fuzzaldrin": "^2.1.0",
44 | "jjv": "^1.0.2",
45 | "js-yaml": "^3.10.0",
46 | "path-is-inside": "^1.0.1",
47 | "strip-json-comments": "^2.0.1"
48 | },
49 | "devDependencies": {
50 | "atom-grammar-test": "<1.0.0",
51 | "babel-eslint": "^6.1.2",
52 | "babel-plugin-syntax-class-properties": "^6.13.0",
53 | "babel-plugin-transform-class-properties": "^6.11.5",
54 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
55 | "babel-preset-node5": "^11.1.0",
56 | "chai": "^3.0.0",
57 | "core-decorators": "^0.12.3",
58 | "eslint": "^3.6.0",
59 | "temp": "^0.8.3"
60 | },
61 | "configSchema": {
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": 10
68 | },
69 | "taggedTemplateGrammar": {
70 | "title": "JavaScript Tagged Template Literal Grammar Extensions",
71 | "description": "Enter a list of comma separated tagged template literals/regex in the form tagname:scope.name.of.grammar",
72 | "type": "array",
73 | "default": [],
74 | "items": {
75 | "type": "string"
76 | },
77 | "order": 20
78 | },
79 | "emmetCSSAutocomplete": {
80 | "title": "Styled-Components Auto-Complete method",
81 | "description": "Use Emmet to auto-complete in addition to the default CSS completion",
82 | "type": "boolean",
83 | "default": false,
84 | "order": 25
85 | },
86 | "allowLocalOverride": {
87 | "description": "Allow .languagebabel files to overide the settings below. Useful for project based configurations.",
88 | "type": "boolean",
89 | "default": false,
90 | "order": 30
91 | },
92 | "transpileOnSave": {
93 | "description": "Check source code validity on file save. Use \"Create Transpiled Code\" option below to save file.",
94 | "type": "boolean",
95 | "default": false,
96 | "order": 40
97 | },
98 | "createTranspiledCode": {
99 | "description": "Save transpiled code to Babel Transpile Path below.",
100 | "type": "boolean",
101 | "default": false,
102 | "order": 50
103 | },
104 | "disableWhenNoBabelrcFileInPath": {
105 | "description": "Suppress transpile when no .babelrc file is in source file path.",
106 | "type": "boolean",
107 | "default": true,
108 | "order": 60
109 | },
110 | "suppressTranspileOnSaveMessages": {
111 | "description": "Suppress non-error notification messages on each save.",
112 | "type": "boolean",
113 | "default": true,
114 | "order": 70
115 | },
116 | "suppressSourcePathMessages": {
117 | "description": "Suppress messages about file not being inside Babel Source Path.",
118 | "type": "boolean",
119 | "default": true,
120 | "order": 75
121 | },
122 | "createMap": {
123 | "description": "Create separate map file.",
124 | "type": "boolean",
125 | "default": false,
126 | "order": 80
127 | },
128 | "babelMapsAddUrl": {
129 | "description": "Append map file name to transpiled output if \"Create separate map file\" is set.",
130 | "type": "boolean",
131 | "default": true,
132 | "order": 90
133 | },
134 | "babelSourcePath": {
135 | "description": "Babel Source Root based on Project root.",
136 | "type": "string",
137 | "default": "",
138 | "order": 100
139 | },
140 | "babelTranspilePath": {
141 | "description": "Babel Transpile Root based on Project root.",
142 | "type": "string",
143 | "default": "",
144 | "order": 120
145 | },
146 | "babelMapsPath": {
147 | "description": "Babel Maps Root based on Project root.",
148 | "type": "string",
149 | "default": "",
150 | "order": 130
151 | },
152 | "createTargetDirectories": {
153 | "description": "Create transpile output target directories.",
154 | "type": "boolean",
155 | "default": true,
156 | "order": 140
157 | },
158 | "keepFileExtension": {
159 | "description": "Source filename extension becomes target filename extension.",
160 | "type": "boolean",
161 | "default": false,
162 | "order": 150
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/spec/create-tag-grammar-spec.js:
--------------------------------------------------------------------------------
1 | /*global atom*/
2 | var temp = require('temp');
3 | var path = require('path');
4 | var CreateTtlGrammar = require('../lib/create-ttl-grammar');
5 |
6 | temp.track();
7 |
8 | describe('Create Ttl Grammar', () => {
9 | var ttlGrammar = null;
10 |
11 | beforeEach(() => {
12 | temp.cleanup();
13 | waitsForPromise(() => {
14 | return atom.packages.activatePackage('language-babel');
15 | });
16 |
17 | return runs(() => {
18 | ttlGrammar = new CreateTtlGrammar();
19 |
20 | });
21 | });
22 |
23 | afterEach(() => {
24 | ttlGrammar.destroy();
25 | ttlGrammar = null;
26 | });
27 |
28 | describe('::getTtlConfig', () => {
29 | return it(
30 | 'should return an array containing the tagged template extensions configuration',
31 | () => {
32 | return expect(ttlGrammar.getTtlConfig()).toEqual([]);
33 | }
34 | );
35 | });
36 |
37 | describe('::generateTtlSHA256', () => {
38 | return it(
39 | 'should return SHA256 hash some text',
40 | () => {
41 | return expect(ttlGrammar.generateTtlSHA256('The Quick Fox')).toEqual('4af51dbb709ee9d85987ca5982e322ee2ec4d72ae8c92f11c5728813277e6b33');
42 | }
43 | );
44 | });
45 |
46 | describe('::makeTtlGrammarFilename', () => {
47 | return it(
48 | 'should return a string prefixed with ttl-',
49 | () => {
50 | expect(ttlGrammar.makeTtlGrammarFilename('filename')).toEqual('ttl-filename.json');
51 | }
52 | );
53 | });
54 |
55 | describe('::getGrammarPath', () => {
56 | return it(
57 | 'should return an absolute path where the language-babel grammar files are',
58 | () => {
59 | expect(path.isAbsolute(ttlGrammar.getGrammarPath())).toEqual(true);
60 | }
61 | );
62 | });
63 |
64 | describe('::makeTtlGrammarFilenameAbsoulute', () => {
65 | return it(
66 | 'should return an absolute path with a filename ',
67 | () => {
68 | expect(path.isAbsolute(ttlGrammar.makeTtlGrammarFilenameAbsoulute('someFile'))).toEqual(true);
69 | }
70 | );
71 | });
72 |
73 | describe('::getGrammarFiles', () => {
74 | return it(
75 | 'should return a list of all language-babel grammar files including Babel Language.json',
76 | () => {
77 | waitsForPromise(() => {
78 | return ttlGrammar.getGrammarFiles().then( (grammarFiles) => {
79 | expect(grammarFiles).toContain('Babel Language.json');
80 | });
81 | });
82 | }
83 | );
84 | });
85 |
86 | describe('::getTtlGrammarFiles', () => {
87 | return it(
88 | 'should return a list of language-babel grammar with a ttl- prefix',
89 | () => {
90 | waitsForPromise(() => {
91 | return ttlGrammar.getTtlGrammarFiles().then( (grammarFiles) => {
92 | expect(grammarFiles).toMatch(/^ttl-/);
93 | });
94 | });
95 | }
96 | );
97 | });
98 |
99 | describe('::doesGrammarFileExist', () => {
100 | return it(
101 | 'checks if a grammar file exists',
102 | () => {
103 | waitsForPromise(() => {
104 | return ttlGrammar.doesGrammarFileExist('Babel Language.json').catch( (rejVal) => {
105 | expect(rejVal).toEqual(true);
106 | });
107 | });
108 | }
109 | );
110 | });
111 |
112 | describe('::removeTtlLanguageFiles', () => {
113 | return it(
114 | 'should remove any files ttl-hashedvalue.json',
115 | () => {
116 | var tempGrammarDir = temp.mkdirSync();
117 | temp.open('ttl-a.json');
118 | temp.open('ttl-b.json');
119 | temp.open('ttl-c.json');
120 |
121 | spyOn(ttlGrammar, 'getGrammarPath').andReturn(tempGrammarDir);
122 |
123 | waitsForPromise( () => {
124 | return ttlGrammar.removeTtlLanguageFiles()
125 | // Previous fs.unlink's queue a delete in Node so delay check
126 | .then( () => setTimeout(()=>void(0) ,1000) )
127 | .then( () => ttlGrammar.getTtlGrammarFiles() )
128 | .then( (ttlFiles) => expect(ttlFiles).toEqual([]) );
129 | });
130 | });
131 | });
132 |
133 | describe('::createGrammarPatterns', () => {
134 | return it(
135 | 'should generate an error when a badly formatted ttl config is entered',
136 | () => {
137 | expect(() => ttlGrammar.createGrammarPatterns('/* test */:trailing.dot.#include')).toThrow();
138 | }
139 | );
140 | });
141 |
142 | describe('::onigurumaCheck', () => {
143 | return it(
144 | 'should return true on a valid regex',
145 | () => {
146 | let ret = ttlGrammar.onigurumaCheck('(?<=\\{)');
147 | expect(ret).toBe(true);
148 | }
149 | );
150 | });
151 |
152 | describe('::onigurumaCheck', () => {
153 | return it(
154 | 'should throw on a invalid regex',
155 | () => {
156 | expect(() => {ttlGrammar.onigurumaCheck('(?<=\\s*\\{)');}).toThrow();
157 | }
158 | );
159 | });
160 |
161 | // Ensure we finish off by creating a valid ttl file
162 | describe('::createGrammar', () => {
163 | return it(
164 | 'should create a valid ttl grammar file based upon some defined config',
165 | () => {
166 | var tempGrammarDir = temp.mkdirSync();
167 |
168 | spyOn(ttlGrammar, 'getGrammarPath').andReturn(tempGrammarDir);
169 | spyOn(ttlGrammar, 'getTtlConfig').andReturn(['"(?:css\\.(?:[a-z])+)":source.css','/* @html */:text.html.basic','sql:source.sql']);
170 |
171 | const grammarText = ttlGrammar.createGrammarText();
172 | const hash = ttlGrammar.generateTtlSHA256(grammarText);
173 | const ttlFilename = ttlGrammar.makeTtlGrammarFilename(hash);
174 | const ttlFilenameAbsolute = ttlGrammar.makeTtlGrammarFilenameAbsoulute(ttlFilename);
175 | waitsForPromise(() => {
176 | return ttlGrammar.createGrammar({ttlFilename, ttlFilenameAbsolute, grammarText }).then( (val) => {
177 | expect(val).toEqual('ttl-21a776c6bf96514f8dd8ffa557f23132510ace330d988f695538558900eeebe9.json');
178 | });
179 | });
180 | }
181 | );
182 | });
183 |
184 | });
185 |
--------------------------------------------------------------------------------
/lib/main.coffee:
--------------------------------------------------------------------------------
1 | {CompositeDisposable} = require 'atom'
2 | autoCompleteJSX = require './auto-complete-jsx'
3 | autoCompleteStyledComponents = require './auto-complete-styled-components'
4 | autoCompeteEmmetCSS = require './auto-complete-emmet-css'
5 | AutoIndent = require './auto-indent'
6 | ttlGrammar = require './create-ttl-grammar'
7 |
8 | INTERFILESAVETIME = 1000
9 | LB = 'language-babel'
10 | observeStatusBarGrammarNameTimer = null
11 | observeStatusBarGrammarNameTimerCalled = 0
12 |
13 | module.exports =
14 | activate: (state) ->
15 | # run observeStatusBarGrammarName until Atom has created the Status Bar Grammar Name DOM node
16 | observeStatusBarGrammarNameTimer = setInterval(@observeStatusBarGrammarName.bind(@), 1000)
17 | autoCompleteStyledComponents.loadProperties()
18 | @transpiler ?= new (require './transpiler')
19 | @ttlGrammar = new ttlGrammar(true)
20 | # track any file save events and transpile if babel
21 | @disposable = new CompositeDisposable
22 | @textEditors = {}
23 | @fileSaveTimes = {}
24 |
25 | @disposable.add atom.packages.onDidActivatePackage @isPackageCompatible
26 |
27 | @disposable.add atom.project.onDidChangePaths =>
28 | @transpiler.stopUnusedTasks()
29 |
30 | @disposable.add atom.workspace.observeTextEditors (textEditor) =>
31 | @textEditors[textEditor.id] = new CompositeDisposable
32 |
33 | @textEditors[textEditor.id].add textEditor.observeGrammar (grammar) =>
34 | # Instantiate indentor for language-babel files
35 | if textEditor.getGrammar().packageName is LB
36 | @textEditors[textEditor.id]?.autoIndent = new AutoIndent(textEditor)
37 | else
38 | @textEditors[textEditor.id]?.autoIndent?.destroy()
39 | delete @textEditors[textEditor.id]?.autoIndent?
40 |
41 | @textEditors[textEditor.id].add textEditor.onDidSave (event) =>
42 | if textEditor.getGrammar().packageName is LB
43 | filePath = textEditor.getPath()
44 | lastSaveTime = @fileSaveTimes[filePath] ? 0
45 | @fileSaveTimes[filePath] = Date.now()
46 | if (lastSaveTime < (@fileSaveTimes[filePath] - INTERFILESAVETIME))
47 | @transpiler.transpile(filePath, textEditor)
48 |
49 | @textEditors[textEditor.id].add textEditor.onDidDestroy () =>
50 | @textEditors[textEditor.id]?.autoIndent?.destroy()
51 | delete @textEditors[textEditor.id]?.autoIndent?
52 | filePath = textEditor.getPath()
53 | if @fileSaveTimes[filePath]? then delete @fileSaveTimes[filePath]
54 | @textEditors[textEditor.id].dispose()
55 | delete @textEditors[textEditor.id]
56 |
57 | deactivate: ->
58 | @disposable.dispose()
59 | for id, disposeable of @textEditors
60 | if @textEditors[id].autoIndent?
61 | @textEditors[id].autoIndent.destroy()
62 | delete @textEditors[id].autoIndent
63 | disposeable.dispose()
64 | @transpiler.stopAllTranspilerTask()
65 | @transpiler.disposables.dispose()
66 | @ttlGrammar.destroy()
67 | @mutateStatusGrammarNameObserver?.disconnet()
68 |
69 | # warns if an activated package is on the incompatible list
70 | isPackageCompatible: (activatedPackage) ->
71 | incompatiblePackages = {
72 | 'source-preview-babel':
73 | "Both vie to preview the same file."
74 | 'source-preview-react':
75 | "Both vie to preview the same file."
76 | 'react':
77 | "The Atom community package 'react' (not to be confused
78 | \nwith Facebook React) monkey patches the atom methods
79 | \nthat provide autoindent features for JSX.
80 | \nAs it detects JSX scopes without regard to the grammar being used,
81 | \nit tries to auto indent JSX that is highlighted by language-babel.
82 | \nAs language-babel also attempts to do auto indentation using
83 | \nstandard atom API's, this creates a potential conflict."
84 | }
85 |
86 | for incompatiblePackage, reason of incompatiblePackages
87 | if activatedPackage.name is incompatiblePackage
88 | atom.notifications.addInfo 'Incompatible Package Detected',
89 | dismissable: true
90 | detail: "language-babel has detected the presence of an
91 | incompatible Atom package named '#{activatedPackage.name}'.
92 | \n \nIt is recommended that you disable either '#{activatedPackage.name}' or language-babel
93 | \n \nReason:\n \n#{reason}"
94 |
95 | # autocomplete-plus providers
96 | autoCompleteProvider: ->
97 | [autoCompleteJSX, autoCompleteStyledComponents, autoCompeteEmmetCSS]
98 |
99 | # preview tranpile provider
100 | provide:->
101 | @transpiler
102 |
103 |
104 | # Kludge to change the grammar name in the status bar from Babel ES6 JavaScipt to Babel
105 | # The grammar name still remains the same for compatibilty with other packages such as atom-beautify
106 | # but is more meaningful and shorter on the status bar.
107 | observeStatusBarGrammarName: ->
108 | # select the target node
109 | target = document.getElementsByTagName('grammar-selector-status');
110 |
111 | # only run this for so many cycles without getting a valid dom node
112 | if ++observeStatusBarGrammarNameTimerCalled > 60
113 | clearInterval(observeStatusBarGrammarNameTimer)
114 | observeStatusBarGrammarNameTimerCalled = 0
115 |
116 | # only expect a single child (grammar name) for this DOM Node
117 | if target.length is 1
118 | target = target[0].childNodes?[0]
119 |
120 | if target
121 | # don't run again as we are now observing
122 | clearInterval(observeStatusBarGrammarNameTimer)
123 |
124 | @mutateStatusBarGrammarName(target)
125 |
126 | # create an observer instance
127 | mutateStatusGrammarNameObserver = new MutationObserver (mutations) =>
128 | mutations.forEach (mutation) =>
129 | @mutateStatusBarGrammarName(mutation.target)
130 |
131 | # configuration of the observer:
132 | config = { attributes: true, childList: false, characterData: false }
133 |
134 | # pass in the target node, as well as the observer options
135 | mutateStatusGrammarNameObserver.observe(target, config);
136 |
137 |
138 | # change name in status bar
139 | mutateStatusBarGrammarName: (elem) ->
140 | if elem?.innerHTML is 'Babel ES6 JavaScript'
141 | elem.innerHTML = 'Babel'
142 |
--------------------------------------------------------------------------------
/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])*)|(?:(\/>)|(>))|(<\s*>)/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 |
24 | jsxTag = @getTriggerTag editor, bufferPosition
25 | return if not jsxTag?
26 |
27 | # build autocomplete list
28 | suggestions = []
29 |
30 | if jsxTag is JSXSTARTTAGEND
31 | startOfJSX = @getStartOfJSX editor, bufferPosition
32 | jsxRange = new Range(startOfJSX, bufferPosition)
33 | tagNameStack = @buildTagStack(editor, jsxRange)
34 | while ( tagName = tagNameStack.pop())?
35 | suggestions.push
36 | snippet: "$1#{tagName}>"
37 | type: "tag"
38 | description: "language-babel tag closer"
39 |
40 | else if jsxTag is JSXENDTAGSTART
41 | startOfJSX = @getStartOfJSX editor, bufferPosition
42 | jsxRange = new Range(startOfJSX, bufferPosition)
43 | tagNameStack = @buildTagStack(editor, jsxRange)
44 | while ( tagName = tagNameStack.pop())?
45 | suggestions.push
46 | snippet: "#{tagName}>"
47 | type: "tag"
48 | description: "language-babel tag closer"
49 |
50 | else if jsxTag is JSXTAG
51 | return if not /^[a-z]/g.exec(prefix)
52 | htmlElements = filter(COMPLETIONS.htmlElements, prefix, {key: "name"})
53 | for htmlElement in htmlElements
54 | if score(htmlElement.name, prefix) < 0.07 then continue
55 | suggestions.push
56 | snippet: htmlElement.name
57 | type: "tag"
58 | description: "language-babel JSX supported elements"
59 | descriptionMoreURL: REACTURL
60 |
61 | else if jsxTag is JSXATTRIBUTE
62 | tagName = @getThisTagName editor, bufferPosition
63 | return if not tagName?
64 | for elementObj in COMPLETIONS.htmlElements
65 | if elementObj.name is tagName then break
66 | attributes = elementObj.attributes.concat COMPLETIONS.globalAttributes
67 | attributes = attributes.concat COMPLETIONS.events
68 | filteredAttributes = filter(attributes, prefix, {key: "name"})
69 | for attribute in filteredAttributes
70 | if score(attribute.name, prefix) < 0.07 then continue
71 | suggestions.push
72 | snippet: attribute.name
73 | type: "attribute"
74 | rightLabel: "<#{tagName}>"
75 | description: "language-babel JSXsupported attributes/events"
76 | descriptionMoreURL: REACTURL
77 |
78 | else return
79 | suggestions
80 |
81 | # get tagname for this attribute
82 | getThisTagName: ( editor, bufferPosition) ->
83 | row = bufferPosition.row
84 | column = null
85 | while row >= 0
86 | rowText = editor.lineTextForBufferRow(row)
87 | if not column?
88 | rowText = rowText.substr 0, column = bufferPosition.column
89 | matches = []
90 | while (( match = TAGREGEXP.exec(rowText)) isnt null )
91 | # save this match if it a valid tag
92 | scopes = editor.scopeDescriptorForBufferPosition([row, match.index+1]).getScopesArray()
93 | if "entity.name.tag.open.jsx" in scopes then matches.push match[1]
94 | # return the tag that is the last one found
95 | if matches.length
96 | return matches.pop()
97 | else row--
98 |
99 |
100 | getTriggerTag: (editor, bufferPosition) ->
101 | # JSX tag scopes we are interested in may already closed once typed
102 | # so we have to backtrack by one char to see if they were typed
103 | column = bufferPosition.column-1
104 | if column >= 0
105 | scopes = editor.scopeDescriptorForBufferPosition([bufferPosition.row, column]).getScopesArray()
106 | if "entity.other.attribute-name.jsx" in scopes then return JSXATTRIBUTE
107 | if "entity.name.tag.open.jsx" in scopes then return JSXTAG
108 | if "JSXStartTagEnd" in scopes then return JSXSTARTTAGEND
109 | if "JSXEndTagStart" in scopes then return JSXENDTAGSTART
110 |
111 |
112 | # find beggining of JSX in buffer and return Point
113 | getStartOfJSX: (editor, bufferPosition) ->
114 | row = bufferPosition.row
115 | # find previous start of row that has no jsx tag
116 | while row >= 0
117 | break if "meta.tag.jsx" not in editor.scopeDescriptorForBufferPosition([row, 0]).getScopesArray()
118 | row--
119 | if row < 0 then row = 0
120 | # maybe jsx appaears later in row
121 | columnLen = editor.lineTextForBufferRow(row).length
122 | column = 0
123 | while column < columnLen
124 | break if "meta.tag.jsx" in editor.scopeDescriptorForBufferPosition([row, column]).getScopesArray()
125 | column++
126 | # adjust row column if jsx not in this row at all
127 | if column is columnLen
128 | row++
129 | column = 0
130 | new Point(row, column)
131 |
132 | # build stack of tagnames opened but not closed in Range
133 | buildTagStack: (editor, range) ->
134 | tagNameStack = []
135 | row = range.start.row
136 | while row <= range.end.row
137 | line = editor.lineTextForBufferRow row
138 | if row is range.end.row
139 | line = line.substr 0, range.end.column
140 | while (( match = JSXREGEXP.exec(line)) isnt null )
141 | matchColumn = match.index
142 | matchPointStart = new Point(row, matchColumn)
143 | matchPointEnd = new Point(row, matchColumn + match[0].length - 1)
144 | matchRange = new Range(matchPointStart, matchPointEnd)
145 | if range.intersectsWith(matchRange)
146 | scopes = editor.scopeDescriptorForBufferPosition([row, match.index]).getScopesArray()
147 | continue if "punctuation.definition.tag.jsx" not in scopes
148 | #check capture groups
149 | if match[1]? # tags starting
156 | tagNameStack.pop()
157 | else if match[6]? # tag fragment stating <>
158 | tagNameStack.push ""
159 |
160 | row++
161 | tagNameStack
162 |
--------------------------------------------------------------------------------
/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 | // ^^ meta.brace.round.js
16 | // ^ punctuation.definition.parameters.end.js
17 | // ^^ meta.brace.curly.js
18 | *generatorMethod() {}
19 | //^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
20 | //^^^^^^^^^^^^^^^^^^ ^^ meta.function.method.js
21 | //^ keyword.generator.asterisk.js
22 | // ^^^^^^^^^^^^^^^ entity.name.function.method.js
23 | // ^ punctuation.definition.parameters.begin.js
24 | // ^^ meta.brace.round.js
25 | // ^ punctuation.definition.parameters.end.js
26 | // ^^ meta.brace.curly.js
27 | static staticRegularMethod() {}
28 | //^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
29 | //^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^ meta.function.method.js
30 | //^^^^^^ storage.modifier.js
31 | // ^^^^^^^^^^^^^^^^^^^ entity.name.function.method.js
32 | // ^ punctuation.definition.parameters.begin.js
33 | // ^^ meta.brace.round.js
34 | // ^ punctuation.definition.parameters.end.js
35 | // ^^ meta.brace.curly.js
36 | static get staticGetterMethod() {}
37 | //^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
38 | //^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^ ^^ meta.accessor.js
39 | //^^^^^^ storage.modifier.js
40 | // ^^^ storage.type.accessor.js
41 | // ^^^^^^^^^^^^^^^^^^ entity.name.function.accessor.js
42 | // ^ punctuation.definition.parameters.begin.js
43 | // ^^ meta.brace.round.js
44 | // ^ punctuation.definition.parameters.end.js
45 | // ^^ meta.brace.curly.js
46 | static set staticSetterMethod(arg) {}
47 | //^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
48 | //^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.accessor.js
49 | //^^^^^^ storage.modifier.js
50 | // ^^^ storage.type.accessor.js
51 | // ^^^^^^^^^^^^^^^^^^ entity.name.function.accessor.js
52 | // ^ punctuation.definition.parameters.begin.js
53 | // ^ ^ meta.brace.round.js
54 | // ^^^ meta.function.parameters.js
55 | // ^^^ variable.other.readwrite.js
56 | // ^ punctuation.definition.parameters.end.js
57 | // ^^ meta.brace.curly.js
58 | static *staticGeneratorMethod() {}
59 | //^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
60 | //^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.function.method.js
61 | //^^^^^^ storage.modifier.js
62 | // ^ keyword.generator.asterisk.js
63 | // ^^^^^^^^^^^^^^^^^^^^^ entity.name.function.method.js
64 | // ^ punctuation.definition.parameters.begin.js
65 | // ^^ meta.brace.round.js
66 | // ^ punctuation.definition.parameters.end.js
67 | // ^^ meta.brace.curly.js
68 | static async staticAsyncMethod() {}
69 | //^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
70 | //^^^^^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^ meta.function.method.js
71 | //^^^^^^ storage.modifier.js
72 | // ^^^^^ storage.type.js
73 | // ^^^^^^^^^^^^^^^^^ entity.name.function.method.js
74 | // ^ punctuation.definition.parameters.begin.js
75 | // ^^ meta.brace.round.js
76 | // ^ punctuation.definition.parameters.end.js
77 | // ^^ meta.brace.curly.js
78 | async asyncMethod() {}
79 | //^^^^^ ^^^^^^^^^^^^^ ^^ meta.class.body.js
80 | //^^^^^ ^^^^^^^^^^^^^ ^^ meta.function.method.js
81 | //^^^^^ storage.type.js
82 | // ^^^^^^^^^^^ entity.name.function.method.js
83 | // ^ punctuation.definition.parameters.begin.js
84 | // ^^ meta.brace.round.js
85 | // ^ punctuation.definition.parameters.end.js
86 | // ^^ meta.brace.curly.js
87 | [computedMethod()]() {}
88 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
89 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.function.method.js
90 | //^ ^ meta.brace.square.js
91 | // ^^^^^^^^^^^^^^^^ meta.function-call.without-arguments.js
92 | // ^^^^^^^^^^^^^^ entity.name.function.js
93 | // ^^ ^^ meta.brace.round.js
94 | // ^ punctuation.definition.parameters.begin.js
95 | // ^ punctuation.definition.parameters.end.js
96 | // ^^ meta.brace.curly.js
97 | ["computedString"]() {}
98 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
99 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.function.method.js
100 | //^ ^ meta.brace.square.js
101 | // ^^^^^^^^^^^^^^^^ string.quoted.double.js
102 | // ^ punctuation.definition.string.begin.js
103 | // ^ punctuation.definition.string.end.js
104 | // ^ punctuation.definition.parameters.begin.js
105 | // ^^ meta.brace.round.js
106 | // ^ punctuation.definition.parameters.end.js
107 | // ^^ meta.brace.curly.js
108 | ["computed" + "String"]() {}
109 | //^^^^^^^^^^^ ^ ^^^^^^^^^^^ ^^ meta.class.body.js
110 | //^^^^^^^^^^^ ^ ^^^^^^^^^^^ ^^ meta.function.method.js
111 | //^ ^ meta.brace.square.js
112 | // ^^^^^^^^^^ ^^^^^^^^ string.quoted.double.js
113 | // ^ ^ punctuation.definition.string.begin.js
114 | // ^ ^ punctuation.definition.string.end.js
115 | // ^ keyword.operator.arithmetic.js
116 | // ^ punctuation.definition.parameters.begin.js
117 | // ^^ meta.brace.round.js
118 | // ^ punctuation.definition.parameters.end.js
119 | // ^^ meta.brace.curly.js
120 | *[Symbol.iterator]() {}
121 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.class.body.js
122 | //^^^^^^^^^^^^^^^^^^^^ ^^ meta.function.method.js
123 | //^ keyword.generator.asterisk.js
124 | // ^ ^ meta.brace.square.js
125 | // ^^^^^^ support.class.builtin.js
126 | // ^ keyword.operator.accessor.js
127 | // ^^^^^^^^ meta.property.object.js
128 | // ^^^^^^^^ variable.other.property.js
129 | // ^ punctuation.definition.parameters.begin.js
130 | // ^^ meta.brace.round.js
131 | // ^ punctuation.definition.parameters.end.js
132 | // ^^ meta.brace.curly.js
133 | }
134 | // <- punctuation.section.class.end.js
135 |
136 |
137 | // >> only:(source.js.jsx)
138 |
--------------------------------------------------------------------------------
/spec/fixtures/grammar/babel-sublime/jsx-features.jsx:
--------------------------------------------------------------------------------
1 | // SYNTAX TEST "source.js.jsx"
2 |
3 | // JSX Fragements
4 |
5 | <>
6 | // <- meta.tag.jsx punctuation.definition.tag.jsx
7 | // <- meta.tag.jsx punctuation.definition.tag.jsx JSXAttrs JSXStartTagEnd
8 | Some fragment
9 | //^^^^ ^^^^^^^^ meta.tag.jsx
10 | //^^^^ ^^^^^^^^ JSXAttrs
11 | //^^^^ ^^^^^^^^ JSXNested
12 | <>Some frag>
13 | //^^^^^^^^^^^ ^^^^^^^^^^^^^ meta.tag.jsx
14 | //^^^^^^^^^^^ ^^^^^^^^^^^^^ JSXAttrs
15 | //^^^^^^^^^^^ ^^^^^^^^^^^^^ JSXNested
16 | //^ ^^^ ^^^^^ ^ punctuation.definition.tag.jsx
17 | // ^^^ entity.name.tag.open.jsx
18 | // ^ ^ JSXStartTagEnd
19 | // ^^ ^^ JSXEndTagStart
20 | // ^^^ entity.name.tag.close.jsx
21 | >
22 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
23 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
24 | //^ meta.tag.jsx
25 | //^ punctuation.definition.tag.jsx
26 |
27 | // tight greater-/less-than operations.
28 |
29 | for (var i=1; i
111 | // <- meta.tag.jsx punctuation.definition.tag.jsx
112 | // <- meta.tag.jsx entity.name.tag.open.jsx
113 | //^^ ^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx
114 | // ^ punctuation.definition.tag.jsx
115 | //^^ entity.name.tag.open.jsx
116 | // ^^ ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^ JSXAttrs
117 | // ^^ ^^^^^^^ ^^ comment.block.js
118 | // ^^ ^^ punctuation.definition.comment.js
119 | // ^^^^^^^ entity.other.attribute-name.jsx
120 | // ^ keyword.operator.assignment.jsx
121 | // ^^^^^^^^^^^^^^ meta.embedded.expression.js
122 | // ^ punctuation.section.embedded.begin.jsx
123 | // ^^^^ variable.language.this.js
124 | // ^ keyword.operator.accessor.js
125 | // ^^^^^^^ meta.property.object.js
126 | // ^^^^^^^ variable.other.property.js
127 | // ^ punctuation.section.embedded.end.jsx
128 | // ^ JSXStartTagEnd
129 |
130 | //^^^^^^^^^^^^^^^^^^^^^^^ ^^ meta.tag.jsx
131 | //^^^^^^^^^^^^^^^^^^^^^^^ ^^ JSXAttrs
132 | //^^^^^^^^^^^^^^^^^^^^^^^ ^^ JSXNested
133 | //^ ^^ punctuation.definition.tag.jsx
134 | // ^^^^^^^^^^^^^^^^^^^^^^ entity.name.tag.open.jsx
135 | // ^^^^^^^^^^^^^^^^^^^^^^ support.class.component.open.jsx
136 |
170 | // ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx
171 | // ^^^^^^^^^^^^^^^^^^^^^^^^^ JSXAttrs
172 | // ^^^^^^^^^^^^^^^^^^^^^^^^^ JSXNested
173 | // ^^^^^^^^^ entity.other.attribute-name.jsx
174 | // ^ keyword.operator.assignment.jsx
175 | // ^^^^^^^^^^^^^^ string.quoted.single.js
176 | // ^ punctuation.definition.string.begin.jsx
177 | // ^ punctuation.definition.string.end.jsx
178 | // ^ punctuation.definition.tag.jsx
179 | // ^ JSXStartTagEnd
180 |
181 | //^^^^^^^^^^^^^^^^^^^^ meta.tag.jsx
182 | //^^^^^^^^^^^^^^^^^^^^ JSXAttrs
183 | //^^^^^^^^^^^^^^^^^^^^ JSXNested
184 | //^^ ^ punctuation.definition.tag.jsx
185 | //^^ JSXEndTagStart
186 | // ^^^^^^^^^^^^^^^^^ entity.name.tag.close.jsx
187 | // ^^^^^^^^^^^^^^^^^ support.class.component.close.jsx
188 |
189 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
190 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
191 | //^^^^ meta.tag.jsx
192 | // ^ punctuation.definition.tag.jsx
193 | //^^^ entity.name.tag.close.jsx
194 |
195 |
196 |
197 | // >> only:(source.js.jsx)
198 |
--------------------------------------------------------------------------------
/lib/auto-complete-styled-components.coffee:
--------------------------------------------------------------------------------
1 | # This code was based upon https://github.com/atom/autocomplete-css but has been modified to allow it to be used
2 | # for styled-componenets. The completions.json file used to auto complete is a copy of the one used by the atom
3 | # package. That package, provided as an Atom base package, has tools to update the completions.json file from the web.
4 | # See that package for more info and just copy the completions.json to this files directory when a refresh is needed.
5 |
6 | fs = require 'fs'
7 | path = require 'path'
8 |
9 | firstInlinePropertyNameWithColonPattern = /{\s*(\S+)\s*:/ # .example { display: }
10 | inlinePropertyNameWithColonPattern = /(?:;.+?)*;\s*(\S+)\s*:/ # .example { display: block; float: left; color: } (match the last one)
11 | propertyNameWithColonPattern = /^\s*(\S+)\s*:/ # display:
12 | propertyNamePrefixPattern = /[a-zA-Z]+[-a-zA-Z]*$/
13 | pesudoSelectorPrefixPattern = /:(:)?([a-z]+[a-z-]*)?$/
14 | tagSelectorPrefixPattern = /(^|\s|,)([a-z]+)?$/
15 | importantPrefixPattern = /(![a-z]+)$/
16 | cssDocsURL = "https://developer.mozilla.org/en-US/docs/Web/CSS"
17 |
18 | module.exports =
19 | selector: '.source.inside-js.css.styled, .source.css.styled'
20 | disableForSelector: ".source.inside-js.css.styled .comment, .source.inside-js.css.styled .string, .source.inside-js.css.styled .entity.quasi.element.js, .source.css.styled .comment, .source.css.styled .string, .source.css.styled .entity.quasi.element.js"
21 |
22 | filterSuggestions: true
23 | inclusionPriority: 10000
24 | excludeLowerPriority: false
25 | suggestionPriority: 90
26 |
27 | getSuggestions: (request) ->
28 | completions = null
29 | scopes = request.scopeDescriptor.getScopesArray()
30 |
31 | if @isCompletingValue(request)
32 | completions = @getPropertyValueCompletions(request)
33 | else if @isCompletingPseudoSelector(request)
34 | completions = @getPseudoSelectorCompletions(request)
35 | else
36 | if @isCompletingName(request)
37 | completions = @getPropertyNameCompletions(request)
38 | else if @isCompletingNameOrTag(request)
39 | completions = @getPropertyNameCompletions(request)
40 | .concat(@getTagCompletions(request))
41 |
42 | return completions
43 |
44 | onDidInsertSuggestion: ({editor, suggestion}) ->
45 | setTimeout(@triggerAutocomplete.bind(this, editor), 1) if suggestion.type is 'property'
46 |
47 | triggerAutocomplete: (editor) ->
48 | atom.commands.dispatch(atom.views.getView(editor), 'autocomplete-plus:activate', {activatedManually: false})
49 |
50 | loadProperties: ->
51 | @properties = {}
52 | fs.readFile path.resolve(__dirname, 'completions.json'), (error, content) =>
53 | {@pseudoSelectors, @properties, @tags} = JSON.parse(content) unless error?
54 |
55 | return
56 |
57 | isCompletingValue: ({scopeDescriptor, bufferPosition, prefix, editor}) ->
58 | scopes = scopeDescriptor.getScopesArray()
59 |
60 | beforePrefixBufferPosition = [bufferPosition.row, Math.max(0, bufferPosition.column - prefix.length - 1)]
61 | beforePrefixScopes = editor.scopeDescriptorForBufferPosition(beforePrefixBufferPosition)
62 | beforePrefixScopesArray = beforePrefixScopes.getScopesArray()
63 |
64 | return (hasScope(scopes, 'meta.property-values.css')) or
65 | (hasScope(beforePrefixScopesArray , 'meta.property-values.css'))
66 |
67 | isCompletingName: ({scopeDescriptor, bufferPosition, editor}) ->
68 | scope = scopeDescriptor.getScopesArray().slice(-1)
69 | prefix = @getPropertyNamePrefix(bufferPosition, editor)
70 | return @isPropertyNamePrefix(prefix) and (scope[0] is 'meta.property-list.css')
71 |
72 | isCompletingNameOrTag: ({scopeDescriptor, bufferPosition, editor}) ->
73 | scope = scopeDescriptor.getScopesArray().slice(-1)
74 | prefix = @getPropertyNamePrefix(bufferPosition, editor)
75 | return @isPropertyNamePrefix(prefix) and
76 | ((scope[0] is 'meta.property-list.css') or
77 | (scope[0] is 'source.css.styled') or
78 | (scope[0] is 'entity.name.tag.css') or
79 | (scope[0] is 'source.inside-js.css.styled'))
80 |
81 | isCompletingPseudoSelector: ({editor, scopeDescriptor, bufferPosition}) ->
82 | scope = scopeDescriptor.getScopesArray().slice(-1)
83 | return ( ( scope[0] is 'constant.language.pseudo.prefixed.css') or
84 | ( scope[0] is 'keyword.operator.pseudo.css') )
85 |
86 | isPropertyValuePrefix: (prefix) ->
87 | prefix = prefix.trim()
88 | prefix.length > 0 and prefix isnt ':'
89 |
90 | isPropertyNamePrefix: (prefix) ->
91 | return false unless prefix?
92 | prefix = prefix.trim()
93 | prefix.match(/^[a-zA-Z-]+$/)
94 |
95 | getImportantPrefix: (editor, bufferPosition) ->
96 | line = editor.getTextInRange([[bufferPosition.row, 0], bufferPosition])
97 | importantPrefixPattern.exec(line)?[1]
98 |
99 | getPreviousPropertyName: (bufferPosition, editor) ->
100 | {row} = bufferPosition
101 | while row >= 0
102 | line = editor.lineTextForBufferRow(row)
103 | propertyName = inlinePropertyNameWithColonPattern.exec(line)?[1]
104 | propertyName ?= firstInlinePropertyNameWithColonPattern.exec(line)?[1]
105 | propertyName ?= propertyNameWithColonPattern.exec(line)?[1]
106 | return propertyName if propertyName
107 | row--
108 | return
109 |
110 | getPropertyValueCompletions: ({bufferPosition, editor, prefix, scopeDescriptor}) ->
111 | property = @getPreviousPropertyName(bufferPosition, editor)
112 | values = @properties[property]?.values
113 | return null unless values?
114 |
115 | scopes = scopeDescriptor.getScopesArray()
116 | addSemicolon = not lineEndsWithSemicolon(bufferPosition, editor)
117 |
118 | completions = []
119 | if @isPropertyValuePrefix(prefix)
120 | for value in values when firstCharsEqual(value, prefix)
121 | completions.push(@buildPropertyValueCompletion(value, property, addSemicolon))
122 | else
123 | for value in values
124 | completions.push(@buildPropertyValueCompletion(value, property, addSemicolon))
125 |
126 | if importantPrefix = @getImportantPrefix(editor, bufferPosition)
127 | completions.push
128 | type: 'keyword'
129 | text: '!important'
130 | displayText: '!important'
131 | replacementPrefix: importantPrefix
132 | description: "Forces this property to override any other declaration of the same property. Use with caution."
133 | descriptionMoreURL: "#{cssDocsURL}/Specificity#The_!important_exception"
134 |
135 | completions
136 |
137 | buildPropertyValueCompletion: (value, propertyName, addSemicolon) ->
138 | text = value
139 | text += ';' if addSemicolon
140 | text = makeSnippet(text)
141 |
142 | {
143 | type: 'value'
144 | snippet: text
145 | displayText: value
146 | description: "#{value} value for the #{propertyName} property"
147 | descriptionMoreURL: "#{cssDocsURL}/#{propertyName}#Values"
148 | }
149 |
150 | getPropertyNamePrefix: (bufferPosition, editor) ->
151 | line = editor.getTextInRange([[bufferPosition.row, 0], bufferPosition])
152 | propertyNamePrefixPattern.exec(line)?[0]
153 |
154 | getPropertyNameCompletions: ({bufferPosition, editor, scopeDescriptor, activatedManually}) ->
155 | scopes = scopeDescriptor.getScopesArray()
156 | line = editor.getTextInRange([[bufferPosition.row, 0], bufferPosition])
157 |
158 | prefix = @getPropertyNamePrefix(bufferPosition, editor)
159 | return [] unless activatedManually or prefix
160 |
161 | completions = []
162 | for property, options of @properties when not prefix or firstCharsEqual(property, prefix)
163 | completions.push(@buildPropertyNameCompletion(property, prefix, options))
164 | completions
165 |
166 | buildPropertyNameCompletion: (propertyName, prefix, {description}) ->
167 | type: 'property'
168 | text: "#{propertyName}: "
169 | displayText: propertyName
170 | replacementPrefix: prefix
171 | description: description
172 | descriptionMoreURL: "#{cssDocsURL}/#{propertyName}"
173 |
174 | getPseudoSelectorPrefix: (editor, bufferPosition) ->
175 | line = editor.getTextInRange([[bufferPosition.row, 0], bufferPosition])
176 | line.match(pesudoSelectorPrefixPattern)?[0]
177 |
178 | getPseudoSelectorCompletions: ({bufferPosition, editor}) ->
179 | prefix = @getPseudoSelectorPrefix(editor, bufferPosition)
180 | return null unless prefix
181 |
182 | completions = []
183 | for pseudoSelector, options of @pseudoSelectors when firstCharsEqual(pseudoSelector, prefix)
184 | completions.push(@buildPseudoSelectorCompletion(pseudoSelector, prefix, options))
185 | completions
186 |
187 | buildPseudoSelectorCompletion: (pseudoSelector, prefix, {argument, description}) ->
188 | completion =
189 | type: 'pseudo-selector'
190 | replacementPrefix: prefix
191 | description: description
192 | descriptionMoreURL: "#{cssDocsURL}/#{pseudoSelector}"
193 |
194 | if argument?
195 | completion.snippet = "#{pseudoSelector}(${1:#{argument}})"
196 | else
197 | completion.text = pseudoSelector
198 | completion
199 |
200 | getTagSelectorPrefix: (editor, bufferPosition) ->
201 | line = editor.getTextInRange([[bufferPosition.row, 0], bufferPosition])
202 | tagSelectorPrefixPattern.exec(line)?[2]
203 |
204 | getTagCompletions: ({bufferPosition, editor, prefix}) ->
205 | completions = []
206 | if prefix
207 | for tag in @tags when firstCharsEqual(tag, prefix)
208 | completions.push(@buildTagCompletion(tag))
209 | completions
210 |
211 | buildTagCompletion: (tag) ->
212 | type: 'tag'
213 | text: tag
214 | description: "Selector for <#{tag}> elements"
215 |
216 | lineEndsWithSemicolon = (bufferPosition, editor) ->
217 | {row} = bufferPosition
218 | line = editor.lineTextForBufferRow(row)
219 | /;\s*$/.test(line)
220 |
221 | hasScope = (scopesArray, scope) ->
222 | scopesArray.indexOf(scope) isnt -1
223 |
224 | firstCharsEqual = (str1, str2) ->
225 | str1[0].toLowerCase() is str2[0].toLowerCase()
226 |
227 | # looks at a string and replaces consecutive () with incrementing snippet positions ($n)
228 | # It also adds a trailing $n at end of text
229 | # e.g translate() becomes translate($1)$2
230 | makeSnippet = (text) ->
231 | snippetNumber = 0
232 | while text.includes('()')
233 | text = text.replace('()', "($#{++snippetNumber})")
234 | text = text + "$#{++snippetNumber}"
235 | return text
236 |
--------------------------------------------------------------------------------
/src/create-ttl-grammar.js:
--------------------------------------------------------------------------------
1 | /*global atom*/
2 | const crypto = require('crypto');
3 | const fs = require('fs');
4 | const path = require('path');
5 | const CompositeDisposable = require('atom').CompositeDisposable;
6 |
7 | // This Class is repsonsible for creating a new Tagged Template grammar
8 | // on detection of a changed Tagged Template Configuration in the package settings
9 | module.exports =
10 | class CreateTtlGrammar {
11 |
12 | disposable = new CompositeDisposable();
13 | configChangedTimer= null;
14 | TTL_GRAMMAR_NAME = 'language-babel-extension';
15 | TTL_SCOPENAME = `languagebabel.ttlextension`;
16 |
17 | constructor(observeConfig = false) {
18 | if (observeConfig) {
19 | // look for changes in tagged template handlers
20 | this.disposable.add(atom.config.observe('language-babel.taggedTemplateGrammar', this.observeTtlConfig.bind(this, 10000)));
21 | }
22 | }
23 |
24 | destroy() {
25 | this.disposable.dispose();
26 | }
27 |
28 | // add new grammars to registry
29 | addGrammars(filename) {
30 | return new Promise((resolve, reject) => {
31 | atom.grammars.loadGrammar(filename, (err) => {
32 | if (err) {
33 | reject(new Error(`Unable to add Grammar to registry\n${filename}`));
34 | }
35 | else resolve();
36 | });
37 | });
38 |
39 | }
40 |
41 | // Check if the grammar exists under this SHA256 file name
42 | // If not then remove all ttl grammars and create a new one
43 | // This returns a Promise that resolves with a ttl filename
44 | // if a new grammar was created or rejects if a problem.
45 | createGrammar({ttlFilename, ttlFilenameAbsolute, grammarText}) {
46 | return new Promise((resolve, reject) => {
47 | this.doesGrammarFileExist(ttlFilename)
48 | .then((ifFileExists) => {
49 | if (ifFileExists) {
50 | resolve();
51 | }
52 | else {
53 | this.removeGrammars();
54 | this.removeTtlLanguageFiles()
55 | .then(() => this.createGrammarFile(ttlFilenameAbsolute, grammarText))
56 | .then(() => this.addGrammars(ttlFilenameAbsolute))
57 | .then(() => {
58 | atom.notifications.addInfo('language-babel', {detail: `Grammar created at \n${ttlFilenameAbsolute}`,dismissable: true});
59 | resolve(ttlFilename);
60 | })
61 | .catch((err) => {
62 | atom.notifications.addWarning('language-babel', {detail: `${err.message}`,dismissable: true});
63 | reject(err);
64 | });
65 | }
66 | });
67 | });
68 | }
69 |
70 | // write the ttl grammar file for this config
71 | createGrammarFile(filename,text) {
72 | return new Promise((resolve, reject) => {
73 | fs.writeFile(filename, text, (err) => {
74 | if (err) reject(new Error(err));
75 | else resolve();
76 | });
77 | });
78 | }
79 |
80 | // create a Grammar file's JSON text
81 | createGrammarText() {
82 | return `{
83 | "name": "${this.TTL_GRAMMAR_NAME}",
84 | "comment": "Auto generated Tag Extensions for language-babel",
85 | "comment": "Please do not edit this file directly",
86 | "scopeName": "${this.TTL_SCOPENAME}",
87 | "fileTypes": [],
88 | "patterns": [
89 | ${this.getTtlConfig().map((ttlString) => (this.createGrammarPatterns(ttlString)))}
90 | ]
91 | }`;
92 | }
93 |
94 | // Create a grammar's pattern derived from a the tagged template string
95 | // in the form matchString:includeScope
96 | createGrammarPatterns(ttlString) {
97 | let lastColonIndex = ttlString.lastIndexOf(':');
98 | let matchString = ttlString.substring(0, lastColonIndex);
99 | let includeScope = ttlString.substring(lastColonIndex+1);
100 | const isValidIncludeScope = /^([a-zA-Z]\w*\.?)*(\w#([a-zA-Z]\w*\.?)*)?\w$/.test(includeScope);
101 | const isQuotedMatchString = /^\".*\"$/.test(matchString);
102 |
103 | if (matchString.length < 1 || !isValidIncludeScope) {
104 | throw new Error(`Error in the Tagged Template Grammar String ${ttlString}`);
105 | }
106 |
107 | if ( isQuotedMatchString ) {
108 | // Found a possible regexp in the form "regex" so strip the "
109 | matchString = matchString.substring(1, matchString.length -1);
110 | try {
111 | this.onigurumaCheck(matchString);
112 | matchString = matchString.replace(/\\/g,"\\\\"); // \ to \\
113 | matchString = matchString.replace(/\\\\["]/g,"\\\\\\\""); // \\" to \\
114 | }
115 | catch (err) {
116 | throw new Error(`You entered an badly formed RegExp in the Tagged Template Grammar settings.\n${matchString}\n${err}`);
117 | }
118 | }
119 | else if ( /"/g.test(matchString)) {
120 | throw new Error(`Bad literal string in the Tagged Template Grammar settings.\n${matchString}`);
121 | }
122 | else {
123 | // User entered a literal string which may contain chars that a special inside a regex.
124 | // Escape any special chars e.g. '/** @html */' -> '\/\*\* @html \*\/'
125 | // The string stored by Atom in the config has the \\ already escaped.
126 | const escapeStringRegExp = /[|{}()[\]^$+*?.]/g;
127 | const preEscapedSlash = /\\/g;
128 | matchString = matchString.replace(preEscapedSlash, '\\\\\\\\');
129 | matchString = matchString.replace(escapeStringRegExp, '\\\\$&');
130 | }
131 |
132 | return `{
133 | "contentName": "${includeScope.match(/^[^#]*/)[0]}",
134 | "begin": "\\\\s*+(${matchString})\\\\s*(\`)",
135 | "beginCaptures": {
136 | "1": { "name": "entity.name.tag.js" },
137 | "2": { "name": "punctuation.definition.quasi.begin.js" }
138 | },
139 | "end": "\\\\s*(?<=[^\\\\\\\\]\\\\\\\\\\\\\\\\|[^\\\\\\\\]|^\\\\\\\\\\\\\\\\|^)((\`))",
140 | "endCaptures": {
141 | "1": { "name": "punctuation.definition.quasi.end.js" }
142 | },
143 | "patterns": [
144 | { "include": "source.js.jsx#literal-quasi-embedded" },
145 | { "include": "${includeScope}" }
146 | ]
147 | }`;
148 | }
149 |
150 | // checks a ttl grammar filename exists
151 | // returns a Promise that resolves to true if ttlFileName exists
152 | doesGrammarFileExist(ttlFilename) {
153 | return new Promise((resolve) => {
154 | fs.access(this.makeTtlGrammarFilenameAbsoulute(ttlFilename), (fs.constants || fs).R_OK, (err) => {
155 | err ? resolve(false): resolve(true);
156 | });
157 | });
158 | }
159 |
160 | // get full path to the language-babel grammar file dir
161 | getGrammarPath() {
162 | return path.normalize(
163 | path.resolve(atom.packages.loadedPackages['language-babel'].path, './grammars')
164 | );
165 | }
166 |
167 | // get an array of all language-babel grammar files
168 | getGrammarFiles() {
169 | return new Promise((resolve,reject) => {
170 | fs.readdir(this.getGrammarPath(),(err, data) => {
171 | if (err) reject(new Error(err));
172 | else {
173 | resolve(data);
174 | }
175 | });
176 | });
177 | }
178 |
179 | // read configurations for tagged templates
180 | getTtlConfig() {
181 | return atom.config.get('language-babel').taggedTemplateGrammar;
182 | }
183 |
184 | // get an array of grammar tagged template extension filenames
185 | getTtlGrammarFiles() {
186 | return this.getGrammarFiles().then(dirFiles => dirFiles.filter(function(filename) {
187 | return /^ttl-/.test(filename);
188 | }));
189 | }
190 |
191 | // generate a SHA256 for some text
192 | generateTtlSHA256(stringToHash) {
193 | let hash = crypto.createHash('sha256');
194 | hash.update(stringToHash);
195 | return hash.digest('hex');
196 | }
197 |
198 | // tagged template filename
199 | makeTtlGrammarFilename(hashString) {
200 | return `ttl-${hashString}.json`;
201 | }
202 |
203 | // get a fully qualified filename
204 | makeTtlGrammarFilenameAbsoulute(ttlFilename) {
205 | return path.resolve(this.getGrammarPath(), ttlFilename);
206 | }
207 |
208 |
209 | // observe changes in the taggedTemplateGrammar config which take place
210 | // because observed config changes are fired as a user types them inside
211 | // settings we need to delay processing the array strings, until last char
212 | // entered was setTimeout seconds ago. parse tagged template configuration
213 | // and then create grammar and generate a SHA256 hash from the grammar
214 | observeTtlConfig(timeout) {
215 | if (this.configChangedTimer) clearTimeout(this.configChangedTimer);
216 | this.configChangedTimer = setTimeout(() => {
217 | try {
218 | const grammarText = this.createGrammarText();
219 | const hash = this.generateTtlSHA256(grammarText);
220 | const ttlFilename = this.makeTtlGrammarFilename(hash);
221 | const ttlFilenameAbsolute = this.makeTtlGrammarFilenameAbsoulute(ttlFilename);
222 | this.createGrammar({ttlFilename, ttlFilenameAbsolute, grammarText});
223 | }
224 | catch(err) {
225 | atom.notifications.addWarning('language-babel', {detail: `${err.message}`,dismissable: true});
226 | }
227 | }, timeout);
228 | }
229 |
230 | // validate a regex with a Oniguruma. This will throw if it fails the checks
231 | // This will return true if the check passes or false if no oniguruma was found
232 | onigurumaCheck(regex) {
233 | let isRegexValid = false;
234 | // We need to call oniguruma's constructor via this convoluted method as I can't include
235 | // the github/atom/node-oniguruma package as npm on Windows get node-gyp errors unless a
236 | // user has installed a compiler. Find Atom's Oniguruma and call the constructor.
237 | if (typeof atom.grammars.grammars === "object") {
238 | atom.grammars.grammars.every((obj) => {
239 | if (obj.name === "Babel ES6 JavaScript") {
240 | let ref, ref1, ref2;
241 | if ((ref = obj.firstLineRegex) != null) {
242 | if ((ref1 = ref.scanner) != null) {
243 | if ((ref2 = ref1.__proto__) != null) {
244 | if (typeof ref2.constructor === "function") {
245 | // now call new obj.firstLineRegex.scanner.__proto__.constructor([onigString]);
246 | // to validate the regex
247 | new ref2.constructor([regex]);
248 | isRegexValid = true;
249 | }
250 | }
251 | }
252 | }
253 | return false;
254 | }
255 | else return true;
256 | });
257 | }
258 | return isRegexValid;
259 | }
260 |
261 | // Remove grammars before upodating
262 | removeGrammars() {
263 | atom.grammars.removeGrammarForScopeName(this.TTL_SCOPENAME);
264 | }
265 |
266 | // remove all language files in tagged template GrammarFiles array
267 | removeTtlLanguageFiles() {
268 | return this.getTtlGrammarFiles().then((ttlGrammarFiles) => {
269 | for (let ttlGrammarFilename of ttlGrammarFiles) {
270 | let ttlGrammarFileAbsoulte = this.makeTtlGrammarFilenameAbsoulute(ttlGrammarFilename);
271 | fs.unlink(ttlGrammarFileAbsoulte);
272 | }
273 | });
274 |
275 | }
276 | };
277 |
--------------------------------------------------------------------------------
/spec/fixtures/grammar/css.js:
--------------------------------------------------------------------------------
1 | styled.div`
2 |
3 | div > .className + #idName
4 | /* psedo selectors */
5 | p::after p::backdrop p::before p::first-letter p::first-line p::selection
6 | p:any-link p:before p:checked p:current p:default p:dir p:disabled p:drop
7 | p:empty p:enabled
8 | p:first p:first-child p:first-letter p:first-line p:first-of-type p:focus
9 | p:fullscreen p:hover p:in-range p:indeterminate p:invalid p:last-child
10 | p:last-of-type p:left p:link p:only-child p:only-of-type p:optional
11 | p:out-of-range p:read-only p:read-write p:required p:right p:root p:scope
12 | p:target p:unresolved p:valid p:visited
13 |
14 | /* functions */
15 | p:lang(en) p:lang("en")
16 | p:not(html) p:has(html) p:matches(p,a) p:nth-child(1n+1) p:nth-last-child(1) p:nth-last-of-type(2n) p:nth-of-type(odd)
17 | [attr][attr=aaa][attr~="_blank" i][attr|="_blank"][attr$="_blank"][attr*="_blank"]
18 | {
19 | color: red;
20 | }
21 |
22 | border:
23 | /* numeric values */
24 | -1, +1, -1 -0.e10 1.0001 16/9
25 | /* units */
26 | 1turn 1rad 1grad 1deg 1kHz 1Hz 1vw 1vmin 1vmax 1vh 1rem 1q 1px 1pt 1pc 1mozmm 1mm 1in 1ex 1em 1cm 1ch
27 | /* hex */
28 | #fff #ffffffff
29 | /* unit after interpolation close */
30 | ${props.something?1:2}px;
31 | /* css properties */
32 | invalid-or-unknown-name:;
33 | --custom-name:;
34 | additive-symbols: top yyyyyy;
35 | all:;
36 | animation:;
37 | animation-delay:;
38 | animation-direction:;
39 | animation-duration:;
40 | animation-fill-mode:;
41 | animation-iteration-count:;
42 | animation-name:;
43 | animation-play-state:;
44 | animation-timing-function:;
45 | appearance:;
46 | backface-visibility:;
47 | background:;
48 | background-attachment:;
49 | background-blend-mode:;
50 | background-clip:;
51 | background-color:;
52 | background-image:;
53 | background-origin:;
54 | background-position:;
55 | background-repeat:;
56 | background-size:;
57 | bleed:;
58 | block-size:;
59 | border:;
60 | border-block-end:;
61 | border-block-end-color:;
62 | border-block-end-style:;
63 | border-block-end-width:;
64 | border-block-start:;
65 | border-block-start-color:;
66 | border-block-start-style:;
67 | border-block-start-width:;
68 | border-bottom:;
69 | border-bottom-color:;
70 | border-bottom-left-radius:;
71 | border-bottom-right-radius:;
72 | border-bottom-style:;
73 | border-bottom-width:;
74 | border-collapse:;
75 | border-color:;
76 | border-image:;
77 | border-image-outset:;
78 | border-image-repeat:;
79 | border-image-slice:;
80 | border-image-source:;
81 | border-image-width:;
82 | border-inline-end:;
83 | border-inline-end-color:;
84 | border-inline-end-style:;
85 | border-inline-end-width:;
86 | border-inline-start:;
87 | border-inline-start-color:;
88 | border-inline-start-style:;
89 | border-inline-start-width:;
90 | border-left:;
91 | border-left-color:;
92 | border-left-style:;
93 | border-left-width:;
94 | border-radius:;
95 | border-right:;
96 | border-right-color:;
97 | border-right-style:;
98 | border-right-width:;
99 | border-spacing:;
100 | border-style:;
101 | border-top:;
102 | border-top-color:;
103 | border-top-left-radius:;
104 | border-top-right-radius:;
105 | border-top-style:;
106 | border-top-width:;
107 | border-width:;
108 | bottom:;
109 | box-decoration-break:;
110 | box-shadow:;
111 | box-sizing:;
112 | break-after:;
113 | break-before:;
114 | break-inside:;
115 | caption-side:;
116 | clear:;
117 | clip-path:;
118 | column-count:;
119 | column-fill:;
120 | column-gap:;
121 | column-rule:;
122 | column-rule-color:;
123 | column-rule-style:;
124 | column-rule-width:;
125 | column-span:;
126 | column-width:;
127 | columns:;
128 | content:;
129 | counter-increment:;
130 | counter-reset:;
131 | cursor:;
132 | direction:;
133 | display:;
134 | empty-cells:;
135 | fallback:;
136 | filter:;
137 | float:;
138 | font:;
139 | flex:;
140 | flex-basis:;
141 | flex-direction:;
142 | flex-flow:;
143 | flex-grow:;
144 | flex-shrink:;
145 | flex-wrap:;
146 | font-family:;
147 | font-feature-settings:;
148 | font-kerning:;
149 | font-language-override:;
150 | font-size:;
151 | font-size-adjust:;
152 | font-stretch:;
153 | font-style:;
154 | font-synthesis:;
155 | font-variant:;
156 | font-variant-alternates:;
157 | font-variant-caps:;
158 | font-variant-east-asian:;
159 | font-variant-ligatures:;
160 | font-variant-numeric:;
161 | font-variant-position:;
162 | font-weight:;
163 | grid:;
164 | grid-area:;
165 | grid-auto-columns:;
166 | grid-auto-flow:;
167 | grid-auto-rows:;
168 | grid-column:;
169 | grid-column-end:;
170 | grid-column-gap:;
171 | grid-column-start:;
172 | grid-gap:;
173 | grid-row:;
174 | grid-row-end:;
175 | grid-row-gap:;
176 | grid-row-start:;
177 | grid-template:;
178 | grid-template-areas:;
179 | grid-template-columns:;
180 | grid-template-rows:;
181 | image-orientation:;
182 | image-rendering:;
183 | image-resolution:;
184 | height:;
185 | hyphens:;
186 | inline-size:;
187 | isolation:;
188 | justify-content:;
189 | left:;
190 | letter-spacing:;
191 | line-break:;
192 | line-height:;
193 | list-style:;
194 | list-style-image:;
195 | list-style-position:;
196 | list-style-type:;
197 | margin:;
198 | margin-block-end:;
199 | margin-block-start:;
200 | margin-bottom:;
201 | margin-inline-end:;
202 | margin-inline-start:;
203 | margin-left:;
204 | margin-right:;
205 | margin-top:;
206 | marks:;
207 | mask:;
208 | mask-clip:;
209 | mask-composite:;
210 | mask-image:;
211 | mask-mode:;
212 | mask-origin:;
213 | mask-position:;
214 | mask-repeat:;
215 | mask-size:;
216 | mask-type:;
217 | max-block-size:;
218 | max-height:;
219 | max-inline-size:;
220 | max-width:;
221 | max-zoom:;
222 | min-block-size:;
223 | min-height:;
224 | min-inline-size:;
225 | min-width:;
226 | min-zoom:;
227 | mix-blend-mode:;
228 | nav-up:;
229 | nav-right:;
230 | nav-left:;
231 | nav-index:;
232 | nav-down:;
233 | negative:;
234 | object-fit:;
235 | object-position:;
236 | offset-block-end:;
237 | offset-block-start:;
238 | offset-inline-end:;
239 | offset-inline-start:;
240 | opacity:;
241 | order:;
242 | orientation:;
243 | orphans:;
244 | outline:;
245 | outline-color:;
246 | outline-offset:;
247 | outline-style:;
248 | outline-width:;
249 | overflow:;
250 | overflow-wrap:;
251 | overflow-x:;
252 | overflow-y:;
253 | pad:;
254 | padding:;
255 | padding-block-end:;
256 | padding-block-start:;
257 | padding-bottom:;
258 | padding-inline-end:;
259 | padding-inline-start:;
260 | padding-left:;
261 | padding-right:;
262 | padding-top:;
263 | page-break-after:;
264 | page-break-before:;
265 | page-break-inside:;
266 | perspective:;
267 | perspective-origin:;
268 | pointer-events:;
269 | position:;
270 | quotes:;
271 | prefix:;
272 | range:;
273 | resize:;
274 | revert:;
275 | right:;
276 | ruby-align:;
277 | ruby-merge:;
278 | ruby-position:;
279 | scroll-behavior:;
280 | scroll-snap-coordinate:;
281 | scroll-snap-destination:;
282 | scroll-snap-type:;
283 | shape-image-threshold:;
284 | shape-margin:;
285 | shape-outside:;
286 | size:;
287 | speak-as:;
288 | src:;
289 | suffix:;
290 | symbols:;
291 | system:;
292 | tab-size:;
293 | table-layout:;
294 | text-align:;
295 | text-align-last:;
296 | text-combine-upright:;
297 | text-decoration:;
298 | text-decoration-color:;
299 | text-decoration-line:;
300 | text-decoration-style:;
301 | text-emphasis:;
302 | text-emphasis-color:;
303 | text-emphasis-position:;
304 | text-emphasis-style:;
305 | text-indent:;
306 | text-justify:;
307 | text-orientation:;
308 | text-overflow:;
309 | text-rendering:;
310 | text-size-adjust:;
311 | text-shadow:;
312 | text-transform:;
313 | text-underline-position:;
314 | top:;
315 | touch-action:;
316 | transform:;
317 | transform-box:;
318 | transform-origin:;
319 | transform-style:;
320 | transition:;
321 | transition-delay:;
322 | transition-duration:;
323 | transition-property:;
324 | transition-timing-function:;
325 | unicode-bidi:;
326 | unicode-range:;
327 | user-zoom:;
328 | vertical-align:;
329 | visibility:;
330 | volume:;
331 | white-space:;
332 | widows:;
333 | width:;
334 | will-change:;
335 | word-break:;
336 | word-spacing:;
337 | word-wrap:;
338 | writing-mode:;
339 | z-index:;
340 | zoom:;
341 |
342 | color:
343 | /* css functions */
344 | annotation()
345 | blur()
346 | attr()
347 | brightness()
348 | calc()
349 | character-variant()
350 | circle()
351 | contrast()
352 | cross-fade()
353 | cubic-bezier()
354 | drop-shadow()
355 | element()
356 | ellipse()
357 | fit-content()
358 | format()
359 | grayscale()
360 | hsl()
361 | hsla()
362 | hue-rotate()
363 | image()
364 | image-set()
365 | inset()
366 | invert()
367 | linear-gradient()
368 | local()
369 | matrix()
370 | matrix3d()
371 | minmax()
372 | opacity()
373 | ornaments()
374 | perspective()
375 | polygon()
376 | radial-gradient()
377 | rect()
378 | repeat()
379 | repeating-linear-gradient()
380 | repeating-radial-gradient()
381 | rgb()
382 | rgba()
383 | rotate()
384 | rotate3d()
385 | rotateX()
386 | rotateY()
387 | rotateZ()
388 | saturate()
389 | scale()
390 | scale3d()
391 | scaleX()
392 | scaleY()
393 | scaleZ()
394 | sepia()
395 | skew()
396 | skewX()
397 | skewY()
398 | steps()
399 | stylistic()
400 | styleset()
401 | swash()
402 | symbols()
403 | translate()
404 | translate3d()
405 | translateX()
406 | translateY()
407 | translateZ()
408 | url()
409 | var();
410 |
411 |
412 | @media print {
413 | body { font-size: 10pt }
414 | }
415 | @media screen {
416 | body { font-size: 13px }
417 | }
418 | @media screen, print {
419 | body { line-height: 1.2 }
420 | }
421 | @media only screen
422 | and ( device-aspect-ratio: 480px)
423 | and ( max-device-width: 480px)
424 | and ( max-device-width: 480px)
425 | and (-webkit-min-device-pixel-ratio: 2) {
426 | body { line-height: 1.4 }
427 | }
428 | @font-face {
429 | font-family: MyHelvetica;
430 | src: local("Helvetica Neue Bold"),
431 | local("HelveticaNeue-Bold"),
432 | url(MgOpenModernaBold.ttf);
433 | font-weight: bold;
434 | font-family: Goudy Bookletter 1911, sans-serif;
435 | font-family: Red/Black, sans-serif;
436 | font-family: "Lucida" Grande, sans-serif;
437 | font-family: Ahem!, sans-serif;
438 | font-family: test@foo, sans-serif;
439 | font-family: #POUND, sans-serif;
440 | font-family: Hawaii 5-0, sans-serif;
441 | }
442 | @font-feature-values Font Two {
443 | @swash {
444 | color: 4;
445 | }
446 | }
447 | @charset "UTF-8"; /* Set the encoding of the style sheet to Unicode UTF-8 */
448 | @charset 'iso-859-15'; /* Set the encoding of the style sheet to Latin-9 (Western European languages, with euro sign) */
449 | @charset "UTF-8"; /* Invalid, there is a character (a space) before the at-rule */
450 | @charset UTF-8; /* Invalid, without ' or ", the charset is not a CSS */
451 | @counter-style circled-alpha {
452 | system: fixed;
453 | symbols: Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ;
454 | suffix: " ";
455 | }
456 | @import url("fineprint.css") print;
457 | @import url("bluish.css") projection, tv;
458 | @import 'custom.css';
459 | @import url("chrome://communicator/skin/");
460 | @import "common.css" screen, projection;
461 | @import url('landscape.css') screen and (orientation:landscape);
462 |
463 | @keyframes important1 {
464 | from { margin-top: 50px; }
465 | 50% { margin-top: 150px !important; } /* ignored */
466 | to { margin-top: 100px; }
467 | }
468 |
469 | @keyframes important2 {
470 | from { margin-top: 50px;
471 | margin-bottom: 100px; }
472 | to { margin-top: 150px !important; /* ignored */
473 | margin-bottom: 50px; }
474 | }
475 | /* Default namespace */
476 | @namespace url(XML-namespace-URL);
477 | @namespace "XML-namespace-URL";
478 |
479 | /* Prefixed namespace */
480 | @namespace prefix url(XML-namespace-URL);
481 | @namespace prefix "XML-namespace-URL";
482 | @page { margin: 2cm } /* All margins set to 2cm */
483 |
484 | @page :first {
485 | margin-top: 10cm /* Top margin on first page 10cm */
486 | }
487 |
488 | @supports ( transform-style: preserve ) or ( -moz-transform-style: preserve ) or
489 | ( -o-transform-style: preserve ) or ( -webkit-transform-style: preserve ) {
490 | margin: 1px;
491 | }
492 | @viewport {
493 | min-width: 640px;
494 | max-width: 800px;
495 | }
496 | @viewport {
497 | zoom: 0.75;
498 | min-zoom: 0.5;
499 | max-zoom: 0.9;
500 | }
501 | @viewport {
502 | orientation: landscape;
503 | }
504 | `
505 |
--------------------------------------------------------------------------------
/spec/auto-indent-spec.coffee:
--------------------------------------------------------------------------------
1 | # Tests for Auto Indenting JSX
2 |
3 | {Range, Point} = require 'atom'
4 | fs = require 'fs-plus'
5 | path = require 'path'
6 | AutoIndent = require '../lib/auto-indent'
7 |
8 | describe 'auto-indent', ->
9 | [autoIndent, editor, notifications, sourceCode, sourceCodeRange, indentJSXRange] = []
10 |
11 | beforeEach ->
12 | waitsForPromise ->
13 | atom.packages.activatePackage('language-babel')
14 |
15 | beforeEach ->
16 | waitsForPromise ->
17 | atom.workspace.open('non-existent.js').then (o) -> editor = o
18 |
19 | runs ->
20 | autoIndent = new AutoIndent(editor)
21 | notifications = atom.notifications
22 |
23 |
24 | # :: constructor
25 | describe '::constructor', ->
26 | it ' should setup some valid indentation defaults', ->
27 | expectedResult =
28 | jsxIndent: [1,1]
29 | jsxIndentProps: [1,1]
30 | jsxClosingBracketLocation: [ 1, { selfClosing: 'tag-aligned', nonEmpty: 'tag-aligned'} ]
31 | expect(autoIndent.eslintIndentOptions).toEqual(expectedResult)
32 |
33 | # ::getEslintrcFilename
34 | describe '::getEslintrcFilename', ->
35 | it 'returns a correct project path for the source file', ->
36 | expect(path.dirname(autoIndent.getEslintrcFilename())).toEqual(path.dirname(editor.getPath()))
37 |
38 | it 'returns a .eslintrc file name', ->
39 | expect(path.basename(autoIndent.getEslintrcFilename())).toEqual('.eslintrc')
40 |
41 | # ::readEslintrcOptions
42 | describe '::readEslintrcOptions', ->
43 | it 'returns an empty object on a missing .eslintrc', ->
44 | expect(autoIndent.readEslintrcOptions('.missing')).toEqual({})
45 |
46 | it 'returns an empty Object and a notification message on bad eslint', ->
47 | spyOn(fs, 'isFileSync').andReturn(true)
48 | spyOn(fs, 'readFileSync').andReturn('{')
49 | spyOn(notifications, 'addError').andCallThrough()
50 | obj = autoIndent.readEslintrcOptions()
51 | expect(notifications.addError).toHaveBeenCalled()
52 | expect(obj).toEqual({})
53 |
54 | it 'returns an empty Object when attempting to read something other than a file', ->
55 | spyOn(fs, 'isFileSync').andReturn(false)
56 | spyOn(fs, 'readFileSync')
57 | spyOn(notifications, 'addError').andCallThrough()
58 | obj = autoIndent.readEslintrcOptions()
59 | expect(fs.readFileSync).not.toHaveBeenCalled()
60 | expect(notifications.addError).not.toHaveBeenCalled()
61 | expect(obj).toEqual({})
62 |
63 | it 'returns an empty Object when eslint with no rules is read', ->
64 | spyOn(fs, 'isFileSync').andReturn(true)
65 | spyOn(fs, 'readFileSync').andReturn('{}')
66 | spyOn(notifications, 'addError').andCallThrough()
67 | obj = autoIndent.readEslintrcOptions()
68 | expect(notifications.addError).not.toHaveBeenCalled()
69 | expect(obj).toEqual({})
70 |
71 | # ::translateIndentOptions
72 | describe '::translateIndentOptions', ->
73 | it 'should return expected defaults when no object is input', ->
74 | result = autoIndent.translateIndentOptions()
75 | expectedResult =
76 | jsxIndent: [1,1]
77 | jsxIndentProps: [1,1]
78 | jsxClosingBracketLocation: [ 1, { selfClosing: 'tag-aligned', nonEmpty: 'tag-aligned'} ]
79 | expect(result).toEqual(expectedResult)
80 |
81 | it 'should return expected defaults when no valid object is input', ->
82 | result = autoIndent.translateIndentOptions({})
83 | expectedResult =
84 | jsxIndent: [1,1]
85 | jsxIndentProps: [1,1]
86 | jsxClosingBracketLocation: [ 1, { selfClosing: 'tag-aligned', nonEmpty: 'tag-aligned'} ]
87 | expect(result).toEqual(expectedResult)
88 |
89 | it 'should return two tab markers for jsx and props when an indent of 4 spaces is found', ->
90 | rules =
91 | "indent": [1, 4]
92 | result = autoIndent.translateIndentOptions(rules)
93 | expectedResult =
94 | jsxIndent: [1,2]
95 | jsxIndentProps: [1,2]
96 | jsxClosingBracketLocation: [ 1, { selfClosing: 'tag-aligned', nonEmpty: 'tag-aligned'} ]
97 | expect(result).toEqual(expectedResult)
98 |
99 | it 'should return one tab markers for jsx and props when an indent "tab" is found', ->
100 | rules =
101 | "indent": [1, "tab"]
102 | result = autoIndent.translateIndentOptions(rules)
103 | expectedResult =
104 | jsxIndent: [1,1]
105 | jsxIndentProps: [1,1]
106 | jsxClosingBracketLocation: [ 1, { selfClosing: 'tag-aligned', nonEmpty: 'tag-aligned'} ]
107 | expect(result).toEqual(expectedResult)
108 |
109 | it 'should return jsxIndent of 2 tabs and jsxIndentProps of 3', ->
110 | rules =
111 | "indent": [1, 6]
112 | "react/jsx-indent": ["warn", 4]
113 | result = autoIndent.translateIndentOptions(rules)
114 | expectedResult =
115 | jsxIndent: ['warn', 2]
116 | jsxIndentProps: [1, 3]
117 | jsxClosingBracketLocation: [ 1, { selfClosing: 'tag-aligned', nonEmpty: 'tag-aligned'} ]
118 | expect(result).toEqual(expectedResult)
119 |
120 | it 'should return jsxIndent of 2 tabs and jsxIndentProps of 2', ->
121 | rules =
122 | "indent": [1, 6]
123 | "react/jsx-indent": ["warn", 4]
124 | "react/jsx-indent-props": [2, 4]
125 | result = autoIndent.translateIndentOptions(rules)
126 | expectedResult =
127 | jsxIndent: ['warn', 2]
128 | jsxIndentProps: [2, 2]
129 | jsxClosingBracketLocation: [ 1, { selfClosing: 'tag-aligned', nonEmpty: 'tag-aligned'} ]
130 | expect(result).toEqual(expectedResult)
131 |
132 | it 'should return jsxIndent of 2 tabs and jsxIndentProps of 2, line-aligned', ->
133 | rules =
134 | "indent": [1, 6]
135 | "react/jsx-indent": ["warn", 4]
136 | "react/jsx-indent-props": [2, 4]
137 | 'react/jsx-closing-bracket-location': [1, 'line-aligned']
138 | result = autoIndent.translateIndentOptions(rules)
139 | expectedResult =
140 | jsxIndent: ['warn', 2]
141 | jsxIndentProps: [2, 2]
142 | jsxClosingBracketLocation: [ 1, { selfClosing: 'line-aligned', nonEmpty: 'line-aligned'} ]
143 | expect(result).toEqual(expectedResult)
144 |
145 | it 'should return jsxIndent of 2 tabs and jsxIndentProps of 2, line-aligned and props-aligned', ->
146 | rules =
147 | "indent": [1, 6]
148 | "react/jsx-indent": ["warn", 4]
149 | "react/jsx-indent-props": [2, 4]
150 | "react/jsx-closing-bracket-location": [ 1,
151 | "nonEmpty": "props-aligned",
152 | "selfClosing": "line-aligned"
153 | ]
154 | result = autoIndent.translateIndentOptions(rules)
155 | expectedResult =
156 | jsxIndent: ['warn', 2]
157 | jsxIndentProps: [2, 2]
158 | jsxClosingBracketLocation: [ 1, { selfClosing: 'line-aligned', nonEmpty: 'props-aligned'} ]
159 | expect(result).toEqual(expectedResult)
160 |
161 | #: indentJSX
162 | describe '::indentJSX', ->
163 |
164 | beforeEach ->
165 | sourceCode = """
166 |
167 | {this._renderPlaceholder()}
168 |
173 |
179 | {this._renderPlaceholder()}
180 |
183 |
184 | { // tests inline JSX
185 | trainerProfile.backgroundImageLink
186 | ?
187 | :
188 | }
189 | {
190 | cond ?
191 |
:
192 |
193 | }
194 |
195 |
196 |
197 | """
198 | editor.insertText(sourceCode)
199 | sourceCodeRange = new Range(new Point(0,0), new Point(31,0))
200 | indentJSXRange = new Range(new Point(0,0), new Point(30,1))
201 |
202 | it 'should indent JSX according to eslint rules', ->
203 | indentedCode = """
204 |
205 | {this._renderPlaceholder()}
206 |
211 |
217 | {this._renderPlaceholder()}
218 |
221 |
222 | { // tests inline JSX
223 | trainerProfile.backgroundImageLink
224 | ?
225 | :
226 | }
227 | {
228 | cond ?
229 |
:
230 |
231 | }
232 |
233 |
234 |
235 | """
236 | # remember this is tabs based on atom default
237 | autoIndent.eslintIndentOptions =
238 | jsxIndent: [1, 1]
239 | jsxIndentProps: [1, 1]
240 | jsxClosingBracketLocation: [ 1,
241 | selfClosing: 'tag-aligned'
242 | nonEmpty: 'tag-aligned' ]
243 | autoIndent.autoJsx = true
244 | autoIndent.indentJSX(indentJSXRange)
245 | expect(editor.getTextInBufferRange(sourceCodeRange)).toEqual(indentedCode)
246 |
247 | it 'should indent JSX according to eslint rules and tag closing alignment', ->
248 | indentedCode = """
249 |
250 | {this._renderPlaceholder()}
251 |
256 |
262 | {this._renderPlaceholder()}
263 |
266 |
267 | { // tests inline JSX
268 | trainerProfile.backgroundImageLink
269 | ?
270 | :
271 | }
272 | {
273 | cond ?
274 |
:
275 |
276 | }
277 |
278 |
279 |
280 | """
281 | # remember this is tabs based on atom default
282 | autoIndent.eslintIndentOptions =
283 | jsxIndent: [1, 2]
284 | jsxIndentProps: [1, 2]
285 | jsxClosingBracketLocation: [ 1,
286 | selfClosing: 'props-aligned'
287 | nonEmpty: 'props-aligned' ]
288 | autoIndent.autoJsx = true
289 | autoIndent.indentJSX(indentJSXRange)
290 | expect(editor.getTextInBufferRange(sourceCodeRange)).toEqual(indentedCode)
291 |
292 | # test insert newline between opening closing JSX tags
293 | describe 'insert-nl-jsx', ->
294 |
295 | it 'should insert two new lines and position cursor between JSX tags', ->
296 | # remember this is tabs based on atom default
297 | autoIndent.eslintIndentOptions =
298 | jsxIndent: [1, 1]
299 | jsxIndentProps: [1, 1]
300 | jsxClosingBracketLocation: [ 1,
301 | selfClosing: 'tabs-aligned'
302 | nonEmpty: 'tabs-aligned' ]
303 | autoIndent.autoJsx = true
304 | editor.insertText('')
305 | editor.setCursorBufferPosition([0,5])
306 | editor.insertText('\n')
307 |
308 | expect(editor.getTextInBufferRange([[0,0],[0,5]])).toEqual("")
309 | expect(editor.getTextInBufferRange([[1,0],[1,2]])).toEqual(" ")
310 | expect(editor.getTextInBufferRange([[2,0],[2,6]])).toEqual("
")
311 | expect(editor.getCursorBufferPosition()).toEqual([1,2])
312 |
--------------------------------------------------------------------------------
/spec/fixtures/grammar/private-fields.js:
--------------------------------------------------------------------------------
1 | // SYNTAX TEST "source.js.jsx"
2 | class Point {
3 | // <- meta.class.js storage.type.class.js
4 | // <- meta.class.js storage.type.class.js
5 | //^^^ meta.class.js
6 | //^^^ storage.type.class.js
7 | // ^^^^^ entity.name.class.js
8 | // ^ punctuation.section.class.begin.js
9 | #x
10 | //^^ meta.class.body.js
11 | //^ keyword.operator.private.js
12 | // ^ variable.other.readwrite.js
13 | #y
14 | //^^ meta.class.body.js
15 | //^ keyword.operator.private.js
16 | // ^ variable.other.readwrite.js
17 | #x = 0,#y = 0
18 | //^^ ^ ^^^^ ^ ^ meta.class.body.js
19 | //^ ^ keyword.operator.private.js
20 | // ^ ^ variable.other.readwrite.js
21 | // ^ ^ keyword.operator.assignment.js
22 | // ^ ^ constant.numeric.js
23 | // ^ meta.delimiter.comma.js
24 | static x = 1, #y, [a]
25 | //^^^^^^ ^ ^ ^^ ^^^ ^^^ meta.class.body.js
26 | //^^^^^^ storage.modifier.js
27 | // ^ ^ ^ variable.other.readwrite.js
28 | // ^ keyword.operator.assignment.js
29 | // ^ constant.numeric.js
30 | // ^ ^ meta.delimiter.comma.js
31 | // ^ keyword.operator.private.js
32 | // ^ ^ meta.brace.square.js
33 | z, #w = 2, [b]
34 | //^^ ^^ ^ ^^ ^^^ meta.class.body.js
35 | //^ ^ ^ variable.other.readwrite.js
36 | // ^ ^ meta.delimiter.comma.js
37 | // ^ keyword.operator.private.js
38 | // ^ keyword.operator.assignment.js
39 | // ^ constant.numeric.js
40 | // ^ ^ meta.brace.square.js
41 | get #x() { return #xValue }
42 | //^^^ ^^^^ ^ ^^^^^^ ^^^^^^^ ^ meta.class.body.js
43 | //^^^ ^^^^ ^ ^^^^^^ ^^^^^^^ ^ meta.accessor.js
44 | //^^^ storage.type.accessor.js
45 | // ^ ^ keyword.operator.private.js
46 | // ^ entity.name.function.accessor.js
47 | // ^ punctuation.definition.parameters.begin.js
48 | // ^^ meta.brace.round.js
49 | // ^ punctuation.definition.parameters.end.js
50 | // ^ ^ meta.brace.curly.js
51 | // ^^^^^^ keyword.control.flow.js
52 | // ^^^^^^ variable.other.readwrite.js
53 | set #x(value) {
54 | //^^^ ^^^^^^^^^ ^ meta.class.body.js
55 | //^^^ ^^^^^^^^^ ^ meta.accessor.js
56 | //^^^ storage.type.accessor.js
57 | // ^ keyword.operator.private.js
58 | // ^ entity.name.function.accessor.js
59 | // ^ punctuation.definition.parameters.begin.js
60 | // ^ ^ meta.brace.round.js
61 | // ^^^^^ meta.function.parameters.js
62 | // ^^^^^ variable.other.readwrite.js
63 | // ^ punctuation.definition.parameters.end.js
64 | // ^ meta.brace.curly.js
65 | this.#xValue = value
66 | // ^^^^^^^^^^^^ ^ ^^^^^ meta.class.body.js
67 | // ^^^^^^^^^^^^ ^ ^^^^^ meta.accessor.js
68 | // ^^^^ variable.language.this.js
69 | // ^ keyword.operator.accessor.js
70 | // ^^^^^^^ meta.property.object.js
71 | // ^ keyword.operator.private.js
72 | // ^^^^^^ variable.other.property.js
73 | // ^ keyword.operator.assignment.js
74 | // ^^^^^ variable.other.readwrite.js
75 | window.requestAnimationFrame(this.#render.bind(this))
76 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.body.js
77 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.accessor.js
78 | // ^^^^^^ support.type.object.dom.js
79 | // ^ ^ ^ keyword.operator.accessor.js
80 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.method-call.with-arguments.js
81 | // ^^^^^^^^^^^^^^^^^^^^^ ^^^^ entity.name.function.js
82 | // ^ ^ ^^ meta.brace.round.js
83 | // ^^^^ ^^^^ variable.language.this.js
84 | // ^^^^^^^ meta.property.object.js
85 | // ^ keyword.operator.private.js
86 | // ^^^^^^ variable.other.property.js
87 | }
88 | //^ meta.class.body.js
89 | //^ meta.accessor.js
90 | //^ meta.brace.curly.js
91 | #clicked() {
92 | //^^^^^^^^^^ ^ meta.class.body.js
93 | //^^^^^^^^^^ ^ meta.function.method.js
94 | //^ keyword.operator.private.js
95 | // ^^^^^^^ entity.name.function.method.js
96 | // ^ punctuation.definition.parameters.begin.js
97 | // ^^ meta.brace.round.js
98 | // ^ punctuation.definition.parameters.end.js
99 | // ^ meta.brace.curly.js
100 | this.#x++
101 | // ^^^^^^^^^ meta.class.body.js
102 | // ^^^^^^^^^ meta.function.method.js
103 | // ^^^^ variable.language.this.js
104 | // ^ keyword.operator.accessor.js
105 | // ^^ meta.property.object.js
106 | // ^ keyword.operator.private.js
107 | // ^ variable.other.property.js
108 | // ^^ keyword.operator.arithmetic.js
109 | }
110 | //^ meta.class.body.js
111 | //^ meta.function.method.js
112 | //^ meta.brace.curly.js
113 | constructor() {
114 | //^^^^^^^^^^^^^ ^ meta.class.body.js
115 | //^^^^^^^^^^^^^ ^ meta.function.method.js
116 | //^^^^^^^^^^^ entity.name.function.method.js
117 | // ^ punctuation.definition.parameters.begin.js
118 | // ^^ meta.brace.round.js
119 | // ^ punctuation.definition.parameters.end.js
120 | // ^ meta.brace.curly.js
121 | super()
122 | // ^^^^^^^ meta.class.body.js
123 | // ^^^^^^^ meta.function.method.js
124 | // ^^^^^^^ meta.function-call.without-arguments.js
125 | // ^^^^^ entity.name.function.js
126 | // ^^ meta.brace.round.js
127 | this.onclick = this.#clicked.bind(this)
128 | // ^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^ meta.class.body.js
129 | // ^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.method.js
130 | // ^^^^ ^^^^ ^^^^ variable.language.this.js
131 | // ^ ^ ^ keyword.operator.accessor.js
132 | // ^^^^^^^ ^^^^^^^^ meta.property.object.js
133 | // ^^^^^^^ ^^^^^^^ variable.other.property.js
134 | // ^ keyword.operator.assignment.js
135 | // ^ keyword.operator.private.js
136 | // ^^^^^^^^^^ meta.method-call.with-arguments.js
137 | // ^^^^ entity.name.function.js
138 | // ^ ^ meta.brace.round.js
139 | #x = +x
140 | // ^^ ^ ^^ meta.class.body.js
141 | // ^^ ^ ^^ meta.function.method.js
142 | // ^ keyword.operator.private.js
143 | // ^ ^ variable.other.readwrite.js
144 | // ^ keyword.operator.assignment.js
145 | // ^ keyword.operator.arithmetic.js
146 | #y = +y
147 | // ^^ ^ ^^ meta.class.body.js
148 | // ^^ ^ ^^ meta.function.method.js
149 | // ^ keyword.operator.private.js
150 | // ^ ^ variable.other.readwrite.js
151 | // ^ keyword.operator.assignment.js
152 | // ^ keyword.operator.arithmetic.js
153 | }
154 | //^ meta.class.body.js
155 | //^ meta.function.method.js
156 | //^ meta.brace.curly.js
157 | connectedCallback() { this.#render() }
158 | //^^^^^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^ ^ meta.class.body.js
159 | //^^^^^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^ ^ meta.function.method.js
160 | //^^^^^^^^^^^^^^^^^ entity.name.function.method.js
161 | // ^ punctuation.definition.parameters.begin.js
162 | // ^^ ^^ meta.brace.round.js
163 | // ^ punctuation.definition.parameters.end.js
164 | // ^ ^ meta.brace.curly.js
165 | // ^^^^ variable.language.this.js
166 | // ^ keyword.operator.accessor.js
167 | // ^^^^^^^^^ meta.method-call.without-arguments.js
168 | // ^ keyword.operator.private.js
169 | // ^^^^^^ entity.name.function.js
170 | #render() {
171 | //^^^^^^^^^ ^ meta.class.body.js
172 | //^^^^^^^^^ ^ meta.function.method.js
173 | //^ keyword.operator.private.js
174 | // ^^^^^^ entity.name.function.method.js
175 | // ^ punctuation.definition.parameters.begin.js
176 | // ^^ meta.brace.round.js
177 | // ^ punctuation.definition.parameters.end.js
178 | // ^ meta.brace.curly.js
179 | this.textContent = this.#x.toString()
180 | // ^^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^ meta.class.body.js
181 | // ^^^^^^^^^^^^^^^^ ^ ^^^^^^^^^^^^^^^^^^ meta.function.method.js
182 | // ^^^^ ^^^^ variable.language.this.js
183 | // ^ ^ ^ keyword.operator.accessor.js
184 | // ^^^^^^^^^^^ ^^ meta.property.object.js
185 | // ^^^^^^^^^^^ ^ variable.other.property.js
186 | // ^ keyword.operator.assignment.js
187 | // ^ keyword.operator.private.js
188 | // ^^^^^^^^^^ meta.method-call.without-arguments.js
189 | // ^^^^^^^^ entity.name.function.js
190 | // ^^ meta.brace.round.js
191 | }
192 | //^ meta.class.body.js
193 | //^ meta.function.method.js
194 | //^ meta.brace.curly.js
195 | get x() { return #x }
196 | //^^^ ^^^ ^ ^^^^^^ ^^ ^ meta.class.body.js
197 | //^^^ ^^^ ^ ^^^^^^ ^^ ^ meta.accessor.js
198 | //^^^ storage.type.accessor.js
199 | // ^ entity.name.function.accessor.js
200 | // ^ punctuation.definition.parameters.begin.js
201 | // ^^ meta.brace.round.js
202 | // ^ punctuation.definition.parameters.end.js
203 | // ^ ^ meta.brace.curly.js
204 | // ^^^^^^ keyword.control.flow.js
205 | // ^ keyword.operator.private.js
206 | // ^ variable.other.readwrite.js
207 | set x(value) { #x = +value }
208 | //^^^ ^^^^^^^^ ^ ^^ ^ ^^^^^^ ^ meta.class.body.js
209 | //^^^ ^^^^^^^^ ^ ^^ ^ ^^^^^^ ^ meta.accessor.js
210 | //^^^ storage.type.accessor.js
211 | // ^ entity.name.function.accessor.js
212 | // ^ punctuation.definition.parameters.begin.js
213 | // ^ ^ meta.brace.round.js
214 | // ^^^^^ meta.function.parameters.js
215 | // ^^^^^ ^ ^^^^^ variable.other.readwrite.js
216 | // ^ punctuation.definition.parameters.end.js
217 | // ^ ^ meta.brace.curly.js
218 | // ^ keyword.operator.private.js
219 | // ^ keyword.operator.assignment.js
220 | // ^ keyword.operator.arithmetic.js
221 | get y() { return #y }
222 | //^^^ ^^^ ^ ^^^^^^ ^^ ^ meta.class.body.js
223 | //^^^ ^^^ ^ ^^^^^^ ^^ ^ meta.accessor.js
224 | //^^^ storage.type.accessor.js
225 | // ^ entity.name.function.accessor.js
226 | // ^ punctuation.definition.parameters.begin.js
227 | // ^^ meta.brace.round.js
228 | // ^ punctuation.definition.parameters.end.js
229 | // ^ ^ meta.brace.curly.js
230 | // ^^^^^^ keyword.control.flow.js
231 | // ^ keyword.operator.private.js
232 | // ^ variable.other.readwrite.js
233 | set y(value) { #y = +value }
234 | //^^^ ^^^^^^^^ ^ ^^ ^ ^^^^^^ ^ meta.class.body.js
235 | //^^^ ^^^^^^^^ ^ ^^ ^ ^^^^^^ ^ meta.accessor.js
236 | //^^^ storage.type.accessor.js
237 | // ^ entity.name.function.accessor.js
238 | // ^ punctuation.definition.parameters.begin.js
239 | // ^ ^ meta.brace.round.js
240 | // ^^^^^ meta.function.parameters.js
241 | // ^^^^^ ^ ^^^^^ variable.other.readwrite.js
242 | // ^ punctuation.definition.parameters.end.js
243 | // ^ ^ meta.brace.curly.js
244 | // ^ keyword.operator.private.js
245 | // ^ keyword.operator.assignment.js
246 | // ^ keyword.operator.arithmetic.js
247 | equals(p) { return #x === p.#x && #y === p.#y }
248 | //^^^^^^^^^ ^ ^^^^^^ ^^ ^^^ ^^^^ ^^ ^^ ^^^ ^^^^ ^ meta.class.body.js
249 | //^^^^^^^^^ ^ ^^^^^^ ^^ ^^^ ^^^^ ^^ ^^ ^^^ ^^^^ ^ meta.function.method.js
250 | //^^^^^^ entity.name.function.method.js
251 | // ^ punctuation.definition.parameters.begin.js
252 | // ^ ^ meta.brace.round.js
253 | // ^ meta.function.parameters.js
254 | // ^ ^ ^ variable.other.readwrite.js
255 | // ^ punctuation.definition.parameters.end.js
256 | // ^ ^ meta.brace.curly.js
257 | // ^^^^^^ keyword.control.flow.js
258 | // ^ ^ ^ ^ keyword.operator.private.js
259 | // ^^^ ^^^ keyword.operator.comparison.js
260 | // ^ ^ variable.other.object.js
261 | // ^ ^ keyword.operator.accessor.js
262 | // ^^ ^^ meta.property.object.js
263 | // ^ ^ variable.other.property.js
264 | // ^^ keyword.operator.logical.js
265 | toString() { return `Point<${ #x },${ #y }>` }
266 | //^^^^^^^^^^ ^ ^^^^^^ ^^^^^^^^^ ^^ ^^^^ ^^ ^^^ ^ meta.class.body.js
267 | //^^^^^^^^^^ ^ ^^^^^^ ^^^^^^^^^ ^^ ^^^^ ^^ ^^^ ^ meta.function.method.js
268 | //^^^^^^^^ entity.name.function.method.js
269 | // ^ punctuation.definition.parameters.begin.js
270 | // ^^ meta.brace.round.js
271 | // ^ punctuation.definition.parameters.end.js
272 | // ^ ^ meta.brace.curly.js
273 | // ^^^^^^ keyword.control.flow.js
274 | // ^^^^^^^^^ ^^ ^^^^ ^^ ^^^ string.quasi.js
275 | // ^^^^^^^^^ ^^ ^^^^ ^^ ^^^ string.quoted.template.js
276 | // ^ punctuation.definition.quasi.begin.js
277 | // ^^ ^^ ^ ^^ ^^ ^ entity.quasi.element.js
278 | // ^^ ^^ punctuation.quasi.element.begin.js
279 | // ^ ^ keyword.operator.private.js
280 | // ^ ^ variable.other.readwrite.js
281 | // ^ ^ punctuation.quasi.element.end.js
282 | // ^ punctuation.definition.quasi.end.js
283 | }
284 | // <- punctuation.section.class.end.js
285 |
286 | // >> only:(source.js.jsx)
287 |
--------------------------------------------------------------------------------
/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 | { name: 'style'}
80 | { name: 'accessKey'}
81 | { name: 'contentEditable'}
82 | { name: 'contextMenu'}
83 | { name: 'dir'}
84 | { name: 'draggable'}
85 | { name: 'hidden'}
86 | { name: 'lang'}
87 | { name: 'spellCheck'}
88 | { name: 'tabIndex'}
89 | { name: 'title'}
90 | ]
91 |
92 | htmlElements: [
93 | { name: 'a'
94 | attributes: [
95 | { name: 'href'}
96 | { name: 'target'}
97 | { name: 'download'}
98 | { name: 'rel'}
99 | { name: 'hrefLang'}
100 | { name: 'type'}
101 | ]}
102 | { name: 'abbr'
103 | attributes: []}
104 | { name: 'address'
105 | attributes: []}
106 | { name: 'area'
107 | attributes: [
108 | { name: 'alt'}
109 | { name: 'coords'}
110 | { name: 'href'}
111 | { name: 'hrefLang'}
112 | { name: 'media'}
113 | { name: 'rel'}
114 | { name: 'shape'}
115 | { name: 'target'}
116 | { name: 'type'}
117 | ]}
118 | { name: 'article'
119 | attributes: []}
120 | { name: 'aside'
121 | attributes: []}
122 | { name: 'audio'
123 | attributes: [
124 | { name: 'autoPlay'}
125 | { name: 'controls'}
126 | { name: 'crossOrigin'}
127 | { name: 'loop'}
128 | { name: 'mediaGroup'}
129 | { name: 'muted'}
130 | { name: 'preload'}
131 | { name: 'src'}
132 | ]}
133 | { name: 'b'
134 | attributes: []}
135 | { name: 'base'
136 | attributes: [
137 | { name: 'href'}
138 | { name: 'target'}
139 | ]}
140 | { name: 'bdi'
141 | attributes: []}
142 | { name: 'bdo'
143 | attributes: []}
144 | { name: 'big'
145 | attributes: []}
146 | { name: 'blockquote'
147 | attributes: []}
148 | { name: 'body'
149 | attributes: []}
150 | { name: 'br'
151 | attributes: []}
152 | { name: 'button'
153 | attributes: [
154 | { name: 'autoFocus'}
155 | { name: 'disabled'}
156 | { name: 'form'}
157 | { name: 'formAction'}
158 | { name: 'formEncType'}
159 | { name: 'formMethod'}
160 | { name: 'formNoValidate'}
161 | { name: 'formTarget'}
162 | { name: 'name'}
163 | { name: 'type'}
164 | { name: 'value'}
165 | ]}
166 | { name: 'canvas'
167 | attributes: [
168 | { name: 'height'}
169 | { name: 'width'}
170 | ]}
171 | { name: 'caption'
172 | attributes: []}
173 | { name: 'cite'
174 | attributes: []}
175 | { name: 'code'
176 | attributes: []}
177 | { name: 'col'
178 | attributes: [
179 | { name: 'span'}
180 | ]}
181 | { name: 'colgroup'
182 | attributes: [
183 | { name: 'span'}
184 | ]}
185 | { name: 'data'
186 | attributes: []}
187 | { name: 'datalist'
188 | attributes: []}
189 | { name: 'dd'
190 | attributes: []}
191 | { name: 'del'
192 | attributes: [
193 | { name: 'dateTime'}
194 | ]}
195 | { name: 'details'
196 | attributes: [
197 | { name: 'open'}
198 | ]}
199 | { name: 'dfn'
200 | attributes: [
201 | { name: 'open'}
202 | ]}
203 | { name: 'dialog'
204 | attributes: []}
205 | { name: 'div'
206 | attributes: []}
207 | { name: 'dl'
208 | attributes: []}
209 | { name: 'dt'
210 | attributes: []}
211 | { name: 'em'
212 | attributes: []}
213 | { name: 'embed'
214 | attributes: [
215 | { name: 'height'}
216 | { name: 'src'}
217 | { name: 'type'}
218 | { name: 'width'}
219 | ]}
220 | { name: 'fieldset'
221 | attributes: [
222 | { name: 'disabled'}
223 | { name: 'form'}
224 | { name: 'name'}
225 | ]}
226 | { name: 'figcaption'
227 | attributes: []}
228 | { name: 'figure'
229 | attributes: []}
230 | { name: 'footer'
231 | attributes: []}
232 | { name: 'form'
233 | attributes: [
234 | { name: 'acceptCharset'}
235 | { name: 'action'}
236 | { name: 'autoComplete'}
237 | { name: 'encType'}
238 | { name: 'method'}
239 | { name: 'name'}
240 | { name: 'noValidate'}
241 | { name: 'target'}
242 | ]}
243 | { name: 'h1'
244 | attributes: []}
245 | { name: 'h2'
246 | attributes: []}
247 | { name: 'h3'
248 | attributes: []}
249 | { name: 'h4'
250 | attributes: []}
251 | { name: 'h5'
252 | attributes: []}
253 | { name: 'h6'
254 | attributes: []}
255 | { name: 'head'
256 | attributes: []}
257 | { name: 'header'
258 | attributes: []}
259 | { name: 'hr'
260 | attributes: []}
261 | { name: 'html'
262 | attributes: [
263 | { name: 'manifest'}
264 | { name: 'lang'}
265 | ]}
266 | { name: 'i'
267 | attributes: []}
268 | { name: 'iframe'
269 | attributes: [
270 | { name: 'height'}
271 | { name: 'name'}
272 | { name: 'sandbox'}
273 | { name: 'seamless'}
274 | { name: 'src'}
275 | { name: 'srcDoc'}
276 | { name: 'width'}
277 | ]}
278 | { name: 'img'
279 | attributes: [
280 | { name: 'alt'}
281 | { name: 'height'}
282 | { name: 'src'}
283 | { name: 'usemap'}
284 | { name: 'width'}
285 | ]}
286 | { name: 'input'
287 | attributes: [
288 | { name: 'accept'}
289 | { name: 'alt'}
290 | { name: 'autoComplete'}
291 | { name: 'autoFocus'}
292 | { name: 'checked'}
293 | { name: 'disabled'}
294 | { name: 'form'}
295 | { name: 'formAction'}
296 | { name: 'formEncType'}
297 | { name: 'formMethod'}
298 | { name: 'formNoValidate'}
299 | { name: 'formTarget'}
300 | { name: 'height'}
301 | { name: 'list'}
302 | { name: 'max'}
303 | { name: 'maxLength'}
304 | { name: 'min'}
305 | { name: 'multiple'}
306 | { name: 'name'}
307 | { name: 'pattern'}
308 | { name: 'placeholder'}
309 | { name: 'readOnly'}
310 | { name: 'required'}
311 | { name: 'size'}
312 | { name: 'src'}
313 | { name: 'step'}
314 | { name: 'type'}
315 | { name: 'value'}
316 | { name: 'width'}
317 | ]}
318 | { name: 'ins'
319 | attributes: [
320 | { name: 'dateTime'}
321 | ]}
322 | { name: 'kbd'
323 | attributes: []}
324 | { name: 'keygen'
325 | attributes: [
326 | { name: 'autoFocus'}
327 | { name: 'challenge'}
328 | { name: 'disabled'}
329 | { name: 'form'}
330 | { name: 'keyType'}
331 | { name: 'name'}
332 | ]}
333 | { name: 'label'
334 | attributes: [
335 | { name: 'htmlFor'}
336 | { name: 'form'}
337 | ]}
338 | { name: 'legend'
339 | attributes: [
340 | { name: 'value'}
341 | ]}
342 | { name: 'li'
343 | attributes: []}
344 | { name: 'link'
345 | attributes: [
346 | { name: 'disabled'}
347 | { name: 'href'}
348 | { name: 'hrefLang'}
349 | { name: 'media'}
350 | { name: 'rel'}
351 | { name: 'sizes'}
352 | { name: 'type'}
353 | ]}
354 | { name: 'main'
355 | attributes: []}
356 | { name: 'map'
357 | attributes: [
358 | { name: 'name'}
359 | ]}
360 | { name: 'mark'
361 | attributes: []}
362 | { name: 'menu'
363 | attributes: [
364 | { name: 'label'}
365 | { name: 'type'}
366 | ]}
367 | { name: 'menuitem'
368 | attributes: []}
369 | { name: 'meta'
370 | attributes: [
371 | { name: 'charset'}
372 | { name: 'content'}
373 | { name: 'httpEquiv'}
374 | { name: 'name'}
375 | ]}
376 | { name: 'meter'
377 | attributes: []}
378 | { name: 'nav'
379 | attributes: []}
380 | { name: 'noscript'
381 | attributes: []}
382 | { name: 'object'
383 | attributes: [
384 | { name: 'data'}
385 | { name: 'form'}
386 | { name: 'height'}
387 | { name: 'name'}
388 | { name: 'type'}
389 | { name: 'usemap'}
390 | { name: 'width'}
391 | ]}
392 | { name: 'ol'
393 | attributes: [
394 | { name: 'start'}
395 | { name: 'type'}
396 | ]}
397 | { name: 'optgroup'
398 | attributes: [
399 | { name: 'disabled'}
400 | { name: 'label'}
401 | ]}
402 | { name: 'option'
403 | attributes: [
404 | { name: 'disabled'}
405 | { name: 'label'}
406 | { name: 'selected'}
407 | { name: 'value'}
408 | ]}
409 | { name: 'output'
410 | attributes: [
411 | { name: 'htmlFor'}
412 | { name: 'form'}
413 | { name: 'name'}
414 | ]}
415 | { name: 'p'
416 | attributes: []}
417 | { name: 'param'
418 | attributes: [
419 | { name: 'name'}
420 | { name: 'value'}
421 | ]}
422 | { name: 'picture'
423 | attributes: []}
424 | { name: 'pre'
425 | attributes: []}
426 | { name: 'progress'
427 | attributes: [
428 | { name: 'form'}
429 | { name: 'max'}
430 | { name: 'value'}
431 | ]}
432 | { name: 'q'
433 | attributes: []}
434 | { name: 'rp'
435 | attributes: []}
436 | { name: 'rt'
437 | attributes: []}
438 | { name: 'ruby'
439 | attributes: []}
440 | { name: 's'
441 | attributes: []}
442 | { name: 'samp'
443 | attributes: []}
444 | { name: 'script'
445 | attributes: [
446 | { name: 'async'}
447 | { name: 'charSet'}
448 | { name: 'defer'}
449 | { name: 'src'}
450 | { name: 'type'}
451 | ]}
452 | { name: 'section'
453 | attributes: []}
454 | { name: 'select'
455 | attributes: [
456 | { name: 'autoFocus'}
457 | { name: 'disabled'}
458 | { name: 'form'}
459 | { name: 'multiple'}
460 | { name: 'name'}
461 | { name: 'required'}
462 | { name: 'size'}
463 | ]}
464 | { name: 'small'
465 | attributes: []}
466 | { name: 'source'
467 | attributes: [
468 | { name: 'media'}
469 | { name: 'src'}
470 | { name: 'type'}
471 | ]}
472 | { name: 'span'
473 | attributes: []}
474 | { name: 'strong'
475 | attributes: []}
476 | { name: 'style'
477 | attributes: [
478 | { name: 'disabled'}
479 | { name: 'media'}
480 | { name: 'scoped'}
481 | { name: 'type'}
482 | ]}
483 | { name: 'sub'
484 | attributes: []}
485 | { name: 'summary'
486 | attributes: []}
487 | { name: 'sup'
488 | attributes: []}
489 | { name: 'table'
490 | attributes: []}
491 | { name: 'tbody'
492 | attributes: []}
493 | { name: 'td'
494 | attributes: [
495 | { name: 'colSpan'}
496 | { name: 'headers'}
497 | { name: 'rowSpan'}
498 | ]}
499 | { name: 'textarea'
500 | attributes: [
501 | { name: 'autoFocus'}
502 | { name: 'cols'}
503 | { name: 'disabled'}
504 | { name: 'form'}
505 | { name: 'label'}
506 | { name: 'maxLength'}
507 | { name: 'name'}
508 | { name: 'placeholder'}
509 | { name: 'readonly'}
510 | { name: 'required'}
511 | { name: 'rows'}
512 | { name: 'wrap'}
513 | ]}
514 | { name: 'tfoot'
515 | attributes: []}
516 | { name: 'th'
517 | attributes: [
518 | { name: 'colSpan'}
519 | { name: 'headers'}
520 | { name: 'rowSpan'}
521 | { name: 'scope'}
522 | ]}
523 | { name: 'thead'
524 | attributes: []}
525 | { name: 'time'
526 | attributes: [
527 | { name: 'dateTime'}
528 | ]}
529 | { name: 'title'
530 | attributes: []}
531 | { name: 'tr'
532 | attributes: []}
533 | { name: 'track'
534 | attributes: [
535 | { name: 'default'}
536 | { name: 'label'}
537 | { name: 'src'}
538 | ]}
539 | { name: 'u'
540 | attributes: []}
541 | { name: 'ul'
542 | attributes: []}
543 | { name: 'var'
544 | attributes: []}
545 | { name: 'video'
546 | attributes: [
547 | { name: 'autoPlay'}
548 | { name: 'controls'}
549 | { name: 'height'}
550 | { name: 'loop'}
551 | { name: 'mediaGroup'}
552 | { name: 'muted'}
553 | { name: 'poster'}
554 | { name: 'preload'}
555 | { name: 'src'}
556 | { name: 'width'}
557 | ]}
558 | { name: 'wbr'
559 | attributes: []}
560 | # svg elements
561 | { name: 'circle'
562 | attributes: [
563 | { name: 'cx'}
564 | { name: 'cy'}
565 | { name: 'r'}
566 | { name: 'stroke'}
567 | { name: 'strokeWidth'}
568 | { name: 'fill'}
569 | ]}
570 | { name: 'clipPath'
571 | attributes: [
572 | { name: 'clipPath'}
573 | ]}
574 | { name: 'defs'
575 | attributes: []}
576 | { name: 'ellipse'
577 | attributes: [
578 | { name: 'cx'}
579 | { name: 'cy'}
580 | { name: 'rx'}
581 | { name: 'ry'}
582 | ]}
583 | { name: 'g'
584 | attributes: [
585 | { name: 'fill'}
586 | { name: 'opacity'}
587 | ]}
588 | { name: 'line'
589 | attributes: [
590 | { name: 'x1'}
591 | { name: 'x2'}
592 | { name: 'y1'}
593 | { name: 'y2'}
594 | ]}
595 | { name: 'linearGradient'
596 | attributes: [
597 | { name: 'x1'}
598 | { name: 'x2'}
599 | { name: 'y1'}
600 | { name: 'y2'}
601 | { name: 'spreadMethod'}
602 | { name: 'xlinkHref'}
603 | ]}
604 | { name: 'mask'
605 | attributes: [
606 | { name: 'mashUnits'}
607 | { name: 'x'}
608 | { name: 'y'}
609 | { name: 'width'}
610 | { name: 'height'}
611 | ]}
612 | { name: 'path'
613 | attributes: [
614 | { name: 'd'}
615 | { name: 'transform'}
616 | ]}
617 | { name: 'pattern'
618 | attributes: [
619 | { name: 'patternContentUnits'}
620 | { name: 'x'}
621 | { name: 'y'}
622 | { name: 'width'}
623 | { name: 'height'}
624 | { name: 'viewBox'}
625 | { name: 'xlinkHref'}
626 | ]}
627 | { name: 'polygon'
628 | attributes: [
629 | { name: 'points'}
630 | ]}
631 | { name: 'polyline'
632 | attributes: [
633 | { name: 'points'}
634 | ]}
635 | { name: 'radialGradient'
636 | attributes: [
637 | { name: 'gradientUnits'}
638 | { name: 'gradientTransform'}
639 | { name: 'cx'}
640 | { name: 'cy'}
641 | { name: 'r'}
642 | { name: 'fx'}
643 | { name: 'fy'}
644 | { name: 'spreadMethod'}
645 | { name: 'xlinkHref'}
646 | ]}
647 | { name: 'rect'
648 | attributes: [
649 | { name: 'x'}
650 | { name: 'y'}
651 | { name: 'rx'}
652 | { name: 'ry'}
653 | { name: 'width'}
654 | { name: 'height'}
655 | ]}
656 | { name: 'stop'
657 | attributes: [
658 | { name: 'offset'}
659 | { name: 'stopColor'}
660 | { name: 'stopOpacity'}
661 | ]}
662 | { name: 'svg'
663 | attributes: [
664 | { name: 'x'}
665 | { name: 'y'}
666 | { name: 'width'}
667 | { name: 'height'}
668 | { name: 'viewBox'}
669 | { name: 'preserveAspectRatio'}
670 | { name: 'zoomAndPan'}
671 | ]}
672 | { name: 'text'
673 | attributes: [
674 | { name: 'x'}
675 | { name: 'y'}
676 | { name: 'dx'}
677 | { name: 'dy'}
678 | { name: 'rotate'}
679 | { name: 'textLength'}
680 | { name: 'lengthAdjust'}
681 | ]}
682 | { name: 'tspan'
683 | attributes: [
684 | { name: 'x'}
685 | { name: 'y'}
686 | { name: 'dx'}
687 | { name: 'dy'}
688 | { name: 'rotate'}
689 | { name: 'textLength'}
690 | { name: 'lengthAdjust'}
691 | { name: 'xlinkHref'}
692 | ]}
693 | ]
694 |
--------------------------------------------------------------------------------
/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 | // ^^ meta.brace.round.js
10 | // ^ punctuation.definition.parameters.end.js
11 | // ^^ meta.brace.curly.js
12 | B = function(z) {}
13 | // <- meta.function.js entity.name.function.js
14 | //^ ^^^^^^^^^^^ ^^ meta.function.js
15 | //^ keyword.operator.assignment.js
16 | // ^^^^^^^^ storage.type.function.js
17 | // ^ punctuation.definition.parameters.begin.js
18 | // ^ ^ meta.brace.round.js
19 | // ^ meta.function.parameters.js
20 | // ^ variable.other.readwrite.js
21 | // ^ punctuation.definition.parameters.end.js
22 | // ^^ meta.brace.curly.js
23 | C = function c() {}
24 | // <- meta.function.js entity.name.function.js
25 | //^ ^^^^^^^^ ^^^ ^^ meta.function.js
26 | // ^ entity.name.function.js
27 | //^ keyword.operator.assignment.js
28 | // ^^^^^^^^ storage.type.function.js
29 | // ^ punctuation.definition.parameters.begin.js
30 | // ^^ meta.brace.round.js
31 | // ^ punctuation.definition.parameters.end.js
32 | // ^^ meta.brace.curly.js
33 | D = function d(z) {}
34 | // <- meta.function.js entity.name.function.js
35 | //^ ^^^^^^^^ ^^^^ ^^ meta.function.js
36 | // ^ entity.name.function.js
37 | //^ keyword.operator.assignment.js
38 | // ^^^^^^^^ storage.type.function.js
39 | // ^ punctuation.definition.parameters.begin.js
40 | // ^ ^ meta.brace.round.js
41 | // ^ meta.function.parameters.js
42 | // ^ variable.other.readwrite.js
43 | // ^ punctuation.definition.parameters.end.js
44 | // ^^ meta.brace.curly.js
45 | E = () => {}
46 | // <- meta.function.arrow.js entity.name.function.js
47 | //^ ^^ ^^ ^^ meta.function.arrow.js
48 | //^ keyword.operator.assignment.js
49 | // ^ punctuation.definition.parameters.begin.js
50 | // ^^ meta.brace.round.js
51 | // ^ punctuation.definition.parameters.end.js
52 | // ^^ storage.type.function.arrow.js
53 | // ^^ meta.brace.curly.js
54 | F = (z) => {}
55 | // <- meta.function.arrow.js entity.name.function.js
56 | //^ ^^^ ^^ ^^ meta.function.arrow.js
57 | //^ keyword.operator.assignment.js
58 | // ^ punctuation.definition.parameters.begin.js
59 | // ^ ^ meta.brace.round.js
60 | // ^ meta.function.parameters.js
61 | // ^ variable.other.readwrite.js
62 | // ^ punctuation.definition.parameters.end.js
63 | // ^^ storage.type.function.arrow.js
64 | // ^^ meta.brace.curly.js
65 | G = z => {}
66 | // <- meta.function.arrow.js entity.name.function.js
67 | //^ ^ ^^ meta.function.arrow.js
68 | //^ keyword.operator.assignment.js
69 | // ^ variable.other.readwrite.js
70 | // ^^ storage.type.function.arrow.js
71 | // ^^ meta.brace.curly.js
72 | function() {}
73 | // <- meta.function.js storage.type.function.js
74 | // <- meta.function.js storage.type.function.js
75 | //^^^^^^^^ ^^ meta.function.js
76 | //^^^^^^ storage.type.function.js
77 | // ^ punctuation.definition.parameters.begin.js
78 | // ^^ meta.brace.round.js
79 | // ^ punctuation.definition.parameters.end.js
80 | // ^^ meta.brace.curly.js
81 | function(z) {}
82 | // <- meta.function.js storage.type.function.js
83 | // <- meta.function.js storage.type.function.js
84 | //^^^^^^^^^ ^^ meta.function.js
85 | //^^^^^^ storage.type.function.js
86 | // ^ punctuation.definition.parameters.begin.js
87 | // ^ ^ meta.brace.round.js
88 | // ^ meta.function.parameters.js
89 | // ^ variable.other.readwrite.js
90 | // ^ punctuation.definition.parameters.end.js
91 | // ^^ meta.brace.curly.js
92 | function H() {}
93 | // <- meta.function.js storage.type.function.js
94 | // <- meta.function.js storage.type.function.js
95 | //^^^^^^ ^^^ ^^ meta.function.js
96 | //^^^^^^ storage.type.function.js
97 | // ^ entity.name.function.js
98 | // ^ punctuation.definition.parameters.begin.js
99 | // ^^ meta.brace.round.js
100 | // ^ punctuation.definition.parameters.end.js
101 | // ^^ meta.brace.curly.js
102 | function I(z) {}
103 | // <- meta.function.js storage.type.function.js
104 | // <- meta.function.js storage.type.function.js
105 | //^^^^^^ ^^^^ ^^ meta.function.js
106 | //^^^^^^ storage.type.function.js
107 | // ^ entity.name.function.js
108 | // ^ punctuation.definition.parameters.begin.js
109 | // ^ ^ meta.brace.round.js
110 | // ^ meta.function.parameters.js
111 | // ^ variable.other.readwrite.js
112 | // ^ punctuation.definition.parameters.end.js
113 | // ^^ meta.brace.curly.js
114 | () => {}
115 | // <- meta.function.arrow.js punctuation.definition.parameters.begin.js meta.brace.round.js
116 | // <- meta.function.arrow.js meta.brace.round.js punctuation.definition.parameters.end.js
117 | // ^^ ^^ meta.function.arrow.js
118 | // ^^ storage.type.function.arrow.js
119 | // ^^ meta.brace.curly.js
120 | (z) => {}
121 | // <- meta.function.arrow.js punctuation.definition.parameters.begin.js meta.brace.round.js
122 | // <- meta.function.arrow.js meta.function.parameters.js variable.other.readwrite.js
123 | //^ ^^ ^^ meta.function.arrow.js
124 | //^ meta.brace.round.js
125 | //^ punctuation.definition.parameters.end.js
126 | // ^^ storage.type.function.arrow.js
127 | // ^^ meta.brace.curly.js
128 | J.prototype.j = () => {}
129 | // <- meta.prototype.function.arrow.js entity.name.class.js
130 | // <- meta.prototype.function.arrow.js keyword.operator.accessor.js
131 | //^^^^^^^^^^^ ^ ^^ ^^ ^^ meta.prototype.function.arrow.js
132 | // ^ keyword.operator.accessor.js
133 | //^^^^^^^^^ variable.language.prototype.js
134 | // ^ entity.name.function.js
135 | // ^ keyword.operator.assignment.js
136 | // ^ punctuation.definition.parameters.begin.js
137 | // ^^ meta.brace.round.js
138 | // ^ punctuation.definition.parameters.end.js
139 | // ^^ storage.type.function.arrow.js
140 | // ^^ meta.brace.curly.js
141 | K.prototype.k = (z) => {}
142 | // <- meta.prototype.function.arrow.js entity.name.class.js
143 | // <- meta.prototype.function.arrow.js keyword.operator.accessor.js
144 | //^^^^^^^^^^^ ^ ^^^ ^^ ^^ meta.prototype.function.arrow.js
145 | // ^ keyword.operator.accessor.js
146 | //^^^^^^^^^ variable.language.prototype.js
147 | // ^ entity.name.function.js
148 | // ^ keyword.operator.assignment.js
149 | // ^ punctuation.definition.parameters.begin.js
150 | // ^ ^ meta.brace.round.js
151 | // ^ meta.function.parameters.js
152 | // ^ variable.other.readwrite.js
153 | // ^ punctuation.definition.parameters.end.js
154 | // ^^ storage.type.function.arrow.js
155 | // ^^ meta.brace.curly.js
156 | L.prototype.l = z => {}
157 | // <- meta.prototype.function.arrow.js entity.name.class.js
158 | // <- meta.prototype.function.arrow.js keyword.operator.accessor.js
159 | //^^^^^^^^^^^ ^ ^ ^^ meta.prototype.function.arrow.js
160 | // ^ keyword.operator.accessor.js
161 | //^^^^^^^^^ variable.language.prototype.js
162 | // ^ entity.name.function.js
163 | // ^ keyword.operator.assignment.js
164 | // ^ variable.other.readwrite.js
165 | // ^^ storage.type.function.arrow.js
166 | // ^^ meta.brace.curly.js
167 | M.prototype.m = function() {}
168 | // <- meta.prototype.function.js entity.name.class.js
169 | // <- meta.prototype.function.js keyword.operator.accessor.js
170 | //^^^^^^^^^^^ ^ ^^^^^^^^^^ ^^ meta.prototype.function.js
171 | // ^ keyword.operator.accessor.js
172 | //^^^^^^^^^ variable.language.prototype.js
173 | // ^ entity.name.function.js
174 | // ^ keyword.operator.assignment.js
175 | // ^^^^^^^^ storage.type.function.js
176 | // ^ punctuation.definition.parameters.begin.js
177 | // ^^ meta.brace.round.js
178 | // ^ punctuation.definition.parameters.end.js
179 | // ^^ meta.brace.curly.js
180 | N.prototype.n = function(z) {}
181 | // <- meta.prototype.function.js entity.name.class.js
182 | // <- meta.prototype.function.js keyword.operator.accessor.js
183 | //^^^^^^^^^^^ ^ ^^^^^^^^^^^ ^^ meta.prototype.function.js
184 | // ^ keyword.operator.accessor.js
185 | //^^^^^^^^^ variable.language.prototype.js
186 | // ^ entity.name.function.js
187 | // ^ keyword.operator.assignment.js
188 | // ^^^^^^^^ storage.type.function.js
189 | // ^ punctuation.definition.parameters.begin.js
190 | // ^ ^ meta.brace.round.js
191 | // ^ meta.function.parameters.js
192 | // ^ variable.other.readwrite.js
193 | // ^ punctuation.definition.parameters.end.js
194 | // ^^ meta.brace.curly.js
195 | O.prototype.o = function oo() {}
196 | // <- meta.prototype.function.js entity.name.class.js
197 | // <- meta.prototype.function.js keyword.operator.accessor.js
198 | //^^^^^^^^^^^ ^ ^^^^^^^^ ^^^^ ^^ meta.prototype.function.js
199 | // ^ keyword.operator.accessor.js
200 | //^^^^^^^^^ variable.language.prototype.js
201 | // ^ ^^ entity.name.function.js
202 | // ^ keyword.operator.assignment.js
203 | // ^^^^^^^^ storage.type.function.js
204 | // ^ punctuation.definition.parameters.begin.js
205 | // ^^ meta.brace.round.js
206 | // ^ punctuation.definition.parameters.end.js
207 | // ^^ meta.brace.curly.js
208 | P.prototype.p = function pp(z) {}
209 | // <- meta.prototype.function.js entity.name.class.js
210 | // <- meta.prototype.function.js keyword.operator.accessor.js
211 | //^^^^^^^^^^^ ^ ^^^^^^^^ ^^^^^ ^^ meta.prototype.function.js
212 | // ^ keyword.operator.accessor.js
213 | //^^^^^^^^^ variable.language.prototype.js
214 | // ^ ^^ entity.name.function.js
215 | // ^ keyword.operator.assignment.js
216 | // ^^^^^^^^ storage.type.function.js
217 | // ^ punctuation.definition.parameters.begin.js
218 | // ^ ^ meta.brace.round.js
219 | // ^ meta.function.parameters.js
220 | // ^ variable.other.readwrite.js
221 | // ^ punctuation.definition.parameters.end.js
222 | // ^^ meta.brace.curly.js
223 | Q.q = () => {}
224 | // <- meta.function.static.arrow.js entity.name.class.js
225 | // <- meta.function.static.arrow.js keyword.operator.accessor.js
226 | //^ ^ ^^ ^^ ^^ meta.function.static.arrow.js
227 | //^ entity.name.function.js
228 | // ^ keyword.operator.assignment.js
229 | // ^ punctuation.definition.parameters.begin.js
230 | // ^^ meta.brace.round.js
231 | // ^ punctuation.definition.parameters.end.js
232 | // ^^ storage.type.function.arrow.js
233 | // ^^ meta.brace.curly.js
234 | R.r = (z) => {}
235 | // <- meta.function.static.arrow.js entity.name.class.js
236 | // <- meta.function.static.arrow.js keyword.operator.accessor.js
237 | //^ ^ ^^^ ^^ ^^ meta.function.static.arrow.js
238 | //^ entity.name.function.js
239 | // ^ keyword.operator.assignment.js
240 | // ^ punctuation.definition.parameters.begin.js
241 | // ^ ^ meta.brace.round.js
242 | // ^ meta.function.parameters.js
243 | // ^ variable.other.readwrite.js
244 | // ^ punctuation.definition.parameters.end.js
245 | // ^^ storage.type.function.arrow.js
246 | // ^^ meta.brace.curly.js
247 | S.s = z => {}
248 | // <- meta.function.static.arrow.js entity.name.class.js
249 | // <- meta.function.static.arrow.js keyword.operator.accessor.js
250 | //^ ^ ^ ^^ meta.function.static.arrow.js
251 | //^ entity.name.function.js
252 | // ^ keyword.operator.assignment.js
253 | // ^ variable.other.readwrite.js
254 | // ^^ storage.type.function.arrow.js
255 | // ^^ meta.brace.curly.js
256 | T.t = function() {}
257 | // <- meta.function.static.js entity.name.class.js
258 | // <- meta.function.static.js keyword.operator.accessor.js
259 | //^ ^ ^^^^^^^^^^ ^^ meta.function.static.js
260 | //^ entity.name.function.js
261 | // ^ keyword.operator.assignment.js
262 | // ^^^^^^^^ storage.type.function.js
263 | // ^ punctuation.definition.parameters.begin.js
264 | // ^^ meta.brace.round.js
265 | // ^ punctuation.definition.parameters.end.js
266 | // ^^ meta.brace.curly.js
267 | U.u = function(z) {}
268 | // <- meta.function.static.js entity.name.class.js
269 | // <- meta.function.static.js keyword.operator.accessor.js
270 | //^ ^ ^^^^^^^^^^^ ^^ meta.function.static.js
271 | //^ entity.name.function.js
272 | // ^ keyword.operator.assignment.js
273 | // ^^^^^^^^ storage.type.function.js
274 | // ^ punctuation.definition.parameters.begin.js
275 | // ^ ^ meta.brace.round.js
276 | // ^ meta.function.parameters.js
277 | // ^ variable.other.readwrite.js
278 | // ^ punctuation.definition.parameters.end.js
279 | // ^^ meta.brace.curly.js
280 | V.v = function vv() {}
281 | // <- meta.function.static.js entity.name.class.js
282 | // <- meta.function.static.js keyword.operator.accessor.js
283 | //^ ^ ^^^^^^^^ ^^^^ ^^ meta.function.static.js
284 | //^ ^^ entity.name.function.js
285 | // ^ keyword.operator.assignment.js
286 | // ^^^^^^^^ storage.type.function.js
287 | // ^ punctuation.definition.parameters.begin.js
288 | // ^^ meta.brace.round.js
289 | // ^ punctuation.definition.parameters.end.js
290 | // ^^ meta.brace.curly.js
291 | W.w = function ww(z) {}
292 | // <- meta.function.static.js entity.name.class.js
293 | // <- meta.function.static.js keyword.operator.accessor.js
294 | //^ ^ ^^^^^^^^ ^^^^^ ^^ meta.function.static.js
295 | //^ ^^ entity.name.function.js
296 | // ^ keyword.operator.assignment.js
297 | // ^^^^^^^^ storage.type.function.js
298 | // ^ punctuation.definition.parameters.begin.js
299 | // ^ ^ meta.brace.round.js
300 | // ^ meta.function.parameters.js
301 | // ^ variable.other.readwrite.js
302 | // ^ punctuation.definition.parameters.end.js
303 | // ^^ meta.brace.curly.js
304 |
305 | class X extends XX {}
306 | // <- meta.class.js storage.type.class.js
307 | // <- meta.class.js storage.type.class.js
308 | //^^^ meta.class.js
309 | //^^^ storage.type.class.js
310 | // ^ ^^ entity.name.class.js
311 | // ^^^^^^^ meta.class.extends.js
312 | // ^^^^^^^ storage.type.extends.js
313 | // ^ punctuation.section.class.begin.js
314 | // ^ punctuation.section.class.end.js
315 | class Y {}
316 | // <- meta.class.js storage.type.class.js
317 | // <- meta.class.js storage.type.class.js
318 | //^^^ meta.class.js
319 | //^^^ storage.type.class.js
320 | // ^ entity.name.class.js
321 | // ^ punctuation.section.class.begin.js
322 | // ^ punctuation.section.class.end.js
323 |
324 |
325 | // >> only:(source.js.jsx)
326 |
--------------------------------------------------------------------------------
/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 | // ^ JSXAttrs
9 | // ^ JSXStartTagEnd
10 | {'it\'s with text inside'}
11 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx
12 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
13 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXNested
14 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js
15 | //^ punctuation.section.embedded.begin.jsx
16 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js
17 | // ^ punctuation.definition.string.begin.jsx
18 | // ^ punctuation.definition.string.end.jsx
19 | // ^ punctuation.section.embedded.end.jsx
20 |
21 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
22 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
23 | //^^^^ meta.tag.jsx
24 | // ^ punctuation.definition.tag.jsx
25 | //^^^ entity.name.tag.close.jsx
26 |
27 | {'it\'s with text inside'}
28 | // <- meta.tag.jsx punctuation.definition.tag.jsx
29 | // <- meta.tag.jsx entity.name.tag.open.jsx
30 | //^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^^^ meta.tag.jsx
31 | // ^ ^^ ^ punctuation.definition.tag.jsx
32 | //^^ entity.name.tag.open.jsx
33 | // ^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^ JSXAttrs
34 | // ^ JSXStartTagEnd
35 | // ^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXNested
36 | // ^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js
37 | // ^ punctuation.section.embedded.begin.jsx
38 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js
39 | // ^ punctuation.definition.string.begin.jsx
40 | // ^ punctuation.definition.string.end.jsx
41 | // ^ punctuation.section.embedded.end.jsx
42 | // ^^ JSXEndTagStart
43 | // ^^^ entity.name.tag.close.jsx
44 |
45 |
51 | //^^^^^^^^ meta.tag.jsx
52 | //^^^^^^^^ JSXAttrs
53 | //^^^^ entity.other.attribute-name.jsx
54 | // ^ keyword.operator.assignment.jsx
55 | // ^^ string.quoted.single.js
56 | // ^ punctuation.definition.string.begin.jsx
57 | // ^ punctuation.definition.string.end.jsx
58 | // ^ punctuation.definition.tag.jsx
59 | // ^ JSXStartTagEnd
60 | {'it\'s with text inside'}
61 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx
62 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
63 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXNested
64 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js
65 | //^ punctuation.section.embedded.begin.jsx
66 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js
67 | // ^ punctuation.definition.string.begin.jsx
68 | // ^ punctuation.definition.string.end.jsx
69 | // ^ punctuation.section.embedded.end.jsx
70 |
71 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
72 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
73 | //^^^^ meta.tag.jsx
74 | // ^ punctuation.definition.tag.jsx
75 | //^^^ entity.name.tag.close.jsx
76 |
77 | {'it\'s with text inside'}
78 | // <- meta.tag.jsx punctuation.definition.tag.jsx
79 | // <- meta.tag.jsx entity.name.tag.open.jsx
80 | //^^ ^^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^^^ meta.tag.jsx
81 | // ^ ^^ ^ punctuation.definition.tag.jsx
82 | //^^ entity.name.tag.open.jsx
83 | // ^^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^ JSXAttrs
84 | // ^^^^ entity.other.attribute-name.jsx
85 | // ^ keyword.operator.assignment.jsx
86 | // ^^ string.quoted.double.js
87 | // ^ ^ punctuation.definition.string.begin.jsx
88 | // ^ ^ punctuation.definition.string.end.jsx
89 | // ^ JSXStartTagEnd
90 | // ^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXNested
91 | // ^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js
92 | // ^ punctuation.section.embedded.begin.jsx
93 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.single.js
94 | // ^ punctuation.section.embedded.end.jsx
95 | // ^^ JSXEndTagStart
96 | // ^^^ entity.name.tag.close.jsx
97 |
103 | //^^^^^^^^ meta.tag.jsx
104 | //^^^^^^^^ JSXAttrs
105 | //^^^^ entity.other.attribute-name.jsx
106 | // ^ keyword.operator.assignment.jsx
107 | // ^^ string.quoted.double.js
108 | // ^ punctuation.definition.string.begin.jsx
109 | // ^ punctuation.definition.string.end.jsx
110 | // ^ punctuation.definition.tag.jsx
111 | // ^ JSXStartTagEnd
112 | {"it's with text inside"}
113 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx
114 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
115 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXNested
116 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js
117 | //^ punctuation.section.embedded.begin.jsx
118 | // ^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.double.js
119 | // ^ punctuation.definition.string.begin.jsx
120 | // ^ punctuation.definition.string.end.jsx
121 | // ^ punctuation.section.embedded.end.jsx
122 |
123 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
124 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
125 | //^^^^ meta.tag.jsx
126 | // ^ punctuation.definition.tag.jsx
127 | //^^^ entity.name.tag.close.jsx
128 |
129 | {"it's with text inside"}
130 | // <- meta.tag.jsx punctuation.definition.tag.jsx
131 | // <- meta.tag.jsx entity.name.tag.open.jsx
132 | //^^ ^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^^^ meta.tag.jsx
133 | // ^ ^^ ^ punctuation.definition.tag.jsx
134 | //^^ entity.name.tag.open.jsx
135 | // ^^^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^ JSXAttrs
136 | // ^^^^ entity.other.attribute-name.jsx
137 | // ^ keyword.operator.assignment.jsx
138 | // ^^ ^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js
139 | // ^ ^ punctuation.section.embedded.begin.jsx
140 | // ^ ^ punctuation.section.embedded.end.jsx
141 | // ^ JSXStartTagEnd
142 | // ^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXNested
143 | // ^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.double.js
144 | // ^ punctuation.definition.string.begin.jsx
145 | // ^ punctuation.definition.string.end.jsx
146 | // ^^ JSXEndTagStart
147 | // ^^^ entity.name.tag.close.jsx
148 |
154 | //^^^^^^^^ meta.tag.jsx
155 | //^^^^^^^^ JSXAttrs
156 | //^^^^ entity.other.attribute-name.jsx
157 | // ^ keyword.operator.assignment.jsx
158 | // ^^ meta.embedded.expression.js
159 | // ^ punctuation.section.embedded.begin.jsx
160 | // ^ punctuation.section.embedded.end.jsx
161 | // ^ punctuation.definition.tag.jsx
162 | // ^ JSXStartTagEnd
163 | {"it's with text inside"}
164 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.tag.jsx
165 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
166 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXNested
167 | //^^^^^^ ^^^^ ^^^^ ^^^^^^^^ meta.embedded.expression.js
168 | //^ punctuation.section.embedded.begin.jsx
169 | // ^^^^^ ^^^^ ^^^^ ^^^^^^^ string.quoted.double.js
170 | // ^ punctuation.definition.string.begin.jsx
171 | // ^ punctuation.definition.string.end.jsx
172 | // ^ punctuation.section.embedded.end.jsx
173 |
174 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
175 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
176 | //^^^^ meta.tag.jsx
177 | // ^ punctuation.definition.tag.jsx
178 | //^^^ entity.name.tag.close.jsx
179 |
180 |
181 | // <- meta.tag.jsx punctuation.definition.tag.jsx
182 | // <- meta.tag.jsx entity.name.tag.open.jsx
183 | //^^^ meta.tag.jsx
184 | // ^ punctuation.definition.tag.jsx
185 | //^^ entity.name.tag.open.jsx
186 | // ^ JSXAttrs
187 | // ^ JSXStartTagEnd
188 | it's with text inside
189 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx
190 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXAttrs
191 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
192 |
193 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
194 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
195 | //^^^^ meta.tag.jsx
196 | // ^ punctuation.definition.tag.jsx
197 | //^^^ entity.name.tag.close.jsx
198 |
199 | it's with text inside
200 | // <- meta.tag.jsx punctuation.definition.tag.jsx
201 | // <- meta.tag.jsx entity.name.tag.open.jsx
202 | //^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx
203 | // ^ ^^ ^ punctuation.definition.tag.jsx
204 | //^^ entity.name.tag.open.jsx
205 | // ^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
206 | // ^ JSXStartTagEnd
207 | // ^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
208 | // ^^ JSXEndTagStart
209 | // ^^^ entity.name.tag.close.jsx
210 |
211 |
217 | //^^^^^^^^ meta.tag.jsx
218 | //^^^^^^^^ JSXAttrs
219 | //^^^^ entity.other.attribute-name.jsx
220 | // ^ keyword.operator.assignment.jsx
221 | // ^^ string.quoted.single.js
222 | // ^ punctuation.definition.string.begin.jsx
223 | // ^ punctuation.definition.string.end.jsx
224 | // ^ punctuation.definition.tag.jsx
225 | // ^ JSXStartTagEnd
226 | it's with text inside
227 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx
228 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXAttrs
229 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
230 |
231 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
232 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
233 | //^^^^ meta.tag.jsx
234 | // ^ punctuation.definition.tag.jsx
235 | //^^^ entity.name.tag.close.jsx
236 |
237 | it's with text inside
238 | // <- meta.tag.jsx punctuation.definition.tag.jsx
239 | // <- meta.tag.jsx entity.name.tag.open.jsx
240 | //^^ ^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx
241 | // ^ ^^ ^ punctuation.definition.tag.jsx
242 | //^^ entity.name.tag.open.jsx
243 | // ^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
244 | // ^^^^ entity.other.attribute-name.jsx
245 | // ^ keyword.operator.assignment.jsx
246 | // ^^ string.quoted.double.js
247 | // ^ punctuation.definition.string.begin.jsx
248 | // ^ punctuation.definition.string.end.jsx
249 | // ^ JSXStartTagEnd
250 | // ^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
251 | // ^^ JSXEndTagStart
252 | // ^^^ entity.name.tag.close.jsx
253 |
259 | //^^^^^^^^ meta.tag.jsx
260 | //^^^^^^^^ JSXAttrs
261 | //^^^^ entity.other.attribute-name.jsx
262 | // ^ keyword.operator.assignment.jsx
263 | // ^^ string.quoted.double.js
264 | // ^ punctuation.definition.string.begin.jsx
265 | // ^ punctuation.definition.string.end.jsx
266 | // ^ punctuation.definition.tag.jsx
267 | // ^ JSXStartTagEnd
268 | it's with text inside
269 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx
270 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXAttrs
271 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
272 |
273 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
274 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
275 | //^^^^ meta.tag.jsx
276 | // ^ punctuation.definition.tag.jsx
277 | //^^^ entity.name.tag.close.jsx
278 |
279 | it's with text inside
280 | // <- meta.tag.jsx punctuation.definition.tag.jsx
281 | // <- meta.tag.jsx entity.name.tag.open.jsx
282 | //^^ ^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx
283 | // ^ ^^ ^ punctuation.definition.tag.jsx
284 | //^^ entity.name.tag.open.jsx
285 | // ^^^^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
286 | // ^^^^ entity.other.attribute-name.jsx
287 | // ^ keyword.operator.assignment.jsx
288 | // ^^ meta.embedded.expression.js
289 | // ^ punctuation.section.embedded.begin.jsx
290 | // ^ punctuation.section.embedded.end.jsx
291 | // ^ JSXStartTagEnd
292 | // ^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
293 | // ^^ JSXEndTagStart
294 | // ^^^ entity.name.tag.close.jsx
295 |
301 | //^^^^^^^^ meta.tag.jsx
302 | //^^^^^^^^ JSXAttrs
303 | //^^^^ entity.other.attribute-name.jsx
304 | // ^ keyword.operator.assignment.jsx
305 | // ^^ meta.embedded.expression.js
306 | // ^ punctuation.section.embedded.begin.jsx
307 | // ^ punctuation.section.embedded.end.jsx
308 | // ^ punctuation.definition.tag.jsx
309 | // ^ JSXStartTagEnd
310 | it's with text inside
311 | //^^^^ ^^^^ ^^^^ ^^^^^^ meta.tag.jsx
312 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXAttrs
313 | //^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
314 |
315 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
316 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXEndTagStart
317 | //^^^^ meta.tag.jsx
318 | // ^ punctuation.definition.tag.jsx
319 | //^^^ entity.name.tag.close.jsx
320 |
321 | it's with text inside
322 | // <- meta.tag.jsx punctuation.definition.tag.jsx
323 | // <- meta.tag.jsx entity.name.tag.open.jsx
324 | //^^ ^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx
325 | // ^ ^^ ^ punctuation.definition.tag.jsx
326 | //^^ entity.name.tag.open.jsx
327 | // ^^^^^^^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
328 | // ^^^^ entity.other.attribute-name.jsx
329 | // ^ JSXStartTagEnd
330 | // ^^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
331 | // ^^ JSXEndTagStart
332 | // ^^^ entity.name.tag.close.jsx
333 |
334 | it's with text inside
340 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXStartTagEnd
341 | // <- meta.tag.jsx JSXAttrs JSXNested
342 | //^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx
343 | //^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
344 | // ^^ ^ punctuation.definition.tag.jsx
345 | //^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
346 | // ^^ JSXEndTagStart
347 | // ^^^ entity.name.tag.close.jsx
348 |
349 | it's with text inside
363 | // <- meta.tag.jsx JSXAttrs punctuation.definition.tag.jsx JSXStartTagEnd
364 | // <- meta.tag.jsx JSXAttrs JSXNested
365 | //^^^ ^^^^ ^^^^ ^^^^^^^^^^^^ meta.tag.jsx
366 | //^^^ ^^^^ ^^^^ ^^^^^^^^ JSXAttrs
367 | // ^^ ^ punctuation.definition.tag.jsx
368 | //^^^ ^^^^ ^^^^ ^^^^^^ JSXNested
369 | // ^^ JSXEndTagStart
370 | // ^^^ entity.name.tag.close.jsx
371 |
--------------------------------------------------------------------------------
/spec/fixtures/grammar/declare.js:
--------------------------------------------------------------------------------
1 | // SYNTAX TEST "source.js.jsx"
2 |
3 | declare module 'a-unique-module-name' {
4 | // <- keyword.other.declare.flowtype
5 | // <- keyword.other.declare.flowtype
6 | //^^^^^ keyword.other.declare.flowtype
7 | // ^^^^^^ storage.type.module.flowtype
8 | // ^^^^^^^^^^^^^^^^^^^^^^ string.quoted.single.js
9 | // ^ punctuation.definition.string.begin.js
10 | // ^ punctuation.definition.string.end.js
11 | // ^ punctuation.section.class.begin.js
12 | declare interface Stack {}
13 | //^^^^^^^ ^^^^^^^^^ ^^^^^^^^ ^^ meta.class.body.js
14 | //^^^^^^^ keyword.other.declare.flowtype
15 | // ^^^^^^^^^ keyword.other.interface.flowtype
16 | // ^^^^^ support.type.class.interface.js
17 | // ^ ^ punctuation.flowtype
18 | // ^ support.type.class.flowtype
19 | // ^ punctuation.section.class.begin.js
20 | // ^ punctuation.section.class.end.js
21 | declare class Response extends A mixins A,B {}
22 | //^^^^^^^ ^^^^^ ^^^^^^^^ ^^^^^^^ ^ ^^^^^^ ^^^ ^^ meta.class.body.js
23 | //^^^^^^^ keyword.other.declare.flowtype
24 | // ^^^^^ storage.type.class.flowtype
25 | // ^^^^^^^^ ^ ^ ^ entity.name.class.js
26 | // ^^^^^^^ ^^^^^^ meta.class.extends.js
27 | // ^^^^^^^ ^^^^^^ storage.type.extends.js
28 | // ^ meta.delimiter.comma.js
29 | // ^ punctuation.section.class.begin.js
30 | // ^ punctuation.section.class.end.js
31 | declare module.exports: () => Function;
32 | //^^^^^^^ ^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^ meta.class.body.js
33 | //^^^^^^^ keyword.other.declare.flowtype
34 | // ^^^^^^ ^^^^^^^ storage.type.module.flowtype
35 | // ^ keyword.operator.accessor.flowtype
36 | // ^ punctuation.type.flowtype
37 | // ^ punctuation.definition.parameters.begin.js
38 | // ^^ meta.brace.round.js
39 | // ^ punctuation.definition.parameters.end.js
40 | // ^^ storage.type.function.arrow.js
41 | // ^^^^^^^^ support.type.builtin.class.flowtype
42 | // ^ punctuation.terminator.statement.js
43 | declare type NextFunction = (error?: Object) => void
44 | //^^^^^^^ ^^^^ ^^^^^^^^^^^^ ^ ^^^^^^^^ ^^^^^^^ ^^ ^^^^ meta.class.body.js
45 | //^^^^^^^ keyword.other.declare.flowtype
46 | // ^^^^ keyword.other.typedef.flowtype
47 | // ^^^^^^^^^^^^ support.type.class.flowtype
48 | // ^ punctuation.definition.parameters.begin.js
49 | // ^ ^ meta.brace.round.js
50 | // ^^^^^^^ ^^^^^^ meta.function.parameters.js
51 | // ^^^^^ variable.other.readwrite.js
52 | // ^ keyword.operator.optional.parameter.flowtype
53 | // ^ punctuation.type.flowtype
54 | // ^^^^^^ support.type.builtin.class.flowtype
55 | // ^ punctuation.definition.parameters.end.js
56 | // ^^^^ support.type.builtin.primitive.flowtype
57 | }
58 | // <- punctuation.section.class.end.js
59 |
60 | interface Iterator {
61 | // <- keyword.other.interface.flowtype
62 | // <- keyword.other.interface.flowtype
63 | //^^^^^^^ keyword.other.interface.flowtype
64 | // ^^^^^^^^ support.type.class.interface.js
65 | // ^ ^ punctuation.flowtype
66 | // ^ support.type.class.flowtype
67 | // ^ punctuation.section.class.begin.js
68 | next(): IteratorResult
69 | // ^^^^^^^ ^^^^^^^^^^^^^^^^^ meta.class.body.js
70 | // ^^^^^^^ ^^^^^^^^^^^^^^^^^ meta.function.method.js
71 | // ^^^^ entity.name.function.method.js
72 | // ^ punctuation.definition.parameters.begin.js
73 | // ^^ meta.brace.round.js
74 | // ^ punctuation.definition.parameters.end.js
75 | // ^ punctuation.type.flowtype
76 | // ^^^^^^^^^^^^^^ ^ support.type.class.flowtype
77 | // ^ ^ punctuation.flowtype
78 | iterator(): Iterator
79 | // ^^^^^^^^^^^ ^^^^^^^^^^^ meta.class.body.js
80 | // ^^^^^^^^^^^ ^^^^^^^^^^^ meta.function.method.js
81 | // ^^^^^^^^ entity.name.function.method.js
82 | // ^ punctuation.definition.parameters.begin.js
83 | // ^^ meta.brace.round.js
84 | // ^ punctuation.definition.parameters.end.js
85 | // ^ punctuation.type.flowtype
86 | // ^^^^^^^^ ^ support.type.class.flowtype
87 | // ^ ^ punctuation.flowtype
88 | }
89 | // <- punctuation.section.class.end.js
90 |
91 | declare var NaN: number
92 | // <- keyword.other.declare.flowtype
93 | // <- keyword.other.declare.flowtype
94 | //^^^^^ keyword.other.declare.flowtype
95 | // ^^^ storage.type.js
96 | // ^^^ variable.other.readwrite.js
97 | // ^ punctuation.type.flowtype
98 | // ^^^^^^ support.type.builtin.primitive.flowtype
99 |
100 | declare var module: {
101 | // <- keyword.other.declare.flowtype
102 | // <- keyword.other.declare.flowtype
103 | //^^^^^ keyword.other.declare.flowtype
104 | // ^^^ storage.type.js
105 | // ^^^^^^ variable.other.readwrite.js
106 | // ^ punctuation.type.flowtype
107 | // ^ meta.brace.curly.open.flowtype
108 | exports: any;
109 | // ^^^^^^^ variable.other.readwrite.js
110 | // ^ punctuation.type.flowtype
111 | // ^^^ support.type.builtin.primitive.flowtype
112 | require(id: string): any;
113 | // ^^^^^^^^^^^ ^^^^^^^^ ^^^ meta.function.method.js
114 | // ^^^^^^^ entity.name.function.method.js
115 | // ^ punctuation.definition.parameters.begin.js
116 | // ^ ^ meta.brace.round.js
117 | // ^^^ ^^^^^^ meta.function.parameters.js
118 | // ^^ variable.other.readwrite.js
119 | // ^ ^ punctuation.type.flowtype
120 | // ^^^^^^ ^^^ support.type.builtin.primitive.flowtype
121 | // ^ punctuation.definition.parameters.end.js
122 | id: string;
123 | // ^^ variable.other.readwrite.js
124 | // ^ punctuation.type.flowtype
125 | // ^^^^^^ support.type.builtin.primitive.flowtype
126 | filename: string;
127 | // ^^^^^^^^ variable.other.readwrite.js
128 | // ^ punctuation.type.flowtype
129 | // ^^^^^^ support.type.builtin.primitive.flowtype
130 | loaded: boolean;
131 | // ^^^^^^ variable.other.readwrite.js
132 | // ^ punctuation.type.flowtype
133 | // ^^^^^^^ support.type.builtin.primitive.flowtype
134 | parent: any;
135 | // ^^^^^^ variable.other.readwrite.js
136 | // ^ punctuation.type.flowtype
137 | // ^^^ support.type.builtin.primitive.flowtype
138 | children: Array;
139 | // ^^^^^^^^ variable.other.readwrite.js
140 | // ^ punctuation.type.flowtype
141 | // ^^^^^ support.type.builtin.class.flowtype
142 | // ^ ^ punctuation.flowtype
143 | // ^^^ support.type.builtin.primitive.flowtype
144 | };
145 | // <- meta.brace.curly.close.flowtype
146 | // <- punctuation.terminator.statement.js
147 |
148 | declare class Blob {
149 | // <- keyword.other.declare.flowtype
150 | // <- keyword.other.declare.flowtype
151 | //^^^^^ keyword.other.declare.flowtype
152 | // ^^^^^ storage.type.class.flowtype
153 | // ^^^^ entity.name.class.js
154 | // ^ punctuation.section.class.begin.js
155 | constructor(blobParts?: Array, options?: {
156 | // ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^ meta.class.body.js
157 | // ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^ meta.function.method.js
158 | // ^^^^^^^^^^^ entity.name.function.method.js
159 | // ^ punctuation.definition.parameters.begin.js
160 | // ^ meta.brace.round.js
161 | // ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^ meta.function.parameters.js
162 | // ^^^^^^^^^ ^^^^^^^ variable.other.readwrite.js
163 | // ^ ^ keyword.operator.optional.parameter.flowtype
164 | // ^ ^ punctuation.type.flowtype
165 | // ^^^^^ support.type.builtin.class.flowtype
166 | // ^ ^ punctuation.flowtype
167 | // ^^^ support.type.builtin.primitive.flowtype
168 | // ^ meta.delimiter.comma.js
169 | // ^ meta.brace.curly.open.flowtype
170 | type?: string
171 | // ^^^^^^ ^^^^^^ meta.class.body.js
172 | // ^^^^^^ ^^^^^^ meta.function.method.js
173 | // ^^^^^^ ^^^^^^ meta.function.parameters.js
174 | // ^^^^ variable.other.readwrite.js
175 | // ^ keyword.operator.optional.parameter.flowtype
176 | // ^ punctuation.type.flowtype
177 | // ^^^^^^ support.type.builtin.primitive.flowtype
178 | endings?: string
179 | // ^^^^^^^^^ ^^^^^^ meta.class.body.js
180 | // ^^^^^^^^^ ^^^^^^ meta.function.method.js
181 | // ^^^^^^^^^ ^^^^^^ meta.function.parameters.js
182 | // ^^^^^^^ variable.other.readwrite.js
183 | // ^ keyword.operator.optional.parameter.flowtype
184 | // ^ punctuation.type.flowtype
185 | // ^^^^^^ support.type.builtin.primitive.flowtype
186 | }): void
187 | // ^^^ ^^^^ meta.class.body.js
188 | // ^^^ ^^^^ meta.function.method.js
189 | // ^ meta.function.parameters.js
190 | // ^ meta.brace.curly.close.flowtype
191 | // ^ punctuation.definition.parameters.end.js
192 | // ^ meta.brace.round.js
193 | // ^ punctuation.type.flowtype
194 | // ^^^^ support.type.builtin.primitive.flowtype
195 | type: string
196 | // ^^^^^ ^^^^^^ meta.class.body.js
197 | // ^^^^^ ^^^^^^ meta.function.method.js
198 | // ^^^^ variable.other.readwrite.js
199 | // ^ punctuation.type.flowtype
200 | // ^^^^^^ support.type.builtin.primitive.flowtype
201 | size: number
202 | // ^^^^^ ^^^^^^ meta.class.body.js
203 | // ^^^^^ ^^^^^^ meta.function.method.js
204 | // ^^^^ variable.other.readwrite.js
205 | // ^ punctuation.type.flowtype
206 | // ^^^^^^ support.type.builtin.primitive.flowtype
207 | slice(start?: number, end?: number, contentType?: string): Blob
208 | // ^^^^^^^^^^^^^ ^^^^^^^ ^^^^^ ^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^ ^^^^ meta.class.body.js
209 | // ^^^^^^^^^^^^^ ^^^^^^^ ^^^^^ ^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^ ^^^^ meta.function.method.js
210 | // ^^^^^ entity.name.function.method.js
211 | // ^ punctuation.definition.parameters.begin.js
212 | // ^ ^ meta.brace.round.js
213 | // ^^^^^^^ ^^^^^^^ ^^^^^ ^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^ meta.function.parameters.js
214 | // ^^^^^ ^^^ ^^^^^^^^^^^ variable.other.readwrite.js
215 | // ^ ^ ^ keyword.operator.optional.parameter.flowtype
216 | // ^ ^ ^ ^ punctuation.type.flowtype
217 | // ^^^^^^ ^^^^^^ ^^^^^^ support.type.builtin.primitive.flowtype
218 | // ^ ^ meta.delimiter.comma.js
219 | // ^ punctuation.definition.parameters.end.js
220 | // ^^^^ support.type.class.flowtype
221 | }
222 | // <- punctuation.section.class.end.js
223 |
224 | type CanvasImageSource = HTMLImageElement | number & string
225 | // <- keyword.other.typedef.flowtype
226 | // <- keyword.other.typedef.flowtype
227 | //^^ keyword.other.typedef.flowtype
228 | // ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ support.type.class.flowtype
229 | // ^ kewyword.operator.union.flowtype
230 | // ^^^^^^ ^^^^^^ support.type.builtin.primitive.flowtype
231 | // ^ kewyword.operator.intersection.flowtype
232 |
233 | type child_process$execOpts = {
234 | // <- keyword.other.typedef.flowtype
235 | // <- keyword.other.typedef.flowtype
236 | //^^ keyword.other.typedef.flowtype
237 | // ^^^^^^^^^^^^^^^^^^^^^^ support.type.primitive.flowtype
238 | // ^ meta.brace.curly.js
239 | cwd?: string
240 | //^^^ variable.other.readwrite.js
241 | // ^ keyword.operator.optional.parameter.flowtype
242 | // ^ punctuation.type.flowtype
243 | // ^^^^^^ support.type.builtin.primitive.flowtype
244 | env?: Object
245 | //^^^ variable.other.readwrite.js
246 | // ^ keyword.operator.optional.parameter.flowtype
247 | // ^ punctuation.type.flowtype
248 | // ^^^^^^ support.type.builtin.class.flowtype
249 | };
250 | // <- meta.brace.curly.js
251 | // <- punctuation.terminator.statement.js
252 |
253 | type ReactClass = _ReactClass
254 | // <- keyword.other.typedef.flowtype
255 | // <- keyword.other.typedef.flowtype
256 | //^^ keyword.other.typedef.flowtype
257 | // ^^^^^^^^^^ ^ ^ ^ ^^^^^^^^^^^ ^ ^ ^ support.type.class.flowtype
258 | // ^ ^ ^ ^ punctuation.flowtype
259 | // ^ ^ ^ ^ ^ meta.delimiter.comma.js
260 | // ^ kewyword.operator.existential.flowtype
261 |
262 | declare function require(id: string): any;
263 | // <- keyword.other.declare.flowtype
264 | // <- keyword.other.declare.flowtype
265 | //^^^^^ keyword.other.declare.flowtype
266 | // ^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^ ^^^ meta.function.js
267 | // ^^^^^^^^ storage.type.function.js
268 | // ^^^^^^^ entity.name.function.js
269 | // ^ punctuation.definition.parameters.begin.js
270 | // ^ ^ meta.brace.round.js
271 | // ^^^ ^^^^^^ meta.function.parameters.js
272 | // ^^ variable.other.readwrite.js
273 | // ^ ^ punctuation.type.flowtype
274 | // ^^^^^^ ^^^ support.type.builtin.primitive.flowtype
275 | // ^ punctuation.definition.parameters.end.js
276 | // ^ punctuation.terminator.statement.js
277 |
278 | declare var foo: (
279 | // <- keyword.other.declare.flowtype
280 | // <- keyword.other.declare.flowtype
281 | //^^^^^ keyword.other.declare.flowtype
282 | // ^^^ storage.type.js
283 | // ^^^ storage.type.function.js
284 | // ^ punctuation.type.flowtype
285 | // ^ punctuation.definition.parameters.begin.js
286 | // ^ meta.brace.round.js
287 | ((x: T) => T) & ((x: T, y: U) => U)
288 | //^^^^^^^ ^^ ^^ ^^ ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ meta.function.parameters.js
289 | //^ ^ ^ ^ ^ ^ ^ ^ meta.brace.round.js
290 | // ^ ^ ^ ^ punctuation.flowtype
291 | // ^ ^ ^ ^ ^ ^ ^ ^ support.type.class.flowtype
292 | // ^ ^ punctuation.definition.parameters.begin.js
293 | // ^ ^ ^ variable.other.readwrite.js
294 | // ^ ^ ^ punctuation.type.flowtype
295 | // ^ ^ punctuation.definition.parameters.end.js
296 | // ^^ ^^ storage.type.function.arrow.js
297 | // ^ kewyword.operator.intersection.flowtype
298 | // ^ ^ meta.delimiter.comma.js
299 | )
300 | // <- punctuation.definition.parameters.end.js meta.brace.round.js
301 |
302 |
303 | // >> only:(source.js.jsx)
304 |
--------------------------------------------------------------------------------