Skip to content

Commit

Permalink
fix(semantic/jsdoc): Support multibyte chars (#2694)
Browse files Browse the repository at this point in the history
Co-authored-by: Boshen <boshenc@gmail.com>
  • Loading branch information
leaysgur and Boshen authored Mar 13, 2024
1 parent c820a5b commit b00d4b8
Showing 1 changed file with 90 additions and 19 deletions.
109 changes: 90 additions & 19 deletions crates/oxc_semantic/src/jsdoc/parser/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ impl<'a> JSDocParser<'a> {
let mut tags = vec![];

// Let's start with the first `@`
while let Some(c) = self.source_text.chars().nth(self.current) {
while let Some(c) = self.source_text[self.current..].chars().next() {
match c {
'@' => {
self.current += 1;
self.current += c.len_utf8();
tags.push(self.parse_tag());
}
_ => {
self.current += 1;
self.current += c.len_utf8();
}
}
}
Expand Down Expand Up @@ -91,7 +91,8 @@ impl<'a> JSDocParser<'a> {
self.skip_whitespace();

// JSDoc.app ignores `-` char between name and comment, but TS doesn't
if self.at('-') {
// Some people use `:` as separator
if self.at('-') || self.at(':') {
self.skip_whitespace();
}

Expand All @@ -103,39 +104,41 @@ impl<'a> JSDocParser<'a> {
//
// Parser utils
//

fn skip_whitespace(&mut self) {
while let Some(c) = self.source_text.chars().nth(self.current) {
while let Some(c) = self.source_text[self.current..].chars().next() {
if c != ' ' {
break;
}
self.current += 1;
self.current += c.len_utf8();
}
}

fn advance(&mut self) {
if self.current < self.source_text.len() {
self.current += 1;
if let Some(c) = self.source_text[self.current..].chars().next() {
self.current += c.len_utf8();
}
}

fn at(&mut self, c: char) -> bool {
let Some(ch) = self.source_text.chars().nth(self.current) else { return false };
if ch == c {
self.advance();
true
if let Some(ch) = self.source_text[self.current..].chars().next() {
if ch == c {
self.advance();
true
} else {
false
}
} else {
false
}
}

fn take_until(&mut self, predicate: fn(char) -> bool) -> &'a str {
let start = self.current;
while let Some(c) = self.source_text.chars().nth(self.current) {
while let Some(c) = self.source_text[self.current..].chars().next() {
if predicate(c) {
break;
}
self.current += 1;
self.current += c.len_utf8();
}
&self.source_text[start..self.current]
}
Expand Down Expand Up @@ -173,13 +176,24 @@ mod test {

assert_eq!(
parse_from_full_text(
"/**
this is comment
"/**
this is
comment
@x
*/"
)
.0,
"this is comment"
"this is\ncomment"
);
assert_eq!(
parse_from_full_text(
"/**
         * 日本語とか
         * multibyte文字はどう?
*/"
)
.0,
"日本語とか\nmultibyte文字はどう?"
);
}

Expand Down Expand Up @@ -394,7 +408,7 @@ comment */"
comment */"
),
parse_from_full_text(
"/**
"/**
* @param {str} name
* comment
*/"
Expand Down Expand Up @@ -445,4 +459,61 @@ comment */"
]
);
}

#[test]
fn parses_practical_with_multibyte() {
let jsdoc = parse_from_full_text(
"/**
* flat tree data on expanded state
*
* @export
* @template T
* @param {*} data : table data
* @param {string} childrenColumnName : 指定树形结构的列名
* @param {Set<Key>} expandedKeys : 展开的行对应的keys
* @param {GetRowKey<T>} getRowKey : 获取当前rowKey的方法
* @returns flattened data
*/",
);
assert_eq!(jsdoc.0, "flat tree data on expanded state");
assert_eq!(
jsdoc.1,
vec![
JSDocTag { kind: JSDocTagKind::Unknown("export"), comment: String::new() },
JSDocTag { kind: JSDocTagKind::Unknown("template"), comment: "T".to_string() },
JSDocTag {
kind: JSDocTagKind::Parameter(Param {
name: "data",
r#type: Some(ParamType { value: "*" })
}),
comment: "table data".to_string(),
},
JSDocTag {
kind: JSDocTagKind::Parameter(Param {
name: "childrenColumnName",
r#type: Some(ParamType { value: "string" })
}),
comment: "指定树形结构的列名".to_string(),
},
JSDocTag {
kind: JSDocTagKind::Parameter(Param {
name: "expandedKeys",
r#type: Some(ParamType { value: "Set<Key>" })
}),
comment: "展开的行对应的keys".to_string(),
},
JSDocTag {
kind: JSDocTagKind::Parameter(Param {
name: "getRowKey",
r#type: Some(ParamType { value: "GetRowKey<T>" })
}),
comment: "获取当前rowKey的方法".to_string(),
},
JSDocTag {
kind: JSDocTagKind::Unknown("returns"),
comment: "flattened data".to_string(),
},
]
);
}
}

0 comments on commit b00d4b8

Please sign in to comment.