Skip to content

Commit

Permalink
fix: avoid expr continuations for period when not followed by identifier
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Mar 8, 2023
1 parent 33d280d commit 61e6966
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-clouds-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"htmljs-parser": patch
---

Avoid continuing expressions after a period if after the whitespace is something that could not be an identifier.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
1╭─ $ $global.
│ │╰─ scriptlet.value "$global."
╰─ ╰─ scriptlet " $global."
2├─
3╭─ <header>
│ ││ ╰─ openTagEnd
│ │╰─ tagName "header"
╰─ ╰─ openTagStart
4╭─ <img.logo src=logo alt="Marko"/>
│ │ ││ ││ │ ││ │ ││ ╰─ openTagEnd:selfClosed "/>"
│ │ ││ ││ │ ││ │ │╰─ attrValue.value "\"Marko\""
│ │ ││ ││ │ ││ │ ╰─ attrValue "=\"Marko\""
│ │ ││ ││ │ ││ ╰─ attrName "alt"
│ │ ││ ││ │ │╰─ attrValue.value "logo"
│ │ ││ ││ │ ╰─ attrValue "=logo"
│ │ ││ ││ ╰─ attrName "src"
│ │ ││ │╰─ tagShorthandClass.quasis[0] "logo"
│ │ ││ ╰─ tagShorthandClass ".logo"
│ │ │╰─ tagName "img"
│ │ ╰─ openTagStart
╰─ ╰─ text "\n "
5╭─ </header>
│ │ │ ╰─ closeTagEnd(header)
│ │ ╰─ closeTagName "header"
│ ├─ text "\n"
╰─ ╰─ closeTagStart "</"
6╰─
5 changes: 5 additions & 0 deletions src/__tests__/fixtures/scriptlet-eof/input.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$ $global.

<header>
<img.logo src=logo alt="Marko"/>
</header>
16 changes: 12 additions & 4 deletions src/states/EXPRESSION.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,17 @@ function lookBehindForOperator(data: string, pos: number): number {
case CODE.OPEN_ANGLE_BRACKET:
case CODE.CLOSE_ANGLE_BRACKET:
case CODE.PERCENT:
case CODE.PERIOD:
case CODE.PIPE:
case CODE.QUESTION:
case CODE.TILDE:
return curPos;

case CODE.PERIOD: {
// Only matches `.` followed by something that could be an identifier.
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos);
return isWordCode(data.charCodeAt(nextPos)) ? nextPos : -1;
}

// special case -- and ++
case CODE.PLUS:
case CODE.HYPHEN: {
Expand Down Expand Up @@ -324,9 +329,11 @@ function lookAheadForOperator(data: string, pos: number): number {
case CODE.OPEN_PAREN:
return pos; // defers to base expression state to track block groups.

case CODE.PERIOD:
// Only match a dot if its not ...
return data.charCodeAt(pos + 1) === CODE.PERIOD ? -1 : pos + 1;
case CODE.PERIOD: {
// Only matches `.` followed by something that could be an identifier.
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos + 1);
return isWordCode(data.charCodeAt(nextPos)) ? nextPos : -1;
}

default: {
for (const keyword of binaryKeywords) {
Expand Down Expand Up @@ -383,6 +390,7 @@ function isWordCode(code: number) {
(code >= CODE.UPPER_A && code <= CODE.UPPER_Z) ||
(code >= CODE.LOWER_A && code <= CODE.LOWER_Z) ||
(code >= CODE.NUMBER_0 && code <= CODE.NUMBER_9) ||
code == CODE.DOLLAR ||
code === CODE.UNDERSCORE
);
}
Expand Down

0 comments on commit 61e6966

Please sign in to comment.