mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
fix(parser): improve lexing of jsx identifier to fix duplicated comments after jsx name (#2687)
This commit is contained in:
parent
6c6adb46d1
commit
cda9c93436
5 changed files with 30 additions and 31 deletions
|
|
@ -20,6 +20,15 @@ fn main() -> Result<(), String> {
|
||||||
println!("AST:");
|
println!("AST:");
|
||||||
println!("{}", serde_json::to_string_pretty(&ret.program).unwrap());
|
println!("{}", serde_json::to_string_pretty(&ret.program).unwrap());
|
||||||
|
|
||||||
|
println!("Comments:");
|
||||||
|
let comments = ret
|
||||||
|
.trivias
|
||||||
|
.comments
|
||||||
|
.into_iter()
|
||||||
|
.map(|(start, end, _)| &source_text[start as usize..end as usize])
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
println!("{comments:?}");
|
||||||
|
|
||||||
if ret.errors.is_empty() {
|
if ret.errors.is_empty() {
|
||||||
println!("Parsed Successfully.");
|
println!("Parsed Successfully.");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -221,9 +221,11 @@ impl<'a> ParserImpl<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tell lexer to re-read a jsx identifier
|
/// Tell lexer to continue reading jsx identifier if the lexer character position is at `-` for `<component-name>`
|
||||||
pub(crate) fn re_lex_jsx_identifier(&mut self) {
|
pub(crate) fn continue_lex_jsx_identifier(&mut self) {
|
||||||
self.token = self.lexer.next_jsx_identifier(self.cur_token().start);
|
if let Some(token) = self.lexer.continue_lex_jsx_identifier() {
|
||||||
|
self.token = token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn re_lex_right_angle(&mut self) -> Kind {
|
pub(crate) fn re_lex_right_angle(&mut self) -> Kind {
|
||||||
|
|
|
||||||
|
|
@ -362,8 +362,8 @@ impl<'a> ParserImpl<'a> {
|
||||||
if !self.at(Kind::Ident) && !self.cur_kind().is_all_keyword() {
|
if !self.at(Kind::Ident) && !self.cur_kind().is_all_keyword() {
|
||||||
return Err(self.unexpected());
|
return Err(self.unexpected());
|
||||||
}
|
}
|
||||||
// we are at a valid normal Ident or Keyword, let's keep on lexing for `-`
|
// Currently at a valid normal Ident or Keyword, keep on lexing for `-` in `<component-name />`
|
||||||
self.re_lex_jsx_identifier();
|
self.continue_lex_jsx_identifier();
|
||||||
self.bump_any();
|
self.bump_any();
|
||||||
let span = self.end_span(span);
|
let span = self.end_span(span);
|
||||||
let name = span.source_text(self.source_text);
|
let name = span.source_text(self.source_text);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use super::{Kind, Lexer, Token};
|
||||||
use crate::diagnostics;
|
use crate::diagnostics;
|
||||||
|
|
||||||
use memchr::{memchr, memchr2};
|
use memchr::{memchr, memchr2};
|
||||||
use oxc_syntax::identifier::{is_identifier_part, is_identifier_start};
|
use oxc_syntax::identifier::is_identifier_part;
|
||||||
|
|
||||||
impl<'a> Lexer<'a> {
|
impl<'a> Lexer<'a> {
|
||||||
/// `JSXDoubleStringCharacters` ::
|
/// `JSXDoubleStringCharacters` ::
|
||||||
|
|
@ -47,13 +47,6 @@ impl<'a> Lexer<'a> {
|
||||||
self.finish_next(kind)
|
self.finish_next(kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expand the current token for `JSXIdentifier`
|
|
||||||
pub(crate) fn next_jsx_identifier(&mut self, start_offset: u32) -> Token {
|
|
||||||
let kind = self.read_jsx_identifier(start_offset);
|
|
||||||
self.lookahead.clear();
|
|
||||||
self.finish_next(kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// [`JSXChild`](https://facebook.github.io/jsx/#prod-JSXChild)
|
/// [`JSXChild`](https://facebook.github.io/jsx/#prod-JSXChild)
|
||||||
/// `JSXChild` :
|
/// `JSXChild` :
|
||||||
/// `JSXText`
|
/// `JSXText`
|
||||||
|
|
@ -90,25 +83,28 @@ impl<'a> Lexer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Expand the current `Ident` token for `JSXIdentifier`
|
||||||
|
///
|
||||||
|
/// The current character is at `Ident`, continue reading for `JSXIdentifier` if it has a `-`
|
||||||
|
///
|
||||||
/// `JSXIdentifier` :
|
/// `JSXIdentifier` :
|
||||||
/// `IdentifierStart`
|
/// `IdentifierStart`
|
||||||
/// `JSXIdentifier` `IdentifierPart`
|
/// `JSXIdentifier` `IdentifierPart`
|
||||||
/// `JSXIdentifier` [no `WhiteSpace` or Comment here] -
|
/// `JSXIdentifier` [no `WhiteSpace` or Comment here] -
|
||||||
fn read_jsx_identifier(&mut self, _start_offset: u32) -> Kind {
|
pub(crate) fn continue_lex_jsx_identifier(&mut self) -> Option<Token> {
|
||||||
|
if self.peek() != Some('-') {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
self.consume_char();
|
||||||
while let Some(c) = self.peek() {
|
while let Some(c) = self.peek() {
|
||||||
if c == '-' || is_identifier_start(c) {
|
if c == '-' || is_identifier_part(c) {
|
||||||
self.consume_char();
|
self.consume_char();
|
||||||
while let Some(c) = self.peek() {
|
|
||||||
if is_identifier_part(c) {
|
|
||||||
self.consume_char();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Ident
|
// Clear the current lookahead `Minus` Token
|
||||||
|
self.lookahead.clear();
|
||||||
|
Some(self.finish_next(Kind::Ident))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16182,14 +16182,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
× Invalid characters after number
|
× Invalid characters after number
|
||||||
╭─[conformance/jsx/tsxAttributeInvalidNames.tsx:12:10]
|
╭─[conformance/jsx/tsxAttributeInvalidNames.tsx:12:10]
|
||||||
11 │ // Invalid names
|
11 │ // Invalid names
|
||||||
12 │ <test1 32data={32} />;
|
|
||||||
· ────
|
|
||||||
13 │ <test2 -data={32} />;
|
|
||||||
╰────
|
|
||||||
|
|
||||||
× Invalid characters after number
|
|
||||||
╭─[conformance/jsx/tsxAttributeInvalidNames.tsx:12:10]
|
|
||||||
11 │ // Invalid names
|
|
||||||
12 │ <test1 32data={32} />;
|
12 │ <test1 32data={32} />;
|
||||||
· ────
|
· ────
|
||||||
13 │ <test2 -data={32} />;
|
13 │ <test2 -data={32} />;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue