mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(ast,parser): use u32 for node spans
The next PR will fix the jargon where Node = Span. relates to #9
This commit is contained in:
parent
39a05030d7
commit
a733856536
20 changed files with 260 additions and 237 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -537,6 +537,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"bitflags",
|
||||
"compact_str",
|
||||
"miette",
|
||||
"num-bigint",
|
||||
"ordered-float",
|
||||
"oxc_allocator",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ compact_str = { workspace = true, features = ["serde"] }
|
|||
thiserror = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true, optional = true }
|
||||
miette = { workspace = true }
|
||||
|
||||
num-bigint = "0.4.3"
|
||||
ryu-js = "0.2.2"
|
||||
|
|
|
|||
|
|
@ -3,29 +3,40 @@ use std::{
|
|||
ops::Range,
|
||||
};
|
||||
|
||||
use miette::{SourceOffset, SourceSpan};
|
||||
use serde::Serialize;
|
||||
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use crate::ast::*;
|
||||
|
||||
pub type Span = Range<usize>;
|
||||
pub type Span = Range<u32>;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Serialize, PartialEq, Eq)]
|
||||
pub struct Node {
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
pub start: u32,
|
||||
pub end: u32,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn new(start: usize, end: usize) -> Self {
|
||||
pub const fn new(start: u32, end: u32) -> Self {
|
||||
Self { start, end }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn range(&self) -> Span {
|
||||
self.start..self.end
|
||||
(self.start)..(self.end)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn len(&self) -> u32 {
|
||||
self.end - self.start
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +47,12 @@ impl Hash for Node {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Node> for SourceSpan {
|
||||
fn from(val: Node) -> Self {
|
||||
Self::new(SourceOffset::from(val.start as usize), SourceOffset::from(val.len() as usize))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GetNode {
|
||||
#[must_use]
|
||||
fn node(&self) -> Node;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{cell::RefCell, ops::Deref, rc::Rc};
|
||||
|
||||
use oxc_ast::{Atom, Span};
|
||||
use oxc_ast::{Atom, Node};
|
||||
use thiserror::Error;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Diagnostic>;
|
||||
|
|
@ -30,120 +30,120 @@ impl Diagnostics {
|
|||
pub enum Diagnostic {
|
||||
#[error("This file panicked")]
|
||||
#[diagnostic()]
|
||||
Panic(#[label("")] Span),
|
||||
Panic(#[label("")] Node),
|
||||
|
||||
#[error("Flow is not supported")]
|
||||
#[diagnostic()]
|
||||
Flow(#[label("")] Span),
|
||||
Flow(#[label("")] Node),
|
||||
|
||||
/* Lexer */
|
||||
#[error("Syntax Error")]
|
||||
#[diagnostic()]
|
||||
UnexpectedToken(#[label("Unexpected Token")] Span),
|
||||
UnexpectedToken(#[label("Unexpected Token")] Node),
|
||||
|
||||
#[error("Syntax Error")]
|
||||
#[diagnostic()]
|
||||
ExpectToken(&'static str, &'static str, #[label("Expect `{0}` here, but found `{1}`")] Span),
|
||||
ExpectToken(&'static str, &'static str, #[label("Expect `{0}` here, but found `{1}`")] Node),
|
||||
|
||||
#[error("Invalid escape sequence")]
|
||||
InvalidEscapeSequence(#[label("Invalid escape sequence")] Span),
|
||||
InvalidEscapeSequence(#[label("Invalid escape sequence")] Node),
|
||||
|
||||
#[error("Invalid escape sequence")]
|
||||
NonOctalDecimalEscapeSequence(#[label("\\8 and \\9 are not allowed in strict mode")] Span),
|
||||
NonOctalDecimalEscapeSequence(#[label("\\8 and \\9 are not allowed in strict mode")] Node),
|
||||
|
||||
#[error("Invalid Unicode escape sequence")]
|
||||
UnicodeEscapeSequence(#[label("Invalid Unicode escape sequence")] Span),
|
||||
UnicodeEscapeSequence(#[label("Invalid Unicode escape sequence")] Node),
|
||||
|
||||
#[error("Invalid Character `{0}`")]
|
||||
InvalidCharacter(char, #[label("Invalid Character `{0}`")] Span),
|
||||
InvalidCharacter(char, #[label("Invalid Character `{0}`")] Node),
|
||||
|
||||
#[error("Invalid characters after number")]
|
||||
InvalidNumberEnd(#[label("Invalid characters after number")] Span),
|
||||
InvalidNumberEnd(#[label("Invalid characters after number")] Node),
|
||||
|
||||
#[error("Unterminated multiLine comment")]
|
||||
UnterminatedMultiLineComment(#[label("Unterminated multiLine comment")] Span),
|
||||
UnterminatedMultiLineComment(#[label("Unterminated multiLine comment")] Node),
|
||||
|
||||
#[error("Unterminated string")]
|
||||
UnterminatedString(#[label("Unterminated string")] Span),
|
||||
UnterminatedString(#[label("Unterminated string")] Node),
|
||||
|
||||
#[error("Unexpected flag {0} in regular expression literal")]
|
||||
RegExpFlag(char, #[label("Unexpected flag {0} in regular expression literal")] Span),
|
||||
RegExpFlag(char, #[label("Unexpected flag {0} in regular expression literal")] Node),
|
||||
|
||||
#[error("Flag {0} is mentioned twice in regular expression literal")]
|
||||
RegExpFlagTwice(
|
||||
char,
|
||||
#[label("Flag {0} is mentioned twice in regular expression literal")] Span,
|
||||
#[label("Flag {0} is mentioned twice in regular expression literal")] Node,
|
||||
),
|
||||
|
||||
#[error("The 'u' and 'v' regular expression flags cannot be enabled at the same time")]
|
||||
RegExpFlagUAndV(
|
||||
#[label("The 'u' and 'v' regular expression flags cannot be enabled at the same time")]
|
||||
Span,
|
||||
Node,
|
||||
),
|
||||
|
||||
#[error("Unexpected end of file")]
|
||||
UnexpectedEnd(#[label("Unexpected end of file")] Span),
|
||||
UnexpectedEnd(#[label("Unexpected end of file")] Node),
|
||||
|
||||
#[error("Unterminated regular expression")]
|
||||
UnterminatedRegExp(#[label("Unterminated regular expression")] Span),
|
||||
UnterminatedRegExp(#[label("Unterminated regular expression")] Node),
|
||||
|
||||
#[error("Invalid Number")]
|
||||
InvalidNumber(&'static str, #[label("{0}")] Span),
|
||||
InvalidNumber(&'static str, #[label("{0}")] Node),
|
||||
|
||||
#[error("Keywords cannot contain escape characters")]
|
||||
#[diagnostic()]
|
||||
EscapedKeyword(#[label("keyword cannot contain escape characters")] Span),
|
||||
EscapedKeyword(#[label("keyword cannot contain escape characters")] Node),
|
||||
/* Syntax Errors */
|
||||
#[error("Automatic Semicolon Insertion")]
|
||||
#[diagnostic(help("Try insert a semicolon here"))]
|
||||
AutoSemicolonInsertion(
|
||||
#[label("Expected a semicolon or an implicit semicolon after a statement, but found none")]
|
||||
Span,
|
||||
Node,
|
||||
),
|
||||
|
||||
#[error("Octal literals are not allowed in strict mode")]
|
||||
#[diagnostic(help("for octal literals use the '0o' prefix instead"))]
|
||||
LegacyOctal(
|
||||
#[label("'0'-prefixed octal literals and octal escape sequences are deprecated")] Span,
|
||||
#[label("'0'-prefixed octal literals and octal escape sequences are deprecated")] Node,
|
||||
),
|
||||
|
||||
#[error("Decimals with leading zeros are not allowed in strict mode")]
|
||||
#[diagnostic(help("remove the leading zero"))]
|
||||
LeadingZeroDecimal(#[label("Decimals with leading zeros are not allowed in strict mode")] Span),
|
||||
LeadingZeroDecimal(#[label("Decimals with leading zeros are not allowed in strict mode")] Node),
|
||||
|
||||
#[error("Line terminator not permitted before arrow")]
|
||||
#[diagnostic()]
|
||||
LineterminatorBeforeArrow(#[label("Line terminator not permitted before arrow")] Span),
|
||||
LineterminatorBeforeArrow(#[label("Line terminator not permitted before arrow")] Node),
|
||||
|
||||
#[error("Unexpected new.target expression")]
|
||||
#[diagnostic(help(
|
||||
"new.target is only allowed in constructors and functions invoked using thew `new` operator"
|
||||
))]
|
||||
NewTarget(#[label("new.target expression is not allowed here")] Span),
|
||||
NewTarget(#[label("new.target expression is not allowed here")] Node),
|
||||
|
||||
#[error("The only valid meta property for new is new.target")]
|
||||
#[diagnostic()]
|
||||
NewTargetProperty(#[label("The only valid meta property for new is new.target")] Span),
|
||||
NewTargetProperty(#[label("The only valid meta property for new is new.target")] Node),
|
||||
|
||||
#[error("Unexpected import.meta expression")]
|
||||
#[diagnostic(help("import.meta is only allowed in module code"))]
|
||||
ImportMeta(#[label("import.meta expression is not allowed here")] Span),
|
||||
ImportMeta(#[label("import.meta expression is not allowed here")] Node),
|
||||
|
||||
#[error("The only valid meta property for import is import.meta")]
|
||||
#[diagnostic()]
|
||||
ImportMetaProperty(#[label("The only valid meta property for import is import.meta")] Span),
|
||||
ImportMetaProperty(#[label("The only valid meta property for import is import.meta")] Node),
|
||||
|
||||
#[error("Illegal break statement")]
|
||||
#[diagnostic(help(
|
||||
"A `break` statement can only be used within an enclosing iteration or switch statement."
|
||||
))]
|
||||
InvalidBreak(#[label("break statement is not allowed here")] Span),
|
||||
InvalidBreak(#[label("break statement is not allowed here")] Node),
|
||||
|
||||
#[error("Illegal continue statement: no surrounding iteration statement")]
|
||||
#[diagnostic(help(
|
||||
"A `continue` statement can only be used within an enclosing `for`, `while` or `do while` "
|
||||
))]
|
||||
InvalidContinue(#[label("continue statement is not allowed here")] Span),
|
||||
InvalidContinue(#[label("continue statement is not allowed here")] Node),
|
||||
|
||||
#[error(
|
||||
"A `{0}` statement can only jump to a label of an enclosing `for`, `while` or `do while` statement."
|
||||
|
|
@ -151,349 +151,349 @@ pub enum Diagnostic {
|
|||
#[diagnostic()]
|
||||
InvalidLabelNonIteration(
|
||||
&'static str,
|
||||
#[label("This is an non-iteration statement")] Span,
|
||||
#[label("for this label")] Span,
|
||||
#[label("This is an non-iteration statement")] Node,
|
||||
#[label("for this label")] Node,
|
||||
),
|
||||
|
||||
#[error("Use of undefined label")]
|
||||
#[diagnostic()]
|
||||
InvalidLabelTarget(#[label("This label is used, but not defined")] Span),
|
||||
InvalidLabelTarget(#[label("This label is used, but not defined")] Node),
|
||||
|
||||
#[error("Jump target cannot cross function boundary.")]
|
||||
#[diagnostic()]
|
||||
InvalidLabelJumpTarget(#[label("Jump target cannot cross function boundary.")] Span),
|
||||
InvalidLabelJumpTarget(#[label("Jump target cannot cross function boundary.")] Node),
|
||||
|
||||
#[error("Unexpected '{0}' strict mode")]
|
||||
#[diagnostic()]
|
||||
UnexpectedIdentifierAssign(Atom, #[label("Cannot assign to '{0}' in strict mode")] Span),
|
||||
UnexpectedIdentifierAssign(Atom, #[label("Cannot assign to '{0}' in strict mode")] Node),
|
||||
|
||||
#[error("Invalid left-hand side in assignment")]
|
||||
#[diagnostic()]
|
||||
UnexpectedLhsAssign(#[label("Invalid left-hand side in assignment")] Span),
|
||||
UnexpectedLhsAssign(#[label("Invalid left-hand side in assignment")] Node),
|
||||
|
||||
#[error("The keyword '{0}' is reserved")]
|
||||
#[diagnostic()]
|
||||
ReservedKeyword(Atom, #[label("{0} is reserved")] Span),
|
||||
ReservedKeyword(Atom, #[label("{0} is reserved")] Node),
|
||||
|
||||
#[error("Identifier `{0}` has already been declared")]
|
||||
#[diagnostic()]
|
||||
Redeclaration(
|
||||
Atom,
|
||||
#[label("`{0}` has already been declared here")] Span,
|
||||
#[label("It can not be redeclared here")] Span,
|
||||
#[label("`{0}` has already been declared here")] Node,
|
||||
#[label("It can not be redeclared here")] Node,
|
||||
),
|
||||
|
||||
#[error("{0} is disallowed as a lexically bound name")]
|
||||
#[diagnostic()]
|
||||
DisallowedLexicalName(Atom, #[label("{0} is disallowed as a lexically bound name")] Span),
|
||||
DisallowedLexicalName(Atom, #[label("{0} is disallowed as a lexically bound name")] Node),
|
||||
|
||||
#[error("`let` cannot be declared as a variable name inside of a `{0}` declaration")]
|
||||
#[diagnostic()]
|
||||
InvalidLetDeclaration(String, #[label("Rename the let identifier here")] Span),
|
||||
InvalidLetDeclaration(String, #[label("Rename the let identifier here")] Node),
|
||||
|
||||
#[error("Missing initializer in destructuring declaration")]
|
||||
#[diagnostic()]
|
||||
InvalidDestrucuringDeclaration(
|
||||
#[label("Missing initializer in destructuring declaration")] Span,
|
||||
#[label("Missing initializer in destructuring declaration")] Node,
|
||||
),
|
||||
|
||||
#[error("Missing initializer in const declaration")]
|
||||
#[diagnostic()]
|
||||
MissinginitializerInConst(#[label("const declaration need an initializer")] Span),
|
||||
MissinginitializerInConst(#[label("const declaration need an initializer")] Node),
|
||||
|
||||
#[error("Functions cannot be labelled")]
|
||||
#[diagnostic(help("This is not allowed in strict mode starting with ECMAScript 2015."))]
|
||||
FunctionsCannotBeLabelled(#[label("Functions cannot be labelled")] Span),
|
||||
FunctionsCannotBeLabelled(#[label("Functions cannot be labelled")] Node),
|
||||
|
||||
#[error("Cannot use {0} outside a method")]
|
||||
MethodCode(&'static str, #[label("Cannot use {0} outside a method")] Span),
|
||||
MethodCode(&'static str, #[label("Cannot use {0} outside a method")] Node),
|
||||
|
||||
#[error("Cannot use {0} outside a module")]
|
||||
#[diagnostic()]
|
||||
ModuleCode(&'static str, #[label("Cannot use {0} outside a module")] Span),
|
||||
ModuleCode(&'static str, #[label("Cannot use {0} outside a module")] Node),
|
||||
|
||||
#[error("Lexical declaration cannot appear in a single-statement context")]
|
||||
#[diagnostic(help("Wrap this declaration in a block statement"))]
|
||||
LexicalDeclarationSingleStatement(#[label("Lexical declaration is not allowed here")] Span),
|
||||
LexicalDeclarationSingleStatement(#[label("Lexical declaration is not allowed here")] Node),
|
||||
|
||||
#[error("Invalid function declaration")]
|
||||
#[diagnostic(help(
|
||||
"In strict mode code, functions can only be declared at top level or inside a block"
|
||||
))]
|
||||
FunctionDeclarationStrict(#[label("function declaration is not allowed here")] Span),
|
||||
FunctionDeclarationStrict(#[label("function declaration is not allowed here")] Node),
|
||||
|
||||
#[error("Async functions can only be declared at the top level or inside a block")]
|
||||
#[diagnostic()]
|
||||
AsyncFunctionDeclaration(
|
||||
#[label("Async functions can only be declared at the top level or inside a block")] Span,
|
||||
#[label("Async functions can only be declared at the top level or inside a block")] Node,
|
||||
),
|
||||
|
||||
#[error("Generators can only be declared at the top level or inside a block")]
|
||||
#[diagnostic()]
|
||||
GeneratorFunctionDeclaration(
|
||||
#[label("Generators can only be declared at the top level or inside a block")] Span,
|
||||
#[label("Generators can only be declared at the top level or inside a block")] Node,
|
||||
),
|
||||
|
||||
#[error("Invalid function declaration")]
|
||||
#[diagnostic(help(
|
||||
"In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement"
|
||||
))]
|
||||
FunctionDeclarationNonStrict(#[label("function declaration is not allowed here")] Span),
|
||||
FunctionDeclarationNonStrict(#[label("function declaration is not allowed here")] Node),
|
||||
|
||||
#[error("`await` is only allowed within async functions and at the top levels of modules")]
|
||||
#[diagnostic()]
|
||||
AwaitExpression(
|
||||
#[label("`await` is only allowed within async functions and at the top levels of modules")]
|
||||
Span,
|
||||
Node,
|
||||
),
|
||||
|
||||
#[error("A 'yield' expression is only allowed in a generator body.")]
|
||||
#[diagnostic()]
|
||||
YieldExpression(#[label("A 'yield' expression is only allowed in a generator body.")] Span),
|
||||
YieldExpression(#[label("A 'yield' expression is only allowed in a generator body.")] Node),
|
||||
|
||||
#[error("Invalid class declaration")]
|
||||
#[diagnostic()]
|
||||
ClassDeclaration(#[label("Classes can only be declared at top level or inside a block")] Span),
|
||||
ClassDeclaration(#[label("Classes can only be declared at top level or inside a block")] Node),
|
||||
|
||||
#[error("Rest element must be last element")]
|
||||
#[diagnostic()]
|
||||
RestElement(#[label("Rest element must be last element")] Span),
|
||||
RestElement(#[label("Rest element must be last element")] Node),
|
||||
|
||||
#[error("Spread must be last element")]
|
||||
#[diagnostic()]
|
||||
SpreadLastElement(#[label("Spread must be last element")] Span),
|
||||
SpreadLastElement(#[label("Spread must be last element")] Node),
|
||||
|
||||
#[error("Unexpected trailing comma after rest element")]
|
||||
#[diagnostic()]
|
||||
RestElementTraillingComma(#[label("Unexpected trailing comma after rest element")] Span),
|
||||
RestElementTraillingComma(#[label("Unexpected trailing comma after rest element")] Node),
|
||||
|
||||
#[error("Invalid rest argument")]
|
||||
#[diagnostic(help("Expected identifier in rest argument"))]
|
||||
InvalidRestArgument(#[label("Invalid rest argument")] Span),
|
||||
InvalidRestArgument(#[label("Invalid rest argument")] Node),
|
||||
|
||||
#[error("Invalid parenthesized parameter")]
|
||||
#[diagnostic(help("remove the parentheses"))]
|
||||
InvalidParenthesizedParameter(#[label("Invliad parenthesized parameter")] Span),
|
||||
InvalidParenthesizedParameter(#[label("Invliad parenthesized parameter")] Node),
|
||||
|
||||
#[error("Invalid parenthesized pattern")]
|
||||
#[diagnostic()]
|
||||
InvalidParenthesizedPattern(#[label("Invliad parenthesized pattern")] Span),
|
||||
InvalidParenthesizedPattern(#[label("Invliad parenthesized pattern")] Node),
|
||||
|
||||
#[error("Invalid assignment")]
|
||||
#[diagnostic()]
|
||||
InvalidAssignment(#[label("Cannot assign to this expression")] Span),
|
||||
InvalidAssignment(#[label("Cannot assign to this expression")] Node),
|
||||
|
||||
#[error("Optional chaining cannot appear in the callee of new expressions")]
|
||||
#[diagnostic()]
|
||||
NewOptionalChain(
|
||||
#[label("Optional chaining cannot appear in the callee of new expressions")] Span,
|
||||
#[label("Optional chaining cannot appear in the callee of new expressions")] Node,
|
||||
),
|
||||
|
||||
#[error("The left-hand side of a `for...of` statement may not be `async`")]
|
||||
#[diagnostic()]
|
||||
ForLoopAsyncOf(
|
||||
#[label("The left-hand side of a `for...of` statement may not be `async`")] Span,
|
||||
#[label("The left-hand side of a `for...of` statement may not be `async`")] Node,
|
||||
),
|
||||
|
||||
#[error("await can only be used in conjunction with `for...of` statements")]
|
||||
#[diagnostic()]
|
||||
ForAwait(#[label("await can only be used in conjunction with `for...of` statements")] Span),
|
||||
ForAwait(#[label("await can only be used in conjunction with `for...of` statements")] Node),
|
||||
|
||||
#[error("Cannot use new with dynamic import")]
|
||||
#[diagnostic()]
|
||||
NewDynamicImport(#[label("Cannot use new with dynamic import")] Span),
|
||||
NewDynamicImport(#[label("Cannot use new with dynamic import")] Node),
|
||||
|
||||
#[error("'{0}' declaration can only be used at the top level of a module")]
|
||||
#[diagnostic()]
|
||||
TopLevel(&'static str, #[label("'{0}' declaration can only appear at the top level")] Span),
|
||||
TopLevel(&'static str, #[label("'{0}' declaration can only appear at the top level")] Node),
|
||||
|
||||
#[error("Duplicated export '{0}'")]
|
||||
#[diagnostic()]
|
||||
DuplicateExport(
|
||||
Atom,
|
||||
#[label("Export has already been declared here")] Span,
|
||||
#[label("It cannot be redeclared here")] Span,
|
||||
#[label("Export has already been declared here")] Node,
|
||||
#[label("It cannot be redeclared here")] Node,
|
||||
),
|
||||
|
||||
#[error("Unexpected private field")]
|
||||
#[diagnostic(help(
|
||||
"Private names are only allowed in property accesses (`obj.#field`) or in `in` expressions (`#field in obj`)."
|
||||
))]
|
||||
UnexpectedPrivateIdentifier(#[label("Unexpected private field")] Span),
|
||||
UnexpectedPrivateIdentifier(#[label("Unexpected private field")] Node),
|
||||
|
||||
#[error("Classes can't have an element named '#constructor'")]
|
||||
#[diagnostic()]
|
||||
PrivateNameConstructor(#[label("Classes can't have an element named '#constructor'")] Span),
|
||||
PrivateNameConstructor(#[label("Classes can't have an element named '#constructor'")] Node),
|
||||
|
||||
#[error("Private field '{0}' must be declared in an enclosing class")]
|
||||
#[diagnostic()]
|
||||
PrivateFieldUndeclared(
|
||||
Atom,
|
||||
#[label("Private field '{0}' must be declared in an enclosing class")] Span,
|
||||
#[label("Private field '{0}' must be declared in an enclosing class")] Node,
|
||||
),
|
||||
|
||||
#[error("Unexpected private identifier")]
|
||||
#[diagnostic()]
|
||||
PrivateNotInClass(
|
||||
Atom,
|
||||
#[label("Private identifier '#{0}' is not allowed outside class bodies")] Span,
|
||||
#[label("Private identifier '#{0}' is not allowed outside class bodies")] Node,
|
||||
),
|
||||
|
||||
#[error("Classes may not have a static property named prototype")]
|
||||
#[diagnostic()]
|
||||
StaticPrototype(#[label("Classes may not have a static property named prototype")] Span),
|
||||
StaticPrototype(#[label("Classes may not have a static property named prototype")] Node),
|
||||
|
||||
#[error("Constructor can't have get/set modifier")]
|
||||
#[diagnostic()]
|
||||
ConstructorGetterSetter(#[label("Constructor can't have get/set modifier")] Span),
|
||||
ConstructorGetterSetter(#[label("Constructor can't have get/set modifier")] Node),
|
||||
|
||||
#[error("Constructor can't be an async method")]
|
||||
#[diagnostic()]
|
||||
ConstructorAsync(#[label("Constructor can't be an async method")] Span),
|
||||
ConstructorAsync(#[label("Constructor can't be an async method")] Node),
|
||||
|
||||
#[error("Cannot use `{0}` as an identifier in an async context")]
|
||||
#[diagnostic()]
|
||||
IdentifierAsync(&'static str, #[label("{0} cannot be used here")] Span),
|
||||
IdentifierAsync(&'static str, #[label("{0} cannot be used here")] Node),
|
||||
|
||||
#[error("Cannot use `{0}` as an identifier in a generator context")]
|
||||
#[diagnostic()]
|
||||
IdentifierGenerator(&'static str, #[label("{0} cannot be used here")] Span),
|
||||
IdentifierGenerator(&'static str, #[label("{0} cannot be used here")] Node),
|
||||
|
||||
#[error("Constructor can't be a generator")]
|
||||
#[diagnostic()]
|
||||
ConstructorGenerator(#[label("Constructor can't be a generator")] Span),
|
||||
ConstructorGenerator(#[label("Constructor can't be a generator")] Node),
|
||||
|
||||
#[error("Classes can't have a field named 'constructor'")]
|
||||
#[diagnostic()]
|
||||
FieldConstructor(#[label("Classes can't have a field named 'constructor'")] Span),
|
||||
FieldConstructor(#[label("Classes can't have a field named 'constructor'")] Node),
|
||||
|
||||
#[error("Multiple constructor implementations are not allowed.")]
|
||||
#[diagnostic()]
|
||||
DuplicateConstructor(
|
||||
#[label("constructor has already been declared here")] Span,
|
||||
#[label("it cannot be redeclared here")] Span,
|
||||
#[label("constructor has already been declared here")] Node,
|
||||
#[label("it cannot be redeclared here")] Node,
|
||||
),
|
||||
|
||||
#[error("An export name cannot include a unicode lone surrogate")]
|
||||
#[diagnostic()]
|
||||
ExportLoneSurrogate(#[label("An export name cannot include a unicode lone surrogate")] Span),
|
||||
ExportLoneSurrogate(#[label("An export name cannot include a unicode lone surrogate")] Node),
|
||||
|
||||
#[error("A string literal cannot be used as an exported binding without `from`")]
|
||||
#[diagnostic(help("Did you mean `export {{ '{0}' as '{1}' }} from 'some-module'`?"))]
|
||||
ExportNamedString(
|
||||
Atom,
|
||||
Atom,
|
||||
#[label("A string literal cannot be used as an exported binding without `from`")] Span,
|
||||
#[label("A string literal cannot be used as an exported binding without `from`")] Node,
|
||||
),
|
||||
|
||||
#[error("Bad escape sequence in untagged template literal")]
|
||||
#[diagnostic()]
|
||||
TemplateLiteral(#[label("Bad escape sequence in untagged template literal")] Span),
|
||||
TemplateLiteral(#[label("Bad escape sequence in untagged template literal")] Node),
|
||||
|
||||
#[error("Delete of an unqualified identifier in strict mode.")]
|
||||
#[diagnostic()]
|
||||
DeleteOfUnqualified(#[label("Delete of an unqualified identifier in strict mode")] Span),
|
||||
DeleteOfUnqualified(#[label("Delete of an unqualified identifier in strict mode")] Node),
|
||||
|
||||
#[error("'with' statements are not allowed")]
|
||||
#[diagnostic()]
|
||||
WithStatement(#[label("'with' statements are not allowed")] Span),
|
||||
WithStatement(#[label("'with' statements are not allowed")] Node),
|
||||
|
||||
#[error("Private fields can not be deleted")]
|
||||
#[diagnostic()]
|
||||
DeletePrivateField(#[label("Private fields can not be deleted")] Span),
|
||||
DeletePrivateField(#[label("Private fields can not be deleted")] Node),
|
||||
|
||||
#[error("Empty parenthesized expression")]
|
||||
#[diagnostic()]
|
||||
EmptyParenthesizedExpression(#[label("Expected an expression here")] Span),
|
||||
EmptyParenthesizedExpression(#[label("Expected an expression here")] Node),
|
||||
|
||||
#[error("Undefined export")]
|
||||
#[diagnostic()]
|
||||
UndefinedExport(Atom, #[label("Export '{0}' is not defined")] Span),
|
||||
UndefinedExport(Atom, #[label("Export '{0}' is not defined")] Node),
|
||||
|
||||
#[error("Logical expressions and coalesce expressions cannot be mixed")]
|
||||
#[diagnostic(help("Wrap either expression by parentheses"))]
|
||||
MixedCoalesce(#[label("Logical expressions and coalesce expressions cannot be mixed")] Span),
|
||||
MixedCoalesce(#[label("Logical expressions and coalesce expressions cannot be mixed")] Node),
|
||||
|
||||
#[error("'Unexpected `{0}`")]
|
||||
#[diagnostic()]
|
||||
UnexpectedKeyword(&'static str, #[label("'{0}' keyword is unexpected here")] Span),
|
||||
UnexpectedKeyword(&'static str, #[label("'{0}' keyword is unexpected here")] Node),
|
||||
|
||||
#[error("{0} loop variable declaration may not have an initializer")]
|
||||
#[diagnostic()]
|
||||
UnexpectedInitializerInForLoopHead(
|
||||
&'static str,
|
||||
#[label("{0} loop variable declaration may not have an initializer")] Span,
|
||||
#[label("{0} loop variable declaration may not have an initializer")] Node,
|
||||
),
|
||||
|
||||
#[error("Only a single declaration is allowed in a `for...{0}` statement")]
|
||||
#[diagnostic()]
|
||||
MultipleDeclarationInForLoopHead(
|
||||
&'static str,
|
||||
#[label("Only a single declaration is allowed in a `for...{0}` statement")] Span,
|
||||
#[label("Only a single declaration is allowed in a `for...{0}` statement")] Node,
|
||||
),
|
||||
|
||||
#[error("Illegal newline after {0}")]
|
||||
#[diagnostic()]
|
||||
IllegalNewline(
|
||||
&'static str,
|
||||
#[label("{0} starts here")] Span,
|
||||
#[label("A newline is not expected here")] Span,
|
||||
#[label("{0} starts here")] Node,
|
||||
#[label("A newline is not expected here")] Node,
|
||||
),
|
||||
|
||||
#[error("Duplicate parameter name not allowed in this context")]
|
||||
#[diagnostic()]
|
||||
DuplicateParameter(#[label("Duplicate parameter name not allowed in this context")] Span),
|
||||
DuplicateParameter(#[label("Duplicate parameter name not allowed in this context")] Node),
|
||||
|
||||
#[error("Illegal 'use strict' directive in function with non-simple parameter list")]
|
||||
#[diagnostic()]
|
||||
IllegalUseStrict(
|
||||
#[label("Illegal 'use strict' directive in function with non-simple parameter list")] Span,
|
||||
#[label("Illegal 'use strict' directive in function with non-simple parameter list")] Node,
|
||||
),
|
||||
|
||||
#[error("'arguments' is not allowed in {0}")]
|
||||
#[diagnostic()]
|
||||
UnexpectedArguments(&'static str, #[label("'arguments' is not allowed in {0}")] Span),
|
||||
UnexpectedArguments(&'static str, #[label("'arguments' is not allowed in {0}")] Node),
|
||||
|
||||
#[error("Unexpected {0} expression")]
|
||||
#[diagnostic()]
|
||||
UnexpectedExpression(&'static str, #[label("Unexpected {0} expression")] Span),
|
||||
UnexpectedExpression(&'static str, #[label("Unexpected {0} expression")] Node),
|
||||
|
||||
#[error("Unexpected exponentiation expression")]
|
||||
#[diagnostic(help("Wrap {0} expression in parentheses to enforce operator precedence"))]
|
||||
UnexpectedExponential(&'static str, #[label("Unexpected exponentiation expression")] Span),
|
||||
UnexpectedExponential(&'static str, #[label("Unexpected exponentiation expression")] Node),
|
||||
|
||||
#[error("Tagged template expressions are not permitted in an optional chain")]
|
||||
#[diagnostic()]
|
||||
OptionalChainTaggedTemplate(
|
||||
#[label("Tagged template expressions are not permitted in an optional chain")] Span,
|
||||
#[label("Tagged template expressions are not permitted in an optional chain")] Node,
|
||||
),
|
||||
|
||||
#[error("A 'get' accessor must not have any formal parameters.")]
|
||||
#[diagnostic()]
|
||||
GetterParameters(#[label("A 'get' accessor must not have any formal parameters.")] Span),
|
||||
GetterParameters(#[label("A 'get' accessor must not have any formal parameters.")] Node),
|
||||
|
||||
#[error("A 'set' accessor must have exactly one parameter.")]
|
||||
#[diagnostic()]
|
||||
SetterParameters(#[label("A 'set' accessor must have exactly one parameter.")] Span),
|
||||
SetterParameters(#[label("A 'set' accessor must have exactly one parameter.")] Node),
|
||||
|
||||
#[error("A 'set' accessor function argument must not be a rest parameter")]
|
||||
#[diagnostic()]
|
||||
SetterParametersRestPattern(
|
||||
#[label("A 'set' accessor function argument must not be a rest parameter")] Span,
|
||||
#[label("A 'set' accessor function argument must not be a rest parameter")] Node,
|
||||
),
|
||||
|
||||
#[error("{0} expression not allowed in formal parameter")]
|
||||
#[diagnostic()]
|
||||
AwaitOrYieldInParameter(
|
||||
&'static str,
|
||||
#[label("{0} expression not allowed in formal parameter")] Span,
|
||||
#[label("{0} expression not allowed in formal parameter")] Node,
|
||||
),
|
||||
|
||||
#[error("Invalid assignment in object literal")]
|
||||
#[diagnostic(help(
|
||||
"Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern."
|
||||
))]
|
||||
CoverInitializedNameError(#[label("Assignment is not allowed here")] Span),
|
||||
CoverInitializedNameError(#[label("Assignment is not allowed here")] Node),
|
||||
|
||||
#[error("Super calls are not permitted outside constructors or in nested functions inside constructors.
|
||||
")]
|
||||
|
|
@ -502,7 +502,7 @@ pub enum Diagnostic {
|
|||
#[label(
|
||||
"Super calls are not permitted outside constructors or in nested functions inside constructors."
|
||||
)]
|
||||
Span,
|
||||
Node,
|
||||
),
|
||||
|
||||
#[error("'super' can only be referenced in members of derived classes or object literal expressions.
|
||||
|
|
@ -511,98 +511,98 @@ pub enum Diagnostic {
|
|||
UnexpectedSuperReference(
|
||||
#[label("'super' can only be referenced in members of derived classes or object literal expressions.
|
||||
")]
|
||||
Span,
|
||||
Node,
|
||||
),
|
||||
|
||||
#[error("'super' can only be used with function calls or in property accesses")]
|
||||
#[diagnostic(help("replace with `super()` or `super.prop` or `super[prop]`"))]
|
||||
UnexpectedSuper(
|
||||
#[label("'super' can only be used with function calls or in property accesses ")] Span,
|
||||
#[label("'super' can only be used with function calls or in property accesses ")] Node,
|
||||
),
|
||||
|
||||
#[error("'super' can only be referenced in a derived class.")]
|
||||
#[diagnostic(help("either remove this super, or extend the class"))]
|
||||
SuperWithoutDerivedClass(
|
||||
#[label("'super' can only be referenced in a derived class.")] Span,
|
||||
#[label("class does not have `extends`")] Span,
|
||||
#[label("'super' can only be referenced in a derived class.")] Node,
|
||||
#[label("class does not have `extends`")] Node,
|
||||
),
|
||||
|
||||
#[error("Private fields cannot be accessed on super")]
|
||||
#[diagnostic()]
|
||||
SuperPrivate(#[label("Private fields cannot be accessed on super")] Span),
|
||||
SuperPrivate(#[label("Private fields cannot be accessed on super")] Node),
|
||||
|
||||
#[error("Expected function name")]
|
||||
#[diagnostic(help("Function name is required in function declaration or named export"))]
|
||||
ExpectFunctionName(#[label("Function name is required here")] Span),
|
||||
ExpectFunctionName(#[label("Function name is required here")] Node),
|
||||
|
||||
#[error("Missing catch or finally clause")]
|
||||
#[diagnostic()]
|
||||
ExpectCatchFinally(#[label("Expected `catch` or `finally` here")] Span),
|
||||
ExpectCatchFinally(#[label("Expected `catch` or `finally` here")] Node),
|
||||
|
||||
#[error("Cannot assign to '{0}' because it is a {1}")]
|
||||
#[diagnostic()]
|
||||
CannotAssignTo(
|
||||
Atom,
|
||||
&'static str,
|
||||
#[label("Cannot assign to '{0}' because this is a {1}")] Span,
|
||||
#[label("Cannot assign to '{0}' because this is a {1}")] Node,
|
||||
),
|
||||
|
||||
#[error("A rest parameter cannot have an initializer")]
|
||||
#[diagnostic()]
|
||||
ARestParameterCannotHaveAnInitializer(
|
||||
#[label("A rest parameter cannot have an initializer")] Span,
|
||||
#[label("A rest parameter cannot have an initializer")] Node,
|
||||
),
|
||||
|
||||
/* TypeScript */
|
||||
#[error("TS1015: Parameter cannot have question mark and initializer")]
|
||||
#[diagnostic()]
|
||||
ParameterCannotHaveQuestionMarkAndInitializer(
|
||||
#[label("Parameter cannot have question mark and initializer")] Span,
|
||||
#[label("Parameter cannot have question mark and initializer")] Node,
|
||||
),
|
||||
|
||||
#[error("TS1047: A rest parameter cannot be optional")]
|
||||
#[diagnostic()]
|
||||
ARestParameterCannotBeOptional(#[label("A rest parameter cannot be optional")] Span),
|
||||
ARestParameterCannotBeOptional(#[label("A rest parameter cannot be optional")] Node),
|
||||
|
||||
#[error("TS1095: A 'set' accessor cannot have a return type annotation")]
|
||||
#[diagnostic()]
|
||||
ASetAccessorCannotHaveAReturnTypeAnnotation(
|
||||
#[label("A 'set' accessor cannot have a return type annotation")] Span,
|
||||
#[label("A 'set' accessor cannot have a return type annotation")] Node,
|
||||
),
|
||||
|
||||
#[error("TS1098: Type parameter list cannot be empty")]
|
||||
#[diagnostic()]
|
||||
TypeParameterListCannotBeEmpty(#[label("Type parameter list cannot be empty")] Span),
|
||||
TypeParameterListCannotBeEmpty(#[label("Type parameter list cannot be empty")] Node),
|
||||
|
||||
#[error("TS1099: Type argument list cannot be empty")]
|
||||
#[diagnostic()]
|
||||
TypeArgumentListCannotBeEmpty(#[label("Type argument list cannot be empty")] Span),
|
||||
TypeArgumentListCannotBeEmpty(#[label("Type argument list cannot be empty")] Node),
|
||||
|
||||
#[error("TS1108: A 'return' statement can only be used within a function body")]
|
||||
#[diagnostic()]
|
||||
ReturnStatementOnlyInFunctionBody(
|
||||
#[label("A 'return' statement can only be used within a function body.")] Span,
|
||||
#[label("A 'return' statement can only be used within a function body.")] Node,
|
||||
),
|
||||
|
||||
#[error("TS1164: Computed property names are not allowed in enums")]
|
||||
#[diagnostic()]
|
||||
ComputedPropertyNamesAreNotAllowedInEnums(
|
||||
#[label("Computed property names are not allowed in enums")] Span,
|
||||
#[label("Computed property names are not allowed in enums")] Node,
|
||||
),
|
||||
|
||||
#[error("TS1313: The body of an 'if' statement cannot be the empty statement")]
|
||||
#[diagnostic()]
|
||||
TheBodyOfAnIfStatementCannotBeTheEmptyStatement(
|
||||
#[label("The body of an 'if' statement cannot be the empty statement")] Span,
|
||||
#[label("The body of an 'if' statement cannot be the empty statement")] Node,
|
||||
),
|
||||
|
||||
#[error("TS1317: A parameter property cannot be declared using a rest parameter")]
|
||||
#[diagnostic()]
|
||||
AParameterPropertyCannotBeDeclaredUsingARestParameter(
|
||||
#[label("A parameter property cannot be declared using a rest parameter")] Span,
|
||||
#[label("A parameter property cannot be declared using a rest parameter")] Node,
|
||||
),
|
||||
|
||||
#[error("TS2452: An enum member cannot have a numeric name")]
|
||||
#[diagnostic()]
|
||||
AnEnumMemberCannotHaveANumericName(#[label("An enum member cannot have a numeric name")] Span),
|
||||
AnEnumMemberCannotHaveANumericName(#[label("An enum member cannot have a numeric name")] Node),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::Parser;
|
|||
pub struct ParserCheckpoint<'a> {
|
||||
lexer: LexerCheckpoint<'a>,
|
||||
cur_token: Token,
|
||||
prev_node_end: usize,
|
||||
prev_node_end: u32,
|
||||
errors_pos: usize,
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +42,8 @@ impl<'a> Parser<'a> {
|
|||
/// Get current source text
|
||||
#[must_use]
|
||||
pub fn cur_src(&self) -> &'a str {
|
||||
unsafe { self.source.get_unchecked(self.cur_token().range()) }
|
||||
let range = self.cur_token().node().range();
|
||||
unsafe { self.source.get_unchecked(range.start as usize..range.end as usize) }
|
||||
}
|
||||
|
||||
/// Get current atom
|
||||
|
|
@ -100,8 +101,8 @@ impl<'a> Parser<'a> {
|
|||
// in IdentifierName hence such escapes cannot be used to write an Identifier
|
||||
// whose code point sequence is the same as a ReservedWord.
|
||||
if self.cur_token().escaped && kind.is_all_keyword() {
|
||||
let range = self.cur_token().range();
|
||||
self.error(Diagnostic::EscapedKeyword(range));
|
||||
let node = self.cur_token().node();
|
||||
self.error(Diagnostic::EscapedKeyword(node));
|
||||
}
|
||||
self.prev_token_end = self.token.end;
|
||||
self.token = self.lexer.next_token();
|
||||
|
|
@ -139,8 +140,8 @@ impl<'a> Parser<'a> {
|
|||
/// # Errors
|
||||
pub fn asi(&mut self) -> Result<()> {
|
||||
if !self.can_insert_semicolon() {
|
||||
let range = self.prev_token_end..self.cur_token().start;
|
||||
return Err(Diagnostic::AutoSemicolonInsertion(range));
|
||||
let node = Node::new(self.prev_token_end, self.cur_token().start);
|
||||
return Err(Diagnostic::AutoSemicolonInsertion(node));
|
||||
}
|
||||
if self.at(Kind::Semicolon) {
|
||||
self.advance(Kind::Semicolon);
|
||||
|
|
@ -169,17 +170,17 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn current_range(&self) -> std::ops::Range<usize> {
|
||||
pub const fn current_range(&self) -> Node {
|
||||
let cur_token = self.cur_token();
|
||||
match self.cur_kind() {
|
||||
Kind::Eof => {
|
||||
if self.prev_token_end < cur_token.end {
|
||||
self.prev_token_end..self.prev_token_end
|
||||
Node::new(self.prev_token_end, self.prev_token_end)
|
||||
} else {
|
||||
self.prev_token_end - 1..self.prev_token_end
|
||||
Node::new(self.prev_token_end - 1, self.prev_token_end)
|
||||
}
|
||||
}
|
||||
_ => cur_token.range(),
|
||||
_ => cur_token.node(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ impl<'a> Parser<'a> {
|
|||
|
||||
if self.at(Kind::Comma) {
|
||||
let error = if self.peek_at(Kind::RBrack) {
|
||||
Diagnostic::RestElementTraillingComma(self.cur_token().range())
|
||||
Diagnostic::RestElementTraillingComma(self.cur_token().node())
|
||||
} else {
|
||||
Diagnostic::RestElement(node.range())
|
||||
Diagnostic::RestElement(node)
|
||||
};
|
||||
self.error(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@ impl<'a> Parser<'a> {
|
|||
let decl = self.parse_class_declaration(/* declare */ false)?;
|
||||
|
||||
if stmt_ctx.is_single_statement() {
|
||||
self.error(Diagnostic::ClassDeclaration(decl.node.start..decl.body.node.start));
|
||||
self.error(Diagnostic::ClassDeclaration(Node::new(
|
||||
decl.node.start,
|
||||
decl.body.node.start,
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(self.ast.class_declaration(decl))
|
||||
|
|
@ -238,7 +241,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
if let PropertyKey::PrivateIdentifier(private_ident) = &key {
|
||||
if private_ident.name == "constructor" {
|
||||
self.error(Diagnostic::PrivateNameConstructor(private_ident.node.range()));
|
||||
self.error(Diagnostic::PrivateNameConstructor(private_ident.node));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -264,17 +267,17 @@ impl<'a> Parser<'a> {
|
|||
)?;
|
||||
if let Some((name, node)) = definition.prop_name() {
|
||||
if r#static && name == "prototype" {
|
||||
self.error(Diagnostic::StaticPrototype(node.range()));
|
||||
self.error(Diagnostic::StaticPrototype(node));
|
||||
}
|
||||
if !r#static && name == "constructor" {
|
||||
if kind == MethodDefinitionKind::Get || kind == MethodDefinitionKind::Set {
|
||||
self.error(Diagnostic::ConstructorGetterSetter(node.range()));
|
||||
self.error(Diagnostic::ConstructorGetterSetter(node));
|
||||
}
|
||||
if r#async {
|
||||
self.error(Diagnostic::ConstructorAsync(node.range()));
|
||||
self.error(Diagnostic::ConstructorAsync(node));
|
||||
}
|
||||
if generator {
|
||||
self.error(Diagnostic::ConstructorGenerator(node.range()));
|
||||
self.error(Diagnostic::ConstructorGenerator(node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -295,10 +298,10 @@ impl<'a> Parser<'a> {
|
|||
)?;
|
||||
if let Some((name, node)) = definition.prop_name() {
|
||||
if name == "constructor" {
|
||||
self.error(Diagnostic::FieldConstructor(node.range()));
|
||||
self.error(Diagnostic::FieldConstructor(node));
|
||||
}
|
||||
if r#static && name == "prototype" {
|
||||
self.error(Diagnostic::StaticPrototype(node.range()));
|
||||
self.error(Diagnostic::StaticPrototype(node));
|
||||
}
|
||||
}
|
||||
Ok(definition)
|
||||
|
|
@ -344,17 +347,17 @@ impl<'a> Parser<'a> {
|
|||
let value = self.parse_method(r#async, generator)?;
|
||||
|
||||
if kind == MethodDefinitionKind::Get && !value.params.is_empty() {
|
||||
self.error(Diagnostic::GetterParameters(value.params.node.range()));
|
||||
self.error(Diagnostic::GetterParameters(value.params.node));
|
||||
}
|
||||
|
||||
if kind == MethodDefinitionKind::Set {
|
||||
if value.params.items.len() != 1 {
|
||||
self.error(Diagnostic::SetterParameters(value.params.node.range()));
|
||||
self.error(Diagnostic::SetterParameters(value.params.node));
|
||||
}
|
||||
|
||||
if value.params.items.len() == 1 {
|
||||
if let BindingPatternKind::RestElement(elem) = &value.params.items[0].pattern.kind {
|
||||
self.error(Diagnostic::SetterParametersRestPattern(elem.node.range()));
|
||||
self.error(Diagnostic::SetterParametersRestPattern(elem.node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ impl<'a> Parser<'a> {
|
|||
// BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]
|
||||
// the grammar forbids `let []`, `let {}`
|
||||
if !matches!(id.kind, BindingPatternKind::BindingIdentifier(_)) {
|
||||
self.error(Diagnostic::InvalidDestrucuringDeclaration(id.node().range()));
|
||||
self.error(Diagnostic::InvalidDestrucuringDeclaration(id.node()));
|
||||
} else if kind == VariableDeclarationKind::Const && !self.ctx.has_ambient() {
|
||||
// It is a Syntax Error if Initializer is not present and IsConstantDeclaration of the LexicalDeclaration containing this LexicalBinding is true.
|
||||
self.error(Diagnostic::MissinginitializerInConst(id.node().range()));
|
||||
self.error(Diagnostic::MissinginitializerInConst(id.node()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ impl<'a> Parser<'a> {
|
|||
expressions.remove(0)
|
||||
} else {
|
||||
if expressions.is_empty() {
|
||||
self.error(Diagnostic::EmptyParenthesizedExpression(list.node.range()));
|
||||
self.error(Diagnostic::EmptyParenthesizedExpression(list.node));
|
||||
}
|
||||
self.ast.sequence_expression(list.node, expressions)
|
||||
};
|
||||
|
|
@ -376,7 +376,7 @@ impl<'a> Parser<'a> {
|
|||
// It is a Syntax Error if any source text is matched by this production.
|
||||
// https://tc39.es/ecma262/#sec-left-hand-side-expressions-static-semantics-early-errors
|
||||
if in_optional_chain {
|
||||
self.error(Diagnostic::OptionalChainTaggedTemplate(quasi.node.range()));
|
||||
self.error(Diagnostic::OptionalChainTaggedTemplate(quasi.node));
|
||||
}
|
||||
Ok(self.ast.tagged_template_expression(node, lhs, quasi, type_parameters))
|
||||
}
|
||||
|
|
@ -384,7 +384,7 @@ impl<'a> Parser<'a> {
|
|||
pub fn parse_template_element(&mut self, tagged: bool) -> TemplateElement {
|
||||
let node = self.start_node();
|
||||
let cur_kind = self.cur_kind();
|
||||
let end_offset = match cur_kind {
|
||||
let end_offset: u32 = match cur_kind {
|
||||
Kind::TemplateHead | Kind::TemplateMiddle => 2,
|
||||
Kind::NoSubstitutionTemplate | Kind::TemplateTail => 1,
|
||||
_ => unreachable!(),
|
||||
|
|
@ -393,7 +393,7 @@ impl<'a> Parser<'a> {
|
|||
// cooked = None when template literal has invalid escape sequence
|
||||
let cooked = self.cur_atom().map(Clone::clone);
|
||||
|
||||
let raw = &self.cur_src()[1..self.cur_src().len() - end_offset];
|
||||
let raw = &self.cur_src()[1..self.cur_src().len() - end_offset as usize];
|
||||
let raw = Atom::from(if cooked.is_some() && raw.contains('\r') {
|
||||
self.ast.new_str(raw.replace("\r\n", "\n").replace('\r', "\n").as_str())
|
||||
} else {
|
||||
|
|
@ -407,7 +407,7 @@ impl<'a> Parser<'a> {
|
|||
node.end -= end_offset;
|
||||
|
||||
if !tagged && cooked.is_none() {
|
||||
self.error(Diagnostic::TemplateLiteral(node.range()));
|
||||
self.error(Diagnostic::TemplateLiteral(node));
|
||||
}
|
||||
|
||||
let tail = matches!(cur_kind, Kind::TemplateTail | Kind::NoSubstitutionTemplate);
|
||||
|
|
@ -475,7 +475,7 @@ impl<'a> Parser<'a> {
|
|||
// SuperCall:
|
||||
// super ( Arguments )
|
||||
if !matches!(self.cur_kind(), Kind::Dot | Kind::LBrack | Kind::LParen) {
|
||||
self.error(Diagnostic::UnexpectedSuper(node.range()));
|
||||
self.error(Diagnostic::UnexpectedSuper(node));
|
||||
}
|
||||
|
||||
self.ast.super_(node)
|
||||
|
|
@ -605,13 +605,13 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
if matches!(callee, Expression::ImportExpression(_)) {
|
||||
self.error(Diagnostic::NewDynamicImport(self.end_node(rhs_node).range()));
|
||||
self.error(Diagnostic::NewDynamicImport(self.end_node(rhs_node)));
|
||||
}
|
||||
|
||||
let node = self.end_node(node);
|
||||
|
||||
if optional {
|
||||
self.error(Diagnostic::NewOptionalChain(node.range()));
|
||||
self.error(Diagnostic::NewOptionalChain(node));
|
||||
}
|
||||
|
||||
Ok(self.ast.new_expression(node, callee, arguments, type_parameter))
|
||||
|
|
|
|||
|
|
@ -155,13 +155,15 @@ impl<'a> Parser<'a> {
|
|||
let decl = self.parse_function_impl(func_kind)?;
|
||||
if stmt_ctx.is_single_statement() {
|
||||
if decl.r#async {
|
||||
self.error(Diagnostic::AsyncFunctionDeclaration(
|
||||
decl.node.start..decl.params.node.end,
|
||||
));
|
||||
self.error(Diagnostic::AsyncFunctionDeclaration(Node::new(
|
||||
decl.node.start,
|
||||
decl.params.node.end,
|
||||
)));
|
||||
} else if decl.generator {
|
||||
self.error(Diagnostic::GeneratorFunctionDeclaration(
|
||||
decl.node.start..decl.params.node.end,
|
||||
));
|
||||
self.error(Diagnostic::GeneratorFunctionDeclaration(Node::new(
|
||||
decl.node.start,
|
||||
decl.params.node.end,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +320,7 @@ impl<'a> Parser<'a> {
|
|||
self.ctx = ctx;
|
||||
|
||||
if kind.is_id_required() && id.is_none() {
|
||||
self.error(Diagnostic::ExpectFunctionName(self.cur_token().range()));
|
||||
self.error(Diagnostic::ExpectFunctionName(self.cur_token().node()));
|
||||
}
|
||||
|
||||
id
|
||||
|
|
@ -431,7 +433,7 @@ impl<'a> Parser<'a> {
|
|||
self.ctx = self.ctx.and_await(has_await);
|
||||
|
||||
if self.cur_token().is_on_new_line {
|
||||
self.error(Diagnostic::LineterminatorBeforeArrow(self.cur_token().range()));
|
||||
self.error(Diagnostic::LineterminatorBeforeArrow(self.cur_token().node()));
|
||||
}
|
||||
|
||||
self.expect(Kind::Arrow)?;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ impl<'a> CoverGrammar<'a, Expression<'a>> for SimpleAssignmentTarget<'a> {
|
|||
let node = expr.node;
|
||||
match expr.unbox().expression {
|
||||
Expression::ObjectExpression(_) | Expression::ArrayExpression(_) => {
|
||||
Err(Diagnostic::InvalidAssignment(node.range()))
|
||||
Err(Diagnostic::InvalidAssignment(node))
|
||||
}
|
||||
expr => SimpleAssignmentTarget::cover(expr, p),
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ impl<'a> CoverGrammar<'a, Expression<'a>> for SimpleAssignmentTarget<'a> {
|
|||
Ok(SimpleAssignmentTarget::TSNonNullExpression(expr))
|
||||
}
|
||||
Expression::TSTypeAssertion(expr) => Ok(SimpleAssignmentTarget::TSTypeAssertion(expr)),
|
||||
expr => Err(Diagnostic::InvalidAssignment(expr.node().range())),
|
||||
expr => Err(Diagnostic::InvalidAssignment(expr.node())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -77,10 +77,10 @@ impl<'a> CoverGrammar<'a, ArrayExpression<'a>> for ArrayAssignmentTarget<'a> {
|
|||
if i == len - 1 {
|
||||
rest = Some(AssignmentTarget::cover(elem.unbox().argument, p)?);
|
||||
if let Some(node) = expr.trailing_comma {
|
||||
p.error(Diagnostic::RestElementTraillingComma(node.range()));
|
||||
p.error(Diagnostic::RestElementTraillingComma(node));
|
||||
}
|
||||
} else {
|
||||
return Err(Diagnostic::SpreadLastElement(elem.node.range()));
|
||||
return Err(Diagnostic::SpreadLastElement(elem.node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ impl<'a> CoverGrammar<'a, ObjectExpression<'a>> for ObjectAssignmentTarget<'a> {
|
|||
if i == len - 1 {
|
||||
rest = Some(AssignmentTarget::cover(spread.unbox().argument, p)?);
|
||||
} else {
|
||||
return Err(Diagnostic::SpreadLastElement(spread.node.range()));
|
||||
return Err(Diagnostic::SpreadLastElement(spread.node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ impl<'a> CoverGrammar<'a, Property<'a>> for AssignmentTargetProperty<'a> {
|
|||
let binding = match property.value {
|
||||
PropertyValue::Expression(expr) => AssignmentTargetMaybeDefault::cover(expr, p)?,
|
||||
PropertyValue::Pattern(_) => {
|
||||
return Err(Diagnostic::InvalidAssignment(property.value.node().range()));
|
||||
return Err(Diagnostic::InvalidAssignment(property.value.node()));
|
||||
}
|
||||
};
|
||||
let target = AssignmentTargetPropertyProperty {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ impl<'a> SeparatedList<'a> for ObjectPatternProperties<'a> {
|
|||
let rest_element = p.parse_rest_element()?;
|
||||
|
||||
if !matches!(rest_element.argument.kind, BindingPatternKind::BindingIdentifier(_)) {
|
||||
p.error(Diagnostic::InvalidRestArgument(rest_element.node.range()));
|
||||
p.error(Diagnostic::InvalidRestArgument(rest_element.node));
|
||||
}
|
||||
|
||||
ObjectPatternProperty::RestElement(rest_element)
|
||||
|
|
@ -291,7 +291,7 @@ impl<'a> SeparatedList<'a> for AssertEntries<'a> {
|
|||
};
|
||||
|
||||
if let Some(old_node) = self.keys.get(&key.as_atom()) {
|
||||
p.error(Diagnostic::Redeclaration(key.as_atom(), old_node.range(), key.node().range()));
|
||||
p.error(Diagnostic::Redeclaration(key.as_atom(), *old_node, key.node()));
|
||||
} else {
|
||||
self.keys.insert(key.as_atom(), key.node());
|
||||
}
|
||||
|
|
@ -396,8 +396,8 @@ impl<'a> ClassElements<'a> {
|
|||
{
|
||||
p.error(Diagnostic::Redeclaration(
|
||||
private_ident.name.clone(),
|
||||
existed.node.range(),
|
||||
private_ident.node.range(),
|
||||
existed.node,
|
||||
private_ident.node,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ impl<'a> Parser<'a> {
|
|||
self.error(Diagnostic::ExportNamedString(
|
||||
literal.value.clone(),
|
||||
specifier.local.name().clone(),
|
||||
literal.node.range(),
|
||||
literal.node,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -384,7 +384,7 @@ impl<'a> Parser<'a> {
|
|||
// ModuleExportName : StringLiteral
|
||||
// It is a Syntax Error if IsStringWellFormedUnicode(the SV of StringLiteral) is false.
|
||||
if !literal.is_string_well_formed_unicode() {
|
||||
self.error(Diagnostic::ExportLoneSurrogate(literal.node.range()));
|
||||
self.error(Diagnostic::ExportLoneSurrogate(literal.node));
|
||||
};
|
||||
Ok(ModuleExportName::StringLiteral(literal))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ impl<'a> Parser<'a> {
|
|||
let method = self.parse_method(false, false)?;
|
||||
|
||||
if !method.params.is_empty() {
|
||||
self.error(Diagnostic::GetterParameters(method.params.node.range()));
|
||||
self.error(Diagnostic::GetterParameters(method.params.node));
|
||||
}
|
||||
|
||||
let value = PropertyValue::Expression(self.ast.function_expression(method));
|
||||
|
|
@ -240,12 +240,12 @@ impl<'a> Parser<'a> {
|
|||
let method = self.parse_method(false, false)?;
|
||||
|
||||
if method.params.items.len() != 1 {
|
||||
self.error(Diagnostic::SetterParameters(method.params.node.range()));
|
||||
self.error(Diagnostic::SetterParameters(method.params.node));
|
||||
}
|
||||
|
||||
if method.params.items.len() == 1 {
|
||||
if let BindingPatternKind::RestElement(elem) = &method.params.items[0].pattern.kind {
|
||||
self.error(Diagnostic::SetterParametersRestPattern(elem.node.range()));
|
||||
self.error(Diagnostic::SetterParametersRestPattern(elem.node));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ impl<'a> Parser<'a> {
|
|||
if expecting_diretives {
|
||||
if let Statement::ExpressionStatement(expr) = &stmt {
|
||||
if let Expression::StringLiteral(string) = &expr.expression {
|
||||
let src = &self.source[string.node.start + 1..string.node.end - 1];
|
||||
let src = &self.source
|
||||
[string.node.start as usize + 1..string.node.end as usize - 1];
|
||||
let directive =
|
||||
self.ast.directive(expr.node, (*string).clone(), src);
|
||||
directives.push(directive);
|
||||
|
|
@ -192,7 +193,7 @@ impl<'a> Parser<'a> {
|
|||
))?;
|
||||
|
||||
if stmt_ctx.is_single_statement() && decl.kind.is_lexical() {
|
||||
self.error(Diagnostic::LexicalDeclarationSingleStatement(decl.node.range()));
|
||||
self.error(Diagnostic::LexicalDeclarationSingleStatement(decl.node));
|
||||
}
|
||||
|
||||
Ok(Statement::Declaration(Declaration::VariableDeclaration(decl)))
|
||||
|
|
@ -297,18 +298,15 @@ impl<'a> Parser<'a> {
|
|||
// for (a.b in ...), for ([a] in ..), for ({a} in ..)
|
||||
if self.at(Kind::In) || self.at(Kind::Of) {
|
||||
let target = AssignmentTarget::cover(init_expression, self)
|
||||
.map_err(|_| Diagnostic::UnexpectedToken(self.end_node(expression_node).range()))?;
|
||||
.map_err(|_| Diagnostic::UnexpectedToken(self.end_node(expression_node)))?;
|
||||
let for_stmt_left = ForStatementLeft::AssignmentTarget(target);
|
||||
|
||||
if !r#await && is_async_of {
|
||||
self.error(Diagnostic::ForLoopAsyncOf(self.end_node(expression_node).range()));
|
||||
self.error(Diagnostic::ForLoopAsyncOf(self.end_node(expression_node)));
|
||||
}
|
||||
|
||||
if is_let_of {
|
||||
self.error(Diagnostic::UnexpectedKeyword(
|
||||
"let",
|
||||
self.end_node(expression_node).range(),
|
||||
));
|
||||
self.error(Diagnostic::UnexpectedKeyword("let", self.end_node(expression_node)));
|
||||
}
|
||||
|
||||
return self.parse_for_in_or_of_loop(node, r#await, for_stmt_left);
|
||||
|
|
@ -330,7 +328,7 @@ impl<'a> Parser<'a> {
|
|||
self.expect(Kind::RParen)?;
|
||||
|
||||
if r#await {
|
||||
self.error(Diagnostic::ForAwait(self.end_node(node).range()));
|
||||
self.error(Diagnostic::ForAwait(self.end_node(node)));
|
||||
}
|
||||
|
||||
let body = self.parse_statement_list_item(StatementContext::For)?;
|
||||
|
|
@ -354,7 +352,7 @@ impl<'a> Parser<'a> {
|
|||
self.expect(Kind::RParen)?;
|
||||
|
||||
if r#await && is_for_in {
|
||||
self.error(Diagnostic::ForAwait(self.end_node(node).range()));
|
||||
self.error(Diagnostic::ForAwait(self.end_node(node)));
|
||||
}
|
||||
|
||||
let body = self.parse_statement_list_item(StatementContext::For)?;
|
||||
|
|
@ -454,8 +452,8 @@ impl<'a> Parser<'a> {
|
|||
if self.cur_token().is_on_new_line {
|
||||
self.error(Diagnostic::IllegalNewline(
|
||||
"throw",
|
||||
self.end_node(node).range(),
|
||||
self.cur_token().range(),
|
||||
self.end_node(node),
|
||||
self.cur_token().node(),
|
||||
));
|
||||
}
|
||||
let argument = self.parse_expression()?;
|
||||
|
|
@ -474,8 +472,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let finalizer = self.eat(Kind::Finally).then(|| self.parse_block()).transpose()?;
|
||||
|
||||
#[allow(clippy::range_plus_one)]
|
||||
let range = self.prev_token_end..self.prev_token_end + 1;
|
||||
let range = Node::new(self.prev_token_end, self.prev_token_end + 1);
|
||||
if handler.is_none() && finalizer.is_none() {
|
||||
self.error(Diagnostic::ExpectCatchFinally(range));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use constants::{
|
|||
pub use kind::Kind;
|
||||
use number::{parse_big_int, parse_float, parse_int};
|
||||
use oxc_allocator::{Allocator, String};
|
||||
use oxc_ast::{Atom, SourceType, Span};
|
||||
use oxc_ast::{Atom, Node, SourceType};
|
||||
use oxc_diagnostics::{Diagnostic, Diagnostics};
|
||||
use simd::{SkipMultilineComment, SkipWhitespace};
|
||||
use string_builder::AutoCow;
|
||||
|
|
@ -205,7 +205,7 @@ impl<'a> Lexer<'a> {
|
|||
}
|
||||
|
||||
/// Expand the current token for `JSXIdentifier`
|
||||
pub fn next_jsx_identifier(&mut self, prev_len: usize) -> Token {
|
||||
pub fn next_jsx_identifier(&mut self, prev_len: u32) -> Token {
|
||||
let kind = self.read_jsx_identifier(prev_len);
|
||||
self.lookahead.clear();
|
||||
self.finish_next(kind)
|
||||
|
|
@ -219,7 +219,7 @@ impl<'a> Lexer<'a> {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
self.current.token.start = self.offset() - offset;
|
||||
self.current.chars = self.source[self.current.token.start + 1..].chars();
|
||||
self.current.chars = self.source[self.current.token.start as usize + 1..].chars();
|
||||
let kind = Kind::LAngle;
|
||||
self.lookahead.clear();
|
||||
self.finish_next(kind)
|
||||
|
|
@ -234,7 +234,7 @@ impl<'a> Lexer<'a> {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
self.current.token.start = self.offset() - offset;
|
||||
self.current.chars = self.source[self.current.token.start + 1..].chars();
|
||||
self.current.chars = self.source[self.current.token.start as usize + 1..].chars();
|
||||
let kind = Kind::RAngle;
|
||||
self.lookahead.clear();
|
||||
self.finish_next(kind)
|
||||
|
|
@ -247,13 +247,14 @@ impl<'a> Lexer<'a> {
|
|||
|
||||
/// Get the length offset from the source, in UTF-8 bytes
|
||||
#[inline]
|
||||
fn offset(&self) -> usize {
|
||||
self.source.len() - self.current.chars.as_str().len()
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
fn offset(&self) -> u32 {
|
||||
(self.source.len() - self.current.chars.as_str().len()) as u32
|
||||
}
|
||||
|
||||
/// Get the current unterminated token range
|
||||
fn unterminated_range(&self) -> Span {
|
||||
self.current.token.start..self.offset()
|
||||
fn unterminated_range(&self) -> Node {
|
||||
Node::new(self.current.token.start, self.offset())
|
||||
}
|
||||
|
||||
/// Peek the next char without advancing the position
|
||||
|
|
@ -279,9 +280,9 @@ impl<'a> Lexer<'a> {
|
|||
matched
|
||||
}
|
||||
|
||||
fn current_offset(&self) -> std::ops::Range<usize> {
|
||||
fn current_offset(&self) -> Node {
|
||||
let offset = self.offset();
|
||||
offset..offset
|
||||
Node::new(offset, offset)
|
||||
}
|
||||
|
||||
/// Return `IllegalCharacter` Error or `UnexpectedEnd` if EOF
|
||||
|
|
@ -316,7 +317,10 @@ impl<'a> Lexer<'a> {
|
|||
match value {
|
||||
Ok(value) => self.current.token.value = value,
|
||||
Err(err) => {
|
||||
self.error(Diagnostic::InvalidNumber(err, self.current.token.start..self.offset()));
|
||||
self.error(Diagnostic::InvalidNumber(
|
||||
err,
|
||||
Node::new(self.current.token.start, self.offset()),
|
||||
));
|
||||
self.current.token.value = TokenValue::Number(std::f64::NAN);
|
||||
}
|
||||
};
|
||||
|
|
@ -710,11 +714,11 @@ impl<'a> Lexer<'a> {
|
|||
self.identifier_unicode_escape_sequence(&mut builder, true);
|
||||
}
|
||||
Some(c) => {
|
||||
self.error(Diagnostic::InvalidCharacter(c, start..self.offset() - 1));
|
||||
self.error(Diagnostic::InvalidCharacter(c, Node::new(start, self.offset() - 1)));
|
||||
return Kind::Undetermined;
|
||||
}
|
||||
None => {
|
||||
self.error(Diagnostic::UnexpectedEnd(start..self.offset() - 1));
|
||||
self.error(Diagnostic::UnexpectedEnd(Node::new(start, self.offset() - 1)));
|
||||
return Kind::Undetermined;
|
||||
}
|
||||
}
|
||||
|
|
@ -931,7 +935,7 @@ impl<'a> Lexer<'a> {
|
|||
break;
|
||||
}
|
||||
}
|
||||
self.error(Diagnostic::InvalidNumberEnd(offset..self.offset()));
|
||||
self.error(Diagnostic::InvalidNumberEnd(Node::new(offset, self.offset())));
|
||||
Kind::Undetermined
|
||||
}
|
||||
|
||||
|
|
@ -958,7 +962,7 @@ impl<'a> Lexer<'a> {
|
|||
let mut is_valid_escape_sequence = true;
|
||||
self.read_string_escape_sequence(text, false, &mut is_valid_escape_sequence);
|
||||
if !is_valid_escape_sequence {
|
||||
let range = start..self.offset();
|
||||
let range = Node::new(start, self.offset());
|
||||
self.error(Diagnostic::InvalidEscapeSequence(range));
|
||||
}
|
||||
}
|
||||
|
|
@ -1080,8 +1084,8 @@ impl<'a> Lexer<'a> {
|
|||
/// `IdentifierStart`
|
||||
/// `JSXIdentifier` `IdentifierPart`
|
||||
/// `JSXIdentifier` [no `WhiteSpace` or Comment here] -
|
||||
fn read_jsx_identifier(&mut self, prev_len: usize) -> Kind {
|
||||
let prev_str = &self.source[prev_len..self.offset()];
|
||||
fn read_jsx_identifier(&mut self, prev_len: u32) -> Kind {
|
||||
let prev_str = &self.source[prev_len as usize..self.offset() as usize];
|
||||
|
||||
let mut builder = AutoCow::new(self);
|
||||
loop {
|
||||
|
|
@ -1185,7 +1189,7 @@ impl<'a> Lexer<'a> {
|
|||
) {
|
||||
let start = self.offset();
|
||||
if self.current.chars.next() != Some('u') {
|
||||
let range = start..self.offset();
|
||||
let range = Node::new(start, self.offset());
|
||||
self.error(Diagnostic::UnicodeEscapeSequence(range));
|
||||
return;
|
||||
}
|
||||
|
|
@ -1196,7 +1200,7 @@ impl<'a> Lexer<'a> {
|
|||
};
|
||||
|
||||
let Some(value) = value else {
|
||||
let range = start..self.offset();
|
||||
let range = Node::new(start,self.offset());
|
||||
self.error(Diagnostic::UnicodeEscapeSequence(range));
|
||||
return;
|
||||
};
|
||||
|
|
@ -1204,7 +1208,7 @@ impl<'a> Lexer<'a> {
|
|||
// For Identifiers, surrogate pair is an invalid grammar, e.g. `var \uD800\uDEA7`.
|
||||
let ch = match value {
|
||||
SurrogatePair::Astral(..) | SurrogatePair::HighLow(..) => {
|
||||
let range = start..self.offset();
|
||||
let range = Node::new(start, self.offset());
|
||||
self.error(Diagnostic::UnicodeEscapeSequence(range));
|
||||
return;
|
||||
}
|
||||
|
|
@ -1212,7 +1216,7 @@ impl<'a> Lexer<'a> {
|
|||
if let Ok(ch) = char::try_from(code_point) {
|
||||
ch
|
||||
} else {
|
||||
let range = start..self.offset();
|
||||
let range = Node::new(start, self.offset());
|
||||
self.error(Diagnostic::UnicodeEscapeSequence(range));
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
//! Token
|
||||
|
||||
use std::ops::Range;
|
||||
|
||||
use num_bigint::BigUint;
|
||||
use oxc_ast::Atom;
|
||||
use oxc_ast::{Atom, Node};
|
||||
|
||||
use super::kind::Kind;
|
||||
|
||||
|
|
@ -13,10 +11,10 @@ pub struct Token {
|
|||
pub kind: Kind,
|
||||
|
||||
/// Start offset in source
|
||||
pub start: usize,
|
||||
pub start: u32,
|
||||
|
||||
/// End offset in source
|
||||
pub end: usize,
|
||||
pub end: u32,
|
||||
|
||||
/// Indicates the token is on a newline
|
||||
pub is_on_new_line: bool,
|
||||
|
|
@ -29,8 +27,8 @@ pub struct Token {
|
|||
|
||||
impl Token {
|
||||
#[must_use]
|
||||
pub const fn range(&self) -> Range<usize> {
|
||||
self.start..self.end
|
||||
pub const fn node(&self) -> Node {
|
||||
Node::new(self.start, self.end)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ pub struct Parser<'a> {
|
|||
token: Token,
|
||||
|
||||
/// The end range of the previous token
|
||||
prev_token_end: usize,
|
||||
prev_token_end: u32,
|
||||
|
||||
/// Parser state
|
||||
state: ParserState<'a>,
|
||||
|
|
@ -102,6 +102,7 @@ impl<'a> Parser<'a> {
|
|||
ParserReturn { program, errors: self.errors.borrow().clone() }
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
fn parse_program(&mut self) -> Result<Program<'a>> {
|
||||
// initialize cur_token and prev_token by moving onto the first token
|
||||
self.bump_any();
|
||||
|
|
@ -109,7 +110,7 @@ impl<'a> Parser<'a> {
|
|||
let (directives, statements) =
|
||||
self.parse_directives_and_statements(/* is_top_level */ true)?;
|
||||
|
||||
let node = Node::new(0, self.source.len());
|
||||
let node = Node::new(0, self.source.len() as u32);
|
||||
Ok(self.ast.program(node, directives, statements, self.source_type))
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +120,7 @@ impl<'a> Parser<'a> {
|
|||
if self.source_type.is_javascript()
|
||||
&& (self.source.starts_with("// @flow") || self.source.starts_with("/* @flow */"))
|
||||
{
|
||||
return Some(Diagnostic::Flow(0..8));
|
||||
return Some(Diagnostic::Flow(Node::new(0, 8)));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use oxc_ast::ast::Decorator;
|
|||
|
||||
#[derive(Default)]
|
||||
pub struct ParserState<'a> {
|
||||
pub not_parenthesized_arrow: HashSet<usize>,
|
||||
pub not_parenthesized_arrow: HashSet<u32>,
|
||||
|
||||
pub decorators: Option<Vec<'a, Decorator<'a>>>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -877,7 +877,7 @@ impl<'a> Parser<'a> {
|
|||
self.bump(Kind::Comma);
|
||||
self.bump(Kind::Semicolon);
|
||||
if !params.is_empty() {
|
||||
self.error(Diagnostic::GetterParameters(params.node.range()));
|
||||
self.error(Diagnostic::GetterParameters(params.node));
|
||||
}
|
||||
Ok(self.ast.ts_method_signature(
|
||||
self.end_node(node),
|
||||
|
|
@ -900,12 +900,10 @@ impl<'a> Parser<'a> {
|
|||
self.bump(Kind::Comma);
|
||||
self.bump(Kind::Semicolon);
|
||||
if params.items.len() != 1 {
|
||||
self.error(Diagnostic::SetterParameters(params.node.range()));
|
||||
self.error(Diagnostic::SetterParameters(params.node));
|
||||
}
|
||||
if let Some(return_type) = return_type.as_ref() {
|
||||
self.error(Diagnostic::ASetAccessorCannotHaveAReturnTypeAnnotation(
|
||||
return_type.node.range(),
|
||||
));
|
||||
self.error(Diagnostic::ASetAccessorCannotHaveAReturnTypeAnnotation(return_type.node));
|
||||
}
|
||||
Ok(self.ast.ts_method_signature(
|
||||
self.end_node(node),
|
||||
|
|
|
|||
Loading…
Reference in a new issue