diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 6e4c23bd..a4f21980 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -91,7 +91,7 @@ jobs:
- name: Build
run: npm run -s build
- name: Test
- run: npm run -s test:mocha
+ run: npm run -s test:cover
- name: Send Coverage
run: npm run -s codecov
env:
diff --git a/package.json b/package.json
index d95d6764..c8483ac9 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,8 @@
"setup": "git submodule update --init && cd test/fixtures/eslint && npm install",
"pretest": "run-s build lint",
"test": "npm run -s test:mocha",
- "test:mocha": "nyc mocha \"test/*.js\" --reporter dot --timeout 60000",
+ "test:mocha": "mocha --require ts-node/register \"test/*.js\" --reporter dot --timeout 60000",
+ "test:cover": "nyc mocha \"test/*.js\" --reporter dot --timeout 60000",
"test:debug": "mocha --require ts-node/register/transpile-only \"test/*.js\" --reporter dot --timeout 60000",
"preupdate-fixtures": "npm run -s build",
"update-fixtures": "node scripts/update-fixtures-ast.js && node scripts/update-fixtures-document-fragment.js",
diff --git a/src/html/tokenizer.ts b/src/html/tokenizer.ts
index f4b8825d..af777f78 100644
--- a/src/html/tokenizer.ts
+++ b/src/html/tokenizer.ts
@@ -1610,14 +1610,14 @@ export class Tokenizer {
this.crStartOffset = this.offset - 1
this.buffer = [AMPERSAND]
- if (isWhitespace(cp) || cp === LESS_THAN_SIGN || cp === EOF) {
- return this.reconsumeAs("CHARACTER_REFERENCE_END")
+ if (isDigit(cp) || isLetter(cp)) {
+ return this.reconsumeAs("NAMED_CHARACTER_REFERENCE")
}
if (cp === NUMBER_SIGN) {
this.buffer.push(cp)
return "NUMERIC_CHARACTER_REFERENCE"
}
- return this.reconsumeAs("NAMED_CHARACTER_REFERENCE")
+ return this.reconsumeAs("CHARACTER_REFERENCE_END")
}
/**
@@ -1818,7 +1818,7 @@ export class Tokenizer {
}
/**
- * https://html.spec.whatwg.org/multipage/parsing.html#character-reference-end-state
+ * https://html.spec.whatwg.org/multipage/parsing.html#flush-code-points-consumed-as-a-character-reference
* @param cp The current code point.
* @returns The next state.
*/
diff --git a/test/espree.js b/test/espree.js
index 33d06918..5b1d1cca 100644
--- a/test/espree.js
+++ b/test/espree.js
@@ -10,9 +10,13 @@ function parentMain() {
describe("Loading espree from ESLint", () => {
it("should load espree from the ESLint location.", (done) => {
- spawn(process.execPath, [__filename, "--child1"], {
- stdio: "inherit",
- })
+ spawn(
+ process.execPath,
+ ["--require", "ts-node/register", __filename, "--child1"],
+ {
+ stdio: "inherit",
+ },
+ )
.on("error", done)
.on("exit", (code) =>
code
@@ -21,9 +25,13 @@ function parentMain() {
)
})
it("should load espree from the ESLint location.", (done) => {
- spawn(process.execPath, [__filename, "--child1"], {
- stdio: "inherit",
- })
+ spawn(
+ process.execPath,
+ ["--require", "ts-node/register", __filename, "--child1"],
+ {
+ stdio: "inherit",
+ },
+ )
.on("error", done)
.on("exit", (code) =>
code
@@ -38,9 +46,13 @@ function parentMain() {
execSync("npm i", {
stdio: "inherit",
})
- spawn(process.execPath, [__filename, "--child2"], {
- stdio: "inherit",
- })
+ spawn(
+ process.execPath,
+ ["--require", "ts-node/register", __filename, "--child2"],
+ {
+ stdio: "inherit",
+ },
+ )
.on("error", done)
.on("exit", (code) =>
code
diff --git a/test/fixtures/ast/html-entities-lone-amp/ast.json b/test/fixtures/ast/html-entities-lone-amp/ast.json
new file mode 100644
index 00000000..53e24b47
--- /dev/null
+++ b/test/fixtures/ast/html-entities-lone-amp/ast.json
@@ -0,0 +1,1723 @@
+{
+ "type": "Program",
+ "start": 0,
+ "end": 0,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 1,
+ "column": 0
+ }
+ },
+ "range": [
+ 0,
+ 0
+ ],
+ "body": [],
+ "sourceType": "script",
+ "comments": [],
+ "tokens": [],
+ "templateBody": {
+ "type": "VElement",
+ "range": [
+ 0,
+ 187
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 8,
+ "column": 11
+ }
+ },
+ "name": "template",
+ "rawName": "template",
+ "namespace": "http://www.w3.org/1999/xhtml",
+ "startTag": {
+ "type": "VStartTag",
+ "range": [
+ 0,
+ 10
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 1,
+ "column": 10
+ }
+ },
+ "selfClosing": false,
+ "attributes": []
+ },
+ "children": [
+ {
+ "type": "VText",
+ "range": [
+ 10,
+ 15
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 10
+ },
+ "end": {
+ "line": 2,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "VElement",
+ "range": [
+ 15,
+ 38
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 4
+ },
+ "end": {
+ "line": 2,
+ "column": 27
+ }
+ },
+ "name": "mycomponent",
+ "rawName": "MyComponent",
+ "namespace": "http://www.w3.org/1999/xhtml",
+ "startTag": {
+ "type": "VStartTag",
+ "range": [
+ 15,
+ 38
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 4
+ },
+ "end": {
+ "line": 2,
+ "column": 27
+ }
+ },
+ "selfClosing": true,
+ "attributes": [
+ {
+ "type": "VAttribute",
+ "range": [
+ 28,
+ 35
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 17
+ },
+ "end": {
+ "line": 2,
+ "column": 24
+ }
+ },
+ "directive": false,
+ "key": {
+ "type": "VIdentifier",
+ "range": [
+ 28,
+ 31
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 17
+ },
+ "end": {
+ "line": 2,
+ "column": 20
+ }
+ },
+ "name": "foo",
+ "rawName": "foo"
+ },
+ "value": {
+ "type": "VLiteral",
+ "range": [
+ 32,
+ 35
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 21
+ },
+ "end": {
+ "line": 2,
+ "column": 24
+ }
+ },
+ "value": "&"
+ }
+ }
+ ]
+ },
+ "children": [],
+ "endTag": null,
+ "variables": []
+ },
+ {
+ "type": "VText",
+ "range": [
+ 38,
+ 43
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 27
+ },
+ "end": {
+ "line": 3,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "VElement",
+ "range": [
+ 43,
+ 66
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 4
+ },
+ "end": {
+ "line": 3,
+ "column": 27
+ }
+ },
+ "name": "mycomponent",
+ "rawName": "MyComponent",
+ "namespace": "http://www.w3.org/1999/xhtml",
+ "startTag": {
+ "type": "VStartTag",
+ "range": [
+ 43,
+ 66
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 4
+ },
+ "end": {
+ "line": 3,
+ "column": 27
+ }
+ },
+ "selfClosing": true,
+ "attributes": [
+ {
+ "type": "VAttribute",
+ "range": [
+ 56,
+ 63
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 17
+ },
+ "end": {
+ "line": 3,
+ "column": 24
+ }
+ },
+ "directive": false,
+ "key": {
+ "type": "VIdentifier",
+ "range": [
+ 56,
+ 59
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 17
+ },
+ "end": {
+ "line": 3,
+ "column": 20
+ }
+ },
+ "name": "foo",
+ "rawName": "foo"
+ },
+ "value": {
+ "type": "VLiteral",
+ "range": [
+ 60,
+ 63
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 21
+ },
+ "end": {
+ "line": 3,
+ "column": 24
+ }
+ },
+ "value": "&"
+ }
+ }
+ ]
+ },
+ "children": [],
+ "endTag": null,
+ "variables": []
+ },
+ {
+ "type": "VText",
+ "range": [
+ 66,
+ 71
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 27
+ },
+ "end": {
+ "line": 4,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "VElement",
+ "range": [
+ 71,
+ 92
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 4
+ },
+ "end": {
+ "line": 4,
+ "column": 25
+ }
+ },
+ "name": "mycomponent",
+ "rawName": "MyComponent",
+ "namespace": "http://www.w3.org/1999/xhtml",
+ "startTag": {
+ "type": "VStartTag",
+ "range": [
+ 71,
+ 92
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 4
+ },
+ "end": {
+ "line": 4,
+ "column": 25
+ }
+ },
+ "selfClosing": true,
+ "attributes": [
+ {
+ "type": "VAttribute",
+ "range": [
+ 84,
+ 89
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 17
+ },
+ "end": {
+ "line": 4,
+ "column": 22
+ }
+ },
+ "directive": false,
+ "key": {
+ "type": "VIdentifier",
+ "range": [
+ 84,
+ 87
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 17
+ },
+ "end": {
+ "line": 4,
+ "column": 20
+ }
+ },
+ "name": "foo",
+ "rawName": "foo"
+ },
+ "value": {
+ "type": "VLiteral",
+ "range": [
+ 88,
+ 89
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 21
+ },
+ "end": {
+ "line": 4,
+ "column": 22
+ }
+ },
+ "value": "&"
+ }
+ }
+ ]
+ },
+ "children": [],
+ "endTag": null,
+ "variables": []
+ },
+ {
+ "type": "VText",
+ "range": [
+ 92,
+ 97
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 25
+ },
+ "end": {
+ "line": 5,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "VElement",
+ "range": [
+ 97,
+ 122
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 4
+ },
+ "end": {
+ "line": 5,
+ "column": 29
+ }
+ },
+ "name": "mycomponent",
+ "rawName": "MyComponent",
+ "namespace": "http://www.w3.org/1999/xhtml",
+ "startTag": {
+ "type": "VStartTag",
+ "range": [
+ 97,
+ 122
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 4
+ },
+ "end": {
+ "line": 5,
+ "column": 29
+ }
+ },
+ "selfClosing": true,
+ "attributes": [
+ {
+ "type": "VAttribute",
+ "range": [
+ 110,
+ 115
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 17
+ },
+ "end": {
+ "line": 5,
+ "column": 22
+ }
+ },
+ "directive": false,
+ "key": {
+ "type": "VIdentifier",
+ "range": [
+ 110,
+ 113
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 17
+ },
+ "end": {
+ "line": 5,
+ "column": 20
+ }
+ },
+ "name": "foo",
+ "rawName": "foo"
+ },
+ "value": {
+ "type": "VLiteral",
+ "range": [
+ 114,
+ 115
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 21
+ },
+ "end": {
+ "line": 5,
+ "column": 22
+ }
+ },
+ "value": "&"
+ }
+ },
+ {
+ "type": "VAttribute",
+ "range": [
+ 116,
+ 119
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 23
+ },
+ "end": {
+ "line": 5,
+ "column": 26
+ }
+ },
+ "directive": false,
+ "key": {
+ "type": "VIdentifier",
+ "range": [
+ 116,
+ 119
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 23
+ },
+ "end": {
+ "line": 5,
+ "column": 26
+ }
+ },
+ "name": "bar",
+ "rawName": "bar"
+ },
+ "value": null
+ }
+ ]
+ },
+ "children": [],
+ "endTag": null,
+ "variables": []
+ },
+ {
+ "type": "VText",
+ "range": [
+ 122,
+ 127
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 29
+ },
+ "end": {
+ "line": 6,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "VElement",
+ "range": [
+ 127,
+ 169
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 4
+ },
+ "end": {
+ "line": 6,
+ "column": 46
+ }
+ },
+ "name": "mycomponent",
+ "rawName": "MyComponent",
+ "namespace": "http://www.w3.org/1999/xhtml",
+ "startTag": {
+ "type": "VStartTag",
+ "range": [
+ 127,
+ 146
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 4
+ },
+ "end": {
+ "line": 6,
+ "column": 23
+ }
+ },
+ "selfClosing": false,
+ "attributes": [
+ {
+ "type": "VAttribute",
+ "range": [
+ 140,
+ 145
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 17
+ },
+ "end": {
+ "line": 6,
+ "column": 22
+ }
+ },
+ "directive": false,
+ "key": {
+ "type": "VIdentifier",
+ "range": [
+ 140,
+ 143
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 17
+ },
+ "end": {
+ "line": 6,
+ "column": 20
+ }
+ },
+ "name": "foo",
+ "rawName": "foo"
+ },
+ "value": {
+ "type": "VLiteral",
+ "range": [
+ 144,
+ 145
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 21
+ },
+ "end": {
+ "line": 6,
+ "column": 22
+ }
+ },
+ "value": "&"
+ }
+ }
+ ]
+ },
+ "children": [
+ {
+ "type": "VExpressionContainer",
+ "range": [
+ 146,
+ 155
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 23
+ },
+ "end": {
+ "line": 6,
+ "column": 32
+ }
+ },
+ "expression": {
+ "type": "BinaryExpression",
+ "start": 148,
+ "end": 153,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 25
+ },
+ "end": {
+ "line": 6,
+ "column": 30
+ }
+ },
+ "range": [
+ 148,
+ 153
+ ],
+ "left": {
+ "type": "Identifier",
+ "start": 148,
+ "end": 149,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 25
+ },
+ "end": {
+ "line": 6,
+ "column": 26
+ }
+ },
+ "range": [
+ 148,
+ 149
+ ],
+ "name": "a"
+ },
+ "operator": "&",
+ "right": {
+ "type": "Identifier",
+ "start": 152,
+ "end": 153,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 29
+ },
+ "end": {
+ "line": 6,
+ "column": 30
+ }
+ },
+ "range": [
+ 152,
+ 153
+ ],
+ "name": "b"
+ }
+ },
+ "references": [
+ {
+ "id": {
+ "type": "Identifier",
+ "start": 148,
+ "end": 149,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 25
+ },
+ "end": {
+ "line": 6,
+ "column": 26
+ }
+ },
+ "range": [
+ 148,
+ 149
+ ],
+ "name": "a"
+ },
+ "mode": "r"
+ },
+ {
+ "id": {
+ "type": "Identifier",
+ "start": 152,
+ "end": 153,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 29
+ },
+ "end": {
+ "line": 6,
+ "column": 30
+ }
+ },
+ "range": [
+ 152,
+ 153
+ ],
+ "name": "b"
+ },
+ "mode": "r"
+ }
+ ]
+ }
+ ],
+ "endTag": {
+ "type": "VEndTag",
+ "range": [
+ 155,
+ 169
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 32
+ },
+ "end": {
+ "line": 6,
+ "column": 46
+ }
+ }
+ },
+ "variables": []
+ },
+ {
+ "type": "VText",
+ "range": [
+ 169,
+ 176
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 46
+ },
+ "end": {
+ "line": 8,
+ "column": 0
+ }
+ },
+ "value": "\n &\n"
+ }
+ ],
+ "endTag": {
+ "type": "VEndTag",
+ "range": [
+ 176,
+ 187
+ ],
+ "loc": {
+ "start": {
+ "line": 8,
+ "column": 0
+ },
+ "end": {
+ "line": 8,
+ "column": 11
+ }
+ }
+ },
+ "variables": [],
+ "tokens": [
+ {
+ "type": "HTMLTagOpen",
+ "range": [
+ 0,
+ 9
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 0
+ },
+ "end": {
+ "line": 1,
+ "column": 9
+ }
+ },
+ "value": "template"
+ },
+ {
+ "type": "HTMLTagClose",
+ "range": [
+ 9,
+ 10
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 9
+ },
+ "end": {
+ "line": 1,
+ "column": 10
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 10,
+ 15
+ ],
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 10
+ },
+ "end": {
+ "line": 2,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLTagOpen",
+ "range": [
+ 15,
+ 27
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 4
+ },
+ "end": {
+ "line": 2,
+ "column": 16
+ }
+ },
+ "value": "mycomponent"
+ },
+ {
+ "type": "HTMLIdentifier",
+ "range": [
+ 28,
+ 31
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 17
+ },
+ "end": {
+ "line": 2,
+ "column": 20
+ }
+ },
+ "value": "foo"
+ },
+ {
+ "type": "HTMLAssociation",
+ "range": [
+ 31,
+ 32
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 20
+ },
+ "end": {
+ "line": 2,
+ "column": 21
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLLiteral",
+ "range": [
+ 32,
+ 35
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 21
+ },
+ "end": {
+ "line": 2,
+ "column": 24
+ }
+ },
+ "value": "&"
+ },
+ {
+ "type": "HTMLSelfClosingTagClose",
+ "range": [
+ 36,
+ 38
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 25
+ },
+ "end": {
+ "line": 2,
+ "column": 27
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 38,
+ 43
+ ],
+ "loc": {
+ "start": {
+ "line": 2,
+ "column": 27
+ },
+ "end": {
+ "line": 3,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLTagOpen",
+ "range": [
+ 43,
+ 55
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 4
+ },
+ "end": {
+ "line": 3,
+ "column": 16
+ }
+ },
+ "value": "mycomponent"
+ },
+ {
+ "type": "HTMLIdentifier",
+ "range": [
+ 56,
+ 59
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 17
+ },
+ "end": {
+ "line": 3,
+ "column": 20
+ }
+ },
+ "value": "foo"
+ },
+ {
+ "type": "HTMLAssociation",
+ "range": [
+ 59,
+ 60
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 20
+ },
+ "end": {
+ "line": 3,
+ "column": 21
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLLiteral",
+ "range": [
+ 60,
+ 63
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 21
+ },
+ "end": {
+ "line": 3,
+ "column": 24
+ }
+ },
+ "value": "&"
+ },
+ {
+ "type": "HTMLSelfClosingTagClose",
+ "range": [
+ 64,
+ 66
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 25
+ },
+ "end": {
+ "line": 3,
+ "column": 27
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 66,
+ 71
+ ],
+ "loc": {
+ "start": {
+ "line": 3,
+ "column": 27
+ },
+ "end": {
+ "line": 4,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLTagOpen",
+ "range": [
+ 71,
+ 83
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 4
+ },
+ "end": {
+ "line": 4,
+ "column": 16
+ }
+ },
+ "value": "mycomponent"
+ },
+ {
+ "type": "HTMLIdentifier",
+ "range": [
+ 84,
+ 87
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 17
+ },
+ "end": {
+ "line": 4,
+ "column": 20
+ }
+ },
+ "value": "foo"
+ },
+ {
+ "type": "HTMLAssociation",
+ "range": [
+ 87,
+ 88
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 20
+ },
+ "end": {
+ "line": 4,
+ "column": 21
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLLiteral",
+ "range": [
+ 88,
+ 89
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 21
+ },
+ "end": {
+ "line": 4,
+ "column": 22
+ }
+ },
+ "value": "&"
+ },
+ {
+ "type": "HTMLSelfClosingTagClose",
+ "range": [
+ 90,
+ 92
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 23
+ },
+ "end": {
+ "line": 4,
+ "column": 25
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 92,
+ 97
+ ],
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 25
+ },
+ "end": {
+ "line": 5,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLTagOpen",
+ "range": [
+ 97,
+ 109
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 4
+ },
+ "end": {
+ "line": 5,
+ "column": 16
+ }
+ },
+ "value": "mycomponent"
+ },
+ {
+ "type": "HTMLIdentifier",
+ "range": [
+ 110,
+ 113
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 17
+ },
+ "end": {
+ "line": 5,
+ "column": 20
+ }
+ },
+ "value": "foo"
+ },
+ {
+ "type": "HTMLAssociation",
+ "range": [
+ 113,
+ 114
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 20
+ },
+ "end": {
+ "line": 5,
+ "column": 21
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLLiteral",
+ "range": [
+ 114,
+ 115
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 21
+ },
+ "end": {
+ "line": 5,
+ "column": 22
+ }
+ },
+ "value": "&"
+ },
+ {
+ "type": "HTMLIdentifier",
+ "range": [
+ 116,
+ 119
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 23
+ },
+ "end": {
+ "line": 5,
+ "column": 26
+ }
+ },
+ "value": "bar"
+ },
+ {
+ "type": "HTMLSelfClosingTagClose",
+ "range": [
+ 120,
+ 122
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 27
+ },
+ "end": {
+ "line": 5,
+ "column": 29
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 122,
+ 127
+ ],
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 29
+ },
+ "end": {
+ "line": 6,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLTagOpen",
+ "range": [
+ 127,
+ 139
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 4
+ },
+ "end": {
+ "line": 6,
+ "column": 16
+ }
+ },
+ "value": "mycomponent"
+ },
+ {
+ "type": "HTMLIdentifier",
+ "range": [
+ 140,
+ 143
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 17
+ },
+ "end": {
+ "line": 6,
+ "column": 20
+ }
+ },
+ "value": "foo"
+ },
+ {
+ "type": "HTMLAssociation",
+ "range": [
+ 143,
+ 144
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 20
+ },
+ "end": {
+ "line": 6,
+ "column": 21
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLLiteral",
+ "range": [
+ 144,
+ 145
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 21
+ },
+ "end": {
+ "line": 6,
+ "column": 22
+ }
+ },
+ "value": "&"
+ },
+ {
+ "type": "HTMLTagClose",
+ "range": [
+ 145,
+ 146
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 22
+ },
+ "end": {
+ "line": 6,
+ "column": 23
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "VExpressionStart",
+ "range": [
+ 146,
+ 148
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 23
+ },
+ "end": {
+ "line": 6,
+ "column": 25
+ }
+ },
+ "value": "{{"
+ },
+ {
+ "type": "Identifier",
+ "value": "a",
+ "start": 148,
+ "end": 149,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 25
+ },
+ "end": {
+ "line": 6,
+ "column": 26
+ }
+ },
+ "range": [
+ 148,
+ 149
+ ]
+ },
+ {
+ "type": "Punctuator",
+ "value": "&",
+ "start": 150,
+ "end": 151,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 27
+ },
+ "end": {
+ "line": 6,
+ "column": 28
+ }
+ },
+ "range": [
+ 150,
+ 151
+ ]
+ },
+ {
+ "type": "Identifier",
+ "value": "b",
+ "start": 152,
+ "end": 153,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 29
+ },
+ "end": {
+ "line": 6,
+ "column": 30
+ }
+ },
+ "range": [
+ 152,
+ 153
+ ]
+ },
+ {
+ "type": "VExpressionEnd",
+ "range": [
+ 153,
+ 155
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 30
+ },
+ "end": {
+ "line": 6,
+ "column": 32
+ }
+ },
+ "value": "}}"
+ },
+ {
+ "type": "HTMLEndTagOpen",
+ "range": [
+ 155,
+ 168
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 32
+ },
+ "end": {
+ "line": 6,
+ "column": 45
+ }
+ },
+ "value": "mycomponent"
+ },
+ {
+ "type": "HTMLTagClose",
+ "range": [
+ 168,
+ 169
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 45
+ },
+ "end": {
+ "line": 6,
+ "column": 46
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 169,
+ 174
+ ],
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 46
+ },
+ "end": {
+ "line": 7,
+ "column": 4
+ }
+ },
+ "value": "\n "
+ },
+ {
+ "type": "HTMLText",
+ "range": [
+ 174,
+ 175
+ ],
+ "loc": {
+ "start": {
+ "line": 7,
+ "column": 4
+ },
+ "end": {
+ "line": 7,
+ "column": 5
+ }
+ },
+ "value": "&"
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 175,
+ 176
+ ],
+ "loc": {
+ "start": {
+ "line": 7,
+ "column": 5
+ },
+ "end": {
+ "line": 8,
+ "column": 0
+ }
+ },
+ "value": "\n"
+ },
+ {
+ "type": "HTMLEndTagOpen",
+ "range": [
+ 176,
+ 186
+ ],
+ "loc": {
+ "start": {
+ "line": 8,
+ "column": 0
+ },
+ "end": {
+ "line": 8,
+ "column": 10
+ }
+ },
+ "value": "template"
+ },
+ {
+ "type": "HTMLTagClose",
+ "range": [
+ 186,
+ 187
+ ],
+ "loc": {
+ "start": {
+ "line": 8,
+ "column": 10
+ },
+ "end": {
+ "line": 8,
+ "column": 11
+ }
+ },
+ "value": ""
+ },
+ {
+ "type": "HTMLWhitespace",
+ "range": [
+ 187,
+ 188
+ ],
+ "loc": {
+ "start": {
+ "line": 8,
+ "column": 11
+ },
+ "end": {
+ "line": 9,
+ "column": 0
+ }
+ },
+ "value": "\n"
+ }
+ ],
+ "comments": [],
+ "errors": [
+ {
+ "message": "non-void-html-element-start-tag-with-trailing-solidus",
+ "index": 15,
+ "lineNumber": 2,
+ "column": 4
+ },
+ {
+ "message": "non-void-html-element-start-tag-with-trailing-solidus",
+ "index": 43,
+ "lineNumber": 3,
+ "column": 4
+ },
+ {
+ "message": "non-void-html-element-start-tag-with-trailing-solidus",
+ "index": 71,
+ "lineNumber": 4,
+ "column": 4
+ },
+ {
+ "message": "non-void-html-element-start-tag-with-trailing-solidus",
+ "index": 97,
+ "lineNumber": 5,
+ "column": 4
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/test/fixtures/ast/html-entities-lone-amp/source.vue b/test/fixtures/ast/html-entities-lone-amp/source.vue
new file mode 100644
index 00000000..b6bac9ef
--- /dev/null
+++ b/test/fixtures/ast/html-entities-lone-amp/source.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+ {{a & b}}
+ &
+
diff --git a/test/fixtures/ast/html-entities-lone-amp/token-ranges.json b/test/fixtures/ast/html-entities-lone-amp/token-ranges.json
new file mode 100644
index 00000000..0f15d840
--- /dev/null
+++ b/test/fixtures/ast/html-entities-lone-amp/token-ranges.json
@@ -0,0 +1,48 @@
+[
+ "",
+ "\n ",
+ "",
+ "\n ",
+ "",
+ "\n ",
+ "",
+ "\n ",
+ "",
+ "\n ",
+ "",
+ "{{",
+ "a",
+ "&",
+ "b",
+ "}}",
+ "",
+ "\n ",
+ "&",
+ "\n",
+ "",
+ "\n"
+]
\ No newline at end of file
diff --git a/test/fixtures/ast/html-entities-lone-amp/tree.json b/test/fixtures/ast/html-entities-lone-amp/tree.json
new file mode 100644
index 00000000..68c8ede7
--- /dev/null
+++ b/test/fixtures/ast/html-entities-lone-amp/tree.json
@@ -0,0 +1,226 @@
+[
+ {
+ "type": "VElement",
+ "text": "\n \n \n \n \n {{a & b}}\n &\n",
+ "children": [
+ {
+ "type": "VStartTag",
+ "text": "",
+ "children": []
+ },
+ {
+ "type": "VText",
+ "text": "\n ",
+ "children": []
+ },
+ {
+ "type": "VElement",
+ "text": "",
+ "children": [
+ {
+ "type": "VStartTag",
+ "text": "",
+ "children": [
+ {
+ "type": "VAttribute",
+ "text": "foo=\"&\"",
+ "children": [
+ {
+ "type": "VIdentifier",
+ "text": "foo",
+ "children": []
+ },
+ {
+ "type": "VLiteral",
+ "text": "\"&\"",
+ "children": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "VText",
+ "text": "\n ",
+ "children": []
+ },
+ {
+ "type": "VElement",
+ "text": "",
+ "children": [
+ {
+ "type": "VStartTag",
+ "text": "",
+ "children": [
+ {
+ "type": "VAttribute",
+ "text": "foo='&'",
+ "children": [
+ {
+ "type": "VIdentifier",
+ "text": "foo",
+ "children": []
+ },
+ {
+ "type": "VLiteral",
+ "text": "'&'",
+ "children": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "VText",
+ "text": "\n ",
+ "children": []
+ },
+ {
+ "type": "VElement",
+ "text": "",
+ "children": [
+ {
+ "type": "VStartTag",
+ "text": "",
+ "children": [
+ {
+ "type": "VAttribute",
+ "text": "foo=&",
+ "children": [
+ {
+ "type": "VIdentifier",
+ "text": "foo",
+ "children": []
+ },
+ {
+ "type": "VLiteral",
+ "text": "&",
+ "children": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "VText",
+ "text": "\n ",
+ "children": []
+ },
+ {
+ "type": "VElement",
+ "text": "",
+ "children": [
+ {
+ "type": "VStartTag",
+ "text": "",
+ "children": [
+ {
+ "type": "VAttribute",
+ "text": "foo=&",
+ "children": [
+ {
+ "type": "VIdentifier",
+ "text": "foo",
+ "children": []
+ },
+ {
+ "type": "VLiteral",
+ "text": "&",
+ "children": []
+ }
+ ]
+ },
+ {
+ "type": "VAttribute",
+ "text": "bar",
+ "children": [
+ {
+ "type": "VIdentifier",
+ "text": "bar",
+ "children": []
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "VText",
+ "text": "\n ",
+ "children": []
+ },
+ {
+ "type": "VElement",
+ "text": "{{a & b}}",
+ "children": [
+ {
+ "type": "VStartTag",
+ "text": "",
+ "children": [
+ {
+ "type": "VAttribute",
+ "text": "foo=&",
+ "children": [
+ {
+ "type": "VIdentifier",
+ "text": "foo",
+ "children": []
+ },
+ {
+ "type": "VLiteral",
+ "text": "&",
+ "children": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "VExpressionContainer",
+ "text": "{{a & b}}",
+ "children": [
+ {
+ "type": "BinaryExpression",
+ "text": "a & b",
+ "children": [
+ {
+ "type": "Identifier",
+ "text": "a",
+ "children": []
+ },
+ {
+ "type": "Identifier",
+ "text": "b",
+ "children": []
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "type": "VEndTag",
+ "text": "",
+ "children": []
+ }
+ ]
+ },
+ {
+ "type": "VText",
+ "text": "\n &\n",
+ "children": []
+ },
+ {
+ "type": "VEndTag",
+ "text": "",
+ "children": []
+ }
+ ]
+ }
+]
\ No newline at end of file