diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index b0eb95d5a4462a485122bc9190497df411651e8c..8f03a6ce55c76fa55807d03abf1357359096471a 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -771,9 +771,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(ArrayType javaArrayType) { - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + boolean needPrimaryType = isInPrimaryTypeContext(); + if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); javaArrayType.getElementType().accept(this); int numDims = javaArrayType.getDimensions(); @@ -783,8 +784,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // ArrayTypeContext - popCurrent(); // PrimaryTypeContext + if (needPrimaryType) popCurrent(); // PrimaryTypeContext return false; } @@ -1672,12 +1673,39 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // Java AST: + // TypeName {[ ]} . class + // NumericType {[ ]} . class + // boolean {[ ]} . class + // void . class + // STS AST: + // SingleExpressionContext + // ClassLiteralExpressionContext + // PrimaryTypeContext . class + @Override + public boolean visit(TypeLiteral node) { + pushCurrent(new ClassLiteralExpressionContext(pushSingleExpression())); + + // Translate type + node.getType().accept(this); + + // Add . and class tokens + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Dot)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Class)); + + popSingleExpression(); // ClassLiteralExpressionContext + + ++countExprTransformed; + return false; + } + // Java tree: // ExpressionStatement: // Expression ; // STS tree: // expressionStatement: // singleExpression SemiColon? + @Override public boolean visit(ExpressionStatement javaExprStmt) { pushStatement(new ExpressionStatementContext(null, 0)); javaExprStmt.getExpression().accept(this); diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 65ca0b0afab8e7741f4ce6662fcc0f498fff7123..aa327e05eb3d731f5bb8ae5aced35df7a4899063 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -180,16 +180,32 @@ public class NodeBuilder { LiteralContext stsLiteral = new LiteralContext(null, 0); CommonToken token; + // parse string representation to create appropriate token - if (value.startsWith("0b")) { + // Ignore d and l suffices that Java allows for numeric literals + // NOTE: The f suffix that Java also allows will be dealt with + // later, as it might conflict with hexadecimal literals. + if (value.endsWith("d") || value.endsWith("D") || + value.endsWith("l") || value.endsWith("L")) { + value = value.substring(0, value.length() - 1); + } + + if (value.startsWith("0b") || value.startsWith("0B")) { token = new CommonToken(StaticTSParser.BinaryIntegerLiteral, value); - } else if (value.startsWith("0x")) { + } + else if (value.startsWith("0x") || value.startsWith("0X")) { token = new CommonToken(StaticTSParser.HexIntegerLiteral, value); - } else if( value.startsWith("0") && !value.contains("89")) { + } + else if (value.startsWith("0") && value.length() > 1 && + !value.contains("89") && !value.contains(".")) { + // STS octal literals start with 0o + value = "0o" + value.substring(1); token = new CommonToken(StaticTSParser.OctalIntegerLiteral, value); - } else { - // Java floats have suffix 'f' - if (value.endsWith("f")) value = value.substring(0,value.length()-1); + } + else { + if (value.endsWith("f") || value.endsWith("F")) { + value = value.substring(0, value.length() - 1); + } token = new CommonToken(StaticTSParser.DecimalLiteral, value); } diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 index 705a2583cb3b3d35af3b52cb93c77c386bee6012..b0ba23ccce21fcc1f05f183e268848d70dc29ae6 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 @@ -86,16 +86,25 @@ BooleanLiteral: 'true' /// Numeric Literals -DecimalLiteral: DecimalIntegerLiteral '.' [0-9]* ExponentPart? - | '.' [0-9]+ ExponentPart? +DecimalLiteral: DecimalIntegerLiteral '.' FractionalPart? ExponentPart? + | '.' FractionalPart ExponentPart? | DecimalIntegerLiteral ExponentPart? ; /// Numeric Literals -HexIntegerLiteral: '0' [xX] HexDigit+; -OctalIntegerLiteral: '0' [oO] [0-7]+ {!this.IsStrictMode()}?; -BinaryIntegerLiteral: '0' [bB] [01]+; +HexIntegerLiteral: '0' [xX] ( + HexDigit + | HexDigit (HexDigit | '_')* HexDigit + ); +OctalIntegerLiteral: '0' [oO] ( + [0-7] + | [0-7] [0-7_]* [0-7] + ); +BinaryIntegerLiteral: '0' [bB] ( + [01] + | [01] [01_]* [01] + ); /// Keywords @@ -240,12 +249,17 @@ fragment HexDigit ; fragment DecimalIntegerLiteral - : '0' - | [1-9] [0-9]* + : [0-9] + | [1-9] [0-9_]* [0-9] + ; + +fragment FractionalPart + : [0-9] + | [0-9] [0-9_]* [0-9] ; fragment ExponentPart - : [eE] [+-]? [0-9]+ + : [eE] [+-]? DecimalIntegerLiteral ; fragment IdentifierPart diff --git a/migrator/test/java/literals.java b/migrator/test/java/literals.java new file mode 100644 index 0000000000000000000000000000000000000000..5c8c11a6b184217d440a162dc9e9e29918f49c8a --- /dev/null +++ b/migrator/test/java/literals.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * 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.ohos.migrator.test.java; + +class literals { + void test() { + // integer literals + byte b = 0; + byte b2 = 1_0_2; + short s = 0x1; + short s2 = 0X1_F; + int i = 02; + int i2 = 03_4_56; + long l = 0b11L; + long l2 = 0B1_01_11l; + + // floating-point literals + float f = 4f; + float f2 = 1_2.23_45e+6F; + float f3 = 3.402_823_5e1_7f; + double d = 5.; + double d2 = .123_456; + double d3 = 0.123876; + double pi = 3.1416D; + double G = 6.6_73_00E-11d; + + // char and string literals + char c = '6'; + char c2 = '\t'; + char c3 = '\''; + String str = "7"; + String str2 = "Who needs \"dots\" over \"eyes\"? ;)\r\n"; + + // null and boolean literals + literals nl = null; + boolean tl = true; + boolean fl = false; + + // class literals + Class cl = literals.class; + Class ll = long.class; + Class sal = String[].class; + Class dal = double[].class; + } +} diff --git a/migrator/test/java/literals.java.sts b/migrator/test/java/literals.java.sts new file mode 100755 index 0000000000000000000000000000000000000000..3e3d7934d4048e83801b310a86286732d32a8398 --- /dev/null +++ b/migrator/test/java/literals.java.sts @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * 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.ohos.migrator.test.java; + +open class literals { + open test(): void { + let b : byte = 0; + let b2 : byte = 1_0_2; + let s : short = 0x1; + let s2 : short = 0X1_F; + let i : int = 0o2; + let i2 : int = 0o3_4_56; + let l : long = 0b11; + let l2 : long = 0B1_01_11; + let f : float = 4; + let f2 : float = 1_2.23_45e+6; + let f3 : float = 3.402_823_5e1_7; + let d : double = 5.; + let d2 : double = .123_456; + let d3 : double = 0.123876; + let pi : double = 3.1416; + let G : double = 6.6_73_00E-11; + let c : char = '6'; + let c2 : char = '\t'; + let c3 : char = '\''; + let str : String = "7"; + let str2 : String = "Who needs \"dots\" over \"eyes\"? ;)\r\n"; + let nl : literals = null; + let tl : boolean = true; + let fl : boolean = false; + let cl : Class = literals.class; + let ll : Class = long.class; + let sal : Class = String[].class; + let dal : Class = double[].class; + } +} +