From 59e26cb13e1a218dcedbfcc6f7cfdfb0c0329782 Mon Sep 17 00:00:00 2001 From: Kai Cataldo Date: Wed, 22 Jan 2020 23:46:35 -0500 Subject: [PATCH 1/5] Throw unexpected token error for } and > in JSXText nodes --- index.js | 11 +- test/tests-jsx.js | 1274 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 972 insertions(+), 313 deletions(-) diff --git a/index.js b/index.js index 6df802b..e12a4eb 100644 --- a/index.js +++ b/index.js @@ -414,9 +414,14 @@ function plugin(options, Parser) { // Parse JSX text - jsx_parseText(value) { - let node = this.parseLiteral(value); + jsx_parseText() { + let node = this.parseLiteral(this.value); node.type = "JSXText"; + for (let i = 0; i < node.value.length; i++) { + const char = node.value[i]; + if (char === "}" || char === ">") + this.raise(node.start + i, "Unexpected token. Did you mean {\"" + char + "\"} instead?"); + } return node; } @@ -430,7 +435,7 @@ function plugin(options, Parser) { parseExprAtom(refShortHandDefaultPos) { if (this.type === tok.jsxText) - return this.jsx_parseText(this.value); + return this.jsx_parseText(); else if (this.type === tok.jsxTagStart) return this.jsx_parseElement(); else diff --git a/test/tests-jsx.js b/test/tests-jsx.js index f8e927b..2cb11ac 100644 --- a/test/tests-jsx.js +++ b/test/tests-jsx.js @@ -1461,316 +1461,316 @@ var fbTestFixture = { } }, - ' right=monkeys /> gorillas />': { - "type": "ExpressionStatement", - "expression": { - "type": "JSXElement", - "openingElement": { - "type": "JSXOpeningElement", - "name": { - "type": "JSXIdentifier", - "name": "LeftRight", - "range": [ - 1, - 10 - ], - "loc": { - "start": { - "line": 1, - "column": 1 - }, - "end": { - "line": 1, - "column": 10 - } - } - }, - "selfClosing": true, - "attributes": [ - { - "type": "JSXAttribute", - "name": { - "type": "JSXIdentifier", - "name": "left", - "range": [ - 11, - 15 - ], - "loc": { - "start": { - "line": 1, - "column": 11 - }, - "end": { - "line": 1, - "column": 15 - } - } - }, - "value": { - "type": "JSXElement", - "openingElement": { - "type": "JSXOpeningElement", - "name": { - "type": "JSXIdentifier", - "name": "a", - "range": [ - 17, - 18 - ], - "loc": { - "start": { - "line": 1, - "column": 17 - }, - "end": { - "line": 1, - "column": 18 - } - } - }, - "selfClosing": true, - "attributes": [], - "range": [ - 16, - 21 - ], - "loc": { - "start": { - "line": 1, - "column": 16 - }, - "end": { - "line": 1, - "column": 21 - } - } - }, - closingElement: null, - "children": [], - "range": [ - 16, - 21 - ], - "loc": { - "start": { - "line": 1, - "column": 16 - }, - "end": { - "line": 1, - "column": 21 - } - } - }, - "range": [ - 11, - 21 - ], - "loc": { - "start": { - "line": 1, - "column": 11 - }, - "end": { - "line": 1, - "column": 21 - } - } - }, - { - "type": "JSXAttribute", - "name": { - "type": "JSXIdentifier", - "name": "right", - "range": [ - 22, - 27 - ], - "loc": { - "start": { - "line": 1, - "column": 22 - }, - "end": { - "line": 1, - "column": 27 - } - } - }, - "value": { - "type": "JSXElement", - "openingElement": { - "type": "JSXOpeningElement", - "name": { - "type": "JSXIdentifier", - "name": "b", - "range": [ - 29, - 30 - ], - "loc": { - "start": { - "line": 1, - "column": 29 - }, - "end": { - "line": 1, - "column": 30 - } - } - }, - "selfClosing": false, - "attributes": [], - "range": [ - 28, - 31 - ], - "loc": { - "start": { - "line": 1, - "column": 28 - }, - "end": { - "line": 1, - "column": 31 - } - } - }, - "closingElement": { - "type": "JSXClosingElement", - "name": { - "type": "JSXIdentifier", - "name": "b", - "range": [ - 52, - 53 - ], - "loc": { - "start": { - "line": 1, - "column": 52 - }, - "end": { - "line": 1, - "column": 53 - } - } - }, - "range": [ - 50, - 54 - ], - "loc": { - "start": { - "line": 1, - "column": 50 - }, - "end": { - "line": 1, - "column": 54 - } - } - }, - "children": [ - { - "type": "JSXText", - "value": "monkeys /> gorillas", - "raw": "monkeys /> gorillas", - "range": [ - 31, - 50 - ], - "loc": { - "start": { - "line": 1, - "column": 31 - }, - "end": { - "line": 1, - "column": 50 - } - } - } - ], - "range": [ - 28, - 54 - ], - "loc": { - "start": { - "line": 1, - "column": 28 - }, - "end": { - "line": 1, - "column": 54 - } - } - }, - "range": [ - 22, - 54 - ], - "loc": { - "start": { - "line": 1, - "column": 22 - }, - "end": { - "line": 1, - "column": 54 - } - } - } - ], - "range": [ - 0, - 57 - ], - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 57 - } - } - }, - closingElement: null, - "children": [], - "range": [ - 0, - 57 - ], - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 57 - } - } - }, - "range": [ - 0, - 57 - ], - "loc": { - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 57 - } - } - }, + // ' right=monkeys /> gorillas />': { + // "type": "ExpressionStatement", + // "expression": { + // "type": "JSXElement", + // "openingElement": { + // "type": "JSXOpeningElement", + // "name": { + // "type": "JSXIdentifier", + // "name": "LeftRight", + // "range": [ + // 1, + // 10 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 1 + // }, + // "end": { + // "line": 1, + // "column": 10 + // } + // } + // }, + // "selfClosing": true, + // "attributes": [ + // { + // "type": "JSXAttribute", + // "name": { + // "type": "JSXIdentifier", + // "name": "left", + // "range": [ + // 11, + // 15 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 11 + // }, + // "end": { + // "line": 1, + // "column": 15 + // } + // } + // }, + // "value": { + // "type": "JSXElement", + // "openingElement": { + // "type": "JSXOpeningElement", + // "name": { + // "type": "JSXIdentifier", + // "name": "a", + // "range": [ + // 17, + // 18 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 17 + // }, + // "end": { + // "line": 1, + // "column": 18 + // } + // } + // }, + // "selfClosing": true, + // "attributes": [], + // "range": [ + // 16, + // 21 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 16 + // }, + // "end": { + // "line": 1, + // "column": 21 + // } + // } + // }, + // closingElement: null, + // "children": [], + // "range": [ + // 16, + // 21 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 16 + // }, + // "end": { + // "line": 1, + // "column": 21 + // } + // } + // }, + // "range": [ + // 11, + // 21 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 11 + // }, + // "end": { + // "line": 1, + // "column": 21 + // } + // } + // }, + // { + // "type": "JSXAttribute", + // "name": { + // "type": "JSXIdentifier", + // "name": "right", + // "range": [ + // 22, + // 27 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 22 + // }, + // "end": { + // "line": 1, + // "column": 27 + // } + // } + // }, + // "value": { + // "type": "JSXElement", + // "openingElement": { + // "type": "JSXOpeningElement", + // "name": { + // "type": "JSXIdentifier", + // "name": "b", + // "range": [ + // 29, + // 30 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 29 + // }, + // "end": { + // "line": 1, + // "column": 30 + // } + // } + // }, + // "selfClosing": false, + // "attributes": [], + // "range": [ + // 28, + // 31 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 28 + // }, + // "end": { + // "line": 1, + // "column": 31 + // } + // } + // }, + // "closingElement": { + // "type": "JSXClosingElement", + // "name": { + // "type": "JSXIdentifier", + // "name": "b", + // "range": [ + // 52, + // 53 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 52 + // }, + // "end": { + // "line": 1, + // "column": 53 + // } + // } + // }, + // "range": [ + // 50, + // 54 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 50 + // }, + // "end": { + // "line": 1, + // "column": 54 + // } + // } + // }, + // "children": [ + // { + // "type": "JSXText", + // "value": "monkeys /> gorillas", + // "raw": "monkeys /> gorillas", + // "range": [ + // 31, + // 50 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 31 + // }, + // "end": { + // "line": 1, + // "column": 50 + // } + // } + // } + // ], + // "range": [ + // 28, + // 54 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 28 + // }, + // "end": { + // "line": 1, + // "column": 54 + // } + // } + // }, + // "range": [ + // 22, + // 54 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 22 + // }, + // "end": { + // "line": 1, + // "column": 54 + // } + // } + // } + // ], + // "range": [ + // 0, + // 57 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 0 + // }, + // "end": { + // "line": 1, + // "column": 57 + // } + // } + // }, + // closingElement: null, + // "children": [], + // "range": [ + // 0, + // 57 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 0 + // }, + // "end": { + // "line": 1, + // "column": 57 + // } + // } + // }, + // "range": [ + // 0, + // 57 + // ], + // "loc": { + // "start": { + // "line": 1, + // "column": 0 + // }, + // "end": { + // "line": 1, + // "column": 57 + // } + // } + // }, '': { type: 'ExpressionStatement', @@ -3958,3 +3958,657 @@ for (var ns in fbTestFixture) { }); } } + +testFail(" right=monkeys /> gorillas />", 'Unexpected token. Did you mean {">"} instead? (1:40)') +testFail("foo{", "Unexpected token (1:8)") +testFail("foo<", "Unexpected token (1:7)") +testFail("foo}", 'Unexpected token. Did you mean {"}"} instead? (1:6)') +testFail("foo>", 'Unexpected token. Did you mean {">"} instead? (1:6)') +test('foo{"{"}', { + "type": "Program", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "name": "A" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 11, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "name": { + "type": "JSXIdentifier", + "start": 13, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "name": "A" + } + }, + "children": [ + { + "type": "JSXText", + "start": 3, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "value": "foo", + "raw": "foo" + }, + { + "type": "JSXExpressionContainer", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "expression": { + "type": "Literal", + "start": 7, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "value": "{", + "raw": "\"{\"" + } + } + ] + } + } + ] +}) +test('foo{"<"}', { + "type": "Program", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "name": "A" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 11, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "name": { + "type": "JSXIdentifier", + "start": 13, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "name": "A" + } + }, + "children": [ + { + "type": "JSXText", + "start": 3, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "value": "foo", + "raw": "foo" + }, + { + "type": "JSXExpressionContainer", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "expression": { + "type": "Literal", + "start": 7, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "value": "<", + "raw": "\"<\"" + } + } + ] + } + } + ] +}) +test('foo{"}"}', { + "type": "Program", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "name": "A" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 11, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "name": { + "type": "JSXIdentifier", + "start": 13, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "name": "A" + } + }, + "children": [ + { + "type": "JSXText", + "start": 3, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "value": "foo", + "raw": "foo" + }, + { + "type": "JSXExpressionContainer", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "expression": { + "type": "Literal", + "start": 7, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "value": "}", + "raw": "\"}\"" + } + } + ] + } + } + ] +}) +test('foo{">"}', { + "type": "Program", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 3, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 3 + } + }, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "name": "A" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 11, + "end": 15, + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 15 + } + }, + "name": { + "type": "JSXIdentifier", + "start": 13, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "name": "A" + } + }, + "children": [ + { + "type": "JSXText", + "start": 3, + "end": 6, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 6 + } + }, + "value": "foo", + "raw": "foo" + }, + { + "type": "JSXExpressionContainer", + "start": 6, + "end": 11, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 11 + } + }, + "expression": { + "type": "Literal", + "start": 7, + "end": 10, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "value": ">", + "raw": "\">\"" + } + } + ] + } + } + ] +}) From 46138e89ce1352cb224dba7c9ab94569b8aac0c5 Mon Sep 17 00:00:00 2001 From: Kai Cataldo Date: Sun, 26 Jan 2020 13:22:29 -0500 Subject: [PATCH 2/5] Refactor --- index.js | 16 +++++++++++----- test/tests-jsx.js | 6 +++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index e12a4eb..cba70eb 100644 --- a/index.js +++ b/index.js @@ -136,6 +136,17 @@ function plugin(options, Parser) { chunkStart = this.pos; break; + case 62: // '>' + case 125: // '}' + this.raise( + this.pos, + `Unexpected token \`${ + this.input[this.pos] + }\`. Did you mean \`${ch === 125 ? "}" : ">"}\`, or \`{"${ + this.input[this.pos] + }"}\`?`, + ); + default: if (isNewLine(ch)) { out += this.input.slice(chunkStart, this.pos); @@ -417,11 +428,6 @@ function plugin(options, Parser) { jsx_parseText() { let node = this.parseLiteral(this.value); node.type = "JSXText"; - for (let i = 0; i < node.value.length; i++) { - const char = node.value[i]; - if (char === "}" || char === ">") - this.raise(node.start + i, "Unexpected token. Did you mean {\"" + char + "\"} instead?"); - } return node; } diff --git a/test/tests-jsx.js b/test/tests-jsx.js index 2cb11ac..b0c5313 100644 --- a/test/tests-jsx.js +++ b/test/tests-jsx.js @@ -3959,11 +3959,11 @@ for (var ns in fbTestFixture) { } } -testFail(" right=monkeys /> gorillas />", 'Unexpected token. Did you mean {">"} instead? (1:40)') +testFail(" right=monkeys /> gorillas />", 'Unexpected token `>`. Did you mean `>`, or `{">"}`? (1:40)') testFail("foo{", "Unexpected token (1:8)") testFail("foo<", "Unexpected token (1:7)") -testFail("foo}", 'Unexpected token. Did you mean {"}"} instead? (1:6)') -testFail("foo>", 'Unexpected token. Did you mean {">"} instead? (1:6)') +testFail("foo}", 'Unexpected token `}`. Did you mean `}`, or `{"}"}`? (1:6)') +testFail("foo>", 'Unexpected token `>`. Did you mean `>`, or `{">"}`? (1:6)') test('foo{"{"}', { "type": "Program", "start": 0, From a5ebc8e295c369ad25d1ac74ae3c34bae8c94756 Mon Sep 17 00:00:00 2001 From: Kai Cataldo Date: Sun, 26 Jan 2020 13:39:09 -0500 Subject: [PATCH 3/5] Update tests --- test/tests-jsx.js | 650 ++++++++++++++++++++++++---------------------- 1 file changed, 336 insertions(+), 314 deletions(-) diff --git a/test/tests-jsx.js b/test/tests-jsx.js index b0c5313..1ac02e2 100644 --- a/test/tests-jsx.js +++ b/test/tests-jsx.js @@ -1461,316 +1461,238 @@ var fbTestFixture = { } }, - // ' right=monkeys /> gorillas />': { - // "type": "ExpressionStatement", - // "expression": { - // "type": "JSXElement", - // "openingElement": { - // "type": "JSXOpeningElement", - // "name": { - // "type": "JSXIdentifier", - // "name": "LeftRight", - // "range": [ - // 1, - // 10 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 1 - // }, - // "end": { - // "line": 1, - // "column": 10 - // } - // } - // }, - // "selfClosing": true, - // "attributes": [ - // { - // "type": "JSXAttribute", - // "name": { - // "type": "JSXIdentifier", - // "name": "left", - // "range": [ - // 11, - // 15 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 11 - // }, - // "end": { - // "line": 1, - // "column": 15 - // } - // } - // }, - // "value": { - // "type": "JSXElement", - // "openingElement": { - // "type": "JSXOpeningElement", - // "name": { - // "type": "JSXIdentifier", - // "name": "a", - // "range": [ - // 17, - // 18 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 17 - // }, - // "end": { - // "line": 1, - // "column": 18 - // } - // } - // }, - // "selfClosing": true, - // "attributes": [], - // "range": [ - // 16, - // 21 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 16 - // }, - // "end": { - // "line": 1, - // "column": 21 - // } - // } - // }, - // closingElement: null, - // "children": [], - // "range": [ - // 16, - // 21 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 16 - // }, - // "end": { - // "line": 1, - // "column": 21 - // } - // } - // }, - // "range": [ - // 11, - // 21 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 11 - // }, - // "end": { - // "line": 1, - // "column": 21 - // } - // } - // }, - // { - // "type": "JSXAttribute", - // "name": { - // "type": "JSXIdentifier", - // "name": "right", - // "range": [ - // 22, - // 27 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 22 - // }, - // "end": { - // "line": 1, - // "column": 27 - // } - // } - // }, - // "value": { - // "type": "JSXElement", - // "openingElement": { - // "type": "JSXOpeningElement", - // "name": { - // "type": "JSXIdentifier", - // "name": "b", - // "range": [ - // 29, - // 30 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 29 - // }, - // "end": { - // "line": 1, - // "column": 30 - // } - // } - // }, - // "selfClosing": false, - // "attributes": [], - // "range": [ - // 28, - // 31 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 28 - // }, - // "end": { - // "line": 1, - // "column": 31 - // } - // } - // }, - // "closingElement": { - // "type": "JSXClosingElement", - // "name": { - // "type": "JSXIdentifier", - // "name": "b", - // "range": [ - // 52, - // 53 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 52 - // }, - // "end": { - // "line": 1, - // "column": 53 - // } - // } - // }, - // "range": [ - // 50, - // 54 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 50 - // }, - // "end": { - // "line": 1, - // "column": 54 - // } - // } - // }, - // "children": [ - // { - // "type": "JSXText", - // "value": "monkeys /> gorillas", - // "raw": "monkeys /> gorillas", - // "range": [ - // 31, - // 50 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 31 - // }, - // "end": { - // "line": 1, - // "column": 50 - // } - // } - // } - // ], - // "range": [ - // 28, - // 54 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 28 - // }, - // "end": { - // "line": 1, - // "column": 54 - // } - // } - // }, - // "range": [ - // 22, - // 54 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 22 - // }, - // "end": { - // "line": 1, - // "column": 54 - // } - // } - // } - // ], - // "range": [ - // 0, - // 57 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 0 - // }, - // "end": { - // "line": 1, - // "column": 57 - // } - // } - // }, - // closingElement: null, - // "children": [], - // "range": [ - // 0, - // 57 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 0 - // }, - // "end": { - // "line": 1, - // "column": 57 - // } - // } - // }, - // "range": [ - // 0, - // 57 - // ], - // "loc": { - // "start": { - // "line": 1, - // "column": 0 - // }, - // "end": { - // "line": 1, - // "column": 57 - // } - // } - // }, + ' right=monkeys /{">"} gorillas />': { + "type": "ExpressionStatement", + "start": 0, + "end": 61, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 61, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 61, + "attributes": [ + { + "type": "JSXAttribute", + "start": 11, + "end": 21, + "name": { + "type": "JSXIdentifier", + "start": 11, + "end": 15, + "name": "left" + }, + "value": { + "type": "JSXElement", + "start": 16, + "end": 21, + "openingElement": { + "type": "JSXOpeningElement", + "start": 16, + "end": 21, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 17, + "end": 18, + "name": "a" + }, + "selfClosing": true + }, + "closingElement": null, + "children": [] + } + }, + { + "type": "JSXAttribute", + "start": 22, + "end": 58, + "name": { + "type": "JSXIdentifier", + "start": 22, + "end": 27, + "name": "right" + }, + "value": { + "type": "JSXElement", + "start": 28, + "end": 58, + "openingElement": { + "type": "JSXOpeningElement", + "start": 28, + "end": 31, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 29, + "end": 30, + "name": "b" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 54, + "end": 58, + "name": { + "type": "JSXIdentifier", + "start": 56, + "end": 57, + "name": "b" + } + }, + "children": [ + { + "type": "JSXText", + "start": 31, + "end": 40, + "value": "monkeys /", + "raw": "monkeys /" + }, + { + "type": "JSXExpressionContainer", + "start": 40, + "end": 45, + "expression": { + "type": "Literal", + "start": 41, + "end": 44, + "value": ">", + "raw": "\">\"" + } + }, + { + "type": "JSXText", + "start": 45, + "end": 54, + "value": " gorillas", + "raw": " gorillas" + } + ] + } + } + ], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 10, + "name": "LeftRight" + }, + "selfClosing": true + }, + "closingElement": null, + "children": [] + } + }, + + ' right=monkeys /> gorillas />': { + "type": "ExpressionStatement", + "start": 0, + "end": 60, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 60, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 60, + "attributes": [ + { + "type": "JSXAttribute", + "start": 11, + "end": 21, + "name": { + "type": "JSXIdentifier", + "start": 11, + "end": 15, + "name": "left" + }, + "value": { + "type": "JSXElement", + "start": 16, + "end": 21, + "openingElement": { + "type": "JSXOpeningElement", + "start": 16, + "end": 21, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 17, + "end": 18, + "name": "a" + }, + "selfClosing": true + }, + "closingElement": null, + "children": [] + } + }, + { + "type": "JSXAttribute", + "start": 22, + "end": 57, + "name": { + "type": "JSXIdentifier", + "start": 22, + "end": 27, + "name": "right" + }, + "value": { + "type": "JSXElement", + "start": 28, + "end": 57, + "openingElement": { + "type": "JSXOpeningElement", + "start": 28, + "end": 31, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 29, + "end": 30, + "name": "b" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 53, + "end": 57, + "name": { + "type": "JSXIdentifier", + "start": 55, + "end": 56, + "name": "b" + } + }, + "children": [ + { + "type": "JSXText", + "start": 31, + "end": 53, + "value": "monkeys /> gorillas", + "raw": "monkeys /> gorillas" + } + ] + } + } + ], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 10, + "name": "LeftRight" + }, + "selfClosing": true + }, + "closingElement": null, + "children": [] + } + }, '': { type: 'ExpressionStatement', @@ -4125,7 +4047,7 @@ test('foo{"{"}', { } } ] -}) +}); test('foo{"<"}', { "type": "Program", "start": 0, @@ -4287,7 +4209,7 @@ test('foo{"<"}', { } } ] -}) +}); test('foo{"}"}', { "type": "Program", "start": 0, @@ -4449,7 +4371,57 @@ test('foo{"}"}', { } } ] -}) +}); +test('foo}', { + "type": "Program", + "start": 0, + "end": 18, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 18, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 18, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 3, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 2, + "name": "A" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 14, + "end": 18, + "name": { + "type": "JSXIdentifier", + "start": 16, + "end": 17, + "name": "A" + } + }, + "children": [ + { + "type": "JSXText", + "start": 3, + "end": 14, + "value": "foo}", + "raw": "foo}" + } + ] + } + } + ] +}); test('foo{">"}', { "type": "Program", "start": 0, @@ -4611,4 +4583,54 @@ test('foo{">"}', { } } ] -}) +}); +test('foo>', { + "type": "Program", + "start": 0, + "end": 14, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 14, + "expression": { + "type": "JSXElement", + "start": 0, + "end": 14, + "openingElement": { + "type": "JSXOpeningElement", + "start": 0, + "end": 3, + "attributes": [], + "name": { + "type": "JSXIdentifier", + "start": 1, + "end": 2, + "name": "A" + }, + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start": 10, + "end": 14, + "name": { + "type": "JSXIdentifier", + "start": 12, + "end": 13, + "name": "A" + } + }, + "children": [ + { + "type": "JSXText", + "start": 3, + "end": 10, + "value": "foo>", + "raw": "foo>" + } + ] + } + } + ] +}); From b8654eb8bb2830f16457ed17154f1ec68beac872 Mon Sep 17 00:00:00 2001 From: Kai Cataldo Date: Sun, 26 Jan 2020 14:04:52 -0500 Subject: [PATCH 4/5] Fix Node <8 compatibility --- index.js | 7 ++----- test/tests-jsx.js | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index cba70eb..0ff263c 100644 --- a/index.js +++ b/index.js @@ -140,11 +140,8 @@ function plugin(options, Parser) { case 125: // '}' this.raise( this.pos, - `Unexpected token \`${ - this.input[this.pos] - }\`. Did you mean \`${ch === 125 ? "}" : ">"}\`, or \`{"${ - this.input[this.pos] - }"}\`?`, + "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" + + (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?" ); default: diff --git a/test/tests-jsx.js b/test/tests-jsx.js index 1ac02e2..06ea016 100644 --- a/test/tests-jsx.js +++ b/test/tests-jsx.js @@ -3881,11 +3881,11 @@ for (var ns in fbTestFixture) { } } -testFail(" right=monkeys /> gorillas />", 'Unexpected token `>`. Did you mean `>`, or `{">"}`? (1:40)') +testFail(" right=monkeys /> gorillas />", 'Unexpected token `>`. Did you mean `>` or `{">"}`? (1:40)') testFail("foo{", "Unexpected token (1:8)") testFail("foo<", "Unexpected token (1:7)") -testFail("foo}", 'Unexpected token `}`. Did you mean `}`, or `{"}"}`? (1:6)') -testFail("foo>", 'Unexpected token `>`. Did you mean `>`, or `{">"}`? (1:6)') +testFail("foo}", 'Unexpected token `}`. Did you mean `}` or `{"}"}`? (1:6)') +testFail("foo>", 'Unexpected token `>`. Did you mean `>` or `{">"}`? (1:6)') test('foo{"{"}', { "type": "Program", "start": 0, From 71541e5b294c5d6c57f2a19646b8e72ba61f16c2 Mon Sep 17 00:00:00 2001 From: Kai Cataldo Date: Sun, 26 Jan 2020 14:11:40 -0500 Subject: [PATCH 5/5] Add missing semicolons --- test/tests-jsx.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/tests-jsx.js b/test/tests-jsx.js index 06ea016..c44c605 100644 --- a/test/tests-jsx.js +++ b/test/tests-jsx.js @@ -3881,11 +3881,11 @@ for (var ns in fbTestFixture) { } } -testFail(" right=monkeys /> gorillas />", 'Unexpected token `>`. Did you mean `>` or `{">"}`? (1:40)') -testFail("foo{", "Unexpected token (1:8)") -testFail("foo<", "Unexpected token (1:7)") -testFail("foo}", 'Unexpected token `}`. Did you mean `}` or `{"}"}`? (1:6)') -testFail("foo>", 'Unexpected token `>`. Did you mean `>` or `{">"}`? (1:6)') +testFail(" right=monkeys /> gorillas />", 'Unexpected token `>`. Did you mean `>` or `{">"}`? (1:40)'); +testFail("foo{", "Unexpected token (1:8)"); +testFail("foo<", "Unexpected token (1:7)"); +testFail("foo}", 'Unexpected token `}`. Did you mean `}` or `{"}"}`? (1:6)'); +testFail("foo>", 'Unexpected token `>`. Did you mean `>` or `{">"}`? (1:6)'); test('foo{"{"}', { "type": "Program", "start": 0,