diff --git a/src/common/lines-and-columns.ts b/src/common/lines-and-columns.ts index e6b7028f..ff1feef5 100644 --- a/src/common/lines-and-columns.ts +++ b/src/common/lines-and-columns.ts @@ -1,5 +1,6 @@ import sortedLastIndex from "lodash/sortedLastIndex" import type { Location } from "../ast" +import type { LocationCalculator } from "./location-calculator" /** * A class for getting lines and columns location. */ @@ -24,4 +25,13 @@ export class LinesAndColumns { const column = index - (line === 1 ? 0 : this.ltOffsets[line - 2]) return { line, column } } + + public createOffsetLocationCalculator(offset: number): LocationCalculator { + return { + getFixOffset() { + return offset + }, + getLocFromIndex: this.getLocFromIndex.bind(this), + } + } } diff --git a/src/html/tokenizer.ts b/src/html/tokenizer.ts index 3357a14e..f4b8825d 100644 --- a/src/html/tokenizer.ts +++ b/src/html/tokenizer.ts @@ -170,6 +170,7 @@ export class Tokenizer { public readonly lineTerminators: number[] private readonly parserOptions: ParserOptions private lastCodePoint: number + private lastCodePointRaw: number private offset: number private column: number private line: number @@ -221,7 +222,7 @@ export class Tokenizer { this.gaps = [] this.lineTerminators = [] this.parserOptions = parserOptions || {} - this.lastCodePoint = NULL + this.lastCodePoint = this.lastCodePointRaw = NULL this.offset = -1 this.column = -1 this.line = 1 @@ -307,14 +308,14 @@ export class Tokenizer { */ private consumeNextCodePoint(): number { if (this.offset >= this.text.length) { - this.lastCodePoint = EOF + this.lastCodePoint = this.lastCodePointRaw = EOF return EOF } this.offset += this.lastCodePoint >= 0x10000 ? 2 : 1 if (this.offset >= this.text.length) { this.advanceLocation() - this.lastCodePoint = EOF + this.lastCodePoint = this.lastCodePointRaw = EOF return EOF } @@ -334,18 +335,19 @@ export class Tokenizer { } // Skip LF to convert CRLF → LF. - if (this.lastCodePoint === CARRIAGE_RETURN && cp === LINE_FEED) { - this.lastCodePoint = LINE_FEED + if (this.lastCodePointRaw === CARRIAGE_RETURN && cp === LINE_FEED) { + this.lastCodePoint = this.lastCodePointRaw = LINE_FEED this.gaps.push(this.offset) return this.consumeNextCodePoint() } // Update locations. this.advanceLocation() - this.lastCodePoint = cp + this.lastCodePoint = this.lastCodePointRaw = cp // To convert CRLF → LF. if (cp === CARRIAGE_RETURN) { + this.lastCodePoint = LINE_FEED return LINE_FEED } @@ -356,7 +358,7 @@ export class Tokenizer { * Advance the current line and column. */ private advanceLocation(): void { - if (this.lastCodePoint === LINE_FEED) { + if (this.lastCodePointRaw === LINE_FEED) { this.lineTerminators.push(this.offset) this.line += 1 this.column = 0 diff --git a/src/index.ts b/src/index.ts index 6bf09da3..afff45e1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -132,10 +132,15 @@ export function parseForESLint( }, ) } else { - result = parseScriptElement(scripts[0], locationCalculator, { - ...options, - parser: scriptParser, - }) + result = parseScriptElement( + scripts[0], + code, + new LinesAndColumns(tokenizer.lineTerminators), + { + ...options, + parser: scriptParser, + }, + ) } if (options.vueFeatures?.styleCSSVariableInjection ?? true) { diff --git a/src/script-setup/index.ts b/src/script-setup/index.ts index 4b5e5e30..c9321b22 100644 --- a/src/script-setup/index.ts +++ b/src/script-setup/index.ts @@ -189,7 +189,7 @@ function parseScript( * Parse the source code of the given `\r + `, + { + sourceType: "module", + }, + ) + const script = parsed.services + .getDocumentFragment() + .children.find( + (child) => child.type === "VElement" && child.name === "script", + ) + assert.ok(!script.children[0].value.includes("\r")) + }) + it("should contain CRLF in script comment.", async () => { + const parsed = parser.parseForESLint( + `\r + `, + { + sourceType: "module", + }, + ) + assert.ok(parsed.ast.comments[0].value.includes("\r\n")) + }) +})