├── .editorconfig ├── .gitattributes ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.d.ts ├── index.js ├── package.json ├── test ├── driver.js ├── run.js ├── tests-jsx.js └── tests-misc.js └── xhtml.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | insert_final_newline = true 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /package-lock.json 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | .* 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '4' 4 | - '6' 5 | - '8' 6 | - '10' 7 | - '12' 8 | - '14' 9 | env: 10 | - ACORN_VERSION=6 11 | - ACORN_VERSION=7 12 | - ACORN_VERSION=8 13 | 14 | install: 15 | - npm install -D acorn@$ACORN_VERSION 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012-2017 by Ingvar Stepanyan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Acorn-JSX 2 | 3 | [![Build Status](https://travis-ci.org/acornjs/acorn-jsx.svg?branch=master)](https://travis-ci.org/acornjs/acorn-jsx) 4 | [![NPM version](https://img.shields.io/npm/v/acorn-jsx.svg)](https://www.npmjs.org/package/acorn-jsx) 5 | 6 | 7 | 8 | This is plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. 9 | 10 | It was created as an experimental alternative, faster [React.js JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) parser. Later, it replaced the [official parser](https://github.com/facebookarchive/esprima) and these days is used by many prominent development tools. 11 | 12 | ## Transpiler 13 | 14 | Please note that this tool only parses source code to JSX AST, which is useful for various language tools and services. If you want to transpile your code to regular ES5-compliant JavaScript with source map, check out [Babel](https://babeljs.io/) and [Buble](https://buble.surge.sh/) transpilers which use `acorn-jsx` under the hood. 15 | 16 | ## Usage 17 | 18 | Requiring this module provides you with an Acorn plugin that you can use like this: 19 | 20 | ```javascript 21 | var acorn = require("acorn"); 22 | var jsx = require("acorn-jsx"); 23 | acorn.Parser.extend(jsx()).parse("my(, 'code');"); 24 | ``` 25 | 26 | Note that official spec doesn't support mix of XML namespaces and object-style access in tag names (#27) like in ``, so it was deprecated in `acorn-jsx@3.0`. If you still want to opt-in to support of such constructions, you can pass the following option: 27 | 28 | ```javascript 29 | acorn.Parser.extend(jsx({ allowNamespacedObjects: true })) 30 | ``` 31 | 32 | Also, since most apps use pure React transformer, a new option was introduced that allows to prohibit namespaces completely: 33 | 34 | ```javascript 35 | acorn.Parser.extend(jsx({ allowNamespaces: false })) 36 | ``` 37 | 38 | Note that by default `allowNamespaces` is enabled for spec compliancy. 39 | 40 | ## License 41 | 42 | This plugin is issued under the [MIT license](./LICENSE). 43 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import * as acorn from 'acorn'; 2 | 3 | interface JsxTokTypes extends AcornTokTypes { 4 | jsxName: acorn.TokenType, 5 | jsxText: acorn.TokenType, 6 | jsxTagEnd: acorn.TokenType, 7 | jsxTagStart: acorn.TokenType 8 | } 9 | 10 | declare const jsx: { 11 | tokTypes: JsxTokTypes; 12 | (options?: jsx.Options): (BaseParser: typeof acorn.Parser) => jsx.AcornJsxParserCtor 13 | } 14 | 15 | type AcornTokTypes = typeof acorn.tokTypes; 16 | 17 | declare namespace jsx { 18 | 19 | type TokTypes = JsxTokTypes 20 | 21 | interface Options { 22 | allowNamespacedObjects?: boolean; 23 | allowNamespaces?: boolean; 24 | } 25 | 26 | interface TokContexts { 27 | tc_oTag: acorn.TokContext, 28 | tc_cTag: acorn.TokContext, 29 | tc_expr: acorn.TokContext 30 | } 31 | 32 | // We pick (statics) from acorn rather than plain extending to avoid complaint 33 | // about base constructors needing the same return type (i.e., we return 34 | // `AcornJsxParser` here) 35 | interface AcornJsxParserCtor extends Pick { 36 | readonly acornJsx: { 37 | tokTypes: TokTypes; 38 | tokContexts: TokContexts 39 | }; 40 | 41 | new (options: acorn.Options, input: string, startPos?: number): AcornJsxParser; 42 | } 43 | 44 | interface AcornJsxParser extends acorn.Parser { 45 | jsx_readToken(): string; 46 | jsx_readNewLine(normalizeCRLF: boolean): void; 47 | jsx_readString(quote: number): void; 48 | jsx_readEntity(): string; 49 | jsx_readWord(): void; 50 | jsx_parseIdentifier(): acorn.Node; 51 | jsx_parseNamespacedName(): acorn.Node; 52 | jsx_parseElementName(): acorn.Node | string; 53 | jsx_parseAttributeValue(): acorn.Node; 54 | jsx_parseEmptyExpression(): acorn.Node; 55 | jsx_parseExpressionContainer(): acorn.Node; 56 | jsx_parseAttribute(): acorn.Node; 57 | jsx_parseOpeningElementAt(startPos: number, startLoc?: acorn.SourceLocation): acorn.Node; 58 | jsx_parseClosingElementAt(startPos: number, startLoc?: acorn.SourceLocation): acorn.Node; 59 | jsx_parseElementAt(startPos: number, startLoc?: acorn.SourceLocation): acorn.Node; 60 | jsx_parseText(): acorn.Node; 61 | jsx_parseElement(): acorn.Node; 62 | } 63 | } 64 | 65 | export = jsx; 66 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const XHTMLEntities = require('./xhtml'); 4 | 5 | const hexNumber = /^[\da-fA-F]+$/; 6 | const decimalNumber = /^\d+$/; 7 | 8 | // The map to `acorn-jsx` tokens from `acorn` namespace objects. 9 | const acornJsxMap = new WeakMap(); 10 | 11 | // Get the original tokens for the given `acorn` namespace object. 12 | function getJsxTokens(acorn) { 13 | acorn = acorn.Parser.acorn || acorn; 14 | let acornJsx = acornJsxMap.get(acorn); 15 | if (!acornJsx) { 16 | const tt = acorn.tokTypes; 17 | const TokContext = acorn.TokContext; 18 | const TokenType = acorn.TokenType; 19 | const tc_oTag = new TokContext('...', true, true); 22 | const tokContexts = { 23 | tc_oTag: tc_oTag, 24 | tc_cTag: tc_cTag, 25 | tc_expr: tc_expr 26 | }; 27 | const tokTypes = { 28 | jsxName: new TokenType('jsxName'), 29 | jsxText: new TokenType('jsxText', {beforeExpr: true}), 30 | jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}), 31 | jsxTagEnd: new TokenType('jsxTagEnd') 32 | }; 33 | 34 | tokTypes.jsxTagStart.updateContext = function() { 35 | this.context.push(tc_expr); // treat as beginning of JSX expression 36 | this.context.push(tc_oTag); // start opening tag context 37 | this.exprAllowed = false; 38 | }; 39 | tokTypes.jsxTagEnd.updateContext = function(prevType) { 40 | let out = this.context.pop(); 41 | if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) { 42 | this.context.pop(); 43 | this.exprAllowed = this.curContext() === tc_expr; 44 | } else { 45 | this.exprAllowed = true; 46 | } 47 | }; 48 | 49 | acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes }; 50 | acornJsxMap.set(acorn, acornJsx); 51 | } 52 | 53 | return acornJsx; 54 | } 55 | 56 | // Transforms JSX element name to string. 57 | 58 | function getQualifiedJSXName(object) { 59 | if (!object) 60 | return object; 61 | 62 | if (object.type === 'JSXIdentifier') 63 | return object.name; 64 | 65 | if (object.type === 'JSXNamespacedName') 66 | return object.namespace.name + ':' + object.name.name; 67 | 68 | if (object.type === 'JSXMemberExpression') 69 | return getQualifiedJSXName(object.object) + '.' + 70 | getQualifiedJSXName(object.property); 71 | } 72 | 73 | module.exports = function(options) { 74 | options = options || {}; 75 | return function(Parser) { 76 | return plugin({ 77 | allowNamespaces: options.allowNamespaces !== false, 78 | allowNamespacedObjects: !!options.allowNamespacedObjects 79 | }, Parser); 80 | }; 81 | }; 82 | 83 | // This is `tokTypes` of the peer dep. 84 | // This can be different instances from the actual `tokTypes` this plugin uses. 85 | Object.defineProperty(module.exports, "tokTypes", { 86 | get: function get_tokTypes() { 87 | return getJsxTokens(require("acorn")).tokTypes; 88 | }, 89 | configurable: true, 90 | enumerable: true 91 | }); 92 | 93 | function plugin(options, Parser) { 94 | const acorn = Parser.acorn || require("acorn"); 95 | const acornJsx = getJsxTokens(acorn); 96 | const tt = acorn.tokTypes; 97 | const tok = acornJsx.tokTypes; 98 | const tokContexts = acorn.tokContexts; 99 | const tc_oTag = acornJsx.tokContexts.tc_oTag; 100 | const tc_cTag = acornJsx.tokContexts.tc_cTag; 101 | const tc_expr = acornJsx.tokContexts.tc_expr; 102 | const isNewLine = acorn.isNewLine; 103 | const isIdentifierStart = acorn.isIdentifierStart; 104 | const isIdentifierChar = acorn.isIdentifierChar; 105 | 106 | return class extends Parser { 107 | // Expose actual `tokTypes` and `tokContexts` to other plugins. 108 | static get acornJsx() { 109 | return acornJsx; 110 | } 111 | 112 | // Reads inline JSX contents token. 113 | jsx_readToken() { 114 | let out = '', chunkStart = this.pos; 115 | for (;;) { 116 | if (this.pos >= this.input.length) 117 | this.raise(this.start, 'Unterminated JSX contents'); 118 | let ch = this.input.charCodeAt(this.pos); 119 | 120 | switch (ch) { 121 | case 60: // '<' 122 | case 123: // '{' 123 | if (this.pos === this.start) { 124 | if (ch === 60 && this.exprAllowed) { 125 | ++this.pos; 126 | return this.finishToken(tok.jsxTagStart); 127 | } 128 | return this.getTokenFromCode(ch); 129 | } 130 | out += this.input.slice(chunkStart, this.pos); 131 | return this.finishToken(tok.jsxText, out); 132 | 133 | case 38: // '&' 134 | out += this.input.slice(chunkStart, this.pos); 135 | out += this.jsx_readEntity(); 136 | chunkStart = this.pos; 137 | break; 138 | 139 | case 62: // '>' 140 | case 125: // '}' 141 | this.raise( 142 | this.pos, 143 | "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" + 144 | (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?" 145 | ); 146 | 147 | default: 148 | if (isNewLine(ch)) { 149 | out += this.input.slice(chunkStart, this.pos); 150 | out += this.jsx_readNewLine(true); 151 | chunkStart = this.pos; 152 | } else { 153 | ++this.pos; 154 | } 155 | } 156 | } 157 | } 158 | 159 | jsx_readNewLine(normalizeCRLF) { 160 | let ch = this.input.charCodeAt(this.pos); 161 | let out; 162 | ++this.pos; 163 | if (ch === 13 && this.input.charCodeAt(this.pos) === 10) { 164 | ++this.pos; 165 | out = normalizeCRLF ? '\n' : '\r\n'; 166 | } else { 167 | out = String.fromCharCode(ch); 168 | } 169 | if (this.options.locations) { 170 | ++this.curLine; 171 | this.lineStart = this.pos; 172 | } 173 | 174 | return out; 175 | } 176 | 177 | jsx_readString(quote) { 178 | let out = '', chunkStart = ++this.pos; 179 | for (;;) { 180 | if (this.pos >= this.input.length) 181 | this.raise(this.start, 'Unterminated string constant'); 182 | let ch = this.input.charCodeAt(this.pos); 183 | if (ch === quote) break; 184 | if (ch === 38) { // '&' 185 | out += this.input.slice(chunkStart, this.pos); 186 | out += this.jsx_readEntity(); 187 | chunkStart = this.pos; 188 | } else if (isNewLine(ch)) { 189 | out += this.input.slice(chunkStart, this.pos); 190 | out += this.jsx_readNewLine(false); 191 | chunkStart = this.pos; 192 | } else { 193 | ++this.pos; 194 | } 195 | } 196 | out += this.input.slice(chunkStart, this.pos++); 197 | return this.finishToken(tt.string, out); 198 | } 199 | 200 | jsx_readEntity() { 201 | let str = '', count = 0, entity; 202 | let ch = this.input[this.pos]; 203 | if (ch !== '&') 204 | this.raise(this.pos, 'Entity must start with an ampersand'); 205 | let startPos = ++this.pos; 206 | while (this.pos < this.input.length && count++ < 10) { 207 | ch = this.input[this.pos++]; 208 | if (ch === ';') { 209 | if (str[0] === '#') { 210 | if (str[1] === 'x') { 211 | str = str.substr(2); 212 | if (hexNumber.test(str)) 213 | entity = String.fromCharCode(parseInt(str, 16)); 214 | } else { 215 | str = str.substr(1); 216 | if (decimalNumber.test(str)) 217 | entity = String.fromCharCode(parseInt(str, 10)); 218 | } 219 | } else { 220 | entity = XHTMLEntities[str]; 221 | } 222 | break; 223 | } 224 | str += ch; 225 | } 226 | if (!entity) { 227 | this.pos = startPos; 228 | return '&'; 229 | } 230 | return entity; 231 | } 232 | 233 | // Read a JSX identifier (valid tag or attribute name). 234 | // 235 | // Optimized version since JSX identifiers can't contain 236 | // escape characters and so can be read as single slice. 237 | // Also assumes that first character was already checked 238 | // by isIdentifierStart in readToken. 239 | 240 | jsx_readWord() { 241 | let ch, start = this.pos; 242 | do { 243 | ch = this.input.charCodeAt(++this.pos); 244 | } while (isIdentifierChar(ch) || ch === 45); // '-' 245 | return this.finishToken(tok.jsxName, this.input.slice(start, this.pos)); 246 | } 247 | 248 | // Parse next token as JSX identifier 249 | 250 | jsx_parseIdentifier() { 251 | let node = this.startNode(); 252 | if (this.type === tok.jsxName) 253 | node.name = this.value; 254 | else if (this.type.keyword) 255 | node.name = this.type.keyword; 256 | else 257 | this.unexpected(); 258 | this.next(); 259 | return this.finishNode(node, 'JSXIdentifier'); 260 | } 261 | 262 | // Parse namespaced identifier. 263 | 264 | jsx_parseNamespacedName() { 265 | let startPos = this.start, startLoc = this.startLoc; 266 | let name = this.jsx_parseIdentifier(); 267 | if (!options.allowNamespaces || !this.eat(tt.colon)) return name; 268 | var node = this.startNodeAt(startPos, startLoc); 269 | node.namespace = name; 270 | node.name = this.jsx_parseIdentifier(); 271 | return this.finishNode(node, 'JSXNamespacedName'); 272 | } 273 | 274 | // Parses element name in any form - namespaced, member 275 | // or single identifier. 276 | 277 | jsx_parseElementName() { 278 | if (this.type === tok.jsxTagEnd) return ''; 279 | let startPos = this.start, startLoc = this.startLoc; 280 | let node = this.jsx_parseNamespacedName(); 281 | if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) { 282 | this.unexpected(); 283 | } 284 | while (this.eat(tt.dot)) { 285 | let newNode = this.startNodeAt(startPos, startLoc); 286 | newNode.object = node; 287 | newNode.property = this.jsx_parseIdentifier(); 288 | node = this.finishNode(newNode, 'JSXMemberExpression'); 289 | } 290 | return node; 291 | } 292 | 293 | // Parses any type of JSX attribute value. 294 | 295 | jsx_parseAttributeValue() { 296 | switch (this.type) { 297 | case tt.braceL: 298 | let node = this.jsx_parseExpressionContainer(); 299 | if (node.expression.type === 'JSXEmptyExpression') 300 | this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression'); 301 | return node; 302 | 303 | case tok.jsxTagStart: 304 | case tt.string: 305 | return this.parseExprAtom(); 306 | 307 | default: 308 | this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text'); 309 | } 310 | } 311 | 312 | // JSXEmptyExpression is unique type since it doesn't actually parse anything, 313 | // and so it should start at the end of last read token (left brace) and finish 314 | // at the beginning of the next one (right brace). 315 | 316 | jsx_parseEmptyExpression() { 317 | let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); 318 | return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc); 319 | } 320 | 321 | // Parses JSX expression enclosed into curly brackets. 322 | 323 | jsx_parseExpressionContainer() { 324 | let node = this.startNode(); 325 | this.next(); 326 | node.expression = this.type === tt.braceR 327 | ? this.jsx_parseEmptyExpression() 328 | : this.parseExpression(); 329 | this.expect(tt.braceR); 330 | return this.finishNode(node, 'JSXExpressionContainer'); 331 | } 332 | 333 | // Parses following JSX attribute name-value pair. 334 | 335 | jsx_parseAttribute() { 336 | let node = this.startNode(); 337 | if (this.eat(tt.braceL)) { 338 | this.expect(tt.ellipsis); 339 | node.argument = this.parseMaybeAssign(); 340 | this.expect(tt.braceR); 341 | return this.finishNode(node, 'JSXSpreadAttribute'); 342 | } 343 | node.name = this.jsx_parseNamespacedName(); 344 | node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null; 345 | return this.finishNode(node, 'JSXAttribute'); 346 | } 347 | 348 | // Parses JSX opening tag starting after '<'. 349 | 350 | jsx_parseOpeningElementAt(startPos, startLoc) { 351 | let node = this.startNodeAt(startPos, startLoc); 352 | node.attributes = []; 353 | let nodeName = this.jsx_parseElementName(); 354 | if (nodeName) node.name = nodeName; 355 | while (this.type !== tt.slash && this.type !== tok.jsxTagEnd) 356 | node.attributes.push(this.jsx_parseAttribute()); 357 | node.selfClosing = this.eat(tt.slash); 358 | this.expect(tok.jsxTagEnd); 359 | return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment'); 360 | } 361 | 362 | // Parses JSX closing tag starting after ''); 410 | } 411 | } 412 | let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment'; 413 | 414 | node['opening' + fragmentOrElement] = openingElement; 415 | node['closing' + fragmentOrElement] = closingElement; 416 | node.children = children; 417 | if (this.type === tt.relational && this.value === "<") { 418 | this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); 419 | } 420 | return this.finishNode(node, 'JSX' + fragmentOrElement); 421 | } 422 | 423 | // Parse JSX text 424 | 425 | jsx_parseText() { 426 | let node = this.parseLiteral(this.value); 427 | node.type = "JSXText"; 428 | return node; 429 | } 430 | 431 | // Parses entire JSX element from current position. 432 | 433 | jsx_parseElement() { 434 | let startPos = this.start, startLoc = this.startLoc; 435 | this.next(); 436 | return this.jsx_parseElementAt(startPos, startLoc); 437 | } 438 | 439 | parseExprAtom(refShortHandDefaultPos) { 440 | if (this.type === tok.jsxText) 441 | return this.jsx_parseText(); 442 | else if (this.type === tok.jsxTagStart) 443 | return this.jsx_parseElement(); 444 | else 445 | return super.parseExprAtom(refShortHandDefaultPos); 446 | } 447 | 448 | readToken(code) { 449 | let context = this.curContext(); 450 | 451 | if (context === tc_expr) return this.jsx_readToken(); 452 | 453 | if (context === tc_oTag || context === tc_cTag) { 454 | if (isIdentifierStart(code)) return this.jsx_readWord(); 455 | 456 | if (code == 62) { 457 | ++this.pos; 458 | return this.finishToken(tok.jsxTagEnd); 459 | } 460 | 461 | if ((code === 34 || code === 39) && context == tc_oTag) 462 | return this.jsx_readString(code); 463 | } 464 | 465 | if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) { 466 | ++this.pos; 467 | return this.finishToken(tok.jsxTagStart); 468 | } 469 | return super.readToken(code); 470 | } 471 | 472 | updateContext(prevType) { 473 | if (this.type == tt.braceL) { 474 | var curContext = this.curContext(); 475 | if (curContext == tc_oTag) this.context.push(tokContexts.b_expr); 476 | else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl); 477 | else super.updateContext(prevType); 478 | this.exprAllowed = true; 479 | } else if (this.type === tt.slash && prevType === tok.jsxTagStart) { 480 | this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore 481 | this.context.push(tc_cTag); // reconsider as closing tag context 482 | this.exprAllowed = false; 483 | } else { 484 | return super.updateContext(prevType); 485 | } 486 | } 487 | }; 488 | } 489 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "acorn-jsx", 3 | "description": "Modern, fast React.js JSX parser", 4 | "homepage": "https://github.com/acornjs/acorn-jsx", 5 | "version": "5.3.2", 6 | "maintainers": [ 7 | { 8 | "name": "Ingvar Stepanyan", 9 | "email": "me@rreverser.com", 10 | "web": "http://rreverser.com/" 11 | } 12 | ], 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/acornjs/acorn-jsx" 16 | }, 17 | "license": "MIT", 18 | "scripts": { 19 | "test": "node test/run.js" 20 | }, 21 | "peerDependencies": { 22 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 23 | }, 24 | "devDependencies": { 25 | "acorn": "^8.0.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/driver.js: -------------------------------------------------------------------------------- 1 | var tests = []; 2 | 3 | exports.test = function(code, ast, options, pluginOptions) { 4 | tests.push({code, ast, options, pluginOptions}); 5 | }; 6 | exports.testFail = function(code, message, options, pluginOptions) { 7 | tests.push({code, error: message, options, pluginOptions}); 8 | }; 9 | exports.testAssert = function(code, assert, options) { 10 | tests.push({code, assert, options}); 11 | }; 12 | 13 | exports.runTests = function(config, callback) { 14 | var parse = config.parse; 15 | 16 | for (var i = 0; i < tests.length; ++i) { 17 | var test = tests[i]; 18 | if (config.filter && !config.filter(test)) continue; 19 | try { 20 | var testOpts = Object.assign({ecmaVersion: 11}, test.options || {locations: true}); 21 | var expected = {}; 22 | if (expected.onComment = testOpts.onComment) { 23 | testOpts.onComment = [] 24 | } 25 | if (expected.onToken = testOpts.onToken) { 26 | testOpts.onToken = []; 27 | } 28 | var ast = parse(test.code, testOpts, test.pluginOptions); 29 | if (test.error) { 30 | if (config.loose) { 31 | callback("ok", test.code); 32 | } else { 33 | callback("fail", test.code, "Expected error message: " + test.error + "\nBut parsing succeeded."); 34 | } 35 | } 36 | else if (test.assert) { 37 | var error = test.assert(ast); 38 | if (error) callback("fail", test.code, 39 | "\n Assertion failed:\n " + error); 40 | else callback("ok", test.code); 41 | } else { 42 | var mis = misMatch(test.ast, ast); 43 | for (var name in expected) { 44 | if (mis) break; 45 | if (expected[name]) { 46 | mis = misMatch(expected[name], testOpts[name]); 47 | testOpts[name] = expected[name]; 48 | } 49 | } 50 | if (mis) callback("fail", test.code, mis); 51 | else callback("ok", test.code); 52 | } 53 | } catch(e) { 54 | if (!(e instanceof SyntaxError)) { 55 | throw e; 56 | } 57 | if (test.error) { 58 | if (e.message == test.error) callback("ok", test.code); 59 | else callback("fail", test.code, 60 | "Expected error message: " + test.error + "\nGot error message: " + e.message); 61 | } else { 62 | callback("error", test.code, e.stack || e.toString()); 63 | } 64 | } 65 | } 66 | }; 67 | 68 | function ppJSON(v) { return v instanceof RegExp ? v.toString() : JSON.stringify(v, null, 2); } 69 | function addPath(str, pt) { 70 | if (str.charAt(str.length-1) == ")") 71 | return str.slice(0, str.length-1) + "/" + pt + ")"; 72 | return str + " (" + pt + ")"; 73 | } 74 | 75 | var misMatch = exports.misMatch = function(exp, act) { 76 | if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) { 77 | if (exp !== act) return ppJSON(exp) + " !== " + ppJSON(act); 78 | } else if (exp instanceof RegExp || act instanceof RegExp) { 79 | var left = ppJSON(exp), right = ppJSON(act); 80 | if (left !== right) return left + " !== " + right; 81 | } else if (exp.splice) { 82 | if (!act.slice) return ppJSON(exp) + " != " + ppJSON(act); 83 | if (act.length != exp.length) return "array length mismatch " + exp.length + " != " + act.length; 84 | for (var i = 0; i < act.length; ++i) { 85 | var mis = misMatch(exp[i], act[i]); 86 | if (mis) return addPath(mis, i); 87 | } 88 | } else { 89 | for (var prop in exp) { 90 | var mis = misMatch(exp[prop], act[prop]); 91 | if (mis) return addPath(mis, prop); 92 | } 93 | } 94 | }; 95 | 96 | function mangle(ast) { 97 | if (typeof ast != "object" || !ast) return; 98 | if (ast.slice) { 99 | for (var i = 0; i < ast.length; ++i) mangle(ast[i]); 100 | } else { 101 | var loc = ast.start && ast.end && {start: ast.start, end: ast.end}; 102 | if (loc) { delete ast.start; delete ast.end; } 103 | for (var name in ast) if (ast.hasOwnProperty(name)) mangle(ast[name]); 104 | if (loc) ast.loc = loc; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /test/run.js: -------------------------------------------------------------------------------- 1 | var driver = require("./driver.js"); 2 | require("./tests-jsx.js"); 3 | require("./tests-misc.js"); 4 | 5 | function group(name) { 6 | if (typeof console === "object" && console.group) { 7 | console.group(name); 8 | } 9 | } 10 | 11 | function groupEnd() { 12 | if (typeof console === "object" && console.groupEnd) { 13 | console.groupEnd(name); 14 | } 15 | } 16 | 17 | function log(title, message) { 18 | if (typeof console === "object") console.log(title, message); 19 | } 20 | 21 | const acorn = require("acorn"), jsx = require("..") 22 | const Parser = acorn.Parser.extend(jsx()) 23 | 24 | var stats, modes = { 25 | Normal: { 26 | config: { 27 | parse: (input, options, pluginOptions) => { 28 | if (!pluginOptions) return Parser.parse(input, options) 29 | else return acorn.Parser.extend(jsx(pluginOptions)).parse(input, options) 30 | } 31 | } 32 | } 33 | }; 34 | 35 | function report(state, code, message) { 36 | if (state != "ok") {++stats.failed; log(code, message);} 37 | ++stats.testsRun; 38 | } 39 | 40 | group("Errors"); 41 | 42 | for (var name in modes) { 43 | group(name); 44 | var mode = modes[name]; 45 | stats = mode.stats = {testsRun: 0, failed: 0}; 46 | var t0 = +new Date; 47 | driver.runTests(mode.config, report); 48 | mode.stats.duration = +new Date - t0; 49 | groupEnd(); 50 | } 51 | 52 | groupEnd(); 53 | 54 | function outputStats(name, stats) { 55 | log(name + ":", stats.testsRun + " tests run in " + stats.duration + "ms; " + 56 | (stats.failed ? stats.failed + " failures." : "all passed.")); 57 | } 58 | 59 | var total = {testsRun: 0, failed: 0, duration: 0}; 60 | 61 | group("Stats"); 62 | 63 | for (var name in modes) { 64 | var stats = modes[name].stats; 65 | outputStats(name + " parser", stats); 66 | for (var key in stats) total[key] += stats[key]; 67 | } 68 | 69 | outputStats("Total", total); 70 | 71 | groupEnd(); 72 | 73 | if (total.failed && typeof process === "object") { 74 | process.stdout.write("", function() { 75 | process.exit(1); 76 | }); 77 | } 78 | -------------------------------------------------------------------------------- /test/tests-jsx.js: -------------------------------------------------------------------------------- 1 | /* 2 | Redistribution and use in source and binary forms, with or without 3 | modification, are permitted provided that the following conditions are met: 4 | 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 14 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 15 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 16 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 17 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 18 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 19 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 20 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21 | */ 22 | 23 | var fbTestFixture = { 24 | // Taken and adapted from esprima-fb/fbtest.js. 25 | 'JSX': { 26 | '': { 27 | type: "ExpressionStatement", 28 | expression: { 29 | type: "JSXElement", 30 | openingElement: { 31 | type: "JSXOpeningElement", 32 | name: { 33 | type: "JSXIdentifier", 34 | name: "a", 35 | range: [1, 2], 36 | loc: { 37 | start: { line: 1, column: 1 }, 38 | end: { line: 1, column: 2 } 39 | } 40 | }, 41 | selfClosing: true, 42 | attributes: [], 43 | range: [0, 5], 44 | loc: { 45 | start: { line: 1, column: 0 }, 46 | end: { line: 1, column: 5 } 47 | } 48 | }, 49 | closingElement: null, 50 | children: [], 51 | range: [0, 5], 52 | loc: { 53 | start: { line: 1, column: 0 }, 54 | end: { line: 1, column: 5 } 55 | } 56 | }, 57 | range: [0, 5], 58 | loc: { 59 | start: { line: 1, column: 0 }, 60 | end: { line: 1, column: 5 } 61 | } 62 | }, 63 | 64 | '': { 65 | type: 'ExpressionStatement', 66 | expression: { 67 | type: 'JSXElement', 68 | openingElement: { 69 | type: 'JSXOpeningElement', 70 | name: { 71 | type: 'JSXNamespacedName', 72 | namespace: { 73 | type: 'JSXIdentifier', 74 | name: 'n', 75 | range: [1, 2], 76 | loc: { 77 | start: { line: 1, column: 1 }, 78 | end: { line: 1, column: 2 } 79 | } 80 | }, 81 | name: { 82 | type: 'JSXIdentifier', 83 | name: 'a', 84 | range: [3, 4], 85 | loc: { 86 | start: { line: 1, column: 3 }, 87 | end: { line: 1, column: 4 } 88 | } 89 | }, 90 | range: [1, 4], 91 | loc: { 92 | start: { line: 1, column: 1 }, 93 | end: { line: 1, column: 4 } 94 | } 95 | }, 96 | selfClosing: true, 97 | attributes: [{ 98 | type: 'JSXAttribute', 99 | name: { 100 | type: 'JSXNamespacedName', 101 | namespace: { 102 | type: 'JSXIdentifier', 103 | name: 'n', 104 | range: [5, 6], 105 | loc: { 106 | start: { line: 1, column: 5 }, 107 | end: { line: 1, column: 6 } 108 | } 109 | }, 110 | name: { 111 | type: 'JSXIdentifier', 112 | name: 'v', 113 | range: [7, 8], 114 | loc: { 115 | start: { line: 1, column: 7 }, 116 | end: { line: 1, column: 8 } 117 | } 118 | }, 119 | range: [5, 8], 120 | loc: { 121 | start: { line: 1, column: 5 }, 122 | end: { line: 1, column: 8 } 123 | } 124 | }, 125 | value: null, 126 | range: [5, 8], 127 | loc: { 128 | start: { line: 1, column: 5 }, 129 | end: { line: 1, column: 8 } 130 | } 131 | }], 132 | range: [0, 11], 133 | loc: { 134 | start: { line: 1, column: 0 }, 135 | end: { line: 1, column: 11 } 136 | } 137 | }, 138 | closingElement: null, 139 | children: [], 140 | range: [0, 11], 141 | loc: { 142 | start: { line: 1, column: 0 }, 143 | end: { line: 1, column: 11 } 144 | } 145 | }, 146 | range: [0, 11], 147 | loc: { 148 | start: { line: 1, column: 0 }, 149 | end: { line: 1, column: 11 } 150 | } 151 | }, 152 | 153 | ' {value} ': { 154 | type: 'ExpressionStatement', 155 | expression: { 156 | type: 'JSXElement', 157 | openingElement: { 158 | type: 'JSXOpeningElement', 159 | name: { 160 | type: 'JSXIdentifier', 161 | name: 'a', 162 | range: [1, 2], 163 | loc: { 164 | start: { line: 1, column: 1 }, 165 | end: { line: 1, column: 2 } 166 | } 167 | }, 168 | selfClosing: false, 169 | attributes: [{ 170 | type: 'JSXAttribute', 171 | name: { 172 | type: 'JSXNamespacedName', 173 | namespace: { 174 | type: 'JSXIdentifier', 175 | name: 'n', 176 | range: [3, 4], 177 | loc: { 178 | start: { line: 1, column: 3 }, 179 | end: { line: 1, column: 4 } 180 | } 181 | }, 182 | name: { 183 | type: 'JSXIdentifier', 184 | name: 'foo', 185 | range: [5, 8], 186 | loc: { 187 | start: { line: 1, column: 5 }, 188 | end: { line: 1, column: 8 } 189 | } 190 | }, 191 | range: [3, 8], 192 | loc: { 193 | start: { line: 1, column: 3 }, 194 | end: { line: 1, column: 8 } 195 | } 196 | }, 197 | value: { 198 | type: 'Literal', 199 | value: 'bar', 200 | raw: '"bar"', 201 | range: [9, 14], 202 | loc: { 203 | start: { line: 1, column: 9 }, 204 | end: { line: 1, column: 14 } 205 | } 206 | }, 207 | range: [3, 14], 208 | loc: { 209 | start: { line: 1, column: 3 }, 210 | end: { line: 1, column: 14 } 211 | } 212 | }], 213 | range: [0, 15], 214 | loc: { 215 | start: { line: 1, column: 0 }, 216 | end: { line: 1, column: 15 } 217 | } 218 | }, 219 | closingElement: { 220 | type: 'JSXClosingElement', 221 | name: { 222 | type: 'JSXIdentifier', 223 | name: 'a', 224 | range: [38, 39], 225 | loc: { 226 | start: { line: 1, column: 38 }, 227 | end: { line: 1, column: 39 } 228 | } 229 | }, 230 | range: [36, 40], 231 | loc: { 232 | start: { line: 1, column: 36 }, 233 | end: { line: 1, column: 40 } 234 | } 235 | }, 236 | children: [{ 237 | type: 'JSXText', 238 | value: ' ', 239 | raw: ' ', 240 | range: [15, 16], 241 | loc: { 242 | start: { line: 1, column: 15 }, 243 | end: { line: 1, column: 16 } 244 | } 245 | }, { 246 | type: 'JSXExpressionContainer', 247 | expression: { 248 | type: 'Identifier', 249 | name: 'value', 250 | range: [17, 22], 251 | loc: { 252 | start: { line: 1, column: 17 }, 253 | end: { line: 1, column: 22 } 254 | } 255 | }, 256 | range: [16, 23], 257 | loc: { 258 | start: { line: 1, column: 16 }, 259 | end: { line: 1, column: 23 } 260 | } 261 | }, { 262 | type: 'JSXText', 263 | value: ' ', 264 | raw: ' ', 265 | range: [23, 24], 266 | loc: { 267 | start: { line: 1, column: 23 }, 268 | end: { line: 1, column: 24 } 269 | } 270 | }, { 271 | type: 'JSXElement', 272 | openingElement: { 273 | type: 'JSXOpeningElement', 274 | name: { 275 | type: 'JSXIdentifier', 276 | name: 'b', 277 | range: [25, 26], 278 | loc: { 279 | start: { line: 1, column: 25 }, 280 | end: { line: 1, column: 26 } 281 | } 282 | }, 283 | selfClosing: false, 284 | attributes: [], 285 | range: [24, 27], 286 | loc: { 287 | start: { line: 1, column: 24 }, 288 | end: { line: 1, column: 27 } 289 | } 290 | }, 291 | closingElement: { 292 | type: 'JSXClosingElement', 293 | name: { 294 | type: 'JSXIdentifier', 295 | name: 'b', 296 | range: [34, 35], 297 | loc: { 298 | start: { line: 1, column: 34 }, 299 | end: { line: 1, column: 35 } 300 | } 301 | }, 302 | range: [32, 36], 303 | loc: { 304 | start: { line: 1, column: 32 }, 305 | end: { line: 1, column: 36 } 306 | } 307 | }, 308 | children: [{ 309 | type: 'JSXElement', 310 | openingElement: { 311 | type: 'JSXOpeningElement', 312 | name: { 313 | type: 'JSXIdentifier', 314 | name: 'c', 315 | range: [28, 29], 316 | loc: { 317 | start: { line: 1, column: 28 }, 318 | end: { line: 1, column: 29 } 319 | } 320 | }, 321 | selfClosing: true, 322 | attributes: [], 323 | range: [27, 32], 324 | loc: { 325 | start: { line: 1, column: 27 }, 326 | end: { line: 1, column: 32 } 327 | } 328 | }, 329 | closingElement: null, 330 | children: [], 331 | range: [27, 32], 332 | loc: { 333 | start: { line: 1, column: 27 }, 334 | end: { line: 1, column: 32 } 335 | } 336 | }], 337 | range: [24, 36], 338 | loc: { 339 | start: { line: 1, column: 24 }, 340 | end: { line: 1, column: 36 } 341 | } 342 | }], 343 | range: [0, 40], 344 | loc: { 345 | start: { line: 1, column: 0 }, 346 | end: { line: 1, column: 40 } 347 | } 348 | }, 349 | range: [0, 40], 350 | loc: { 351 | start: { line: 1, column: 0 }, 352 | end: { line: 1, column: 40 } 353 | } 354 | }, 355 | 356 | '': { 357 | type: "ExpressionStatement", 358 | expression: { 359 | type: "JSXElement", 360 | openingElement: { 361 | type: "JSXOpeningElement", 362 | name: { 363 | type: "JSXIdentifier", 364 | name: "a", 365 | range: [1, 2] 366 | }, 367 | selfClosing: true, 368 | attributes: [ 369 | { 370 | type: "JSXAttribute", 371 | name: { 372 | type: "JSXIdentifier", 373 | name: "b", 374 | range: [3, 4] 375 | }, 376 | value: { 377 | type: "JSXExpressionContainer", 378 | expression: { 379 | type: "Literal", 380 | value: " ", 381 | raw: "\" \"", 382 | range: [6, 9] 383 | }, 384 | range: [5, 10] 385 | }, 386 | range: [3, 10] 387 | }, 388 | { 389 | type: "JSXAttribute", 390 | name: { 391 | type: "JSXIdentifier", 392 | name: "c", 393 | range: [11, 12] 394 | }, 395 | value: { 396 | type: "Literal", 397 | value: " ", 398 | raw: "\" \"", 399 | range: [13, 16] 400 | }, 401 | range: [11, 16] 402 | }, 403 | { 404 | type: "JSXAttribute", 405 | name: { 406 | type: "JSXIdentifier", 407 | name: "d", 408 | range: [17, 18] 409 | }, 410 | value: { 411 | type: "Literal", 412 | value: "&", 413 | raw: "\"&\"", 414 | range: [19, 26] 415 | }, 416 | range: [17, 26] 417 | }, 418 | { 419 | type: "JSXAttribute", 420 | name: { 421 | type: "JSXIdentifier", 422 | name: "e", 423 | range: [27, 28] 424 | }, 425 | value: { 426 | type: "Literal", 427 | value: "&r;", 428 | raw: "\"&r;\"", 429 | range: [29, 37] 430 | }, 431 | range: [27, 37] 432 | } 433 | ], 434 | range: [0, 40] 435 | }, 436 | closingElement: null, 437 | children: [], 438 | range: [0, 40] 439 | }, 440 | range: [0, 40] 441 | }, 442 | 443 | '': { 444 | type: "ExpressionStatement", 445 | expression: { 446 | type: "JSXElement", 447 | openingElement: { 448 | type: "JSXOpeningElement", 449 | name: { 450 | type: "JSXIdentifier", 451 | name: "a", 452 | range: [ 453 | 1, 454 | 2 455 | ], 456 | loc: { 457 | start: { 458 | line: 1, 459 | column: 1 460 | }, 461 | end: { 462 | line: 1, 463 | column: 2 464 | } 465 | } 466 | }, 467 | selfClosing: true, 468 | attributes: [], 469 | range: [ 470 | 0, 471 | 5 472 | ], 473 | loc: { 474 | start: { 475 | line: 1, 476 | column: 0 477 | }, 478 | end: { 479 | line: 2, 480 | column: 2 481 | } 482 | } 483 | }, 484 | closingElement: null, 485 | children: [], 486 | range: [ 487 | 0, 488 | 5 489 | ], 490 | loc: { 491 | start: { 492 | line: 1, 493 | column: 0 494 | }, 495 | end: { 496 | line: 2, 497 | column: 2 498 | } 499 | } 500 | }, 501 | range: [ 502 | 0, 503 | 5 504 | ], 505 | loc: { 506 | start: { 507 | line: 1, 508 | column: 0 509 | }, 510 | end: { 511 | line: 2, 512 | column: 2 513 | } 514 | } 515 | }, 516 | 517 | '<日本語>': { 518 | type: "ExpressionStatement", 519 | expression: { 520 | type: "JSXElement", 521 | openingElement: { 522 | type: "JSXOpeningElement", 523 | name: { 524 | type: "JSXIdentifier", 525 | name: "日本語", 526 | range: [ 527 | 1, 528 | 4 529 | ], 530 | loc: { 531 | start: { 532 | line: 1, 533 | column: 1 534 | }, 535 | end: { 536 | line: 1, 537 | column: 4 538 | } 539 | } 540 | }, 541 | selfClosing: false, 542 | attributes: [], 543 | range: [ 544 | 0, 545 | 5 546 | ], 547 | loc: { 548 | start: { 549 | line: 1, 550 | column: 0 551 | }, 552 | end: { 553 | line: 1, 554 | column: 5 555 | } 556 | } 557 | }, 558 | closingElement: { 559 | type: "JSXClosingElement", 560 | name: { 561 | type: "JSXIdentifier", 562 | name: "日本語", 563 | range: [ 564 | 7, 565 | 10 566 | ], 567 | loc: { 568 | start: { 569 | line: 1, 570 | column: 7 571 | }, 572 | end: { 573 | line: 1, 574 | column: 10 575 | } 576 | } 577 | }, 578 | range: [ 579 | 5, 580 | 11 581 | ], 582 | loc: { 583 | start: { 584 | line: 1, 585 | column: 5 586 | }, 587 | end: { 588 | line: 1, 589 | column: 11 590 | } 591 | } 592 | }, 593 | children: [], 594 | range: [ 595 | 0, 596 | 11 597 | ], 598 | loc: { 599 | start: { 600 | line: 1, 601 | column: 0 602 | }, 603 | end: { 604 | line: 1, 605 | column: 11 606 | } 607 | } 608 | }, 609 | range: [ 610 | 0, 611 | 11 612 | ], 613 | loc: { 614 | start: { 615 | line: 1, 616 | column: 0 617 | }, 618 | end: { 619 | line: 1, 620 | column: 11 621 | } 622 | } 623 | }, 624 | 625 | '\nbar\nbaz\n': { 626 | type: "ExpressionStatement", 627 | expression: { 628 | type: "JSXElement", 629 | openingElement: { 630 | type: "JSXOpeningElement", 631 | name: { 632 | type: "JSXIdentifier", 633 | name: "AbC-def", 634 | range: [ 635 | 1, 636 | 8 637 | ], 638 | loc: { 639 | start: { 640 | line: 1, 641 | column: 1 642 | }, 643 | end: { 644 | line: 1, 645 | column: 8 646 | } 647 | } 648 | }, 649 | selfClosing: false, 650 | attributes: [ 651 | { 652 | type: "JSXAttribute", 653 | name: { 654 | type: "JSXIdentifier", 655 | name: "test", 656 | range: [ 657 | 11, 658 | 15 659 | ], 660 | loc: { 661 | start: { 662 | line: 2, 663 | column: 2 664 | }, 665 | end: { 666 | line: 2, 667 | column: 6 668 | } 669 | } 670 | }, 671 | value: { 672 | type: "Literal", 673 | value: "&&", 674 | raw: "\"&&\"", 675 | range: [ 676 | 16, 677 | 31 678 | ], 679 | loc: { 680 | start: { 681 | line: 2, 682 | column: 7 683 | }, 684 | end: { 685 | line: 2, 686 | column: 22 687 | } 688 | } 689 | }, 690 | range: [ 691 | 11, 692 | 31 693 | ], 694 | loc: { 695 | start: { 696 | line: 2, 697 | column: 2 698 | }, 699 | end: { 700 | line: 2, 701 | column: 22 702 | } 703 | } 704 | } 705 | ], 706 | range: [ 707 | 0, 708 | 32 709 | ], 710 | loc: { 711 | start: { 712 | line: 1, 713 | column: 0 714 | }, 715 | end: { 716 | line: 2, 717 | column: 23 718 | } 719 | } 720 | }, 721 | closingElement: { 722 | type: "JSXClosingElement", 723 | name: { 724 | type: "JSXIdentifier", 725 | name: "AbC-def", 726 | range: [ 727 | 43, 728 | 50 729 | ], 730 | loc: { 731 | start: { 732 | line: 5, 733 | column: 2 734 | }, 735 | end: { 736 | line: 5, 737 | column: 9 738 | } 739 | } 740 | }, 741 | range: [ 742 | 41, 743 | 51 744 | ], 745 | loc: { 746 | start: { 747 | line: 5, 748 | column: 0 749 | }, 750 | end: { 751 | line: 5, 752 | column: 10 753 | } 754 | } 755 | }, 756 | children: [ 757 | { 758 | type: "JSXText", 759 | value: "\nbar\nbaz\n", 760 | raw: "\nbar\nbaz\n", 761 | range: [ 762 | 32, 763 | 41 764 | ], 765 | loc: { 766 | start: { 767 | line: 2, 768 | column: 23 769 | }, 770 | end: { 771 | line: 5, 772 | column: 0 773 | } 774 | } 775 | } 776 | ], 777 | range: [ 778 | 0, 779 | 51 780 | ], 781 | loc: { 782 | start: { 783 | line: 1, 784 | column: 0 785 | }, 786 | end: { 787 | line: 5, 788 | column: 10 789 | } 790 | } 791 | }, 792 | range: [ 793 | 0, 794 | 51 795 | ], 796 | loc: { 797 | start: { 798 | line: 1, 799 | column: 0 800 | }, 801 | end: { 802 | line: 5, 803 | column: 10 804 | } 805 | } 806 | }, 807 | 808 | ' : } />': { 809 | type: "ExpressionStatement", 810 | expression: { 811 | type: "JSXElement", 812 | openingElement: { 813 | type: "JSXOpeningElement", 814 | name: { 815 | type: "JSXIdentifier", 816 | name: "a", 817 | range: [ 818 | 1, 819 | 2 820 | ], 821 | loc: { 822 | start: { 823 | line: 1, 824 | column: 1 825 | }, 826 | end: { 827 | line: 1, 828 | column: 2 829 | } 830 | } 831 | }, 832 | selfClosing: true, 833 | attributes: [ 834 | { 835 | type: "JSXAttribute", 836 | name: { 837 | type: "JSXIdentifier", 838 | name: "b", 839 | range: [ 840 | 3, 841 | 4 842 | ], 843 | loc: { 844 | start: { 845 | line: 1, 846 | column: 3 847 | }, 848 | end: { 849 | line: 1, 850 | column: 4 851 | } 852 | } 853 | }, 854 | value: { 855 | type: "JSXExpressionContainer", 856 | expression: { 857 | type: "ConditionalExpression", 858 | test: { 859 | type: "Identifier", 860 | name: "x", 861 | range: [ 862 | 6, 863 | 7 864 | ], 865 | loc: { 866 | start: { 867 | line: 1, 868 | column: 6 869 | }, 870 | end: { 871 | line: 1, 872 | column: 7 873 | } 874 | } 875 | }, 876 | consequent: { 877 | type: "JSXElement", 878 | openingElement: { 879 | type: "JSXOpeningElement", 880 | name: { 881 | type: "JSXIdentifier", 882 | name: "c", 883 | range: [ 884 | 11, 885 | 12 886 | ], 887 | loc: { 888 | start: { 889 | line: 1, 890 | column: 11 891 | }, 892 | end: { 893 | line: 1, 894 | column: 12 895 | } 896 | } 897 | }, 898 | selfClosing: true, 899 | attributes: [], 900 | range: [ 901 | 10, 902 | 15 903 | ], 904 | loc: { 905 | start: { 906 | line: 1, 907 | column: 10 908 | }, 909 | end: { 910 | line: 1, 911 | column: 15 912 | } 913 | } 914 | }, 915 | closingElement: null, 916 | children: [], 917 | range: [ 918 | 10, 919 | 15 920 | ], 921 | loc: { 922 | start: { 923 | line: 1, 924 | column: 10 925 | }, 926 | end: { 927 | line: 1, 928 | column: 15 929 | } 930 | } 931 | }, 932 | alternate: { 933 | type: "JSXElement", 934 | openingElement: { 935 | type: "JSXOpeningElement", 936 | name: { 937 | type: "JSXIdentifier", 938 | name: "d", 939 | range: [ 940 | 19, 941 | 20 942 | ], 943 | loc: { 944 | start: { 945 | line: 1, 946 | column: 19 947 | }, 948 | end: { 949 | line: 1, 950 | column: 20 951 | } 952 | } 953 | }, 954 | selfClosing: true, 955 | attributes: [], 956 | range: [ 957 | 18, 958 | 23 959 | ], 960 | loc: { 961 | start: { 962 | line: 1, 963 | column: 18 964 | }, 965 | end: { 966 | line: 1, 967 | column: 23 968 | } 969 | } 970 | }, 971 | closingElement: null, 972 | children: [], 973 | range: [ 974 | 18, 975 | 23 976 | ], 977 | loc: { 978 | start: { 979 | line: 1, 980 | column: 18 981 | }, 982 | end: { 983 | line: 1, 984 | column: 23 985 | } 986 | } 987 | }, 988 | range: [ 989 | 6, 990 | 23 991 | ], 992 | loc: { 993 | start: { 994 | line: 1, 995 | column: 6 996 | }, 997 | end: { 998 | line: 1, 999 | column: 23 1000 | } 1001 | } 1002 | }, 1003 | range: [ 1004 | 5, 1005 | 24 1006 | ], 1007 | loc: { 1008 | start: { 1009 | line: 1, 1010 | column: 5 1011 | }, 1012 | end: { 1013 | line: 1, 1014 | column: 24 1015 | } 1016 | } 1017 | }, 1018 | range: [ 1019 | 3, 1020 | 24 1021 | ], 1022 | loc: { 1023 | start: { 1024 | line: 1, 1025 | column: 3 1026 | }, 1027 | end: { 1028 | line: 1, 1029 | column: 24 1030 | } 1031 | } 1032 | } 1033 | ], 1034 | range: [ 1035 | 0, 1036 | 27 1037 | ], 1038 | loc: { 1039 | start: { 1040 | line: 1, 1041 | column: 0 1042 | }, 1043 | end: { 1044 | line: 1, 1045 | column: 27 1046 | } 1047 | } 1048 | }, 1049 | closingElement: null, 1050 | children: [], 1051 | range: [ 1052 | 0, 1053 | 27 1054 | ], 1055 | loc: { 1056 | start: { 1057 | line: 1, 1058 | column: 0 1059 | }, 1060 | end: { 1061 | line: 1, 1062 | column: 27 1063 | } 1064 | } 1065 | }, 1066 | range: [ 1067 | 0, 1068 | 27 1069 | ], 1070 | loc: { 1071 | start: { 1072 | line: 1, 1073 | column: 0 1074 | }, 1075 | end: { 1076 | line: 1, 1077 | column: 27 1078 | } 1079 | } 1080 | }, 1081 | 1082 | '{}': { 1083 | type: 'ExpressionStatement', 1084 | expression: { 1085 | type: 'JSXElement', 1086 | openingElement: { 1087 | type: 'JSXOpeningElement', 1088 | name: { 1089 | type: 'JSXIdentifier', 1090 | name: 'a', 1091 | range: [1, 2], 1092 | loc: { 1093 | start: { line: 1, column: 1 }, 1094 | end: { line: 1, column: 2 } 1095 | } 1096 | }, 1097 | selfClosing: false, 1098 | attributes: [], 1099 | range: [0, 3], 1100 | loc: { 1101 | start: { line: 1, column: 0 }, 1102 | end: { line: 1, column: 3 } 1103 | } 1104 | }, 1105 | closingElement: { 1106 | type: 'JSXClosingElement', 1107 | name: { 1108 | type: 'JSXIdentifier', 1109 | name: 'a', 1110 | range: [7, 8], 1111 | loc: { 1112 | start: { line: 1, column: 7 }, 1113 | end: { line: 1, column: 8 } 1114 | } 1115 | }, 1116 | range: [5, 9], 1117 | loc: { 1118 | start: { line: 1, column: 5 }, 1119 | end: { line: 1, column: 9 } 1120 | } 1121 | }, 1122 | children: [{ 1123 | type: 'JSXExpressionContainer', 1124 | expression: { 1125 | type: 'JSXEmptyExpression', 1126 | range: [4, 4], 1127 | loc: { 1128 | start: { line: 1, column: 4 }, 1129 | end: { line: 1, column: 4 } 1130 | } 1131 | }, 1132 | range: [3, 5], 1133 | loc: { 1134 | start: { line: 1, column: 3 }, 1135 | end: { line: 1, column: 5 } 1136 | } 1137 | }], 1138 | range: [0, 9], 1139 | loc: { 1140 | start: { line: 1, column: 0 }, 1141 | end: { line: 1, column: 9 } 1142 | } 1143 | }, 1144 | range: [0, 9], 1145 | loc: { 1146 | start: { line: 1, column: 0 }, 1147 | end: { line: 1, column: 9 } 1148 | } 1149 | }, 1150 | 1151 | '{/* this is a comment */}': { 1152 | type: 'ExpressionStatement', 1153 | expression: { 1154 | type: 'JSXElement', 1155 | openingElement: { 1156 | type: 'JSXOpeningElement', 1157 | name: { 1158 | type: 'JSXIdentifier', 1159 | name: 'a', 1160 | range: [1, 2], 1161 | loc: { 1162 | start: { line: 1, column: 1 }, 1163 | end: { line: 1, column: 2 } 1164 | } 1165 | }, 1166 | selfClosing: false, 1167 | attributes: [], 1168 | range: [0, 3], 1169 | loc: { 1170 | start: { line: 1, column: 0 }, 1171 | end: { line: 1, column: 3 } 1172 | } 1173 | }, 1174 | closingElement: { 1175 | type: 'JSXClosingElement', 1176 | name: { 1177 | type: 'JSXIdentifier', 1178 | name: 'a', 1179 | range: [30, 31], 1180 | loc: { 1181 | start: { line: 1, column: 30 }, 1182 | end: { line: 1, column: 31 } 1183 | } 1184 | }, 1185 | range: [28, 32], 1186 | loc: { 1187 | start: { line: 1, column: 28 }, 1188 | end: { line: 1, column: 32 } 1189 | } 1190 | }, 1191 | children: [{ 1192 | type: 'JSXExpressionContainer', 1193 | expression: { 1194 | type: 'JSXEmptyExpression', 1195 | range: [4, 27], 1196 | loc: { 1197 | start: { line: 1, column: 4 }, 1198 | end: { line: 1, column: 27 } 1199 | } 1200 | }, 1201 | range: [3, 28], 1202 | loc: { 1203 | start: { line: 1, column: 3 }, 1204 | end: { line: 1, column: 28 } 1205 | } 1206 | }], 1207 | range: [0, 32], 1208 | loc: { 1209 | start: { line: 1, column: 0 }, 1210 | end: { line: 1, column: 32 } 1211 | } 1212 | }, 1213 | range: [0, 32], 1214 | loc: { 1215 | start: { line: 1, column: 0 }, 1216 | end: { line: 1, column: 32 } 1217 | } 1218 | }, 1219 | 1220 | '
@test content
': { 1221 | type: 'ExpressionStatement', 1222 | expression: { 1223 | type: 'JSXElement', 1224 | openingElement: { 1225 | type: 'JSXOpeningElement', 1226 | name: { 1227 | type: 'JSXIdentifier', 1228 | name: 'div', 1229 | range: [1, 4], 1230 | loc: { 1231 | start: { line: 1, column: 1 }, 1232 | end: { line: 1, column: 4 } 1233 | } 1234 | }, 1235 | selfClosing: false, 1236 | attributes: [], 1237 | range: [0, 5], 1238 | loc: { 1239 | start: { line: 1, column: 0 }, 1240 | end: { line: 1, column: 5 } 1241 | } 1242 | }, 1243 | closingElement: { 1244 | type: 'JSXClosingElement', 1245 | name: { 1246 | type: 'JSXIdentifier', 1247 | name: 'div', 1248 | range: [20, 23], 1249 | loc: { 1250 | start: { line: 1, column: 20 }, 1251 | end: { line: 1, column: 23 } 1252 | } 1253 | }, 1254 | range: [18, 24], 1255 | loc: { 1256 | start: { line: 1, column: 18 }, 1257 | end: { line: 1, column: 24 } 1258 | } 1259 | }, 1260 | children: [{ 1261 | type: 'JSXText', 1262 | value: '@test content', 1263 | raw: '@test content', 1264 | range: [5, 18], 1265 | loc: { 1266 | start: { line: 1, column: 5 }, 1267 | end: { line: 1, column: 18 } 1268 | } 1269 | }], 1270 | range: [0, 24], 1271 | loc: { 1272 | start: { line: 1, column: 0 }, 1273 | end: { line: 1, column: 24 } 1274 | } 1275 | }, 1276 | range: [0, 24], 1277 | loc: { 1278 | start: { line: 1, column: 0 }, 1279 | end: { line: 1, column: 24 } 1280 | } 1281 | }, 1282 | 1283 | '

7x invalid-js-identifier
': { 1284 | type: 'ExpressionStatement', 1285 | expression: { 1286 | type: 'JSXElement', 1287 | openingElement: { 1288 | type: 'JSXOpeningElement', 1289 | name: { 1290 | type: 'JSXIdentifier', 1291 | name: 'div', 1292 | range: [ 1293 | 1, 1294 | 4 1295 | ], 1296 | loc: { 1297 | start: { 1298 | line: 1, 1299 | column: 1 1300 | }, 1301 | end: { 1302 | line: 1, 1303 | column: 4 1304 | } 1305 | } 1306 | }, 1307 | selfClosing: false, 1308 | attributes: [], 1309 | range: [ 1310 | 0, 1311 | 5 1312 | ], 1313 | loc: { 1314 | start: { 1315 | line: 1, 1316 | column: 0 1317 | }, 1318 | end: { 1319 | line: 1, 1320 | column: 5 1321 | } 1322 | } 1323 | }, 1324 | closingElement: { 1325 | type: 'JSXClosingElement', 1326 | name: { 1327 | type: 'JSXIdentifier', 1328 | name: 'div', 1329 | range: [ 1330 | 37, 1331 | 40 1332 | ], 1333 | loc: { 1334 | start: { 1335 | line: 1, 1336 | column: 37 1337 | }, 1338 | end: { 1339 | line: 1, 1340 | column: 40 1341 | } 1342 | } 1343 | }, 1344 | range: [ 1345 | 35, 1346 | 41 1347 | ], 1348 | loc: { 1349 | start: { 1350 | line: 1, 1351 | column: 35 1352 | }, 1353 | end: { 1354 | line: 1, 1355 | column: 41 1356 | } 1357 | } 1358 | }, 1359 | children: [{ 1360 | type: 'JSXElement', 1361 | openingElement: { 1362 | type: 'JSXOpeningElement', 1363 | name: { 1364 | type: 'JSXIdentifier', 1365 | name: 'br', 1366 | range: [ 1367 | 6, 1368 | 8 1369 | ], 1370 | loc: { 1371 | start: { 1372 | line: 1, 1373 | column: 6 1374 | }, 1375 | end: { 1376 | line: 1, 1377 | column: 8 1378 | } 1379 | } 1380 | }, 1381 | selfClosing: true, 1382 | attributes: [], 1383 | range: [ 1384 | 5, 1385 | 11 1386 | ], 1387 | loc: { 1388 | start: { 1389 | line: 1, 1390 | column: 5 1391 | }, 1392 | end: { 1393 | line: 1, 1394 | column: 11 1395 | } 1396 | } 1397 | }, 1398 | closingElement: null, 1399 | children: [], 1400 | range: [ 1401 | 5, 1402 | 11 1403 | ], 1404 | loc: { 1405 | start: { 1406 | line: 1, 1407 | column: 5 1408 | }, 1409 | end: { 1410 | line: 1, 1411 | column: 11 1412 | } 1413 | } 1414 | }, { 1415 | type: 'JSXText', 1416 | value: '7x invalid-js-identifier', 1417 | raw: '7x invalid-js-identifier', 1418 | range: [ 1419 | 11, 1420 | 35 1421 | ], 1422 | loc: { 1423 | start: { 1424 | line: 1, 1425 | column: 11 1426 | }, 1427 | end: { 1428 | line: 1, 1429 | column: 35 1430 | } 1431 | } 1432 | }], 1433 | range: [ 1434 | 0, 1435 | 41 1436 | ], 1437 | loc: { 1438 | start: { 1439 | line: 1, 1440 | column: 0 1441 | }, 1442 | end: { 1443 | line: 1, 1444 | column: 41 1445 | } 1446 | } 1447 | }, 1448 | range: [ 1449 | 0, 1450 | 41 1451 | ], 1452 | loc: { 1453 | start: { 1454 | line: 1, 1455 | column: 0 1456 | }, 1457 | end: { 1458 | line: 1, 1459 | column: 41 1460 | } 1461 | } 1462 | }, 1463 | 1464 | ' right=monkeys /{">"} gorillas />': { 1465 | "type": "ExpressionStatement", 1466 | "start": 0, 1467 | "end": 61, 1468 | "expression": { 1469 | "type": "JSXElement", 1470 | "start": 0, 1471 | "end": 61, 1472 | "openingElement": { 1473 | "type": "JSXOpeningElement", 1474 | "start": 0, 1475 | "end": 61, 1476 | "attributes": [ 1477 | { 1478 | "type": "JSXAttribute", 1479 | "start": 11, 1480 | "end": 21, 1481 | "name": { 1482 | "type": "JSXIdentifier", 1483 | "start": 11, 1484 | "end": 15, 1485 | "name": "left" 1486 | }, 1487 | "value": { 1488 | "type": "JSXElement", 1489 | "start": 16, 1490 | "end": 21, 1491 | "openingElement": { 1492 | "type": "JSXOpeningElement", 1493 | "start": 16, 1494 | "end": 21, 1495 | "attributes": [], 1496 | "name": { 1497 | "type": "JSXIdentifier", 1498 | "start": 17, 1499 | "end": 18, 1500 | "name": "a" 1501 | }, 1502 | "selfClosing": true 1503 | }, 1504 | "closingElement": null, 1505 | "children": [] 1506 | } 1507 | }, 1508 | { 1509 | "type": "JSXAttribute", 1510 | "start": 22, 1511 | "end": 58, 1512 | "name": { 1513 | "type": "JSXIdentifier", 1514 | "start": 22, 1515 | "end": 27, 1516 | "name": "right" 1517 | }, 1518 | "value": { 1519 | "type": "JSXElement", 1520 | "start": 28, 1521 | "end": 58, 1522 | "openingElement": { 1523 | "type": "JSXOpeningElement", 1524 | "start": 28, 1525 | "end": 31, 1526 | "attributes": [], 1527 | "name": { 1528 | "type": "JSXIdentifier", 1529 | "start": 29, 1530 | "end": 30, 1531 | "name": "b" 1532 | }, 1533 | "selfClosing": false 1534 | }, 1535 | "closingElement": { 1536 | "type": "JSXClosingElement", 1537 | "start": 54, 1538 | "end": 58, 1539 | "name": { 1540 | "type": "JSXIdentifier", 1541 | "start": 56, 1542 | "end": 57, 1543 | "name": "b" 1544 | } 1545 | }, 1546 | "children": [ 1547 | { 1548 | "type": "JSXText", 1549 | "start": 31, 1550 | "end": 40, 1551 | "value": "monkeys /", 1552 | "raw": "monkeys /" 1553 | }, 1554 | { 1555 | "type": "JSXExpressionContainer", 1556 | "start": 40, 1557 | "end": 45, 1558 | "expression": { 1559 | "type": "Literal", 1560 | "start": 41, 1561 | "end": 44, 1562 | "value": ">", 1563 | "raw": "\">\"" 1564 | } 1565 | }, 1566 | { 1567 | "type": "JSXText", 1568 | "start": 45, 1569 | "end": 54, 1570 | "value": " gorillas", 1571 | "raw": " gorillas" 1572 | } 1573 | ] 1574 | } 1575 | } 1576 | ], 1577 | "name": { 1578 | "type": "JSXIdentifier", 1579 | "start": 1, 1580 | "end": 10, 1581 | "name": "LeftRight" 1582 | }, 1583 | "selfClosing": true 1584 | }, 1585 | "closingElement": null, 1586 | "children": [] 1587 | } 1588 | }, 1589 | 1590 | ' right=monkeys /> gorillas />': { 1591 | "type": "ExpressionStatement", 1592 | "start": 0, 1593 | "end": 60, 1594 | "expression": { 1595 | "type": "JSXElement", 1596 | "start": 0, 1597 | "end": 60, 1598 | "openingElement": { 1599 | "type": "JSXOpeningElement", 1600 | "start": 0, 1601 | "end": 60, 1602 | "attributes": [ 1603 | { 1604 | "type": "JSXAttribute", 1605 | "start": 11, 1606 | "end": 21, 1607 | "name": { 1608 | "type": "JSXIdentifier", 1609 | "start": 11, 1610 | "end": 15, 1611 | "name": "left" 1612 | }, 1613 | "value": { 1614 | "type": "JSXElement", 1615 | "start": 16, 1616 | "end": 21, 1617 | "openingElement": { 1618 | "type": "JSXOpeningElement", 1619 | "start": 16, 1620 | "end": 21, 1621 | "attributes": [], 1622 | "name": { 1623 | "type": "JSXIdentifier", 1624 | "start": 17, 1625 | "end": 18, 1626 | "name": "a" 1627 | }, 1628 | "selfClosing": true 1629 | }, 1630 | "closingElement": null, 1631 | "children": [] 1632 | } 1633 | }, 1634 | { 1635 | "type": "JSXAttribute", 1636 | "start": 22, 1637 | "end": 57, 1638 | "name": { 1639 | "type": "JSXIdentifier", 1640 | "start": 22, 1641 | "end": 27, 1642 | "name": "right" 1643 | }, 1644 | "value": { 1645 | "type": "JSXElement", 1646 | "start": 28, 1647 | "end": 57, 1648 | "openingElement": { 1649 | "type": "JSXOpeningElement", 1650 | "start": 28, 1651 | "end": 31, 1652 | "attributes": [], 1653 | "name": { 1654 | "type": "JSXIdentifier", 1655 | "start": 29, 1656 | "end": 30, 1657 | "name": "b" 1658 | }, 1659 | "selfClosing": false 1660 | }, 1661 | "closingElement": { 1662 | "type": "JSXClosingElement", 1663 | "start": 53, 1664 | "end": 57, 1665 | "name": { 1666 | "type": "JSXIdentifier", 1667 | "start": 55, 1668 | "end": 56, 1669 | "name": "b" 1670 | } 1671 | }, 1672 | "children": [ 1673 | { 1674 | "type": "JSXText", 1675 | "start": 31, 1676 | "end": 53, 1677 | "value": "monkeys /> gorillas", 1678 | "raw": "monkeys /> gorillas" 1679 | } 1680 | ] 1681 | } 1682 | } 1683 | ], 1684 | "name": { 1685 | "type": "JSXIdentifier", 1686 | "start": 1, 1687 | "end": 10, 1688 | "name": "LeftRight" 1689 | }, 1690 | "selfClosing": true 1691 | }, 1692 | "closingElement": null, 1693 | "children": [] 1694 | } 1695 | }, 1696 | 1697 | '': { 1698 | type: 'ExpressionStatement', 1699 | expression: { 1700 | type: 'JSXElement', 1701 | openingElement: { 1702 | type: 'JSXOpeningElement', 1703 | name: { 1704 | type: 'JSXMemberExpression', 1705 | object: { 1706 | type: 'JSXIdentifier', 1707 | name: 'a', 1708 | range: [1, 2], 1709 | loc: { 1710 | start: { line: 1, column: 1 }, 1711 | end: { line: 1, column: 2 } 1712 | } 1713 | }, 1714 | property: { 1715 | type: 'JSXIdentifier', 1716 | name: 'b', 1717 | range: [3, 4], 1718 | loc: { 1719 | start: { line: 1, column: 3 }, 1720 | end: { line: 1, column: 4 } 1721 | } 1722 | }, 1723 | range: [1, 4], 1724 | loc: { 1725 | start: { line: 1, column: 1 }, 1726 | end: { line: 1, column: 4 } 1727 | } 1728 | }, 1729 | selfClosing: false, 1730 | attributes: [], 1731 | range: [0, 5], 1732 | loc: { 1733 | start: { line: 1, column: 0 }, 1734 | end: { line: 1, column: 5 } 1735 | } 1736 | }, 1737 | closingElement: { 1738 | type: 'JSXClosingElement', 1739 | name: { 1740 | type: 'JSXMemberExpression', 1741 | object: { 1742 | type: 'JSXIdentifier', 1743 | name: 'a', 1744 | range: [7, 8], 1745 | loc: { 1746 | start: { line: 1, column: 7 }, 1747 | end: { line: 1, column: 8 } 1748 | } 1749 | }, 1750 | property: { 1751 | type: 'JSXIdentifier', 1752 | name: 'b', 1753 | range: [9, 10], 1754 | loc: { 1755 | start: { line: 1, column: 9 }, 1756 | end: { line: 1, column: 10 } 1757 | } 1758 | }, 1759 | range: [7, 10], 1760 | loc: { 1761 | start: { line: 1, column: 7 }, 1762 | end: { line: 1, column: 10 } 1763 | } 1764 | }, 1765 | range: [5, 11], 1766 | loc: { 1767 | start: { line: 1, column: 5 }, 1768 | end: { line: 1, column: 11 } 1769 | } 1770 | }, 1771 | children: [], 1772 | range: [0, 11], 1773 | loc: { 1774 | start: { line: 1, column: 0 }, 1775 | end: { line: 1, column: 11 } 1776 | } 1777 | }, 1778 | range: [0, 11], 1779 | loc: { 1780 | start: { line: 1, column: 0 }, 1781 | end: { line: 1, column: 11 } 1782 | } 1783 | }, 1784 | 1785 | '': { 1786 | type: 'ExpressionStatement', 1787 | expression: { 1788 | type: 'JSXElement', 1789 | openingElement: { 1790 | type: 'JSXOpeningElement', 1791 | name: { 1792 | type: 'JSXMemberExpression', 1793 | object: { 1794 | type: 'JSXMemberExpression', 1795 | object: { 1796 | type: 'JSXIdentifier', 1797 | name: 'a', 1798 | range: [1, 2], 1799 | loc: { 1800 | start: { line: 1, column: 1 }, 1801 | end: { line: 1, column: 2 } 1802 | } 1803 | }, 1804 | property: { 1805 | type: 'JSXIdentifier', 1806 | name: 'b', 1807 | range: [3, 4], 1808 | loc: { 1809 | start: { line: 1, column: 3 }, 1810 | end: { line: 1, column: 4 } 1811 | } 1812 | }, 1813 | range: [1, 4], 1814 | loc: { 1815 | start: { line: 1, column: 1 }, 1816 | end: { line: 1, column: 4 } 1817 | } 1818 | }, 1819 | property: { 1820 | type: 'JSXIdentifier', 1821 | name: 'c', 1822 | range: [5, 6], 1823 | loc: { 1824 | start: { line: 1, column: 5 }, 1825 | end: { line: 1, column: 6 } 1826 | } 1827 | }, 1828 | range: [1, 6], 1829 | loc: { 1830 | start: { line: 1, column: 1 }, 1831 | end: { line: 1, column: 6 } 1832 | } 1833 | }, 1834 | selfClosing: false, 1835 | attributes: [], 1836 | range: [0, 7], 1837 | loc: { 1838 | start: { line: 1, column: 0 }, 1839 | end: { line: 1, column: 7 } 1840 | } 1841 | }, 1842 | closingElement: { 1843 | type: 'JSXClosingElement', 1844 | name: { 1845 | type: 'JSXMemberExpression', 1846 | object: { 1847 | type: 'JSXMemberExpression', 1848 | object: { 1849 | type: 'JSXIdentifier', 1850 | name: 'a', 1851 | range: [9, 10], 1852 | loc: { 1853 | start: { line: 1, column: 9 }, 1854 | end: { line: 1, column: 10 } 1855 | } 1856 | }, 1857 | property: { 1858 | type: 'JSXIdentifier', 1859 | name: 'b', 1860 | range: [11, 12], 1861 | loc: { 1862 | start: { line: 1, column: 11 }, 1863 | end: { line: 1, column: 12 } 1864 | } 1865 | }, 1866 | range: [9, 12], 1867 | loc: { 1868 | start: { line: 1, column: 9 }, 1869 | end: { line: 1, column: 12 } 1870 | } 1871 | }, 1872 | property: { 1873 | type: 'JSXIdentifier', 1874 | name: 'c', 1875 | range: [13, 14], 1876 | loc: { 1877 | start: { line: 1, column: 13 }, 1878 | end: { line: 1, column: 14 } 1879 | } 1880 | }, 1881 | range: [9, 14], 1882 | loc: { 1883 | start: { line: 1, column: 9 }, 1884 | end: { line: 1, column: 14 } 1885 | } 1886 | }, 1887 | range: [7, 15], 1888 | loc: { 1889 | start: { line: 1, column: 7 }, 1890 | end: { line: 1, column: 15 } 1891 | } 1892 | }, 1893 | children: [], 1894 | range: [0, 15], 1895 | loc: { 1896 | start: { line: 1, column: 0 }, 1897 | end: { line: 1, column: 15 } 1898 | } 1899 | }, 1900 | range: [0, 15], 1901 | loc: { 1902 | start: { line: 1, column: 0 }, 1903 | end: { line: 1, column: 15 } 1904 | } 1905 | }, 1906 | 1907 | // In order to more useful parse errors, we disallow following an 1908 | // JSXElement by a less-than symbol. In the rare case that the binary 1909 | // operator was intended, the tag can be wrapped in parentheses: 1910 | '(
) < x;': { 1911 | type: 'ExpressionStatement', 1912 | expression: { 1913 | type: 'BinaryExpression', 1914 | operator: '<', 1915 | left: { 1916 | type: 'JSXElement', 1917 | openingElement: { 1918 | type: 'JSXOpeningElement', 1919 | name: { 1920 | type: 'JSXIdentifier', 1921 | name: 'div', 1922 | range: [2, 5], 1923 | loc: { 1924 | start: { line: 1, column: 2 }, 1925 | end: { line: 1, column: 5 } 1926 | } 1927 | }, 1928 | selfClosing: true, 1929 | attributes: [], 1930 | range: [1, 8], 1931 | loc: { 1932 | start: { line: 1, column: 1 }, 1933 | end: { line: 1, column: 8 } 1934 | } 1935 | }, 1936 | closingElement: null, 1937 | children: [], 1938 | range: [1, 8], 1939 | loc: { 1940 | start: { line: 1, column: 1 }, 1941 | end: { line: 1, column: 8 } 1942 | } 1943 | }, 1944 | right: { 1945 | type: 'Identifier', 1946 | name: 'x', 1947 | range: [12, 13], 1948 | loc: { 1949 | start: { line: 1, column: 12 }, 1950 | end: { line: 1, column: 13 } 1951 | } 1952 | }, 1953 | range: [0, 13], 1954 | loc: { 1955 | start: { line: 1, column: 0 }, 1956 | end: { line: 1, column: 13 } 1957 | } 1958 | }, 1959 | range: [0, 14], 1960 | loc: { 1961 | start: { line: 1, column: 0 }, 1962 | end: { line: 1, column: 14 } 1963 | } 1964 | }, 1965 | 1966 | '
': { 1967 | "type": "ExpressionStatement", 1968 | "expression": { 1969 | "type": "JSXElement", 1970 | "openingElement": { 1971 | "type": "JSXOpeningElement", 1972 | "name": { 1973 | "type": "JSXIdentifier", 1974 | "name": "div", 1975 | "range": [ 1976 | 1, 1977 | 4 1978 | ], 1979 | "loc": { 1980 | "start": { 1981 | "line": 1, 1982 | "column": 1 1983 | }, 1984 | "end": { 1985 | "line": 1, 1986 | "column": 4 1987 | } 1988 | } 1989 | }, 1990 | "selfClosing": true, 1991 | "attributes": [ 1992 | { 1993 | "type": "JSXSpreadAttribute", 1994 | "argument": { 1995 | "type": "Identifier", 1996 | "name": "props", 1997 | "range": [ 1998 | 9, 1999 | 14 2000 | ], 2001 | "loc": { 2002 | "start": { 2003 | "line": 1, 2004 | "column": 9 2005 | }, 2006 | "end": { 2007 | "line": 1, 2008 | "column": 14 2009 | } 2010 | } 2011 | }, 2012 | "range": [ 2013 | 5, 2014 | 15 2015 | ], 2016 | "loc": { 2017 | "start": { 2018 | "line": 1, 2019 | "column": 5 2020 | }, 2021 | "end": { 2022 | "line": 1, 2023 | "column": 15 2024 | } 2025 | } 2026 | } 2027 | ], 2028 | "range": [ 2029 | 0, 2030 | 18 2031 | ], 2032 | "loc": { 2033 | "start": { 2034 | "line": 1, 2035 | "column": 0 2036 | }, 2037 | "end": { 2038 | "line": 1, 2039 | "column": 18 2040 | } 2041 | } 2042 | }, 2043 | closingElement: null, 2044 | "children": [], 2045 | "range": [ 2046 | 0, 2047 | 18 2048 | ], 2049 | "loc": { 2050 | "start": { 2051 | "line": 1, 2052 | "column": 0 2053 | }, 2054 | "end": { 2055 | "line": 1, 2056 | "column": 18 2057 | } 2058 | } 2059 | }, 2060 | "range": [ 2061 | 0, 2062 | 18 2063 | ], 2064 | "loc": { 2065 | "start": { 2066 | "line": 1, 2067 | "column": 0 2068 | }, 2069 | "end": { 2070 | "line": 1, 2071 | "column": 18 2072 | } 2073 | } 2074 | }, 2075 | 2076 | '
': { 2077 | "type": "ExpressionStatement", 2078 | "expression": { 2079 | "type": "JSXElement", 2080 | "openingElement": { 2081 | "type": "JSXOpeningElement", 2082 | "name": { 2083 | "type": "JSXIdentifier", 2084 | "name": "div", 2085 | "range": [ 2086 | 1, 2087 | 4 2088 | ], 2089 | "loc": { 2090 | "start": { 2091 | "line": 1, 2092 | "column": 1 2093 | }, 2094 | "end": { 2095 | "line": 1, 2096 | "column": 4 2097 | } 2098 | } 2099 | }, 2100 | "selfClosing": true, 2101 | "attributes": [ 2102 | { 2103 | "type": "JSXSpreadAttribute", 2104 | "argument": { 2105 | "type": "Identifier", 2106 | "name": "props", 2107 | "range": [ 2108 | 9, 2109 | 14 2110 | ], 2111 | "loc": { 2112 | "start": { 2113 | "line": 1, 2114 | "column": 9 2115 | }, 2116 | "end": { 2117 | "line": 1, 2118 | "column": 14 2119 | } 2120 | } 2121 | }, 2122 | "range": [ 2123 | 5, 2124 | 15 2125 | ], 2126 | "loc": { 2127 | "start": { 2128 | "line": 1, 2129 | "column": 5 2130 | }, 2131 | "end": { 2132 | "line": 1, 2133 | "column": 15 2134 | } 2135 | } 2136 | }, 2137 | { 2138 | "type": "JSXAttribute", 2139 | "name": { 2140 | "type": "JSXIdentifier", 2141 | "name": "post", 2142 | "range": [ 2143 | 16, 2144 | 20 2145 | ], 2146 | "loc": { 2147 | "start": { 2148 | "line": 1, 2149 | "column": 16 2150 | }, 2151 | "end": { 2152 | "line": 1, 2153 | "column": 20 2154 | } 2155 | } 2156 | }, 2157 | "value": { 2158 | "type": "Literal", 2159 | "value": "attribute", 2160 | "raw": "\"attribute\"", 2161 | "range": [ 2162 | 21, 2163 | 32 2164 | ], 2165 | "loc": { 2166 | "start": { 2167 | "line": 1, 2168 | "column": 21 2169 | }, 2170 | "end": { 2171 | "line": 1, 2172 | "column": 32 2173 | } 2174 | } 2175 | }, 2176 | "range": [ 2177 | 16, 2178 | 32 2179 | ], 2180 | "loc": { 2181 | "start": { 2182 | "line": 1, 2183 | "column": 16 2184 | }, 2185 | "end": { 2186 | "line": 1, 2187 | "column": 32 2188 | } 2189 | } 2190 | } 2191 | ], 2192 | "range": [ 2193 | 0, 2194 | 35 2195 | ], 2196 | "loc": { 2197 | "start": { 2198 | "line": 1, 2199 | "column": 0 2200 | }, 2201 | "end": { 2202 | "line": 1, 2203 | "column": 35 2204 | } 2205 | } 2206 | }, 2207 | closingElement: null, 2208 | "children": [], 2209 | "range": [ 2210 | 0, 2211 | 35 2212 | ], 2213 | "loc": { 2214 | "start": { 2215 | "line": 1, 2216 | "column": 0 2217 | }, 2218 | "end": { 2219 | "line": 1, 2220 | "column": 35 2221 | } 2222 | } 2223 | }, 2224 | "range": [ 2225 | 0, 2226 | 35 2227 | ], 2228 | "loc": { 2229 | "start": { 2230 | "line": 1, 2231 | "column": 0 2232 | }, 2233 | "end": { 2234 | "line": 1, 2235 | "column": 35 2236 | } 2237 | } 2238 | }, 2239 | 2240 | '
': { 2241 | "type": "ExpressionStatement", 2242 | "expression": { 2243 | "type": "JSXElement", 2244 | "openingElement": { 2245 | "type": "JSXOpeningElement", 2246 | "name": { 2247 | "type": "JSXIdentifier", 2248 | "name": "div", 2249 | "range": [ 2250 | 1, 2251 | 4 2252 | ], 2253 | "loc": { 2254 | "start": { 2255 | "line": 1, 2256 | "column": 1 2257 | }, 2258 | "end": { 2259 | "line": 1, 2260 | "column": 4 2261 | } 2262 | } 2263 | }, 2264 | "selfClosing": false, 2265 | "attributes": [ 2266 | { 2267 | "type": "JSXAttribute", 2268 | "name": { 2269 | "type": "JSXIdentifier", 2270 | "name": "pre", 2271 | "range": [ 2272 | 5, 2273 | 8 2274 | ], 2275 | "loc": { 2276 | "start": { 2277 | "line": 1, 2278 | "column": 5 2279 | }, 2280 | "end": { 2281 | "line": 1, 2282 | "column": 8 2283 | } 2284 | } 2285 | }, 2286 | "value": { 2287 | "type": "Literal", 2288 | "value": "leading", 2289 | "raw": "\"leading\"", 2290 | "range": [ 2291 | 9, 2292 | 18 2293 | ], 2294 | "loc": { 2295 | "start": { 2296 | "line": 1, 2297 | "column": 9 2298 | }, 2299 | "end": { 2300 | "line": 1, 2301 | "column": 18 2302 | } 2303 | } 2304 | }, 2305 | "range": [ 2306 | 5, 2307 | 18 2308 | ], 2309 | "loc": { 2310 | "start": { 2311 | "line": 1, 2312 | "column": 5 2313 | }, 2314 | "end": { 2315 | "line": 1, 2316 | "column": 18 2317 | } 2318 | } 2319 | }, 2320 | { 2321 | "type": "JSXAttribute", 2322 | "name": { 2323 | "type": "JSXIdentifier", 2324 | "name": "pre2", 2325 | "range": [ 2326 | 19, 2327 | 23 2328 | ], 2329 | "loc": { 2330 | "start": { 2331 | "line": 1, 2332 | "column": 19 2333 | }, 2334 | "end": { 2335 | "line": 1, 2336 | "column": 23 2337 | } 2338 | } 2339 | }, 2340 | "value": { 2341 | "type": "Literal", 2342 | "value": "attribute", 2343 | "raw": "\"attribute\"", 2344 | "range": [ 2345 | 24, 2346 | 35 2347 | ], 2348 | "loc": { 2349 | "start": { 2350 | "line": 1, 2351 | "column": 24 2352 | }, 2353 | "end": { 2354 | "line": 1, 2355 | "column": 35 2356 | } 2357 | } 2358 | }, 2359 | "range": [ 2360 | 19, 2361 | 35 2362 | ], 2363 | "loc": { 2364 | "start": { 2365 | "line": 1, 2366 | "column": 19 2367 | }, 2368 | "end": { 2369 | "line": 1, 2370 | "column": 35 2371 | } 2372 | } 2373 | }, 2374 | { 2375 | "type": "JSXSpreadAttribute", 2376 | "argument": { 2377 | "type": "Identifier", 2378 | "name": "props", 2379 | "range": [ 2380 | 40, 2381 | 45 2382 | ], 2383 | "loc": { 2384 | "start": { 2385 | "line": 1, 2386 | "column": 40 2387 | }, 2388 | "end": { 2389 | "line": 1, 2390 | "column": 45 2391 | } 2392 | } 2393 | }, 2394 | "range": [ 2395 | 36, 2396 | 46 2397 | ], 2398 | "loc": { 2399 | "start": { 2400 | "line": 1, 2401 | "column": 36 2402 | }, 2403 | "end": { 2404 | "line": 1, 2405 | "column": 46 2406 | } 2407 | } 2408 | } 2409 | ], 2410 | "range": [ 2411 | 0, 2412 | 47 2413 | ], 2414 | "loc": { 2415 | "start": { 2416 | "line": 1, 2417 | "column": 0 2418 | }, 2419 | "end": { 2420 | "line": 1, 2421 | "column": 47 2422 | } 2423 | } 2424 | }, 2425 | "closingElement": { 2426 | "type": "JSXClosingElement", 2427 | "name": { 2428 | "type": "JSXIdentifier", 2429 | "name": "div", 2430 | "range": [ 2431 | 49, 2432 | 52 2433 | ], 2434 | "loc": { 2435 | "start": { 2436 | "line": 1, 2437 | "column": 49 2438 | }, 2439 | "end": { 2440 | "line": 1, 2441 | "column": 52 2442 | } 2443 | } 2444 | }, 2445 | "range": [ 2446 | 47, 2447 | 53 2448 | ], 2449 | "loc": { 2450 | "start": { 2451 | "line": 1, 2452 | "column": 47 2453 | }, 2454 | "end": { 2455 | "line": 1, 2456 | "column": 53 2457 | } 2458 | } 2459 | }, 2460 | "children": [], 2461 | "range": [ 2462 | 0, 2463 | 53 2464 | ], 2465 | "loc": { 2466 | "start": { 2467 | "line": 1, 2468 | "column": 0 2469 | }, 2470 | "end": { 2471 | "line": 1, 2472 | "column": 53 2473 | } 2474 | } 2475 | }, 2476 | "range": [ 2477 | 0, 2478 | 53 2479 | ], 2480 | "loc": { 2481 | "start": { 2482 | "line": 1, 2483 | "column": 0 2484 | }, 2485 | "end": { 2486 | "line": 1, 2487 | "column": 53 2488 | } 2489 | } 2490 | }, 2491 | 2492 | '
{aa.b}
': { 2493 | "type": "ExpressionStatement", 2494 | "start": 0, 2495 | "end": 52, 2496 | "loc": { 2497 | "start": { 2498 | "line": 1, 2499 | "column": 0 2500 | }, 2501 | "end": { 2502 | "line": 1, 2503 | "column": 52 2504 | } 2505 | }, 2506 | "range": [ 2507 | 0, 2508 | 52 2509 | ], 2510 | "expression": { 2511 | "type": "JSXElement", 2512 | "start": 0, 2513 | "end": 52, 2514 | "loc": { 2515 | "start": { 2516 | "line": 1, 2517 | "column": 0 2518 | }, 2519 | "end": { 2520 | "line": 1, 2521 | "column": 52 2522 | } 2523 | }, 2524 | "range": [ 2525 | 0, 2526 | 52 2527 | ], 2528 | "openingElement": { 2529 | "type": "JSXOpeningElement", 2530 | "start": 0, 2531 | "end": 31, 2532 | "loc": { 2533 | "start": { 2534 | "line": 1, 2535 | "column": 0 2536 | }, 2537 | "end": { 2538 | "line": 1, 2539 | "column": 31 2540 | } 2541 | }, 2542 | "range": [ 2543 | 0, 2544 | 31 2545 | ], 2546 | "attributes": [ 2547 | { 2548 | "type": "JSXAttribute", 2549 | "start": 3, 2550 | "end": 16, 2551 | "loc": { 2552 | "start": { 2553 | "line": 1, 2554 | "column": 3 2555 | }, 2556 | "end": { 2557 | "line": 1, 2558 | "column": 16 2559 | } 2560 | }, 2561 | "range": [ 2562 | 3, 2563 | 16 2564 | ], 2565 | "name": { 2566 | "type": "JSXIdentifier", 2567 | "start": 3, 2568 | "end": 5, 2569 | "loc": { 2570 | "start": { 2571 | "line": 1, 2572 | "column": 3 2573 | }, 2574 | "end": { 2575 | "line": 1, 2576 | "column": 5 2577 | } 2578 | }, 2579 | "range": [ 2580 | 3, 2581 | 5 2582 | ], 2583 | "name": "aa" 2584 | }, 2585 | "value": { 2586 | "type": "JSXExpressionContainer", 2587 | "start": 6, 2588 | "end": 16, 2589 | "loc": { 2590 | "start": { 2591 | "line": 1, 2592 | "column": 6 2593 | }, 2594 | "end": { 2595 | "line": 1, 2596 | "column": 16 2597 | } 2598 | }, 2599 | "range": [ 2600 | 6, 2601 | 16 2602 | ], 2603 | "expression": { 2604 | "type": "MemberExpression", 2605 | "start": 7, 2606 | "end": 15, 2607 | "loc": { 2608 | "start": { 2609 | "line": 1, 2610 | "column": 7 2611 | }, 2612 | "end": { 2613 | "line": 1, 2614 | "column": 15 2615 | } 2616 | }, 2617 | "range": [ 2618 | 7, 2619 | 15 2620 | ], 2621 | "object": { 2622 | "type": "MemberExpression", 2623 | "start": 7, 2624 | "end": 12, 2625 | "loc": { 2626 | "start": { 2627 | "line": 1, 2628 | "column": 7 2629 | }, 2630 | "end": { 2631 | "line": 1, 2632 | "column": 12 2633 | } 2634 | }, 2635 | "range": [ 2636 | 7, 2637 | 12 2638 | ], 2639 | "object": { 2640 | "type": "Identifier", 2641 | "start": 7, 2642 | "end": 9, 2643 | "loc": { 2644 | "start": { 2645 | "line": 1, 2646 | "column": 7 2647 | }, 2648 | "end": { 2649 | "line": 1, 2650 | "column": 9 2651 | } 2652 | }, 2653 | "range": [ 2654 | 7, 2655 | 9 2656 | ], 2657 | "name": "aa" 2658 | }, 2659 | "property": { 2660 | "type": "Identifier", 2661 | "start": 10, 2662 | "end": 12, 2663 | "loc": { 2664 | "start": { 2665 | "line": 1, 2666 | "column": 10 2667 | }, 2668 | "end": { 2669 | "line": 1, 2670 | "column": 12 2671 | } 2672 | }, 2673 | "range": [ 2674 | 10, 2675 | 12 2676 | ], 2677 | "name": "bb" 2678 | }, 2679 | "computed": false 2680 | }, 2681 | "property": { 2682 | "type": "Identifier", 2683 | "start": 13, 2684 | "end": 15, 2685 | "loc": { 2686 | "start": { 2687 | "line": 1, 2688 | "column": 13 2689 | }, 2690 | "end": { 2691 | "line": 1, 2692 | "column": 15 2693 | } 2694 | }, 2695 | "range": [ 2696 | 13, 2697 | 15 2698 | ], 2699 | "name": "cc" 2700 | }, 2701 | "computed": false 2702 | } 2703 | } 2704 | }, 2705 | { 2706 | "type": "JSXAttribute", 2707 | "start": 17, 2708 | "end": 30, 2709 | "loc": { 2710 | "start": { 2711 | "line": 1, 2712 | "column": 17 2713 | }, 2714 | "end": { 2715 | "line": 1, 2716 | "column": 30 2717 | } 2718 | }, 2719 | "range": [ 2720 | 17, 2721 | 30 2722 | ], 2723 | "name": { 2724 | "type": "JSXIdentifier", 2725 | "start": 17, 2726 | "end": 19, 2727 | "loc": { 2728 | "start": { 2729 | "line": 1, 2730 | "column": 17 2731 | }, 2732 | "end": { 2733 | "line": 1, 2734 | "column": 19 2735 | } 2736 | }, 2737 | "range": [ 2738 | 17, 2739 | 19 2740 | ], 2741 | "name": "bb" 2742 | }, 2743 | "value": { 2744 | "type": "JSXExpressionContainer", 2745 | "start": 20, 2746 | "end": 30, 2747 | "loc": { 2748 | "start": { 2749 | "line": 1, 2750 | "column": 20 2751 | }, 2752 | "end": { 2753 | "line": 1, 2754 | "column": 30 2755 | } 2756 | }, 2757 | "range": [ 2758 | 20, 2759 | 30 2760 | ], 2761 | "expression": { 2762 | "type": "MemberExpression", 2763 | "start": 21, 2764 | "end": 29, 2765 | "loc": { 2766 | "start": { 2767 | "line": 1, 2768 | "column": 21 2769 | }, 2770 | "end": { 2771 | "line": 1, 2772 | "column": 29 2773 | } 2774 | }, 2775 | "range": [ 2776 | 21, 2777 | 29 2778 | ], 2779 | "object": { 2780 | "type": "MemberExpression", 2781 | "start": 21, 2782 | "end": 26, 2783 | "loc": { 2784 | "start": { 2785 | "line": 1, 2786 | "column": 21 2787 | }, 2788 | "end": { 2789 | "line": 1, 2790 | "column": 26 2791 | } 2792 | }, 2793 | "range": [ 2794 | 21, 2795 | 26 2796 | ], 2797 | "object": { 2798 | "type": "Identifier", 2799 | "start": 21, 2800 | "end": 23, 2801 | "loc": { 2802 | "start": { 2803 | "line": 1, 2804 | "column": 21 2805 | }, 2806 | "end": { 2807 | "line": 1, 2808 | "column": 23 2809 | } 2810 | }, 2811 | "range": [ 2812 | 21, 2813 | 23 2814 | ], 2815 | "name": "bb" 2816 | }, 2817 | "property": { 2818 | "type": "Identifier", 2819 | "start": 24, 2820 | "end": 26, 2821 | "loc": { 2822 | "start": { 2823 | "line": 1, 2824 | "column": 24 2825 | }, 2826 | "end": { 2827 | "line": 1, 2828 | "column": 26 2829 | } 2830 | }, 2831 | "range": [ 2832 | 24, 2833 | 26 2834 | ], 2835 | "name": "cc" 2836 | }, 2837 | "computed": false 2838 | }, 2839 | "property": { 2840 | "type": "Identifier", 2841 | "start": 27, 2842 | "end": 29, 2843 | "loc": { 2844 | "start": { 2845 | "line": 1, 2846 | "column": 27 2847 | }, 2848 | "end": { 2849 | "line": 1, 2850 | "column": 29 2851 | } 2852 | }, 2853 | "range": [ 2854 | 27, 2855 | 29 2856 | ], 2857 | "name": "dd" 2858 | }, 2859 | "computed": false 2860 | } 2861 | } 2862 | } 2863 | ], 2864 | "name": { 2865 | "type": "JSXIdentifier", 2866 | "start": 1, 2867 | "end": 2, 2868 | "loc": { 2869 | "start": { 2870 | "line": 1, 2871 | "column": 1 2872 | }, 2873 | "end": { 2874 | "line": 1, 2875 | "column": 2 2876 | } 2877 | }, 2878 | "range": [ 2879 | 1, 2880 | 2 2881 | ], 2882 | "name": "A" 2883 | }, 2884 | "selfClosing": false 2885 | }, 2886 | "closingElement": { 2887 | "type": "JSXClosingElement", 2888 | "start": 48, 2889 | "end": 52, 2890 | "loc": { 2891 | "start": { 2892 | "line": 1, 2893 | "column": 48 2894 | }, 2895 | "end": { 2896 | "line": 1, 2897 | "column": 52 2898 | } 2899 | }, 2900 | "range": [ 2901 | 48, 2902 | 52 2903 | ], 2904 | "name": { 2905 | "type": "JSXIdentifier", 2906 | "start": 50, 2907 | "end": 51, 2908 | "loc": { 2909 | "start": { 2910 | "line": 1, 2911 | "column": 50 2912 | }, 2913 | "end": { 2914 | "line": 1, 2915 | "column": 51 2916 | } 2917 | }, 2918 | "range": [ 2919 | 50, 2920 | 51 2921 | ], 2922 | "name": "A" 2923 | } 2924 | }, 2925 | "children": [ 2926 | { 2927 | "type": "JSXElement", 2928 | "start": 31, 2929 | "end": 48, 2930 | "loc": { 2931 | "start": { 2932 | "line": 1, 2933 | "column": 31 2934 | }, 2935 | "end": { 2936 | "line": 1, 2937 | "column": 48 2938 | } 2939 | }, 2940 | "range": [ 2941 | 31, 2942 | 48 2943 | ], 2944 | "openingElement": { 2945 | "type": "JSXOpeningElement", 2946 | "start": 31, 2947 | "end": 36, 2948 | "loc": { 2949 | "start": { 2950 | "line": 1, 2951 | "column": 31 2952 | }, 2953 | "end": { 2954 | "line": 1, 2955 | "column": 36 2956 | } 2957 | }, 2958 | "range": [ 2959 | 31, 2960 | 36 2961 | ], 2962 | "attributes": [], 2963 | "name": { 2964 | "type": "JSXIdentifier", 2965 | "start": 32, 2966 | "end": 35, 2967 | "loc": { 2968 | "start": { 2969 | "line": 1, 2970 | "column": 32 2971 | }, 2972 | "end": { 2973 | "line": 1, 2974 | "column": 35 2975 | } 2976 | }, 2977 | "range": [ 2978 | 32, 2979 | 35 2980 | ], 2981 | "name": "div" 2982 | }, 2983 | "selfClosing": false 2984 | }, 2985 | "closingElement": { 2986 | "type": "JSXClosingElement", 2987 | "start": 42, 2988 | "end": 48, 2989 | "loc": { 2990 | "start": { 2991 | "line": 1, 2992 | "column": 42 2993 | }, 2994 | "end": { 2995 | "line": 1, 2996 | "column": 48 2997 | } 2998 | }, 2999 | "range": [ 3000 | 42, 3001 | 48 3002 | ], 3003 | "name": { 3004 | "type": "JSXIdentifier", 3005 | "start": 44, 3006 | "end": 47, 3007 | "loc": { 3008 | "start": { 3009 | "line": 1, 3010 | "column": 44 3011 | }, 3012 | "end": { 3013 | "line": 1, 3014 | "column": 47 3015 | } 3016 | }, 3017 | "range": [ 3018 | 44, 3019 | 47 3020 | ], 3021 | "name": "div" 3022 | } 3023 | }, 3024 | "children": [ 3025 | { 3026 | "type": "JSXExpressionContainer", 3027 | "start": 36, 3028 | "end": 42, 3029 | "loc": { 3030 | "start": { 3031 | "line": 1, 3032 | "column": 36 3033 | }, 3034 | "end": { 3035 | "line": 1, 3036 | "column": 42 3037 | } 3038 | }, 3039 | "range": [ 3040 | 36, 3041 | 42 3042 | ], 3043 | "expression": { 3044 | "type": "MemberExpression", 3045 | "start": 37, 3046 | "end": 41, 3047 | "loc": { 3048 | "start": { 3049 | "line": 1, 3050 | "column": 37 3051 | }, 3052 | "end": { 3053 | "line": 1, 3054 | "column": 41 3055 | } 3056 | }, 3057 | "range": [ 3058 | 37, 3059 | 41 3060 | ], 3061 | "object": { 3062 | "type": "Identifier", 3063 | "start": 37, 3064 | "end": 39, 3065 | "loc": { 3066 | "start": { 3067 | "line": 1, 3068 | "column": 37 3069 | }, 3070 | "end": { 3071 | "line": 1, 3072 | "column": 39 3073 | } 3074 | }, 3075 | "range": [ 3076 | 37, 3077 | 39 3078 | ], 3079 | "name": "aa" 3080 | }, 3081 | "property": { 3082 | "type": "Identifier", 3083 | "start": 40, 3084 | "end": 41, 3085 | "loc": { 3086 | "start": { 3087 | "line": 1, 3088 | "column": 40 3089 | }, 3090 | "end": { 3091 | "line": 1, 3092 | "column": 41 3093 | } 3094 | }, 3095 | "range": [ 3096 | 40, 3097 | 41 3098 | ], 3099 | "name": "b" 3100 | }, 3101 | "computed": false 3102 | } 3103 | } 3104 | ] 3105 | } 3106 | ] 3107 | } 3108 | }, 3109 | 3110 | '<>
': { 3111 | type: 'ExpressionStatement', 3112 | start: 0, 3113 | end: 16, 3114 | loc: { 3115 | start: { 3116 | line: 1, 3117 | column: 0 3118 | }, 3119 | end: { 3120 | line: 1, 3121 | column: 16 3122 | } 3123 | }, 3124 | range: [0, 16], 3125 | expression: { 3126 | type: 'JSXFragment', 3127 | start: 0, 3128 | end: 16, 3129 | loc: { 3130 | start: { 3131 | line: 1, 3132 | column: 0 3133 | }, 3134 | end: { 3135 | line: 1, 3136 | column: 16 3137 | } 3138 | }, 3139 | range: [0, 16], 3140 | openingFragment: { 3141 | type: 'JSXOpeningFragment', 3142 | start: 0, 3143 | end: 2, 3144 | loc: { 3145 | start: { 3146 | line: 1, 3147 | column: 0 3148 | }, 3149 | end: { 3150 | line: 1, 3151 | column: 2 3152 | } 3153 | }, 3154 | range: [0, 2], 3155 | attributes: [], 3156 | selfClosing: false 3157 | }, 3158 | closingFragment: { 3159 | type: 'JSXClosingFragment', 3160 | start: 13, 3161 | end: 16, 3162 | loc: { 3163 | start: { 3164 | line: 1, 3165 | column: 13 3166 | }, 3167 | end: { 3168 | line: 1, 3169 | column: 16 3170 | } 3171 | }, 3172 | range: [13, 16] 3173 | }, 3174 | children: [{ 3175 | type: 'JSXElement', 3176 | start: 2, 3177 | end: 13, 3178 | loc: { 3179 | start: { 3180 | line: 1, 3181 | column: 2 3182 | }, 3183 | end: { 3184 | line: 1, 3185 | column: 13 3186 | } 3187 | }, 3188 | range: [2, 13], 3189 | openingElement: { 3190 | type: 'JSXOpeningElement', 3191 | start: 2, 3192 | end: 7, 3193 | loc: { 3194 | start: { 3195 | line: 1, 3196 | column: 2 3197 | }, 3198 | end: { 3199 | line: 1, 3200 | column: 7 3201 | } 3202 | }, 3203 | range: [2, 7], 3204 | attributes: [], 3205 | name: { 3206 | type: 'JSXIdentifier', 3207 | start: 3, 3208 | end: 6, 3209 | loc: { 3210 | start: { 3211 | line: 1, 3212 | column: 3 3213 | }, 3214 | end: { 3215 | line: 1, 3216 | column: 6 3217 | } 3218 | }, 3219 | range: [3, 6], 3220 | name: 'div' 3221 | }, 3222 | selfClosing: false 3223 | }, 3224 | closingElement: { 3225 | type: 'JSXClosingElement', 3226 | start: 7, 3227 | end: 13, 3228 | loc: { 3229 | start: { 3230 | line: 1, 3231 | column: 7 3232 | }, 3233 | end: { 3234 | line: 1, 3235 | column: 13 3236 | } 3237 | }, 3238 | range: [7, 13], 3239 | name: { 3240 | type: 'JSXIdentifier', 3241 | start: 9, 3242 | end: 12, 3243 | loc: { 3244 | start: { 3245 | line: 1, 3246 | column: 9 3247 | }, 3248 | end: { 3249 | line: 1, 3250 | column: 12 3251 | } 3252 | }, 3253 | range: [9, 12], 3254 | name: 'div' 3255 | } 3256 | }, 3257 | children: [] 3258 | }] 3259 | } 3260 | } 3261 | }, 3262 | 'Regression': { 3263 | '

foo bar baz

;': { 3264 | type: "ExpressionStatement", 3265 | start: 0, 3266 | end: 40, 3267 | expression: { 3268 | type: "JSXElement", 3269 | start: 0, 3270 | end: 38, 3271 | openingElement: { 3272 | type: "JSXOpeningElement", 3273 | start: 0, 3274 | end: 3, 3275 | attributes: [], 3276 | name: { 3277 | type: "JSXIdentifier", 3278 | start: 1, 3279 | end: 2, 3280 | name: "p" 3281 | }, 3282 | selfClosing: false 3283 | }, 3284 | closingElement: { 3285 | type: "JSXClosingElement", 3286 | start: 34, 3287 | end: 38, 3288 | name: { 3289 | type: "JSXIdentifier", 3290 | start: 36, 3291 | end: 37, 3292 | name: "p" 3293 | } 3294 | }, 3295 | children: [ 3296 | { 3297 | type: "JSXText", 3298 | start: 3, 3299 | end: 7, 3300 | value: "foo ", 3301 | raw: "foo " 3302 | }, 3303 | { 3304 | type: "JSXElement", 3305 | start: 7, 3306 | end: 30, 3307 | openingElement: { 3308 | type: "JSXOpeningElement", 3309 | start: 7, 3310 | end: 22, 3311 | attributes: [{ 3312 | type: "JSXAttribute", 3313 | start: 10, 3314 | end: 21, 3315 | name: { 3316 | type: "JSXIdentifier", 3317 | start: 10, 3318 | end: 14, 3319 | name: "href" 3320 | }, 3321 | value: { 3322 | type: "Literal", 3323 | start: 15, 3324 | end: 21, 3325 | value: "test", 3326 | raw: "\"test\"" 3327 | } 3328 | }], 3329 | name: { 3330 | type: "JSXIdentifier", 3331 | start: 8, 3332 | end: 9, 3333 | name: "a" 3334 | }, 3335 | selfClosing: false 3336 | }, 3337 | closingElement: { 3338 | type: "JSXClosingElement", 3339 | start: 26, 3340 | end: 30, 3341 | name: { 3342 | type: "JSXIdentifier", 3343 | start: 28, 3344 | end: 29, 3345 | name: "a" 3346 | } 3347 | }, 3348 | children: [{ 3349 | type: "JSXText", 3350 | start: 22, 3351 | end: 26, 3352 | value: " bar", 3353 | raw: " bar" 3354 | }] 3355 | }, 3356 | { 3357 | type: "JSXText", 3358 | start: 30, 3359 | end: 34, 3360 | value: " baz", 3361 | raw: " baz" 3362 | } 3363 | ] 3364 | } 3365 | }, 3366 | 3367 | '
{
}
': { 3368 | type: 'ExpressionStatement', 3369 | start: 0, 3370 | end: 30, 3371 | expression: { 3372 | type: 'JSXElement', 3373 | start: 0, 3374 | end: 30, 3375 | openingElement: { 3376 | type: 'JSXOpeningElement', 3377 | start: 0, 3378 | end: 5, 3379 | attributes: [], 3380 | name: { 3381 | type: 'JSXIdentifier', 3382 | start: 1, 3383 | end: 4, 3384 | name: 'div' 3385 | }, 3386 | selfClosing: false 3387 | }, 3388 | closingElement: { 3389 | type: 'JSXClosingElement', 3390 | start: 24, 3391 | end: 30, 3392 | name: { 3393 | type: 'JSXIdentifier', 3394 | start: 26, 3395 | end: 29, 3396 | name: 'div' 3397 | } 3398 | }, 3399 | children: [{ 3400 | type: 'JSXExpressionContainer', 3401 | start: 5, 3402 | end: 24, 3403 | expression: { 3404 | type: 'JSXElement', 3405 | start: 6, 3406 | end: 23, 3407 | openingElement: { 3408 | type: 'JSXOpeningElement', 3409 | start: 6, 3410 | end: 23, 3411 | attributes: [ 3412 | { 3413 | type: 'JSXSpreadAttribute', 3414 | start: 11, 3415 | end: 20, 3416 | argument: { 3417 | type: 'Identifier', 3418 | start: 15, 3419 | end: 19, 3420 | name: 'test' 3421 | } 3422 | } 3423 | ], 3424 | name: { 3425 | type: 'JSXIdentifier', 3426 | start: 7, 3427 | end: 10, 3428 | name: 'div' 3429 | }, 3430 | selfClosing: true 3431 | }, 3432 | closingElement: null, 3433 | children: [] 3434 | } 3435 | }] 3436 | } 3437 | }, 3438 | 3439 | '
{ {a} }
': { 3440 | type: "ExpressionStatement", 3441 | start: 0, 3442 | end: 18, 3443 | expression: { 3444 | type: "JSXElement", 3445 | start: 0, 3446 | end: 18, 3447 | openingElement: { 3448 | type: "JSXOpeningElement", 3449 | start: 0, 3450 | end: 5, 3451 | attributes: [], 3452 | name: { 3453 | type: "JSXIdentifier", 3454 | start: 1, 3455 | end: 4, 3456 | name: "div" 3457 | }, 3458 | selfClosing: false 3459 | }, 3460 | closingElement: { 3461 | type: "JSXClosingElement", 3462 | start: 12, 3463 | end: 18, 3464 | name: { 3465 | type: "JSXIdentifier", 3466 | start: 14, 3467 | end: 17, 3468 | name: "div" 3469 | } 3470 | }, 3471 | children: [{ 3472 | type: "JSXExpressionContainer", 3473 | start: 5, 3474 | end: 12, 3475 | expression: { 3476 | type: "ObjectExpression", 3477 | start: 7, 3478 | end: 10, 3479 | properties: [{ 3480 | type: "Property", 3481 | start: 8, 3482 | end: 9, 3483 | method: false, 3484 | shorthand: true, 3485 | computed: false, 3486 | key: { 3487 | type: "Identifier", 3488 | start: 8, 3489 | end: 9, 3490 | name: "a" 3491 | }, 3492 | kind: "init", 3493 | value: { 3494 | type: "Identifier", 3495 | start: 8, 3496 | end: 9, 3497 | name: "a" 3498 | } 3499 | }] 3500 | } 3501 | }] 3502 | } 3503 | }, 3504 | 3505 | '
/text
': { 3506 | type: "ExpressionStatement", 3507 | start: 0, 3508 | end: 16, 3509 | expression: { 3510 | type: "JSXElement", 3511 | start: 0, 3512 | end: 16, 3513 | openingElement: { 3514 | type: "JSXOpeningElement", 3515 | start: 0, 3516 | end: 5, 3517 | attributes: [], 3518 | name: { 3519 | type: "JSXIdentifier", 3520 | start: 1, 3521 | end: 4, 3522 | name: "div" 3523 | }, 3524 | selfClosing: false 3525 | }, 3526 | closingElement: { 3527 | type: "JSXClosingElement", 3528 | start: 10, 3529 | end: 16, 3530 | name: { 3531 | type: "JSXIdentifier", 3532 | start: 12, 3533 | end: 15, 3534 | name: "div" 3535 | } 3536 | }, 3537 | children: [{ 3538 | type: "JSXText", 3539 | start: 5, 3540 | end: 10, 3541 | value: "/text", 3542 | raw: "/text" 3543 | }] 3544 | } 3545 | }, 3546 | 3547 | '
{a}{b}
': { 3548 | type: "ExpressionStatement", 3549 | start: 0, 3550 | end: 17, 3551 | expression: { 3552 | type: "JSXElement", 3553 | start: 0, 3554 | end: 17, 3555 | openingElement: { 3556 | type: "JSXOpeningElement", 3557 | start: 0, 3558 | end: 5, 3559 | attributes: [], 3560 | name: { 3561 | type: "JSXIdentifier", 3562 | start: 1, 3563 | end: 4, 3564 | name: "div" 3565 | }, 3566 | selfClosing: false 3567 | }, 3568 | closingElement: { 3569 | type: "JSXClosingElement", 3570 | start: 11, 3571 | end: 17, 3572 | name: { 3573 | type: "JSXIdentifier", 3574 | start: 13, 3575 | end: 16, 3576 | name: "div" 3577 | } 3578 | }, 3579 | children: [{ 3580 | type: 'JSXExpressionContainer', 3581 | expression: { 3582 | type: 'Identifier', 3583 | name: 'a', 3584 | range: [6, 7], 3585 | loc: { 3586 | start: { 3587 | line: 1, 3588 | column: 6 3589 | }, 3590 | end: { 3591 | line: 1, 3592 | column: 7 3593 | } 3594 | } 3595 | }, 3596 | range: [5, 8], 3597 | loc: { 3598 | start: { 3599 | line: 1, 3600 | column: 5 3601 | }, 3602 | end: { 3603 | line: 1, 3604 | column: 8 3605 | } 3606 | } 3607 | }, { 3608 | type: 'JSXExpressionContainer', 3609 | expression: { 3610 | type: 'Identifier', 3611 | name: 'b', 3612 | range: [9, 10], 3613 | loc: { 3614 | start: { 3615 | line: 1, 3616 | column: 9 3617 | }, 3618 | end: { 3619 | line: 1, 3620 | column: 10 3621 | } 3622 | } 3623 | }, 3624 | range: [8, 11], 3625 | loc: { 3626 | start: { 3627 | line: 1, 3628 | column: 8 3629 | }, 3630 | end: { 3631 | line: 1, 3632 | column: 11 3633 | } 3634 | } 3635 | } 3636 | ] 3637 | } 3638 | }, 3639 | 3640 | '
': { 3641 | type: "ExpressionStatement", 3642 | range: [0, 32], 3643 | expression: { 3644 | type: "JSXElement", 3645 | range: [0, 32], 3646 | openingElement: { 3647 | type: "JSXOpeningElement", 3648 | range: [0, 32], 3649 | attributes: [ 3650 | { 3651 | type: "JSXAttribute", 3652 | range: [5, 18], 3653 | name: { 3654 | type: "JSXIdentifier", 3655 | range: [5, 8], 3656 | name: "pre" 3657 | }, 3658 | value: { 3659 | type: "Literal", 3660 | range: [9, 18], 3661 | value: "leading" 3662 | } 3663 | }, 3664 | { 3665 | type: "JSXSpreadAttribute", 3666 | range: [19, 29], 3667 | argument: { 3668 | type: "Identifier", 3669 | range: [23, 28], 3670 | name: "props" 3671 | } 3672 | } 3673 | ], 3674 | name: { 3675 | type: "JSXIdentifier", 3676 | range: [1, 4], 3677 | name: "div" 3678 | }, 3679 | selfClosing: true 3680 | }, 3681 | closingElement: null, 3682 | children: [] 3683 | } 3684 | }, 3685 | '': { 3686 | type: "ExpressionStatement", 3687 | expression: { 3688 | type: "JSXElement", 3689 | range: [0, 64], 3690 | openingElement: { 3691 | type: "JSXOpeningElement", 3692 | range: [0, 64], 3693 | attributes: [ 3694 | { 3695 | type: "JSXAttribute", 3696 | range: [6, 62], 3697 | name: { 3698 | type: "JSXIdentifier", 3699 | range: [6, 7], 3700 | name: "d" 3701 | }, 3702 | value: { 3703 | type: "Literal", 3704 | loc: { 3705 | start: { line: 1, column: 8 }, 3706 | end: { line: 3, column: 15 } 3707 | }, 3708 | range: [8, 62], 3709 | value: "M230 80\n\t\tA 45 45, 0, 1, 0, 275 125 \r\n L 275 80 Z", 3710 | raw: "\"M230 80\n\t\tA 45 45, 0, 1, 0, 275 125 \r\n L 275 80 Z\"" 3711 | } 3712 | } 3713 | ], 3714 | name: { 3715 | type: "JSXIdentifier", 3716 | range: [1, 5], 3717 | name: "path" 3718 | }, 3719 | selfClosing: true 3720 | }, 3721 | closingElement: null, 3722 | children: [] 3723 | } 3724 | } 3725 | } 3726 | }; 3727 | 3728 | if (typeof exports !== "undefined") { 3729 | var test = require("./driver.js").test; 3730 | var testFail = require("./driver.js").testFail; 3731 | var jsxTokens = require("..").tokTypes; 3732 | var acornTokens = require("acorn").tokTypes; 3733 | } 3734 | 3735 | testFail("var x =
one
two
;", "Adjacent JSX elements must be wrapped in an enclosing tag (1:22)"); 3736 | 3737 | testFail("", "Unexpected token (1:4)"); 3738 | 3739 | test("", { 3740 | type: "Program", 3741 | range: [0, 9], 3742 | body: [{ 3743 | type: "ExpressionStatement", 3744 | range: [0, 9], 3745 | expression: { 3746 | type: "JSXElement", 3747 | range: [0, 9], 3748 | openingElement: { 3749 | type: "JSXOpeningElement", 3750 | range: [0, 9], 3751 | attributes: [], 3752 | name: { 3753 | type: "JSXMemberExpression", 3754 | range: [1, 6], 3755 | object: { 3756 | type: "JSXNamespacedName", 3757 | range: [1, 4], 3758 | namespace: { 3759 | type: "JSXIdentifier", 3760 | range: [1, 2], 3761 | name: "a" 3762 | }, 3763 | name: { 3764 | type: "JSXIdentifier", 3765 | range: [3, 4], 3766 | name: "b" 3767 | } 3768 | }, 3769 | property: { 3770 | type: "JSXIdentifier", 3771 | range: [5, 6], 3772 | name: "c" 3773 | } 3774 | }, 3775 | selfClosing: true 3776 | }, 3777 | closingElement: null, 3778 | children: [] 3779 | } 3780 | }] 3781 | }, { 3782 | ranges: true 3783 | }, { 3784 | allowNamespacedObjects: true 3785 | }); 3786 | 3787 | testFail('', 'Unexpected token (1:3)', {}, { 3788 | allowNamespaces: false 3789 | }); 3790 | 3791 | testFail('
', 'Unexpected token (1:7)', {}, { 3792 | allowNamespaces: false 3793 | }); 3794 | 3795 | test('{/* foo */}', {}, { 3796 | onToken: [ 3797 | { 3798 | type: jsxTokens.jsxTagStart, 3799 | value: undefined, 3800 | start: 0, 3801 | end: 1 3802 | }, 3803 | { 3804 | type: jsxTokens.jsxName, 3805 | value: 'a', 3806 | start: 1, 3807 | end: 2 3808 | }, 3809 | { 3810 | type: jsxTokens.jsxTagEnd, 3811 | value: undefined, 3812 | start: 2, 3813 | end: 3 3814 | }, 3815 | { 3816 | type: acornTokens.braceL, 3817 | value: undefined, 3818 | start: 3, 3819 | end: 4 3820 | }, 3821 | { 3822 | type: acornTokens.braceR, 3823 | value: undefined, 3824 | start: 13, 3825 | end: 14 3826 | }, 3827 | { 3828 | type: jsxTokens.jsxTagStart, 3829 | value: undefined, 3830 | start: 14, 3831 | end: 15 3832 | }, 3833 | { 3834 | type: acornTokens.slash, 3835 | value: '/', 3836 | start: 15, 3837 | end: 16 3838 | }, 3839 | { 3840 | type: jsxTokens.jsxName, 3841 | value: 'a', 3842 | start: 16, 3843 | end: 17 3844 | }, 3845 | { 3846 | type: jsxTokens.jsxTagEnd, 3847 | value: undefined, 3848 | start: 17, 3849 | end: 18 3850 | }, 3851 | { 3852 | type: acornTokens.eof, 3853 | value: undefined, 3854 | start: 18, 3855 | end: 18 3856 | } 3857 | ] 3858 | }); 3859 | 3860 | test('