diff --git a/rust/src/ast_utils.rs b/rust/src/ast_utils.rs index a3e06752..dac7e2f2 100644 --- a/rust/src/ast_utils.rs +++ b/rust/src/ast_utils.rs @@ -46,6 +46,8 @@ pub struct JavaAstTokenFactory { method_create_generic_operator: JStaticMethodID, method_create_ident_known: JStaticMethodID, method_create_ident_other: JStaticMethodID, + method_create_jsx_tag_name: JStaticMethodID, + method_create_jsx_tag_text: JStaticMethodID, method_create_keyword: JStaticMethodID, method_create_null: JStaticMethodID, method_create_number: JStaticMethodID, @@ -116,6 +118,20 @@ impl JavaAstTokenFactory { "(Ljava/lang/String;IIZ)Lcom/caoccao/javet/swc4j/ast/words/Swc4jAstTokenIdentKnown;", ) .expect("Couldn't find method Swc4jAstTokenFactory.createIdentKnown"); + let method_create_jsx_tag_name = env + .get_static_method_id( + &class, + "createJsxName", + "(Ljava/lang/String;IIZ)Lcom/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagName;", + ) + .expect("Couldn't find method Swc4jAstTokenFactory.createJsxTagName"); + let method_create_jsx_tag_text = env + .get_static_method_id( + &class, + "createJsxText", + "(Ljava/lang/String;IIZ)Lcom/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagText;", + ) + .expect("Couldn't find method Swc4jAstTokenFactory.createJsxTagText"); let method_create_keyword = env .get_static_method_id( &class, @@ -196,6 +212,8 @@ impl JavaAstTokenFactory { method_create_generic_operator, method_create_ident_known, method_create_ident_other, + method_create_jsx_tag_name, + method_create_jsx_tag_text, method_create_keyword, method_create_null, method_create_number, @@ -462,6 +480,76 @@ impl JavaAstTokenFactory { token } + pub fn create_jsx_tag_name<'local, 'a>( + &self, + env: &mut JNIEnv<'local>, + text: &str, + range: Range, + line_break_ahead: bool, + ) -> JObject<'a> + where + 'local: 'a, + { + let java_string = converter::string_to_jstring(env, &text); + let text = jvalue { + l: java_string.as_raw(), + }; + let start_position = jvalue { i: range.start as i32 }; + let end_position = jvalue { i: range.end as i32 }; + let line_break_ahead = jvalue { + z: line_break_ahead as u8, + }; + let token = unsafe { + env + .call_static_method_unchecked( + &self.class, + self.method_create_jsx_tag_name, + ReturnType::Object, + &[text, start_position, end_position, line_break_ahead], + ) + .expect("Couldn't create Swc4jAstTokenJsxName") + .l() + .expect("Couldn't convert Swc4jAstTokenJsxName") + }; + env.delete_local_ref(java_string).expect("Couldn't delete local text"); + token + } + + pub fn create_jsx_tag_text<'local, 'a>( + &self, + env: &mut JNIEnv<'local>, + text: &str, + range: Range, + line_break_ahead: bool, + ) -> JObject<'a> + where + 'local: 'a, + { + let java_string = converter::string_to_jstring(env, &text); + let text = jvalue { + l: java_string.as_raw(), + }; + let start_position = jvalue { i: range.start as i32 }; + let end_position = jvalue { i: range.end as i32 }; + let line_break_ahead = jvalue { + z: line_break_ahead as u8, + }; + let token = unsafe { + env + .call_static_method_unchecked( + &self.class, + self.method_create_jsx_tag_text, + ReturnType::Object, + &[text, start_position, end_position, line_break_ahead], + ) + .expect("Couldn't create Swc4jAstTokenJsxText") + .l() + .expect("Couldn't convert Swc4jAstTokenJsxText") + }; + env.delete_local_ref(java_string).expect("Couldn't delete local text"); + token + } + pub fn create_keyword<'local, 'a>( &self, env: &mut JNIEnv<'local>, @@ -689,8 +777,12 @@ impl JavaAstTokenFactory { .l() .expect("Couldn't convert Swc4jAstTokenShebang") }; - env.delete_local_ref(java_string_text).expect("Couldn't delete local text"); - env.delete_local_ref(java_string_value).expect("Couldn't delete local value"); + env + .delete_local_ref(java_string_text) + .expect("Couldn't delete local text"); + env + .delete_local_ref(java_string_value) + .expect("Couldn't delete local value"); token } @@ -971,6 +1063,12 @@ pub fn token_and_spans_to_java_list<'local>( Token::Error(error) => { java_ast_token_factory.create_error(env, &text, &error, index_range, line_break_ahead) } + Token::JSXName { name } => { + java_ast_token_factory.create_jsx_tag_name(env, &name, index_range, line_break_ahead) + } + Token::JSXText { raw } => { + java_ast_token_factory.create_jsx_tag_text(env, &raw, index_range, line_break_ahead) + } token => match &AstTokenType::parse_by_generic_operator(token) { AstTokenType::Unknown => { eprintln!("Unknown {:?}", token); diff --git a/rust/src/enums.rs b/rust/src/enums.rs index ae8be939..3e33470f 100644 --- a/rust/src/enums.rs +++ b/rust/src/enums.rs @@ -140,15 +140,20 @@ pub enum AstTokenType { OrAssign, // 99 NullishAssign, // 100 // Atom - Uni - Error, // 101 + Shebang, // 101 + Error, // 102 // Atom - Bi - Str, // 102 - Num, // 103 - BigInt, // 104 - Template, // 105 - Shebang, // 106 + Str, // 103 + Num, // 104 + BigInt, // 105 + Template, // 106 // Atom - Tri Regex, // 107 + // Jsx + JSXTagStart, // 108 + JSXTagEnd, // 109 + JSXTagName, // 110 + JSXTagText, // 111 } impl IdentifiableEnum for AstTokenType { @@ -254,13 +259,17 @@ impl IdentifiableEnum for AstTokenType { AstTokenType::AndAssign => 98, AstTokenType::OrAssign => 99, AstTokenType::NullishAssign => 100, - AstTokenType::Error => 101, - AstTokenType::Str => 102, - AstTokenType::Num => 103, - AstTokenType::BigInt => 104, - AstTokenType::Template => 105, - AstTokenType::Shebang => 106, + AstTokenType::Shebang => 101, + AstTokenType::Error => 102, + AstTokenType::Str => 103, + AstTokenType::Num => 104, + AstTokenType::BigInt => 105, + AstTokenType::Template => 106, AstTokenType::Regex => 107, + AstTokenType::JSXTagStart => 108, + AstTokenType::JSXTagEnd => 109, + AstTokenType::JSXTagName => 110, + AstTokenType::JSXTagText => 111, _ => 0, } } @@ -366,13 +375,17 @@ impl IdentifiableEnum for AstTokenType { 98 => AstTokenType::AndAssign, 99 => AstTokenType::OrAssign, 100 => AstTokenType::NullishAssign, - 101 => AstTokenType::Error, - 102 => AstTokenType::Str, - 103 => AstTokenType::Num, - 104 => AstTokenType::BigInt, - 105 => AstTokenType::Template, - 106 => AstTokenType::Shebang, + 101 => AstTokenType::Shebang, + 102 => AstTokenType::Error, + 103 => AstTokenType::Str, + 104 => AstTokenType::Num, + 105 => AstTokenType::BigInt, + 106 => AstTokenType::Template, 107 => AstTokenType::Regex, + 108 => AstTokenType::JSXTagStart, + 109 => AstTokenType::JSXTagEnd, + 110 => AstTokenType::JSXTagName, + 111 => AstTokenType::JSXTagText, _ => AstTokenType::Unknown, } } @@ -451,6 +464,8 @@ impl AstTokenType { Token::PlusPlus => AstTokenType::PlusPlus, Token::MinusMinus => AstTokenType::MinusMinus, Token::Tilde => AstTokenType::Tilde, + Token::JSXTagStart => AstTokenType::JSXTagStart, + Token::JSXTagEnd => AstTokenType::JSXTagEnd, _ => AstTokenType::Unknown, } } diff --git a/src/main/java/com/caoccao/javet/swc4j/ast/Swc4jAstTokenFactory.java b/src/main/java/com/caoccao/javet/swc4j/ast/Swc4jAstTokenFactory.java index 264df74f..a6d6bd78 100644 --- a/src/main/java/com/caoccao/javet/swc4j/ast/Swc4jAstTokenFactory.java +++ b/src/main/java/com/caoccao/javet/swc4j/ast/Swc4jAstTokenFactory.java @@ -16,11 +16,12 @@ package com.caoccao.javet.swc4j.ast; -import com.caoccao.javet.swc4j.ast.atom.bi.*; +import com.caoccao.javet.swc4j.ast.atom.bi.Swc4jAstTokenBigInt; +import com.caoccao.javet.swc4j.ast.atom.bi.Swc4jAstTokenNumber; +import com.caoccao.javet.swc4j.ast.atom.bi.Swc4jAstTokenString; +import com.caoccao.javet.swc4j.ast.atom.bi.Swc4jAstTokenTemplate; import com.caoccao.javet.swc4j.ast.atom.tri.Swc4jAstTokenRegex; -import com.caoccao.javet.swc4j.ast.atom.uni.Swc4jAstTokenError; -import com.caoccao.javet.swc4j.ast.atom.uni.Swc4jAstTokenShebang; -import com.caoccao.javet.swc4j.ast.atom.uni.Swc4jAstTokenUnknown; +import com.caoccao.javet.swc4j.ast.atom.uni.*; import com.caoccao.javet.swc4j.ast.operators.Swc4jAstTokenAssignOperator; import com.caoccao.javet.swc4j.ast.operators.Swc4jAstTokenBinaryOperator; import com.caoccao.javet.swc4j.ast.operators.Swc4jAstTokenGenericOperator; @@ -156,6 +157,36 @@ public static Swc4jAstTokenIdentOther createIdentOther( return new Swc4jAstTokenIdentOther(text, startPosition, endPosition, lineBreakAhead); } + /** + * Create ast token jsx name. + * + * @param text the text + * @param startPosition the start position + * @param endPosition the end position + * @param lineBreakAhead the line break ahead + * @return the ast token jsx name + * @since 0.2.0 + */ + public static Swc4jAstTokenJsxTagName createJsxName( + String text, int startPosition, int endPosition, boolean lineBreakAhead) { + return new Swc4jAstTokenJsxTagName(text, startPosition, endPosition, lineBreakAhead); + } + + /** + * Create ast token jsx text. + * + * @param text the text + * @param startPosition the start position + * @param endPosition the end position + * @param lineBreakAhead the line break ahead + * @return the ast token jsx text + * @since 0.2.0 + */ + public static Swc4jAstTokenJsxTagText createJsxText( + String text, int startPosition, int endPosition, boolean lineBreakAhead) { + return new Swc4jAstTokenJsxTagText(text, startPosition, endPosition, lineBreakAhead); + } + /** * Create ast token keyword. * diff --git a/src/main/java/com/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagName.java b/src/main/java/com/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagName.java new file mode 100644 index 00000000..c2c3fe63 --- /dev/null +++ b/src/main/java/com/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagName.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024. caoccao.com Sam Cao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.caoccao.javet.swc4j.ast.atom.uni; + +import com.caoccao.javet.swc4j.ast.atom.BaseSwc4jAstTokenUniAtom; +import com.caoccao.javet.swc4j.enums.Swc4jAstTokenType; + +/** + * The type Swc4j ast token jsx tag name. + * + * @since 0.2.0 + */ +public class Swc4jAstTokenJsxTagName extends BaseSwc4jAstTokenUniAtom { + /** + * Instantiates a new Swc4j ast token jsx tag name. + * + * @param text the text + * @param startPosition the start position + * @param endPosition the end position + * @param lineBreakAhead the line break ahead + * @since 0.2.0 + */ + public Swc4jAstTokenJsxTagName(String text, int startPosition, int endPosition, boolean lineBreakAhead) { + super(text, startPosition, endPosition, lineBreakAhead); + } + + @Override + public Swc4jAstTokenType getType() { + return Swc4jAstTokenType.JsxTagName; + } +} diff --git a/src/main/java/com/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagText.java b/src/main/java/com/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagText.java new file mode 100644 index 00000000..d2d6ade2 --- /dev/null +++ b/src/main/java/com/caoccao/javet/swc4j/ast/atom/uni/Swc4jAstTokenJsxTagText.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024. caoccao.com Sam Cao + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.caoccao.javet.swc4j.ast.atom.uni; + +import com.caoccao.javet.swc4j.ast.atom.BaseSwc4jAstTokenUniAtom; +import com.caoccao.javet.swc4j.enums.Swc4jAstTokenType; + +/** + * The type Swc4j ast token jsx tag text. + * + * @since 0.2.0 + */ +public class Swc4jAstTokenJsxTagText extends BaseSwc4jAstTokenUniAtom { + /** + * Instantiates a new Swc4j ast token jsx tag text. + * + * @param text the text + * @param startPosition the start position + * @param endPosition the end position + * @param lineBreakAhead the line break ahead + * @since 0.2.0 + */ + public Swc4jAstTokenJsxTagText(String text, int startPosition, int endPosition, boolean lineBreakAhead) { + super(text, startPosition, endPosition, lineBreakAhead); + } + + @Override + public Swc4jAstTokenType getType() { + return Swc4jAstTokenType.JsxTagText; + } +} diff --git a/src/main/java/com/caoccao/javet/swc4j/enums/Swc4jAstTokenType.java b/src/main/java/com/caoccao/javet/swc4j/enums/Swc4jAstTokenType.java index 7654fc3c..9b1ffec1 100644 --- a/src/main/java/com/caoccao/javet/swc4j/enums/Swc4jAstTokenType.java +++ b/src/main/java/com/caoccao/javet/swc4j/enums/Swc4jAstTokenType.java @@ -126,15 +126,20 @@ public enum Swc4jAstTokenType { OrAssign(99, "||=", Swc4jAstTokenSubType.AssignOperator), NullishAssign(100, "??=", Swc4jAstTokenSubType.AssignOperator), // Atom - Uni - Error(101, "$Error", Swc4jAstTokenSubType.UniAtom), + Shebang(101, "$Shebang", Swc4jAstTokenSubType.UniAtom), + Error(102, "$Error", Swc4jAstTokenSubType.UniAtom), // Atom - Bi - Str(102, "$Str", Swc4jAstTokenSubType.BiAtom), - Num(103, "$Num", Swc4jAstTokenSubType.BiAtom), - BigInt(104, "$BigInt", Swc4jAstTokenSubType.BiAtom), - Template(105, "$Template", Swc4jAstTokenSubType.BiAtom), - Shebang(106, "$Shebang", Swc4jAstTokenSubType.BiAtom), + Str(103, "$Str", Swc4jAstTokenSubType.BiAtom), + Num(104, "$Num", Swc4jAstTokenSubType.BiAtom), + BigInt(105, "$BigInt", Swc4jAstTokenSubType.BiAtom), + Template(106, "$Template", Swc4jAstTokenSubType.BiAtom), // Atom - Tri Regex(107, "$Regex", Swc4jAstTokenSubType.TriAtom), + // Jsx + JsxTagStart(108, "<", Swc4jAstTokenSubType.GenericOperator), + JsxTagEnd(109, ">", Swc4jAstTokenSubType.GenericOperator), + JsxTagName(110, "$JsxTagName", Swc4jAstTokenSubType.UniAtom), + JsxTagText(111, "$JsxTagText", Swc4jAstTokenSubType.UniAtom), ; private static final int LENGTH = values().length; diff --git a/src/test/java/com/caoccao/javet/swc4j/TestSwc4j.java b/src/test/java/com/caoccao/javet/swc4j/TestSwc4j.java index 4ee2b602..c9402810 100644 --- a/src/test/java/com/caoccao/javet/swc4j/TestSwc4j.java +++ b/src/test/java/com/caoccao/javet/swc4j/TestSwc4j.java @@ -131,10 +131,12 @@ public void testParseTypeScriptWithCaptureTokens() throws Swc4jCoreException { assertTrue(tokens.get(0).isLineBreakAhead()); assertEquals(Swc4jAstTokenType.Return, tokens.get(12).getType()); assertFalse(tokens.get(12).isLineBreakAhead()); - tokens.forEach(token -> - assertEquals( - code.substring(token.getStartPosition(), token.getEndPosition()), - token.getText())); + tokens.forEach(token -> { + assertNotEquals(Swc4jAstTokenType.Unknown, token.getType()); + assertEquals( + code.substring(token.getStartPosition(), token.getEndPosition()), + token.getText()); + }); } // Keyword parseAndAssert("await f()", options, Swc4jAstTokenType.Await, "await", 0, 5, 0, 4); @@ -256,6 +258,12 @@ public void testParseTypeScriptWithCaptureTokens() throws Swc4jCoreException { assertTokenValue("a ", parseAndAssert("`a ${b} c`", options, Swc4jAstTokenType.Template, "a ", 1, 3, 1, 7)); parseAndAssert("`a ${b} c`", options, Swc4jAstTokenType.IdentOther, "b", 5, 6, 3, 7); assertTokenValue(" c", parseAndAssert("`a ${b} c`", options, Swc4jAstTokenType.Template, " c", 7, 9, 5, 7)); + // Jsx + options.setMediaType(Swc4jMediaType.Jsx); + parseAndAssert("const a =

b

;", options, Swc4jAstTokenType.JsxTagStart, "<", 10, 11, 3, 12); + parseAndAssert("const a =

b

;", options, Swc4jAstTokenType.JsxTagEnd, ">", 13, 14, 5, 12); + parseAndAssert("const a =

b

;", options, Swc4jAstTokenType.JsxTagName, "h1", 11, 13, 4, 12); + parseAndAssert("const a =

b

;", options, Swc4jAstTokenType.JsxTagText, "b", 14, 15, 6, 12); } @Test