New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: make no-misleading-character-class
report more granular errors
#18082
Changes from 1 commit
82d7b3c
1e8525f
45006ec
836fe39
d8fd769
d351f21
b2cb30e
90bee47
53e262a
448d9a9
b1cf05f
7bb7e55
072f256
6792594
ea6f183
ed8d1cd
7eaf8b4
ebe11f8
64813fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -32,6 +32,12 @@ class SourceReader { | |||||
this.source = source; | ||||||
this.pos = 0; | ||||||
} | ||||||
|
||||||
read(offset = 0, length = 1) { | ||||||
const start = offset + this.pos; | ||||||
|
||||||
return this.source.slice(start, start + length); | ||||||
} | ||||||
} | ||||||
|
||||||
const SIMPLE_ESCAPE_SEQUENCES = | ||||||
|
@@ -44,11 +50,10 @@ const SIMPLE_ESCAPE_SEQUENCES = | |||||
* @returns {string} A code unit. | ||||||
*/ | ||||||
function readHexSequence(reader, length) { | ||||||
const { source, pos } = reader; | ||||||
const str = source.slice(pos, pos + length); | ||||||
const str = reader.read(0, length); | ||||||
const charCode = parseInt(str, 16); | ||||||
|
||||||
reader.pos = pos + length; | ||||||
reader.pos += length; | ||||||
return String.fromCharCode(charCode); | ||||||
} | ||||||
|
||||||
|
@@ -58,11 +63,10 @@ function readHexSequence(reader, length) { | |||||
* @returns {string} A code unit. | ||||||
*/ | ||||||
function readUnicodeSequence(reader) { | ||||||
const { source, pos } = reader; | ||||||
const regExp = /\{(?<hexDigits>[\dA-Fa-f]+)\}/uy; | ||||||
|
||||||
regExp.lastIndex = pos; | ||||||
const match = regExp.exec(source); | ||||||
regExp.lastIndex = reader.pos; | ||||||
const match = regExp.exec(reader.source); | ||||||
|
||||||
if (match) { | ||||||
const codePoint = parseInt(match.groups.hexDigits, 16); | ||||||
|
@@ -80,25 +84,23 @@ function readUnicodeSequence(reader) { | |||||
* @returns {string} A code unit. | ||||||
*/ | ||||||
function readOctalSequence(reader, maxLength) { | ||||||
const posAfterBackslash = reader.pos - 1; | ||||||
const [octalStr] = reader.source.slice(posAfterBackslash, posAfterBackslash + maxLength).match(/^[0-7]+/u); | ||||||
const [octalStr] = reader.read(-1, maxLength).match(/^[0-7]+/u); | ||||||
|
||||||
reader.pos = posAfterBackslash + octalStr.length; | ||||||
reader.pos += octalStr.length - 1; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because you refactored to include a
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good idea 👍🏻 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All done in b1cf05f. |
||||||
const octal = parseInt(octalStr, 8); | ||||||
|
||||||
return String.fromCharCode(octal); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Reads an escape sequence or line continuation. | ||||||
* @param {SourceReader} reader The reader should be positioned after the backslash. | ||||||
* @param {SourceReader} reader The reader should be positioned on the backslash. | ||||||
* @returns {string} A string of zero, one or two code units. | ||||||
*/ | ||||||
function readEscapeSequenceOrLineContinuation(reader) { | ||||||
const { source, pos } = reader; | ||||||
const char = source[pos]; | ||||||
const char = reader.read(1); | ||||||
|
||||||
reader.pos = pos + 1; | ||||||
reader.pos += 2; | ||||||
const unitChar = SIMPLE_ESCAPE_SEQUENCES[char]; | ||||||
|
||||||
if (unitChar) { | ||||||
|
@@ -110,8 +112,8 @@ function readEscapeSequenceOrLineContinuation(reader) { | |||||
case "u": | ||||||
return readUnicodeSequence(reader); | ||||||
case "\r": | ||||||
if (source[pos + 1] === "\n") { | ||||||
reader.pos = pos + 2; | ||||||
if (reader.read() === "\n") { | ||||||
reader.pos += 1; | ||||||
} | ||||||
|
||||||
// fallthrough | ||||||
|
@@ -140,7 +142,7 @@ function readEscapeSequenceOrLineContinuation(reader) { | |||||
* @returns {Generator<CodeUnit>} Zero, one or two `CodeUnit` elements. | ||||||
*/ | ||||||
function *mapEscapeSequenceOrLineContinuation(reader) { | ||||||
const start = reader.pos++; | ||||||
const start = reader.pos; | ||||||
const str = readEscapeSequenceOrLineContinuation(reader); | ||||||
const end = reader.pos; | ||||||
const source = reader.source.slice(start, end); | ||||||
|
@@ -165,23 +167,22 @@ function *mapEscapeSequenceOrLineContinuation(reader) { | |||||
*/ | ||||||
function parseStringLiteral(source) { | ||||||
const reader = new SourceReader(source); | ||||||
const quote = source[0]; | ||||||
const quote = reader.read(); | ||||||
|
||||||
reader.pos = 1; | ||||||
const codeUnits = []; | ||||||
|
||||||
for (;;) { | ||||||
const { pos } = reader; | ||||||
const char = source[pos]; | ||||||
const char = reader.read(); | ||||||
|
||||||
if (char === quote) { | ||||||
break; | ||||||
} | ||||||
if (char === "\\") { | ||||||
codeUnits.push(...mapEscapeSequenceOrLineContinuation(reader)); | ||||||
} else { | ||||||
reader.pos = pos + 1; | ||||||
codeUnits.push(new CodeUnit(pos, char)); | ||||||
codeUnits.push(new CodeUnit(reader.pos, char)); | ||||||
reader.pos += 1; | ||||||
} | ||||||
} | ||||||
return codeUnits; | ||||||
|
@@ -199,25 +200,23 @@ function parseTemplateToken(source) { | |||||
const codeUnits = []; | ||||||
|
||||||
for (;;) { | ||||||
const { pos } = reader; | ||||||
const char = source[pos]; | ||||||
const char = reader.read(); | ||||||
|
||||||
if (char === "`" || char === "$" && source[pos + 1] === "{") { | ||||||
if (char === "`" || char === "$" && reader.read(1) === "{") { | ||||||
break; | ||||||
} | ||||||
if (char === "\\") { | ||||||
codeUnits.push(...mapEscapeSequenceOrLineContinuation(reader)); | ||||||
} else { | ||||||
let unitSource; | ||||||
|
||||||
if (char === "\r" && source[pos + 1] === "\n") { | ||||||
if (char === "\r" && reader.read(1) === "\n") { | ||||||
unitSource = "\r\n"; | ||||||
reader.pos = pos + 2; | ||||||
} else { | ||||||
unitSource = char; | ||||||
reader.pos = pos + 1; | ||||||
} | ||||||
codeUnits.push(new CodeUnit(pos, unitSource)); | ||||||
codeUnits.push(new CodeUnit(reader.pos, unitSource)); | ||||||
reader.pos += unitSource.length; | ||||||
} | ||||||
} | ||||||
return codeUnits; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add some JSDoc here?