From 8d72b6fb9f874fddad19cbc7b00f022cecbd4ab9 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Tue, 6 Sep 2022 15:21:25 +0300 Subject: [PATCH 1/4] Add qualified version of new class instance expression to support inner class instance creation. Also a minor change to a relevant test to validate this functionality. Change-Id: I2e711be8c2874d74d7bde7e25c76dbec9166f95c Signed-off-by: Mikhail Velikanov --- .../com/ohos/migrator/java/JavaTransformer.java | 13 ++++++++----- .../migrator/staticTS/parser/StaticTSParser.g4 | 6 +++--- .../migrator/staticTS/writer/StaticTSWriter.java | 10 ++++++++-- migrator/test/java/class_instance_creation.java | 11 +++++++++++ .../test/java/class_instance_creation.java.sts | 14 ++++++++++++++ migrator/test/java/generic_class_2.java.sts | 4 ++-- 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 8a67148c8..d472ad48b 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -2674,12 +2674,12 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // AnonymousClassDeclaration: { ClassBodyDeclaration } // STS tree: // singleExpression: - // | New typeReference arguments? classBody? # NewClassExpression + // | New (singleExpression Dot)? typeReference arguments? classBody? # NewClassExpression // arguments: OpenParen expressionSequence? CloseParen // classBody: OpenBrace classMember* clinit=classInitializer? classMember* CloseBrace // NOTE: If ctor called by class instance creation expression can throw exceptions, // wrap result in try expression. - // | Try singleExpression #TryExpression + // | Try singleExpression #TryExpression @Override public boolean visit(ClassInstanceCreation javaClassInstanceCreation) { IMethodBinding javaCtorBinding = javaClassInstanceCreation.resolveConstructorBinding(); @@ -2698,9 +2698,12 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } pushCurrent(new NewClassExpressionContext(pushSingleExpression())); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)).setParent(stsCurrent); - // TODO: What to do with javaClassInstanceCreation.getExpression() ? + + // Add outer class object, if any. + Expression javaOuterObject = javaClassInstanceCreation.getExpression(); + if (javaOuterObject != null) javaOuterObject.accept(this); + javaClassInstanceCreation.getType().accept(this); translateArguments(javaClassInstanceCreation.arguments()); @@ -2710,7 +2713,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaAnonymousClassDeclaration.accept(this); } - popSingleExpression(); + popSingleExpression(); // NewClassExpressionContext if (ctorCanThrow) { popSingleExpression(); // TryExpressionContext diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index af215832c..f235d8720 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -418,11 +418,11 @@ expressionStatement // Expressions singleExpression - : OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + : OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression | singleExpression indexExpression # ArrayAccessExpression | singleExpression Dot Identifier # MemberAccessExpression - | New typeReference arguments? classBody? # NewClassExpression - | New primaryType indexExpression+ # NewArrayExpression + | New (singleExpression Dot)? typeReference arguments? classBody? # NewClassExpression + | New primaryType indexExpression+ (OpenBracket CloseBracket)* # NewArrayExpression | singleExpression typeArguments? arguments # CallExpression | singleExpression {this.notLineTerminator()}? PlusPlus # PostIncrementExpression | singleExpression {this.notLineTerminator()}? MinusMinus # PostDecreaseExpression diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 6cff9ad2d..e527a7ef5 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1578,11 +1578,17 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // | New typeReference arguments? classBody? # NewClassExpression + // | New (singleExpression Dot)? typeReference arguments? classBody? # NewClassExpression @Override public Void visitNewClassExpression(NewClassExpressionContext stsNewClassExpression) { sb.append(stsNewClassExpression.New().getText()).append(' '); + SingleExpressionContext stsOuterObject = stsNewClassExpression.singleExpression(); + if (stsOuterObject != null) { + stsOuterObject.accept(this); + sb.append('.'); + } + visitTypeReference(stsNewClassExpression.typeReference()); ArgumentsContext stsArguments = stsNewClassExpression.arguments(); @@ -1598,7 +1604,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // | New primaryType indexExpression+ # NewArrayExpression + // | New primaryType indexExpression+ (OpenBracket CloseBracket)* # NewArrayExpression @Override public Void visitNewArrayExpression(NewArrayExpressionContext stsNewArrayExpression) { TerminalNode termNew = stsNewArrayExpression.New(); diff --git a/migrator/test/java/class_instance_creation.java b/migrator/test/java/class_instance_creation.java index 53d1eb020..f609c943c 100644 --- a/migrator/test/java/class_instance_creation.java +++ b/migrator/test/java/class_instance_creation.java @@ -29,4 +29,15 @@ class class_instance_creation { private int f; public void foo() { f = 2; } }; + + class inner { + inner(int i) {} + } + + inner inner_inst1 = new inner(1); + inner inner_inst2 = inst1.new inner(2); + inner inner_inst3 = inst4.new inner(3) { + private String s; + public void bar() { s = "bar"; } + }; } diff --git a/migrator/test/java/class_instance_creation.java.sts b/migrator/test/java/class_instance_creation.java.sts index 73b567831..fcd50901c 100644 --- a/migrator/test/java/class_instance_creation.java.sts +++ b/migrator/test/java/class_instance_creation.java.sts @@ -36,5 +36,19 @@ open class class_instance_creation { f = 2; } }; + + open class inner { + constructor(i : int) { + } + } + + inner_inst1 : inner = new inner(1); + inner_inst2 : inner = new inst1.inner(2); + inner_inst3 : inner = new inst4.inner(3) { + private s : String ; + public open bar(): void { + s = "bar"; + } + }; } diff --git a/migrator/test/java/generic_class_2.java.sts b/migrator/test/java/generic_class_2.java.sts index 1bd7124f4..2837a5960 100644 --- a/migrator/test/java/generic_class_2.java.sts +++ b/migrator/test/java/generic_class_2.java.sts @@ -35,7 +35,7 @@ open class Seq { return new Seq>(); } else { - let tailZipper : Seq.Zipper = new Zipper(); + let tailZipper : Seq.Zipper = new tail.Zipper(); return new Seq>(new Pair(head, that.head), tailZipper.zip(that.tail)); } } @@ -57,7 +57,7 @@ open class Test { public static main(args : String[]): void { let strs : Seq = new Seq("a", new Seq("b", new Seq())); let nums : Seq = new Seq(new Integer(1), new Seq(new Double(1.5), new Seq())); - let zipper : Seq.Zipper = new Zipper(); + let zipper : Seq.Zipper = new strs.Zipper(); let combined : Seq> = zipper.zip(nums); } } -- Gitee From a689c8e25388be745bd4bb30a9be9fcdb072e057 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Tue, 6 Sep 2022 17:14:32 +0300 Subject: [PATCH 2/4] Clean-up of the incomplete implementations, mostly around new array expression and array literal expression. Change-Id: I7acf4bf8e0d3f64e0c0803d1dc614000596479a9 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 97 ++++++++----------- .../staticTS/writer/StaticTSWriter.java | 12 ++- migrator/test/java/array_creation.java | 8 +- migrator/test/java/array_creation.java.sts | 6 +- 4 files changed, 57 insertions(+), 66 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index d472ad48b..13b6b74ba 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -186,10 +186,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // TODO: Remove as translation of remaining Java AST nodes is implemented! @Override - public boolean visit(TryStatement node) { - return false; - } - @Override public boolean visit(ThrowStatement node) { return false; } @@ -1413,8 +1409,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (javaBlock == null) { // Abstract method. pushCurrent(new AbstractOrNativeClassMethodContext(stsClassMethodDeclaration)); - // TODO: Check if 'abstract' has to be forced here or it will be automatically added in translateJavaModifiers(). - //stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Abstract)).setParent(stsCurrent); } else { // not abstract method pushCurrent(new ClassMethodWithBodyContext(stsClassMethodDeclaration)); } @@ -1534,9 +1528,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ParameterContext(stsCurrent, 0)); } - // TODO: The next line is not applicable for FormalParameter. So it should be checked/reworked later. - //translateJavaModifiers(javaSingleVariableDeclaration.getModifiers()); - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaSingleVariableDeclaration.getName())); // Parameter type @@ -1547,14 +1538,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (extraDims > 0) NodeBuilder.addExtraDimensions(stsCurrent, extraDims); popCurrent(); // TypeAnnotationContext - - // TODO: { Dimension } - //javaSingleVariableDeclaration. - // TODO: [= Expression ] -// Expression javaExpression = javaSingleVariableDeclaration.getInitializer(); -// if (javaExpression != null) { -// } - popCurrent(); // ParameterContext | VariadicParameterContext ++countDeclTransformed; @@ -2543,69 +2526,66 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } // Java tree: - // Expression: - // | ArrayCreation // ArrayCreation: - // new PrimitiveType [ Expression ] { [ Expression ] } { [ ] } - // new TypeName [ < Type { , Type } > ] [ Expression ] { [ Expression ] } { [ ] } - // new PrimitiveType [ ] { [ ] } ArrayInitializer - // new TypeName [ < Type { , Type } > ] [ ] { [ ] } ArrayInitializer + // new PrimitiveType [ Expression ] { [ Expression ]+ } { [ ]+ } + // new TypeName [ < Type { , Type }* > ] [ Expression ] { [ Expression ]+ } { [ ]+ } // STS tree: // singleExpression: - // | New primaryType indexExpression+ # NewArrayExpression + // | New primaryType indexExpression+ (OpenBracket CloseBracket)* # NewArrayExpression + // + // Java tree: + // new PrimitiveType [ ] { [ ]+ } ArrayInitializer + // new TypeName [ < Type { , Type }* > ] [ ] { [ ]+ } ArrayInitializer + // STS tree: + // singleExpression: + // | OpenBracket expressionSequence? CloseBracket # ArrayLiteralExpression @Override public boolean visit(ArrayCreation javaArrayCreation) { - pushCurrent(new NewArrayExpressionContext(pushSingleExpression())); + ArrayInitializer javaArrayInitializer = javaArrayCreation.getInitializer(); + if (javaArrayInitializer != null) { + // For array creation expressions with array initializer, + // emit ArrayLiteralExpressionContext node + javaArrayInitializer.accept(this); + return false; + } - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)).setParent(stsCurrent); + // Otherwise, emit NewArrayExpressionContext node + pushCurrent(new NewArrayExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)); - // Java tree: - // ArrayType: Type Dimension { Dimension } - // Dimension: { Annotation } [] - // STS tree: - // primaryType - javaArrayCreation.getType().getElementType().accept(this); + ArrayType javaArrayType = javaArrayCreation.getType(); + javaArrayType.getElementType().accept(this); List javaIndexExpressions = javaArrayCreation.dimensions(); for (Expression javaIndexExpression : javaIndexExpressions) { pushCurrent(new IndexExpressionContext(stsCurrent, 0)); - - if (javaIndexExpression != null) // May be 'null' to create just an empty index expression: [] - javaIndexExpression.accept(this); - + javaIndexExpression.accept(this); popCurrent(); // IndexExpressionContext } - // TODO: -// int n = javaArrayType.getDimensions(); -// for (int i = 0; i < n; i++) { -// createIndexExpression(null); // create just an empty index expression: [] -// } + int javaNumIndexExpr = javaIndexExpressions.size(); + int javaArrayTypeDims = javaArrayType.dimensions().size(); + if (javaArrayTypeDims > javaNumIndexExpr) { + // Dimensionality of array type can exceed the number of index expressions + // in the case current new array creation expression ends with empty dimensions. + // All we need to do here is to emit the same empty dimensions here. + for (int i = javaNumIndexExpr; i < javaArrayTypeDims; ++i) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); + } + } - // The NewArrayExpression has to be pop in any case. If there's no initializers then - // this is the end of the translation. If the initializer is present then it will be - // added directly to the parent node without the NewArrayExpression. popSingleExpression(); // NewArrayExpressionContext - // STS tree: - ArrayInitializer javaArrayInitializer = javaArrayCreation.getInitializer(); - if (javaArrayInitializer != null) { - stsCurrent.removeLastChild(); // Remove NewArrayExpression from the parent Initializer. - - // Java tree: - // ArrayInitializer: { [ Expression { , Expression} [ , ]] } - // STS tree: - // arrayLiteral: OpenBracket expressionSequence? CloseBracket - javaArrayInitializer.accept(this); - } - + ++countExprTransformed; return false; } // Java tree: // ArrayInitializer: { [ Expression { , Expression} [ , ]] } // STS tree: - // arrayLiteral: OpenBracket expressionSequence? CloseBracket + // singleExpression: + // | OpenBracket expressionSequence? CloseBracket # ArrayLiteralExpression @Override public boolean visit(ArrayInitializer javaArrayInitializer) { List javaExpressions = javaArrayInitializer.expressions(); @@ -2621,8 +2601,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ExpressionSequenceContext popSingleExpression(); // ArrayLiteralContext - // TODO: Needs reworking - // ++countExprTransformed; + ++countExprTransformed; return false; } diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index e527a7ef5..b50fd8cd6 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1607,8 +1607,8 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // | New primaryType indexExpression+ (OpenBracket CloseBracket)* # NewArrayExpression @Override public Void visitNewArrayExpression(NewArrayExpressionContext stsNewArrayExpression) { - TerminalNode termNew = stsNewArrayExpression.New(); - sb.append(termNew.getText()).append(' '); + TerminalNode stsTerm = stsNewArrayExpression.New(); + sb.append(stsTerm.getText()).append(' '); PrimaryTypeContext stsPrimaryType = stsNewArrayExpression.primaryType(); visitPrimaryType(stsPrimaryType); @@ -1618,6 +1618,14 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { for (IndexExpressionContext stsIndex : stsIndexList) visitIndexExpression(stsIndex); + List emptyDims = stsNewArrayExpression.OpenBracket(); + if (emptyDims != null && !emptyDims.isEmpty()) { + assert(stsNewArrayExpression.CloseBracket().size() == emptyDims.size()); + for (int i = 0; i < emptyDims.size(); ++i) { + sb.append("[]"); + } + } + return null; } diff --git a/migrator/test/java/array_creation.java b/migrator/test/java/array_creation.java index 03209c9a4..85cea69ed 100644 --- a/migrator/test/java/array_creation.java +++ b/migrator/test/java/array_creation.java @@ -17,11 +17,13 @@ package com.ohos.migrator.test.java; public class array_creation { private final byte b1[] = new byte[8]; + private final byte b2[][] = new byte[8][]; private final char c1[] = new char[] {'a', 'b', 'c'}; + private final char c2[][][] = new char[5][][]; - private void foo(char c2[]) {} + private void foo(char c2[][]) {} public void bar() { - foo(new char[] {'g', 'k', 'h'}); + foo(new char[][] {{'g'}, {'k', 'h'}}); } -} \ No newline at end of file +} diff --git a/migrator/test/java/array_creation.java.sts b/migrator/test/java/array_creation.java.sts index 6267de618..f71941dc6 100644 --- a/migrator/test/java/array_creation.java.sts +++ b/migrator/test/java/array_creation.java.sts @@ -17,10 +17,12 @@ package com.ohos.migrator.test.java; export open class array_creation { private const b1 : byte[] = new byte[8]; + private const b2 : byte[][] = new byte[8][]; private const c1 : char[] = ['a', 'b', 'c']; - private foo(c2 : char[]): void { + private const c2 : char[][][] = new char[5][][]; + private foo(c2 : char[][]): void { } public open bar(): void { - foo(['g', 'k', 'h']); + foo([['g'], ['k', 'h']]); } } -- Gitee From 0243439cf6070d9e5406bdaa71895dbbbdfcb315 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 7 Sep 2022 12:29:37 +0300 Subject: [PATCH 3/4] Improved metrics computation by excluding nodes that we don't intend to visit for the moment or don't expect to see in the input sources. Change-Id: Ifabca6fc2d21750bab9a120c47a580aa90d9106e Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/Main.java | 14 +- .../ohos/migrator/java/JavaTransformer.java | 431 +++++++++++++----- 2 files changed, 316 insertions(+), 129 deletions(-) diff --git a/migrator/src/com/ohos/migrator/Main.java b/migrator/src/com/ohos/migrator/Main.java index cacf67668..fe277dd1c 100644 --- a/migrator/src/com/ohos/migrator/Main.java +++ b/migrator/src/com/ohos/migrator/Main.java @@ -41,6 +41,7 @@ public class Main { static boolean verboseMode = false; static boolean strictMode = false; + static boolean convRateMode = false; public static void finish(ResultCode exitCode) { if(verboseMode) { for (TranspileException e: errorList) { @@ -66,6 +67,7 @@ public class Main { public static boolean isVerboseMode() { return verboseMode; } public static boolean isStrictMode() { return strictMode; } + public static boolean isConvRateMode() { return convRateMode; } public static boolean hasErrors() { return !errorList.isEmpty(); } public static void addError(ResultCode code, String message) { @@ -103,6 +105,7 @@ public class Main { if (cmd.hasOption("verbose")) verboseMode = true; if (cmd.hasOption("strict")) strictMode = true; + if (cmd.hasOption("conversion-rate")) convRateMode = true; String outDir = null; if (cmd.hasOption("o")) { @@ -195,7 +198,7 @@ public class Main { outFiles.addAll(javaTranspiler.getOutFiles()); errorList.addAll(javaTranspiler.getErrorList()); - convRate += javaTranspiler.getConversionRate(); + if (convRateMode) convRate += javaTranspiler.getConversionRate(); ++numLanguages; } @@ -208,15 +211,16 @@ public class Main { outFiles.addAll(kotlinTranspiler.getOutFiles()); errorList.addAll(kotlinTranspiler.getErrorList()); - convRate += kotlinTranspiler.getConversionRate(); + if (convRateMode) convRate += kotlinTranspiler.getConversionRate(); ++numLanguages; } - if (numLanguages > 0) convRate /= numLanguages; - if (resultCode == ResultCode.OK) System.out.println("Transpilation OK."); - if (cmd.hasOption("conversion-rate")) + + if (convRateMode) { + if (numLanguages > 0) convRate /= numLanguages; System.out.println("Conversion rate: " + String.format("%.1f", convRate) + "%"); + } // Check syntax of all STS files produced. // NOTE: This is for development process only, probably to be removed afterwards. diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 13b6b74ba..541b7488f 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -29,9 +29,7 @@ import org.eclipse.jdt.core.dom.*; import org.jetbrains.annotations.NotNull; import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; +import java.util.*; /** * Performs transformation of the Java AST (Eclipse JDT AST) into StaticTS AST. @@ -60,10 +58,14 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private static int countExprTotal = 0; private static int countDeclTotal = 0; private static int countTypeTotal = 0; - private static int countExprTransformed = 0; private static int countStmtTransformed = 0; + private static int countExprTransformed = 0; private static int countDeclTransformed = 0; private static int countTypeTransformed = 0; + private final Set exprTransformed = new HashSet<>(); + private final Set stmtTransformed = new HashSet<>(); + private final Set declTransformed = new HashSet<>(); + private final Set typeTransformed = new HashSet<>(); public static double getTransformationRate() { double result = 0.; @@ -86,6 +88,13 @@ public class JavaTransformer extends ASTVisitor implements Transformer { result += countTypeTransformed / (double)countTypeTotal; } + if (Main.isVerboseMode()) { + System.out.println("Statements: " + countStmtTransformed + " out of " + countStmtTotal); + System.out.println("Expressions: " + countExprTransformed + " out of " + countExprTotal); + System.out.println("Declarations: " + countDeclTransformed + " out of " + countDeclTotal); + System.out.println("Types: " + countTypeTransformed + " out of " + countTypeTotal); + } + return (normFactor > 0) ? result / (double)normFactor : 0.; } @@ -165,51 +174,194 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } public CompilationUnitContext transform() { - // Compute total counts of statements and expressions in - // Java AST. This is used in conversion rate computation. - javaCU.accept(new ASTVisitor() { - @Override - public void postVisit(ASTNode node) { - if (node instanceof Expression) - ++countExprTotal; - else if (node instanceof Statement) - ++countStmtTotal; - else if (node instanceof BodyDeclaration - || node instanceof VariableDeclaration - || node.getNodeType() == ASTNode.ANONYMOUS_CLASS_DECLARATION - || node.getNodeType() == ASTNode.IMPORT_DECLARATION - || node.getNodeType() == ASTNode.PACKAGE_DECLARATION) - ++countDeclTotal; - else if (node instanceof Type) - ++countTypeTotal; - } + if (Main.isConvRateMode()) { + // Compute total counts of statements, expressions, declarations + // and types in Java AST that we expect to transform. This is used + // in conversion rate computation. + javaCU.accept(new ASTVisitor() { + @Override + public void postVisit(ASTNode node) { + if (node instanceof Expression && + !(node instanceof Annotation) && + // names are translated manually by and large, + // almost never by accept, so it's hard to count + // them properly. Assume we handle them all and ignore. + !(node instanceof Name) && + node.getNodeType() != ASTNode.SWITCH_EXPRESSION && + node.getNodeType() != ASTNode.TEXT_BLOCK) + ++countExprTotal; + else if (node instanceof Statement && + node.getNodeType() != ASTNode.YIELD_STATEMENT) + ++countStmtTotal; + else if ((node instanceof BodyDeclaration + && node.getNodeType() != ASTNode.ANNOTATION_TYPE_DECLARATION + && node.getNodeType() != ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION) + || node instanceof VariableDeclaration + || node.getNodeType() == ASTNode.ANONYMOUS_CLASS_DECLARATION + || node.getNodeType() == ASTNode.IMPORT_DECLARATION + || node.getNodeType() == ASTNode.PACKAGE_DECLARATION) + ++countDeclTotal; + else if (node instanceof Type && node.getNodeType() != ASTNode.UNION_TYPE) + ++countTypeTotal; + } - // TODO: Remove as translation of remaining Java AST nodes is implemented! - @Override - public boolean visit(ThrowStatement node) { - return false; - } - @Override - public boolean visit(ExpressionMethodReference node) { - return false; - } - @Override - public boolean visit(SuperMethodReference node) { - return false; - } - @Override - public boolean visit(TypeMethodReference node) { - return false; - } - @Override - public boolean visit(CreationReference node) { - return false; - } - }); + // NOTE: The following AST nodes are not intended to be visited at the moment! + @Override + public boolean visit(MarkerAnnotation node) { + return false; + } + + @Override + public boolean visit(NormalAnnotation node) { + return false; + } + + @Override + public boolean visit(SingleMemberAnnotation node) { + return false; + } + + @Override + public boolean visit(SwitchExpression node) { + return false; + } + + @Override + public boolean visit(TextBlock node) { + return false; + } + + @Override + public boolean visit(YieldStatement node) { + return false; + } + + @Override + public boolean visit(AnnotationTypeDeclaration node) { + return false; + } + + @Override + public boolean visit(AnnotationTypeMemberDeclaration node) { + return false; + } + + @Override + public boolean visit(UnionType node) { + return false; + } + + // NOTE: The following AST nodes are being visited by JavaTransformer + // but need special treatment. + @Override + public boolean visit(ArrayCreation node) { + // If initializer is present, it's the only child node that gets visited. + ArrayInitializer initializer = node.getInitializer(); + if (initializer != null) { + initializer.accept(this); + return false; + } + + // We don't visit ArrayType inside ArrayCreation node. + node.getType().getElementType().accept(this); + + List indices = node.dimensions(); + for (Expression index : indices) + index.accept(this); + + return false; + } + + @Override + public boolean visit(MethodDeclaration node) { + // We don't visit list of exceptions thrown. + Type rt = node.getReturnType2(); + if (rt != null) rt.accept(this); + + List params = node.parameters(); + for (SingleVariableDeclaration param : params) + param.accept(this); + + // We don't visit the block itself, only statements inside it. + visitBodyStatements(node.getBody()); + + return false; + } + + private void visitBodyStatements(Block body) { + if (body != null) { + List stmts = body.statements(); + for (Statement stmt : stmts) + stmt.accept(this); + } + } + + @Override + public boolean visit(TryStatement node) { + // We don't visit the block itself, only statements inside it. + visitBodyStatements(node.getBody()); + + Block finallyBody = node.getFinally(); + if (finallyBody != null) finallyBody.accept(this); + + List catches = node.catchClauses(); + for (CatchClause catchClause : catches) + catchClause.accept(this); + + return false; + } + + @Override + public boolean visit(CatchClause node) { + // We visit only exception type, and if it's a union type, + // we visit only its component types. + SingleVariableDeclaration exception = node.getException(); + Type excType = exception.getType(); + if (excType.isUnionType()) { + List componentTypes = ((UnionType)excType).types(); + for (Type componentType : componentTypes) + componentType.accept(this); + } + else + excType.accept(this); + + // We don't visit the block itself, only statements inside it. + visitBodyStatements(node.getBody()); + + return false; + } + + @Override + public boolean visit(LambdaExpression node) { + List params = node.parameters(); + for (VariableDeclaration param : params) + param.accept(this); + + ASTNode body = node.getBody(); + if (body != null) { + // We don't visit the block itself, only statements inside it. + if (body.getNodeType() == ASTNode.BLOCK) + visitBodyStatements((Block)body); + else if (body instanceof Expression) + body.accept(this); + } + + return false; + } + }); + } // Visit Java AST and construct StaticTS AST. javaCU.accept(this); + if (Main.isConvRateMode()) { + // Update transformed AST node counts. + countStmtTransformed += stmtTransformed.size(); + countExprTransformed += exprTransformed.size(); + countDeclTransformed += declTransformed.size(); + countTypeTransformed += typeTransformed.size(); + } + return stsCU; } @@ -247,7 +399,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // PackageDeclarationContext - ++countDeclTransformed; + declTransformed.add(javaPackageDeclaration); return false; } @@ -326,7 +478,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // topDeclarationContext // Export? // ClassDeclarationContext - // TermminalNode <(static? (abstract | open) | (abstract | open)? static)?> ? + // TerminalNode <(static? (abstract | open) | (abstract | open)? static)?> ? // TerminalNode // TerminalNode // TypeParametersContext ? @@ -335,14 +487,14 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // ClassBodyContext // TerminalNode <{> // ClassMemberContext * - // clinit = CclassInitializerContext ? + // clinit = ClassInitializerContext ? // ClassMemberContext * // TerminalNode <}> // STS tree for interface declaration: // topDeclarationContext // Export? // InterfaceDeclarationContext - // TermminalNode ? + // TerminalNode ? // TerminalNode // TerminalNode // TypeParametersContext ? @@ -399,7 +551,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // Interface/ClassDeclarationContext popCurrent(); // DeclarationOrMemberContext - ++countDeclTransformed; + declTransformed.add(javaTypeDeclaration); return false; } @@ -480,7 +632,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaTypeParameter.getName())); - // ExtendedModifiers are ignored at the moment and seems do not need to be translated. + // ExtendedModifiers are ignored at the moment. List javaTypeBounds = javaTypeParameter.typeBounds(); @@ -663,7 +815,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // stsClassOrInterMember } - ++countDeclTransformed; + declTransformed.add(javaFieldDecl); return false; } @@ -690,7 +842,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ImportDeclarationContext - ++countDeclTransformed; + declTransformed.add(javaImportDeclaration); return false; } @@ -735,7 +887,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext - ++countTypeTransformed; + typeTransformed.add(javaPrimitiveType); return false; } @@ -756,7 +908,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext - ++countTypeTransformed; + typeTransformed.add(javaSimpleType); return false; } @@ -793,7 +945,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext - ++countTypeTransformed; + typeTransformed.add(javaQualifiedType); return false; } @@ -817,7 +969,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext - ++countTypeTransformed; + typeTransformed.add(javaNameQualifiedType); return false; } @@ -850,7 +1002,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext - ++countTypeTransformed; + typeTransformed.add(javaParametrizedType); return false; } @@ -872,7 +1024,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // WildcardTypeContext - ++countTypeTransformed; + typeTransformed.add(javaWildcardType); return false; } @@ -894,14 +1046,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext - ++countTypeTransformed; - return false; - } - - @Override - public boolean visit(UnionType javaUnionType) { - // UnionType is not expected to be present in Java sources the transpiler is supposed to translate. - assert(false) : "Unsupported Java syntax: Union types!"; + typeTransformed.add(javaArrayType); return false; } @@ -920,7 +1065,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext - ++countTypeTransformed; + typeTransformed.add(javaIntersectionType); return false; } @@ -952,7 +1097,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(NullLiteral javaLiteral) { stsCurrent.addChild(NodeBuilder.nullLiteral()).setParent(stsCurrent); - ++countExprTransformed; + exprTransformed.add(javaLiteral); return false; } @@ -964,7 +1109,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(BooleanLiteral javaLiteral) { stsCurrent.addChild(NodeBuilder.boolLiteral(javaLiteral.booleanValue())).setParent(stsCurrent); - ++countExprTransformed; + exprTransformed.add(javaLiteral); return false; } @@ -976,7 +1121,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(CharacterLiteral javaLiteral) { stsCurrent.addChild(NodeBuilder.charLiteral(javaLiteral.getEscapedValue())).setParent(stsCurrent); - ++countExprTransformed; + exprTransformed.add(javaLiteral); return false; } @@ -988,7 +1133,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(StringLiteral javaLiteral) { stsCurrent.addChild(NodeBuilder.stringLiteral(javaLiteral.getEscapedValue())).setParent(stsCurrent); - ++countExprTransformed; + exprTransformed.add(javaLiteral); return false; } @@ -1005,7 +1150,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(NumberLiteral javaLiteral) { stsCurrent.addChild(NodeBuilder.numericLiteral(javaLiteral.getToken())).setParent(stsCurrent); - ++countExprTransformed; + exprTransformed.add(javaLiteral); return false; } @@ -1018,7 +1163,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(SimpleName javaSimpleName) { String name = javaSimpleName.getIdentifier(); stsCurrent.addChild(NodeBuilder.identifierExpression(name)).setParent(stsCurrent); - ++countExprTransformed; + // Don't count names as transformed as most of them are transformed manually. return false; } @@ -1031,7 +1176,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(QualifiedName javaQualifiedName) { String name = javaQualifiedName.getFullyQualifiedName(); stsCurrent.addChild(NodeBuilder.identifierExpression(name)).setParent(stsCurrent); - ++countExprTransformed; + // Don't count names as transformed as most of them are transformed manually. return false; } @@ -1144,7 +1289,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // InfixExpression } - ++countExprTransformed; + exprTransformed.add(javaInfixExpression); return false; } @@ -1189,7 +1334,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); - ++countExprTransformed; + exprTransformed.add(javaPostfixExpression); return false; } @@ -1253,7 +1398,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); - ++countExprTransformed; + exprTransformed.add(javaPrefixExpression); return false; } @@ -1273,7 +1418,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); - ++countExprTransformed; + exprTransformed.add(javaParenthesizedExpression); return false; } @@ -1483,7 +1628,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ClassMemberContext or InterfaceMemberContext - ++countDeclTransformed; + declTransformed.add(javaMethodDeclaration); return false; } @@ -1540,7 +1685,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeAnnotationContext popCurrent(); // ParameterContext | VariadicParameterContext - ++countDeclTransformed; + declTransformed.add(javaSingleVariableDeclaration); return false; } @@ -1580,7 +1725,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ParameterContext - ++countDeclTransformed; + declTransformed.add(javaVariableDeclarationFragment); return false; } @@ -1719,7 +1864,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // stsClassDecl popCurrent(); // member context - ++countDeclTransformed; + declTransformed.add(javaEnumDeclaration); return false; } @@ -1981,7 +2126,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ClassFieldDeclarationContext popCurrent(); // ClassMemberContext - ++countDeclTransformed; + declTransformed.add(javaEnumConstant); return false; } @@ -1999,7 +2144,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { translateBlockStatements(javaBlock); popStatement(); // BlockContext - ++countStmtTransformed; + stmtTransformed.add(javaBlock); return false; } @@ -2019,7 +2164,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); } - ++countStmtTransformed; + stmtTransformed.add(javaEmptyStmnt); return false; } @@ -2035,7 +2180,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); - ++countStmtTransformed; + stmtTransformed.add(javaLabeledStmnt); return false; } @@ -2087,7 +2232,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // VarOrConstDeclaration - ++countDeclTransformed; // Each VariableDeclarationFragment is a separate declaration construct! + declTransformed.add(javaVarDeclFragment); // Each VariableDeclarationFragment is a separate declaration construct! } popCurrent(); // VarOrConstDeclarationList @@ -2113,7 +2258,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { createAndFillVarOrConstDeclarationList(javaVarStmnt.getModifiers(), javaVarStmnt.fragments(), javaVarStmnt.getType()); popStatement(); // VariableStatementContext - ++countStmtTransformed; + stmtTransformed.add(javaVarStmnt); return false; } @@ -2127,7 +2272,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(VariableDeclarationExpression javaVarDeclExpr) { createAndFillVarOrConstDeclarationList(javaVarDeclExpr.getModifiers(), javaVarDeclExpr.fragments(), javaVarDeclExpr.getType()); - ++countExprTransformed; + exprTransformed.add(javaVarDeclExpr); return false; } @@ -2165,7 +2310,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); // IfStatementContext - ++countStmtTransformed; + stmtTransformed.add(javaIfStmt); return false; } @@ -2183,6 +2328,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaLoopBody.accept(this); popIterationStatement(); // WhileStatementContext + + stmtTransformed.add(javaWhileStmt); return false; } @@ -2203,6 +2350,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaExpr.accept(this); popIterationStatement(); // DoStatementContext + + stmtTransformed.add(javaDoStmt); return false; } @@ -2282,7 +2431,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsInitStmts.addAll(stsBlock.statementOrLocalDeclaration()); } - ++countDeclTransformed; + declTransformed.add(javaInitializer); return false; } @@ -2296,11 +2445,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // ClassLiteralExpressionContext // PrimaryTypeContext . class @Override - public boolean visit(TypeLiteral node) { + public boolean visit(TypeLiteral javaTypeLiteral) { pushCurrent(new ClassLiteralExpressionContext(pushSingleExpression())); // Translate type - node.getType().accept(this); + javaTypeLiteral.getType().accept(this); // Add . and class tokens stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Dot)); @@ -2308,7 +2457,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // ClassLiteralExpressionContext - ++countExprTransformed; + exprTransformed.add(javaTypeLiteral); return false; } @@ -2324,7 +2473,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaExprStmt.getExpression().accept(this); popStatement(); - ++countStmtTransformed; + stmtTransformed.add(javaExprStmt); return false; } @@ -2361,7 +2510,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // AssignmentExpressionContext or AssignmentOperatorExpressionContext - ++countExprTransformed; + exprTransformed.add(javaAssignment); return false; } @@ -2392,7 +2541,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); - ++countStmtTransformed; + stmtTransformed.add(javaAssertStmt); return false; } @@ -2423,7 +2572,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaCtorInvocation.arguments(), null, isThrowingCall); - ++countStmtTransformed; + stmtTransformed.add(javaCtorInvocation); return false; } @@ -2457,7 +2606,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaSuperCtorInvocation.getExpression(), isThrowingCall); - ++countStmtTransformed; + stmtTransformed.add(javaSuperCtorInvocation); return false; } @@ -2521,7 +2670,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // IndexExpressionContext popSingleExpression(); // ArrayAccessExpression - ++countExprTransformed; + exprTransformed.add(javaArrayAccess); return false; } @@ -2577,7 +2726,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // NewArrayExpressionContext - ++countExprTransformed; + exprTransformed.add(javaArrayCreation); return false; } @@ -2601,7 +2750,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ExpressionSequenceContext popSingleExpression(); // ArrayLiteralContext - ++countExprTransformed; + exprTransformed.add(javaArrayInitializer); return false; } @@ -2620,7 +2769,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // CastExpressionContext - ++countExprTransformed; + exprTransformed.add(javaCastExpression); return false; } @@ -2640,7 +2789,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ClassBodyContext - ++countDeclTransformed; + declTransformed.add(javaAnonymousClassDeclaration); return false; } @@ -2698,7 +2847,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // TryExpressionContext } - ++countExprTransformed; + exprTransformed.add(javaClassInstanceCreation); return false; } @@ -2761,7 +2910,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popIterationStatement(); // IterationStatementContext + ForStatementContext - ++countStmtTransformed; + stmtTransformed.add(javaForStmt); return false; } @@ -2791,7 +2940,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popIterationStatement(); // IterationStatementContext + ForOfStatementContext - ++countStmtTransformed; + stmtTransformed.add(javaEnhancedForStmt); return false; } @@ -2811,7 +2960,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popStatement(); // BreakStatementContext - ++countStmtTransformed; + stmtTransformed.add(javaBreak); return false; } @@ -2831,7 +2980,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popStatement(); // ContinueStatementContext - ++countStmtTransformed; + stmtTransformed.add(javaContinue); return false; } @@ -2852,7 +3001,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popStatement(); // ReturnStatementContext - ++countStmtTransformed; + stmtTransformed.add(javaReturn); return false; } @@ -2872,7 +3021,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // TernaryExpressionContext - ++countExprTransformed; + exprTransformed.add(javaConditionalExpr); return false; } @@ -2891,7 +3040,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // MemberAccessExpressionContext - ++countExprTransformed; + exprTransformed.add(javaFieldAccess); return false; } @@ -2919,7 +3068,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaSuperFieldAccess.getName())); popSingleExpression(); // MemberAccessExpressionContext - ++countExprTransformed; + exprTransformed.add(javaSuperFieldAccess); return false; } @@ -2941,7 +3090,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // InstanceofExpression - ++countExprTransformed; + exprTransformed.add(javaInstanceofExpr); return false; } @@ -3001,7 +3150,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // TryExpressionContext } - ++countExprTransformed; + exprTransformed.add(javaMethodInvocation); return false; } @@ -3038,7 +3187,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { translateArguments(javaSuperMethodInvocation.arguments()); popSingleExpression(); // CallExpressionContext - ++countExprTransformed; + exprTransformed.add(javaSuperMethodInvocation); return false; } @@ -3058,7 +3207,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.This)); popSingleExpression(); // ThisExpressionContext - ++countExprTransformed; + exprTransformed.add(javaThisExpr); return false; } @@ -3074,7 +3223,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { javaTypeDeclarationStmt.getDeclaration().accept(this); - ++countStmtTransformed; + stmtTransformed.add(javaTypeDeclarationStmt); return false; } @@ -3174,7 +3323,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); // BlockContext } - ++countStmtTransformed; + stmtTransformed.add(javaSwitchStmt); return false; } @@ -3202,7 +3351,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } // SwitchCase is treated as Statement node, thus increment the count. - ++countStmtTransformed; + stmtTransformed.add(javaSwitchCase); return false; } @@ -3313,7 +3462,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } } - ++countStmtTransformed; + stmtTransformed.add(javaVarDeclStmt); } private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, @@ -3437,7 +3586,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // LambdaBodyContext popSingleExpression(); // LambdaExpressionContext - ++countExprTransformed; + exprTransformed.add(javaLambdaExpr); return false; } @@ -3570,7 +3719,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); // TrapStatementContext } - ++countStmtTransformed; + stmtTransformed.add(javaTryStatement); return false; } @@ -3654,7 +3803,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); // BlockContext - ++countStmtTransformed; + stmtTransformed.add(javaSynchrStmt); return false; } @@ -3681,6 +3830,40 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return stsCallExpr; } + // NOTE: The following AST nodes should not appear in Java 9 sources + // but since they are supported by the version of Eclipse JDT we use, + // let's report in case we see them. + @Override + public boolean visit(UnionType javaUnionType) { + // Emit __UnknownType__, warn and continue. + reportError("Unsupported Java syntax (union type)", javaUnionType); + return false; + } + + @Override + public boolean visit(TextBlock javaTextBlock) { + // Emit __untranslatedExpression call, warn and continue. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaTextBlock)).setParent(stsCurrent); + reportError("Unsupported Java syntax (text block)", javaTextBlock); + return false; + } + + @Override + public boolean visit(SwitchExpression javaSwitchExpression) { + // Emit __untranslatedExpression call, warn and continue. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaSwitchExpression)).setParent(stsCurrent); + reportError("Unsupported Java syntax (switch expression)", javaSwitchExpression); + return false; + } + + @Override + public boolean visit(YieldStatement javaYieldStatement) { + // Emit __untranslatedStatement call, warn and continue. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaYieldStatement)).setParent(stsCurrent); + reportError("Unsupported Java syntax (yield statement)", javaYieldStatement); + return false; + } + // The list of not yet translated Java Expressions: // CreationReference, // SuperMethodReference, -- Gitee From 4835f736c7c35e8cfe9ea226fe6032420f77df6b Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 7 Sep 2022 12:52:55 +0300 Subject: [PATCH 4/4] Fixed a bug in translation of parameter-less ctors of Java enums which was causing NPEs. Extended test to validate this fix. Change-Id: I606eac5e001d05cc67d97a1ee1e461a4014ff391 Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 4 ++++ migrator/test/java/enum_with_class_behavior.java | 8 ++++++++ migrator/test/java/enum_with_class_behavior.java.sts | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 541b7488f..611d2c416 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1888,7 +1888,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Get parameter list or create if there isn't one ParameterListContext stsEnumCtorParams = stsEnumCtor.parameterList(); if (stsEnumCtorParams == null) { + // ParameterListContext ctor doesn't initialize children field + // which we use below, so initialize it explicitly. stsEnumCtorParams = new ParameterListContext(stsEnumCtor, 0); + stsEnumCtorParams.children = new ArrayList<>(); + stsEnumCtor.addChild(stsEnumCtorParams).setParent(stsEnumCtor); } diff --git a/migrator/test/java/enum_with_class_behavior.java b/migrator/test/java/enum_with_class_behavior.java index 2331696ad..ff6d2406b 100644 --- a/migrator/test/java/enum_with_class_behavior.java +++ b/migrator/test/java/enum_with_class_behavior.java @@ -78,6 +78,14 @@ enum Planet { this(mass, radius, PlanetType.ROCK); } + // Checks addition of name and ordinal parameters + // to explciitly-defined parameter-less enum ctor. + private Planet() { + mass = 0.; + radius = 0.; + type = PlanetType.ROCK; + } + // universal gravitational constant (m3 kg-1 s-2) public static final double G = 6.67300E-11; diff --git a/migrator/test/java/enum_with_class_behavior.java.sts b/migrator/test/java/enum_with_class_behavior.java.sts index 6fab978ac..2fb6e6d4c 100644 --- a/migrator/test/java/enum_with_class_behavior.java.sts +++ b/migrator/test/java/enum_with_class_behavior.java.sts @@ -101,6 +101,13 @@ class Planet extends Enum { this(name, ordinal, mass, radius, PlanetType.ROCK); } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + mass = 0.; + radius = 0.; + type = PlanetType.ROCK; + } + public static const G : double = 6.67300E-11; open surfaceGravity(): double { -- Gitee