From 1c505c10d7504f8f2bc15271c3853e470aa79d5d Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Fri, 5 Aug 2022 16:29:37 +0300 Subject: [PATCH 01/60] ExpressionMethodReference translation is implemented. A few bugs in generics translation are fixed. Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 227 ++++++++++++++++-- .../ohos/migrator/staticTS/NodeBuilder.java | 58 +++-- .../staticTS/writer/StaticTSWriter.java | 10 + migrator/test/java/generic_class_1.java | 28 +++ migrator/test/java/generic_class_1.java.sts | 31 +++ migrator/test/java/generic_class_2.java | 57 +++++ migrator/test/java/generic_class_2.java.sts | 65 +++++ migrator/test/java/generic_class_3.java | 50 ++++ migrator/test/java/generic_class_3.java.sts | 56 +++++ migrator/test/java/generic_class_4.java | 22 ++ migrator/test/java/generic_class_4.java.sts | 23 ++ migrator/test/java/generic_interface_1.java | 26 ++ .../test/java/generic_interface_1.java.sts | 25 ++ migrator/test/java/generic_interface_2.java | 28 +++ .../test/java/generic_interface_2.java.sts | 28 +++ migrator/test/java/generic_interface_3.java | 26 ++ .../test/java/generic_interface_3.java.skip | 0 17 files changed, 718 insertions(+), 42 deletions(-) create mode 100644 migrator/test/java/generic_class_1.java create mode 100644 migrator/test/java/generic_class_1.java.sts create mode 100644 migrator/test/java/generic_class_2.java create mode 100644 migrator/test/java/generic_class_2.java.sts create mode 100644 migrator/test/java/generic_class_3.java create mode 100644 migrator/test/java/generic_class_3.java.sts create mode 100644 migrator/test/java/generic_class_4.java create mode 100644 migrator/test/java/generic_class_4.java.sts create mode 100644 migrator/test/java/generic_interface_1.java create mode 100644 migrator/test/java/generic_interface_1.java.sts create mode 100644 migrator/test/java/generic_interface_2.java create mode 100644 migrator/test/java/generic_interface_2.java.sts create mode 100644 migrator/test/java/generic_interface_3.java create mode 100644 migrator/test/java/generic_interface_3.java.skip diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index b0eb95d5a..853907a48 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -412,13 +412,58 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeParametersContext } + // Java tree: + // TypeParameter: { ExtendedModifier } Identifier [ extends Type { & Type } ] + // STS tree: + // typeParameter: Identifier constraint?; + // constraint: Extends (typeReference | intersectionType); + // typeReference: typeReferencePart (Dot typeReferencePart)* + // typeReferencePart: qualifiedName typeArguments? + // typeArguments: LessThan typeArgumentList? MoreThan + // intersectionType: OpenParen typeReference (BitAnd typeReference)+ CloseParen @Override public boolean visit(TypeParameter javaTypeParameter) { pushCurrent(new TypeParameterContext(stsCurrent, 0)); - // TODO: Add constraints! stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaTypeParameter.getName())); + // TODO: Add constraints! + List javaModifiers = javaTypeParameter.modifiers(); + if (javaModifiers != null && !javaModifiers.isEmpty()) { + // TODO: Translate the modifiers. + } + + List javaTypeBounds = javaTypeParameter.typeBounds(); + if (!javaTypeBounds.isEmpty()) { + pushCurrent(new ConstraintContext(stsCurrent, 0)); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Extends)); + + if (javaTypeBounds.size() == 1) { + javaTypeBounds.get(0).accept(this); + } else { + pushCurrent(new IntersectionTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); + + boolean first = true; + for (Type javaType : javaTypeBounds) { + if (!first) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.BitAnd)); + } else { + first = false; + } + + javaType.accept(this); + } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); + popCurrent(); // IntersectionTypeContext + } + + popCurrent(); // ConstraintContext + } + + popCurrent(); // TypeParameterContext return false; } @@ -709,6 +754,21 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + private void translateTypeArgumens(List javaTypeArgs) { + pushCurrent(new TypeArgumentsContext(stsCurrent, 0)); + pushCurrent(new TypeArgumentListContext(stsCurrent, 0)); + + for (Type javaTypeArg : javaTypeArgs) { + pushCurrent(new TypeArgumentContext(stsCurrent, 0)); + javaTypeArg.accept(this); + popCurrent(); // TypeArgumentContext + } + + popCurrent(); // TypeArgumentListContext + popCurrent(); // TypeArgumentsContext + + } + @Override public boolean visit(ParameterizedType javaParametrizedType) { boolean needPrimaryType = isInPrimaryTypeContext(); @@ -730,17 +790,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { assert(lastChild instanceof TypeReferencePartContext && lastChild.getChildCount() == 1); pushCurrent((TypeReferencePartContext)lastChild, false); - pushCurrent(new TypeArgumentsContext(stsCurrent, 0)); - pushCurrent(new TypeArgumentListContext(stsCurrent, 0)); - - for (Type javaTypeArg : javaTypeArgs) { - pushCurrent(new TypeArgumentContext(stsCurrent, 0)); - javaTypeArg.accept(this); - popCurrent(); // TypeArgumentContext - } + translateTypeArgumens(javaTypeArgs); - popCurrent(); // TypeArgumentListContext - popCurrent(); // TypeArgumentsContext popCurrent(); // (TypeReferencePartContext)lastChild popCurrent(); // (TypeReferenceContext)lastChild } @@ -1128,7 +1179,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // typeParameters: LessThan typeParameterList? MoreThan // typeParameterList: typeParameter (Comma typeParameter)* - private void createStsTypeParameters(List javaTypeParameters) { + private void createStsTypeParameters(List javaTypeParameters) { assert(javaTypeParameters != null); if (!javaTypeParameters.isEmpty()) { @@ -1138,8 +1189,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // typeParameterList: typeParameter (Comma typeParameter)* pushCurrent(new TypeParameterListContext(stsCurrent, 0)); - for (Type javaType : javaTypeParameters) { - javaType.accept(this); + for (TypeParameter javaTypeParameter : javaTypeParameters) { + javaTypeParameter.accept(this); // Note: TerminalToken (Comma) is not added to the tree. Check if it works OK. } @@ -1343,7 +1394,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaSingleVariableDeclaration.getType().accept(this); popCurrent(); // TypeAnnotationContext - // TODO: { Dimention } + // TODO: { Dimension } //javaSingleVariableDeclaration. // TODO: [= Expression ] // Expression javaExpression = javaSingleVariableDeclaration.getInitializer(); @@ -1903,10 +1954,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaArrayInitializer.accept(this); } -// popSingleExpression(); // NewArrayExpression - - // TODO: Needs reworking. - // ++countExprTransformed. return false; } @@ -2006,7 +2053,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: // ForStatement: // for ( @@ -2246,7 +2292,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Dot Identifier # MemberAccessExpression - // where the next singleExpresion is + // where the next singleExpression is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(SuperFieldAccess javaSuperFieldAccess) { @@ -2274,7 +2320,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Instanceof primaryType # instanceofExpression - // where the next singleExpresion is + // where the next singleExpression is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(InstanceofExpression javaInstanceofExpr) { @@ -2413,12 +2459,147 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // Java tree: + // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier + // STS tree: + // singleExpression: + // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // lambdaBody: singleExpression | block; + @Override + public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { + pushCurrent(new LambdaExpressionContext(pushSingleExpression())); + + javaExpressionMethodReference.getExpression().accept(this); + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + stsCurrent.removeLastChild(); + assert(lastChild instanceof SingleExpressionContext); + SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; + + // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); + // parameterList: parameter... + pushCurrent(new ParameterListContext(stsCurrent, 0)); + // parameter: Identifier typeAnnotation + pushCurrent(new ParameterContext(stsCurrent, 0)); + + // TODO: Check if the fixed object name used here may cause a names conflict. + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. + assert (stsTypeExpr.getChildCount() == 1); + ParseTree stsNode = stsTypeExpr.getChild(0); + if (stsNode instanceof IdentifierExpressionContext) { + String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); + stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); + } + else { + // TODO: May it ever happens? + assert false; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + popCurrent(); // ParameterContext + popCurrent(); // ParameterListContext + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. + + IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); + ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + if (javaReturnType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaReturnType.isEnum()) { + // TODO: + } else if (javaReturnType.isArray()) { + // TODO: + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + + ITypeBinding javaElementType = javaReturnType.getElementType(); + if (javaElementType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaElementType.isClass() || javaElementType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaElementType.isEnum()) { + // TODO: + } else { + // Is this ever can be in case of array type? + assert false; + } + + int numDims = javaReturnType.getDimensions(); + for (int i = 0; i < numDims; ++i) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); + } + + popCurrent(); // ArrayTypeContext + } else { + assert false : "Need implementation of the translation"; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + // TODO: translation of type arguments. +// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); +// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { +// translateTypeArgumens(javaTypeArguments); +// } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); + // lambdaBody: singleExpression | block + // Use here + // singleExpression: + // | singleExpression typeArguments? arguments # CallExpression + // to produce object_arg.method_name() + pushCurrent(new LambdaBodyContext(stsCurrent, 0)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + + // | singleExpression Dot identifier # MemberAccessExpression + pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); + // singleExpression + // | Identifier IdentifierExpression + pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); + popSingleExpression(); // IdentifierExpressionContext + + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); + popSingleExpression(); // MemberAccessExpressionContext + + //translateTypeArguments(javaMethodInvocation.typeArguments()); + //translateArguments(javaMethodInvocation.arguments()); + stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. + + popSingleExpression(); // CallExpressionContext + popCurrent(); // LambdaBodyContext + popSingleExpression(); // LambdaExpressionContext + + ++countExprTransformed; + return false; + } + // The list of not yet translated Java Expressions: // Expression: // Annotation, //?? CaseDefaultExpression, // CreationReference, - //?? ExpressionMethodReference, // InstanceofExpression, // LambdaExpression, //? MethodReference, diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 65ca0b0af..b2bc65cb6 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -49,7 +49,7 @@ public class NodeBuilder { return stsName; } - private static TerminalNode terminalIdentifier(String identifier) { + public static TerminalNode terminalIdentifier(String identifier) { return new TerminalNodeImpl(new CommonToken(StaticTSParser.Identifier, identifier)); } @@ -72,24 +72,15 @@ public class NodeBuilder { int stsTypeNameCode = -1; PrimitiveType.Code javaTypeCode = javaPrimitive.getPrimitiveTypeCode(); - if (javaTypeCode == PrimitiveType.BOOLEAN) - stsTypeNameCode = StaticTSParser.Boolean; - else if (javaTypeCode == PrimitiveType.BYTE) - stsTypeNameCode = StaticTSParser.Byte; - else if (javaTypeCode == PrimitiveType.CHAR) - stsTypeNameCode = StaticTSParser.Char; - else if (javaTypeCode == PrimitiveType.INT) - stsTypeNameCode = StaticTSParser.Int; - else if (javaTypeCode == PrimitiveType.DOUBLE) - stsTypeNameCode = StaticTSParser.Double; - else if (javaTypeCode == PrimitiveType.FLOAT) - stsTypeNameCode = StaticTSParser.Float; - else if (javaTypeCode == PrimitiveType.LONG) - stsTypeNameCode = StaticTSParser.Long; - else if (javaTypeCode == PrimitiveType.SHORT) - stsTypeNameCode = StaticTSParser.Short; - else if (javaTypeCode == PrimitiveType.VOID) - stsTypeNameCode = StaticTSParser.Void; + if (javaTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; + else if (javaTypeCode == PrimitiveType.BYTE) stsTypeNameCode = StaticTSParser.Byte; + else if (javaTypeCode == PrimitiveType.CHAR) stsTypeNameCode = StaticTSParser.Char; + else if (javaTypeCode == PrimitiveType.INT) stsTypeNameCode = StaticTSParser.Int; + else if (javaTypeCode == PrimitiveType.DOUBLE) stsTypeNameCode = StaticTSParser.Double; + else if (javaTypeCode == PrimitiveType.FLOAT) stsTypeNameCode = StaticTSParser.Float; + else if (javaTypeCode == PrimitiveType.LONG) stsTypeNameCode = StaticTSParser.Long; + else if (javaTypeCode == PrimitiveType.SHORT) stsTypeNameCode = StaticTSParser.Short; + else if (javaTypeCode == PrimitiveType.VOID) stsTypeNameCode = StaticTSParser.Void; else assert false : "Unknown type"; @@ -103,6 +94,35 @@ public class NodeBuilder { return stsPredefinedType; } + private static int stsTypeNameCode(String javaTypeName) { + int stsTypeNameCode = -1; + + if (PrimitiveType.BOOLEAN.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Boolean; + else if (PrimitiveType.BYTE.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Byte; + else if (PrimitiveType.CHAR.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Char; + else if (PrimitiveType.INT.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Int; + else if (PrimitiveType.DOUBLE.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Double; + else if (PrimitiveType.FLOAT.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Float; + else if (PrimitiveType.LONG.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Long; + else if (PrimitiveType.SHORT.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Short; + else if (PrimitiveType.VOID.toString().equals(javaTypeName)) stsTypeNameCode = StaticTSParser.Void; + else + assert false : "Unknown type"; + + return stsTypeNameCode; + } + + public static PredefinedTypeContext predefinedType(ITypeBinding javaTypeBinding) { + assert javaTypeBinding.isPrimitive() : "Not a primitive Java type"; + + String javaTypeName = javaTypeBinding.getName(); + + // predefinedType -> TerminalNode + PredefinedTypeContext stsPredefinedType = new PredefinedTypeContext(null, 0); + stsPredefinedType.addChild(terminalNode(stsTypeNameCode(javaTypeName))); + return stsPredefinedType; + } + public static AccessibilityModifierContext accessibilityModifier(int javaModifiers) { int stsModifierCode = -1; if ((javaModifiers & Modifier.PRIVATE) != 0) diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 13b5c09ff..8c4b5fd4c 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -118,7 +118,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeParameterList(stsTypeParameterList); } + if (sb.charAt(sb.length()-1) == '>') { + sb.append(" >"); + } + else { sb.append('>'); + } return null; } @@ -179,7 +184,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeArgumentList(stsTypeArgumentList); } + if (sb.charAt(sb.length()-1) == '>') { + sb.append(" >"); + } + else { sb.append('>'); + } return null; } diff --git a/migrator/test/java/generic_class_1.java b/migrator/test/java/generic_class_1.java new file mode 100644 index 000000000..838e687d1 --- /dev/null +++ b/migrator/test/java/generic_class_1.java @@ -0,0 +1,28 @@ +/* + * 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; + +// Java specification Example 8.1.2-1. Mutually Recursive Type Variable Bounds: + +interface ConvertibleTo { + T convert(); +} + +class ReprChange, S extends ConvertibleTo> { + T t; + void set(S s) { t = s.convert(); } + S get() { return t.convert(); } +} \ No newline at end of file diff --git a/migrator/test/java/generic_class_1.java.sts b/migrator/test/java/generic_class_1.java.sts new file mode 100644 index 000000000..a49c7758f --- /dev/null +++ b/migrator/test/java/generic_class_1.java.sts @@ -0,0 +1,31 @@ +/* + * 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; + +interface ConvertibleTo { + convert(): T ; +} + +open class ReprChange, S extends ConvertibleTo > { + t : T ; + open set(s : S): void { + t = s.convert(); + } + open get(): S { + return t.convert(); + } +} + diff --git a/migrator/test/java/generic_class_2.java b/migrator/test/java/generic_class_2.java new file mode 100644 index 000000000..6959f15b3 --- /dev/null +++ b/migrator/test/java/generic_class_2.java @@ -0,0 +1,57 @@ +/* + * 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; + +// Java specification Example 8.1.2-2. Nested Generic Classes + +class Seq { + T head; + Seq tail; + Seq() { this(null, null); } + Seq(T head, Seq tail) { + this.head = head; + this.tail = tail; + } + + boolean isEmpty() { return tail == null; } + + class Zipper { + Seq> zip(Seq that) { + if (isEmpty() || that.isEmpty()) { + return new Seq>(); + } else { + Seq.Zipper tailZipper = tail.new Zipper(); + + return new Seq>(new Pair(head, that.head), tailZipper.zip(that.tail)); + } + } + } +} + +class Pair { + T fst; + S snd; + Pair(T f, S s) { fst = f; snd = s; } +} + +class Test { + public static void main(String[] args) { + Seq strs = new Seq("a", new Seq("b", new Seq())); + Seq nums = new Seq(new Integer(1), new Seq(new Double(1.5), new Seq())); + Seq.Zipper zipper = strs.new Zipper(); + Seq> combined = zipper.zip(nums); + } +} \ No newline at end of file diff --git a/migrator/test/java/generic_class_2.java.sts b/migrator/test/java/generic_class_2.java.sts new file mode 100644 index 000000000..6331c3e71 --- /dev/null +++ b/migrator/test/java/generic_class_2.java.sts @@ -0,0 +1,65 @@ +/* + * 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 Seq { + head : T ; + tail : Seq ; + constructor() { + this(null, null); + } + + constructor(head : T, tail : Seq) { + this.head = head; + this.tail = tail; + } + + open isEmpty(): boolean { + return tail == null; + } + open class Zipper { + open zip(that : Seq): Seq > { + if (isEmpty() || that.isEmpty()) { + return new Seq >(); + } + else { + let tailZipper : Seq.Zipper = new Zipper(); + return new Seq >(new Pair(head, that.head), tailZipper.zip(that.tail)); + } + } + } + +} + +open class Pair { + fst : T ; + snd : S ; + constructor(f : T, s : S) { + fst = f; + snd = s; + } + +} + +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 combined : Seq > = zipper.zip(nums); + } +} + diff --git a/migrator/test/java/generic_class_3.java b/migrator/test/java/generic_class_3.java new file mode 100644 index 000000000..0ceb85c28 --- /dev/null +++ b/migrator/test/java/generic_class_3.java @@ -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; + +interface Fun { R apply(T arg); } + +class C { + int size() { return 0; } + + int size(Object arg) { return 1; } + + int size(C arg) { return 2; } + + static class H { + int size() {return 3;} + } + + H h = new H(); + + void test1() { + Fun f1 = C::size; // f1 = (C c) :Integer { return c.size(); } + System.out.print(f1.apply(this)); + } + + void test2() { + Fun f1 = H::size; // f1 = (H h) :Integer { return h.size(); } + System.out.print(f1.apply(this.h)); + } +} + +class Main { + public static void main(String args[]) { + C c = new C(); + c.test1(); + c.test2(); + } +} \ No newline at end of file diff --git a/migrator/test/java/generic_class_3.java.sts b/migrator/test/java/generic_class_3.java.sts new file mode 100644 index 000000000..0f3b3f74c --- /dev/null +++ b/migrator/test/java/generic_class_3.java.sts @@ -0,0 +1,56 @@ +/* + * 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; + +interface Fun { + apply(arg : T): R ; +} + +open class C { + open size(): int { + return 0; + } + open size(arg : Object): int { + return 1; + } + open size(arg : C): int { + return 2; + } + static open class H { + open size(): int { + return 3; + } + } + + h : H = new H(); + open test1(): void { + let f1 : Fun = (object_arg : C): int =>object_arg.size(); + System.out.print(f1.apply(this)); + } + open test2(): void { + let f1 : Fun = (object_arg : H): int =>object_arg.size(); + System.out.print(f1.apply(this.h)); + } +} + +open class Main { + public static main(args : String): void { + let c : C = new C(); + c.test1(); + c.test2(); + } +} + diff --git a/migrator/test/java/generic_class_4.java b/migrator/test/java/generic_class_4.java new file mode 100644 index 000000000..6b48d1b69 --- /dev/null +++ b/migrator/test/java/generic_class_4.java @@ -0,0 +1,22 @@ +/* + * 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 test_generic { + Class choose(boolean b, Class c1, Class c2) { + return b ? c1 : c2; + } +} \ No newline at end of file diff --git a/migrator/test/java/generic_class_4.java.sts b/migrator/test/java/generic_class_4.java.sts new file mode 100644 index 000000000..ebec1d974 --- /dev/null +++ b/migrator/test/java/generic_class_4.java.sts @@ -0,0 +1,23 @@ +/* + * 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 test_generic { + open choose(b : boolean, c1 : Class, c2 : Class): Class { + return b ? c1 : c2; + } +} + diff --git a/migrator/test/java/generic_interface_1.java b/migrator/test/java/generic_interface_1.java new file mode 100644 index 000000000..3f8d042da --- /dev/null +++ b/migrator/test/java/generic_interface_1.java @@ -0,0 +1,26 @@ +/* + * 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; + +// Java specification Example 9.8-3. Generic Functional Interfaces + +//interface I { Object m(Class c); } + +interface J { S m(Class c); } + +interface K { T m(Class c); } + +//interface Functional extends I, J, K {} \ No newline at end of file diff --git a/migrator/test/java/generic_interface_1.java.sts b/migrator/test/java/generic_interface_1.java.sts new file mode 100644 index 000000000..867ca6aa4 --- /dev/null +++ b/migrator/test/java/generic_interface_1.java.sts @@ -0,0 +1,25 @@ +/* + * 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; + +interface J { + m(c : Class): S ; +} + +interface K { + m(c : Class): T ; +} + diff --git a/migrator/test/java/generic_interface_2.java b/migrator/test/java/generic_interface_2.java new file mode 100644 index 000000000..9c82acd99 --- /dev/null +++ b/migrator/test/java/generic_interface_2.java @@ -0,0 +1,28 @@ +/* + * 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; + +// Java specification Example 9.9-2. Generic Function Types + +interface G1 { + Object m() throws E; +} + +interface G2 { + String m() throws Exception; +} + +interface G extends G1, G2 {} \ No newline at end of file diff --git a/migrator/test/java/generic_interface_2.java.sts b/migrator/test/java/generic_interface_2.java.sts new file mode 100644 index 000000000..a26be0363 --- /dev/null +++ b/migrator/test/java/generic_interface_2.java.sts @@ -0,0 +1,28 @@ +/* + * 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; + +interface G1 { + m(): Object ; +} + +interface G2 { + m(): String ; +} + +interface G { +} + diff --git a/migrator/test/java/generic_interface_3.java b/migrator/test/java/generic_interface_3.java new file mode 100644 index 000000000..b1ccedea7 --- /dev/null +++ b/migrator/test/java/generic_interface_3.java @@ -0,0 +1,26 @@ +/* + * 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; + +import java.util.List; + +interface ListFactory { + List make(); +} + +ListFactory lf = ArrayList::new; +List ls = lf.make(); +List ln = lf.make(); \ No newline at end of file diff --git a/migrator/test/java/generic_interface_3.java.skip b/migrator/test/java/generic_interface_3.java.skip new file mode 100644 index 000000000..e69de29bb -- Gitee From 2134637904ea33e28f74730326e732727b1ded1e Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 25 Jul 2022 19:44:01 +0300 Subject: [PATCH 02/60] Switch statement + local type declaration. Change-Id: I341d05705db6c87ef7c0ac4c732e43e9382dabe2 Signed-off-by: Evgeniy Okolnov --- .../ohos/migrator/java/JavaTransformer.java | 293 +++++++++++++++++- .../staticTS/parser/StaticTSParser.g4 | 6 +- .../staticTS/writer/StaticTSWriter.java | 45 +-- .../test/java/conditional_expression.java | 2 +- migrator/test/java/for_statement.java.sts | 13 +- migrator/test/java/method_invocation.java | 2 +- migrator/test/java/switch_statement.java | 226 ++++++++++++++ migrator/test/java/switch_statement.java.sts | 236 ++++++++++++++ 8 files changed, 766 insertions(+), 57 deletions(-) create mode 100644 migrator/test/java/switch_statement.java create mode 100644 migrator/test/java/switch_statement.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 853907a48..3d2b66176 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -42,6 +42,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private static int countStmtTotal = 0; private static int countExprTotal = 0; @@ -477,6 +478,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsMemberContext = new ClassMemberContext(stsCurrent, 0); else if (isInInterfaceContext) stsMemberContext = new InterfaceMemberContext(stsCurrent, 0); + else if (stsCurrent instanceof BlockContext || stsCurrent instanceof ConstructorBodyContext) + stsMemberContext = new StatementOrLocalDeclarationContext(stsCurrent, 0); else stsMemberContext = new TopDeclarationContext(stsCurrent, 0); @@ -1541,6 +1544,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } private void createAndFillVarOrConstDeclarationList(int javaModifiers, List javaVarDeclFragments, Type javaType) { + createAndFillVarOrConstDeclarationList(javaModifiers, javaVarDeclFragments, javaType, true); + } + + private void createAndFillVarOrConstDeclarationList(int javaModifiers, List javaVarDeclFragments, Type javaType, boolean translateVarInitializers) { pushCurrent(createVarOrConstDeclarationList(javaModifiers)); for (VariableDeclarationFragment javaVarDeclFragment : javaVarDeclFragments) { @@ -1553,13 +1560,15 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaType.accept(this); popCurrent(); // TypeAnnotationContext - Expression javaInitializer = javaVarDeclFragment.getInitializer(); + if (translateVarInitializers) { + Expression javaInitializer = javaVarDeclFragment.getInitializer(); - if (javaInitializer != null) { - pushCurrent(new InitializerContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitializer.accept(this); - popCurrent(); // InitializerContext + if (javaInitializer != null) { + pushCurrent(new InitializerContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitializer.accept(this); + popCurrent(); // InitializerContext + } } popCurrent(); // VarOrConstDeclaration @@ -2595,6 +2604,276 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // TypeDeclarationStatement: + // TypeDeclaration + // EnumDeclaration + // STS tree: + // statementOrLocalDeclaration: + // | classDeclaration + // | enumDeclaration + @Override + public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { + javaTypeDeclarationStmt.getDeclaration().accept(this); + + ++countStmtTransformed; + return false; + } + + // Java tree: + // switch ( Expression ) + // { { SwitchCase | Statement } } + // SwitchCase: + // case Expression : + // default : + // STS tree: + // switchStatement: + // switch OpenParen singleExpression CloseParen caseBlock + // caseBlock: + // OpenBrace caseClause* defaultClause? caseClause* CloseBrace + // caseClause: + // case singleExpression ':' statement* + // defaultClause: + // default ':' statement* + @Override + public boolean visit(SwitchStatement javaSwitchStmt) { + SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); + pushStatement(stsSwitch); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); + + javaSwitchStmt.getExpression().accept(this); + + CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); + pushCurrent(stsCaseBlock); + + List javaVariablesToMove = new ArrayList<>(); + SwitchCase javaCurrentSwitchCase = null; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { + javaCurrentSwitchCase = (SwitchCase) javaStmt; + } + else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { + wrapCaseClauseStatementsWithBlock(); + } + else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { + processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, + javaSwitchStmt, javaVariablesToMove); + + // We've already processed variable declaration, proceed to the next statement. + continue; + } + + javaStmt.accept(this); + } + + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + popCurrent(); // CaseBlockContext + popStatement(); // SwitchStatementContext + + // Move variable declarations in front of switch statement, and enclose both + // declarations and switch with additional block. + if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { + // Remove switch statement from current STS node. + stsCurrent.removeLastChild(); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + + for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { + VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); + + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); + popStatement(); // VariableOrConstantDeclarationContext + } + + pushStatement(stsSwitch); + popStatement(); // SwitchContext + + popStatement(); // BlockContext + } + + ++countStmtTransformed; + return false; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + if (javaSwitchCase.isDefault()) { + pushCurrent(new DefaultClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); + } else { + pushCurrent(new CaseClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); + javaSwitchCase.getExpression().accept(this); + } + + // SwitchCase is treated as Statement node, thus increment the count. + ++countStmtTransformed; + return false; + } + + private void popCaseClauseIfNeeded() { + // Check if we need to pop additional block added as work around to add + // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() + // method for details). + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) { + popStatement(); // BlockContext + } + + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause + || stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause) { + popCurrent(); // CaseClauseContext | DefaultClauseContext + } + } + + private void wrapCaseClauseStatementsWithBlock() { + // In StaticTS, CaseClause may contain only statements, and is not allowed to + // have local declarations. In contrast, Java permits to have local declarations + // in case clause scope, so when encounter one, wrap up all statements in case clause + // with additional block as a workaround, (since block can have local declarations). + + // Check if already inserted additional block. + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) + return; + + assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || + stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; + + List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); + stsCurrent.children.removeAll(stsCaseStmts); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + for (StatementContext stsStmt : stsCaseStmts) { + StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); + stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); + stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); + } + } + + + private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, + SwitchStatement javaSwitchStmt, List javaVariablesToMove) { + // Java permits to declare local variables in switch scope. Such variables exist + // in all following case clauses. In StaticTS, case clauses don't have a common + // scope, and allow only statements, not declarations. To work around this, we + // have to track whether a particular local variable has been referenced in another + // case clause and, in such case, move declaration of that variable in front of + // switch statement, additionally enclosing both variable declaration and switch + // statement, so that variables are only visible in context of switch statement. + + List javaVarFragments = javaVarDeclStmt.fragments(); + for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { + if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { + javaVariablesToMove.add(javaVarFragment); + + // Since evaluation of initializer expression can cause side effects, + // in order to preserve the behaviour and result of program, all + // expressions must evaluate in the same order as before. For that + // purpose, we move the variable declaration without initializer part + // and replace initialization with simple assignment. + Expression javaInitExpr = javaVarFragment.getInitializer(); + if (javaInitExpr != null) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); + + javaVarFragment.getName().accept(this); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitExpr.accept(this); + + popSingleExpression(); // AssignmentExpressionContext; + popStatement(); // ExpressionStatementContext + } + } else { + wrapCaseClauseStatementsWithBlock(); + + // For variables, that don't need to be moved, emit single variable + // declaration here to preserve the correct order of evaluation of + // initializer expressions (including assignments emitted for variables + // that are moved). + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); + popStatement(); // VariableOrConstantDeclarationContext + } + } + + ++countStmtTransformed; + } + + private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, + SwitchStatement javaSwitchStmt) { + IVariableBinding javaVarBinding = javaVarDecl.resolveBinding(); + + ASTVisitor localVarUsageLookupVisitor = new ASTVisitor() { + boolean done = false; + int nestedSwitchCount = 0; + SwitchCase currentSwitchCase = null; + + @Override + public boolean preVisit2(ASTNode javaNode) { + // This line will prevent from visiting further AST nodes, + // once we are done with the work. + return !done; + } + + @Override + public boolean visit(SimpleName javaName) { + IBinding binding = javaName.resolveBinding(); + + if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { + javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); + done = true; + } + + return false; + } + + @Override + public boolean visit(VariableDeclarationFragment javaVarDeclFragment) { + // Do NOT visit declaration of the variable that we are looking up. + return javaVarDeclFragment != javaVarDecl; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Do not change currentSwitchCase when visiting nested switch statements. + if (nestedSwitchCount == 0) { + currentSwitchCase = javaSwitchCase; + } + + return false; + } + + @Override + public boolean visit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount++; + return true; + } + + @Override + public void endVisit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount--; + } + }; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + javaStmt.accept(localVarUsageLookupVisitor); + + if (javaVarDecl.getProperty(USED_IN_ANOTHER_CASE_CLAUSE) != null) + return true; + } + + return false; + } + // The list of not yet translated Java Expressions: // Expression: // Annotation, @@ -2608,4 +2887,4 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // SwitchExpression, // TypeLiteral, // TypeMethodReference -} \ No newline at end of file +} diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 30cfd3fdc..75c6218a7 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -373,11 +373,7 @@ switchStatement ; caseBlock - : OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace - ; - -caseClauses - : caseClause+ + : OpenBrace caseClause* defaultClause? caseClause* CloseBrace ; caseClause diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 8c4b5fd4c..6037ef39a 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1010,9 +1010,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // continueStatement: Continue Identifier? SemiColon @Override public Void visitContinueStatement(ContinueStatementContext stsContinueStatement) { - if (!doNeededIndent()) { - sb.append(' '); - } + doNeededIndent(); sb.append(stsContinueStatement.Continue().getText()); TerminalNode termIdentifier = stsContinueStatement.Identifier(); @@ -1028,10 +1026,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // breakStatement: Break Identifier? SemiColon @Override public Void visitBreakStatement(BreakStatementContext stsBreakStatement) { - if (!doNeededIndent()) { - sb.append(' '); - } - + doNeededIndent(); sb.append(stsBreakStatement.Break().getText()); TerminalNode termIdentifier = stsBreakStatement.Identifier(); @@ -1099,16 +1094,17 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { public Void visitSwitchStatement(SwitchStatementContext stsSwitchStatement) { doNeededIndent(); - sb.append(stsSwitchStatement.Switch().getText()).append('('); + sb.append(stsSwitchStatement.Switch().getText()).append(" ("); stsSwitchStatement.singleExpression().accept(this); - sb.append(")\n"); + sb.append(')'); visitCaseBlock(stsSwitchStatement.caseBlock()); + sb.append('\n'); return null; } - // caseBlock: '{' leftCases=caseClauses? defaultClause? rightCases=caseClauses? '}' + // caseBlock: '{' caseClause* defaultClause? caseClause* '}' @Override public Void visitCaseBlock(CaseBlockContext stsCaseBlock) { if (!doNeededIndent()) { @@ -1118,33 +1114,10 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append("{\n"); indentIncrement(); - if (stsCaseBlock.leftCases != null) { - visitCaseClauses(stsCaseBlock.leftCases); - } - - DefaultClauseContext stsDefaultClause = stsCaseBlock.defaultClause(); - if (stsDefaultClause != null) { - visitDefaultClause(stsDefaultClause); - } - - if (stsCaseBlock.rightCases != null) { - visitCaseClauses(stsCaseBlock.rightCases); - } + visitChildren(stsCaseBlock); indentDecrement(); - sb.append(indentCurrent).append("}\n\n"); - - return null; - } - - // caseClauses: caseClause+ - @Override - public Void visitCaseClauses(CaseClausesContext stsCaseClauses) { - List stsCaseClauseList = stsCaseClauses.caseClause(); - - for (CaseClauseContext stsCaseClause : stsCaseClauseList) { - visitCaseClause(stsCaseClause); - } + sb.append(indentCurrent).append("}\n"); return null; } @@ -1164,7 +1137,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitStatement(stsStatement); indentDecrement(); - sb.append('\n'); return null; } @@ -1181,7 +1153,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitStatement(stsStatement); indentDecrement(); - sb.append('\n'); return null; } diff --git a/migrator/test/java/conditional_expression.java b/migrator/test/java/conditional_expression.java index 40b5fb2dc..2032053fc 100644 --- a/migrator/test/java/conditional_expression.java +++ b/migrator/test/java/conditional_expression.java @@ -23,4 +23,4 @@ class ConditionalExpression { boolean someCondition = true; result = someCondition ? value1 : value2; } -} \ No newline at end of file +} diff --git a/migrator/test/java/for_statement.java.sts b/migrator/test/java/for_statement.java.sts index cbdfd1b45..c1c6e6c92 100644 --- a/migrator/test/java/for_statement.java.sts +++ b/migrator/test/java/for_statement.java.sts @@ -17,19 +17,19 @@ package com.ohos.migrator.test.java; open class ForStatements { public static Test(): void { - for (; ; ) break; + for (; ; ) break; for (; ; ) { break; } for (let i : int = 0; ; ) { i++; - if (i == 2) continue; - if (i == 5) break; + if (i == 2) continue; + if (i == 5) break; } let a : int = 0; for (; a < 5; ) a++; for (; ; a--) { - if (a == 0) break; + if (a == 0) break; } for (let i : int = 0, j : int = 0; i < 5; i++, j++) { let k : int = i * j; @@ -40,9 +40,10 @@ open class ForStatements { } outerLoop: for (let i : int = 0; i < 5; i++) { innerLoop: for (let j : int = 0; j < 5; j++) { - if (j == 2) continue innerLoop; - if (i * j == 20) break outerLoop; + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; } } } } + diff --git a/migrator/test/java/method_invocation.java b/migrator/test/java/method_invocation.java index 55d81d8f8..1c8887cb5 100644 --- a/migrator/test/java/method_invocation.java +++ b/migrator/test/java/method_invocation.java @@ -93,4 +93,4 @@ class Test3 { ColoredPoint2 cp = new ColoredPoint2(); //test(cp, cp); // Compile-time error } -} \ No newline at end of file +} diff --git a/migrator/test/java/switch_statement.java b/migrator/test/java/switch_statement.java new file mode 100644 index 000000000..31e61720d --- /dev/null +++ b/migrator/test/java/switch_statement.java @@ -0,0 +1,226 @@ +/* + * 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; + +public class switch_statement { + + public static String ReturnFromSwitch(int id) { + switch (id) { + case 1: + return "First"; + case 2: + return "Second"; + default: + return "Unknown"; + } + } + + public static void CaseClausesVariations() { + int a = 0; + + // empty switch + switch (1) { + } + + // no default clause + switch (2) { + case 1: + a = 21; + break; + case 2: + a = 22; + break; + } + + // only default case + switch (3) { + default: + a = 31; + break; + } + + // case clause followed by default + switch (4) { + case 1: + a = 41; + break; + case 2: + break; + default: + a = 43; + break; + } + + // case clause following default clause + switch (5) { + default: + a = 51; + break; + case 1: + a = 52; + break; + case 2: + a = 53; + break; + } + + // case clauses before and after default clause + switch (6) { + case 1: + a = 61; + break; + default: + a = 62; + break; + case 2: + a = 63; + break; + } + + // Fall-through + switch (7) { + case 1: + case 2: + System.out.println("Falling through case 1 and case 2"); + break; + default: + System.out.println("Default case"); + break; + } + + // Fall-through + switch (8) { + case 1: + default: + System.out.println("Falling through both case and default clauses"); + break; + } + } + + public static void SwitchWithLocalDeclarations() { + int i = 10; + + // Local variable is referenced across several case clauses. + switch (i) { + case 0: + int q = 5; + int w = q; // This declaration is moved in front of switch. Initialization is turned into assignment. + int e; // This declaration is moved in front of switch. No initialization. + break; + default: + w = 10; + e = 20; + System.out.println(w + e); + break; + } + + // Multiple variables in single variable declaration list. + switch (i) { + case 0: + int q = 5, w, e = 10, r; // 'q' and 'r' are moved in front of switch. + int z = 20, x; // Both 'z' and 'x' declarations are left in this block. + System.out.println(q + e + z); + break; + default: + q = 2; + r = 4; + System.out.println(q + r); + break; + } + + // Block variable and hiding. + switch (i) { + case 1: + { + String localVar = "some value"; // 'String localVar' will hide the 'int localVar' in current block scope. + } + break; + case 2: + int localVar = 5; + break; + default: + localVar = 6; + break; + } + + // Local variable is initialized with expression that can cause side-effects. + // The order of evaluation of variable initializers must be preserved. + switch (i) { + case 0: + int q = i++, w = i++, e = i++; + break; + default: + q = 1; + e = 2; + break; + } + + // Variable 'k' is referenced from nested switch, though, it's still being used + // only within the case clause it was declared in. + switch (i) { + case 1: + int k = 10; + + switch (i) { + case 3: + k = 20; + break; + default: + break; + } + + break; + default: + break; + } + + // Switch with local class declaration + switch (i) { + case 1: + class LocalClass { + void M() { + System.out.println("LocalClass.M()"); + } + } + new LocalClass().M(); + break; + default: + break; + } + } + + enum Color { + Red, + Green, + Blue + } + + private static void SwitchWithEnumValues() { + Color color = Color.Green; + + switch (color) { + case Red: + System.out.println("Color is red"); + break; + case Blue: + System.out.println("Color is blue"); + break; + default: + System.out.println("Color is default"); + break; + } + } +} diff --git a/migrator/test/java/switch_statement.java.sts b/migrator/test/java/switch_statement.java.sts new file mode 100644 index 000000000..9c40fe12f --- /dev/null +++ b/migrator/test/java/switch_statement.java.sts @@ -0,0 +1,236 @@ +/* + * 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; + +export open class switch_statement { + public static ReturnFromSwitch(id : int): String { + switch (id) { + case 1: + return "First"; + case 2: + return "Second"; + default: + return "Unknown"; + } + + } + public static CaseClausesVariations(): void { + let a : int = 0; + switch (1) { + } + + switch (2) { + case 1: + a = 21; + break; + case 2: + a = 22; + break; + } + + switch (3) { + default: + a = 31; + break; + } + + switch (4) { + case 1: + a = 41; + break; + case 2: + break; + default: + a = 43; + break; + } + + switch (5) { + default: + a = 51; + break; + case 1: + a = 52; + break; + case 2: + a = 53; + break; + } + + switch (6) { + case 1: + a = 61; + break; + default: + a = 62; + break; + case 2: + a = 63; + break; + } + + switch (7) { + case 1: + case 2: + System.out.println("Falling through case 1 and case 2"); + break; + default: + System.out.println("Default case"); + break; + } + + switch (8) { + case 1: + default: + System.out.println("Falling through both case and default clauses"); + break; + } + + } + public static SwitchWithLocalDeclarations(): void { + let i : int = 10; + { + let w : int ; + let e : int ; + switch (i) { + case 0: + { + let q : int = 5; + w = q; + break; + } + default: + w = 10; + e = 20; + System.out.println(w + e); + break; + } + + } + { + let q : int ; + let r : int ; + switch (i) { + case 0: + { + q = 5; + let w : int ; + let e : int = 10; + let z : int = 20; + let x : int ; + System.out.println(q + e + z); + break; + } + default: + q = 2; + r = 4; + System.out.println(q + r); + break; + } + + } + { + let localVar : int ; + switch (i) { + case 1: + { + let localVar : String = "some value"; + } + break; + case 2: + localVar = 5; + break; + default: + localVar = 6; + break; + } + + } + { + let q : int ; + let e : int ; + switch (i) { + case 0: + { + q = i++; + let w : int = i++; + e = i++; + break; + } + default: + q = 1; + e = 2; + break; + } + + } + switch (i) { + case 1: + { + let k : int = 10; + switch (i) { + case 3: + k = 20; + break; + default: + break; + } + + break; + } + default: + break; + } + + switch (i) { + case 1: + { + open class LocalClass { + open M(): void { + System.out.println("LocalClass.M()"); + } + } + + new LocalClass().M(); + break; + } + default: + break; + } + + } + enum Color { + Red, + Green, + Blue + } + private static SwitchWithEnumValues(): void { + let color : Color = Color.Green; + switch (color) { + case Red: + System.out.println("Color is red"); + break; + case Blue: + System.out.println("Color is blue"); + break; + default: + System.out.println("Color is default"); + break; + } + + } +} + \ No newline at end of file -- Gitee From fe414e7c4e5195513f979ab2e267a4c0ccb470c1 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Mon, 1 Aug 2022 15:18:52 +0300 Subject: [PATCH 03/60] Minor fix to switch statement translation to make sure original order of cases is preserved (important for fall-through cases). Also extended the test to cover this fix. Change-Id: I96cb3c5998ff29c39c98da26e3305a344938ee40 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 58 +++++++++++++++++-- .../staticTS/parser/StaticTSParser.g4 | 6 +- .../staticTS/writer/StaticTSWriter.java | 26 ++++++++- migrator/test/java/switch_statement.java | 12 ++++ migrator/test/java/switch_statement.java.sts | 13 ++++- 5 files changed, 107 insertions(+), 8 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 3d2b66176..293691e69 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -27,6 +27,7 @@ import org.eclipse.jdt.core.dom.*; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Stack; @@ -2629,7 +2630,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // switchStatement: // switch OpenParen singleExpression CloseParen caseBlock // caseBlock: - // OpenBrace caseClause* defaultClause? caseClause* CloseBrace + // OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace + // caseClauses: + // caseClause+ // caseClause: // case singleExpression ':' statement* // defaultClause: @@ -2643,6 +2646,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaSwitchStmt.getExpression().accept(this); CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); + stsCaseBlock.leftCases = null; + stsCaseBlock.rightCases = null; pushCurrent(stsCaseBlock); List javaVariablesToMove = new ArrayList<>(); @@ -2670,6 +2675,17 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Close the last case clause. popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + // Create CaseClausesContext node and transfer all cases translated thus far to it. + // If we've seen default node, initialize rightCases field of CaseBlockContext node; + // otherwise, initialize leftCases field of CaseBlockContext node. + CaseClausesContext stsCaseClauses = createAndFillCaseClausesContext(stsCaseBlock); + if (stsCaseBlock.defaultClause() != null) { + stsCaseBlock.rightCases = stsCaseClauses; + } + else { + stsCaseBlock.leftCases = stsCaseClauses; + } + popCurrent(); // CaseBlockContext popStatement(); // SwitchStatementContext @@ -2686,7 +2702,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); + + ArrayList declFragmentList = new ArrayList<>(); + declFragmentList.add(javaVarFragment); + + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), declFragmentList, javaVarDeclStmt.getType(), false); popStatement(); // VariableOrConstantDeclarationContext } @@ -2705,10 +2725,19 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Close the last case clause. popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + assert(stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseBlock); + CaseBlockContext stsCaseBlock = (CaseBlockContext)stsCurrent; + if (javaSwitchCase.isDefault()) { + // If any cases have been translated thus far, create CaseClauseContext node, + // transfer those cases to it, and initialize leftCases field of CaseBlockContext node. + stsCaseBlock.leftCases = createAndFillCaseClausesContext(stsCaseBlock); + + // Translate default clause pushCurrent(new DefaultClauseContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); - } else { + } + else { pushCurrent(new CaseClauseContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); javaSwitchCase.getExpression().accept(this); @@ -2719,6 +2748,23 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + private CaseClausesContext createAndFillCaseClausesContext(CaseBlockContext stsCaseBlock) { + List stsCaseList = stsCaseBlock.getRuleContexts(CaseClauseContext.class); + CaseClausesContext stsCaseClauses = null; + + if (!stsCaseList.isEmpty()) { + stsCaseClauses = new CaseClausesContext(stsCurrent, 0); + for (CaseClauseContext stsCase : stsCaseList) { + stsCaseClauses.addChild(stsCase).setParent(stsCaseClauses); + } + stsCaseBlock.children.removeAll(stsCaseList); + + // Add CaseClauseContext node to CaseBlockContext + stsCaseBlock.addChild(stsCaseClauses).setParent(stsCaseBlock); + } + + return stsCaseClauses; + } private void popCaseClauseIfNeeded() { // Check if we need to pop additional block added as work around to add // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() @@ -2799,7 +2845,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // initializer expressions (including assignments emitted for variables // that are moved). pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); + + ArrayList declFragmentList = new ArrayList<>(); + declFragmentList.add(javaVarFragment); + + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), declFragmentList, javaVarDeclStmt.getType()); popStatement(); // VariableOrConstantDeclarationContext } } diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 75c6218a7..30cfd3fdc 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -373,7 +373,11 @@ switchStatement ; caseBlock - : OpenBrace caseClause* defaultClause? caseClause* CloseBrace + : OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace + ; + +caseClauses + : caseClause+ ; caseClause diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 6037ef39a..22fe22fe8 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1104,7 +1104,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // caseBlock: '{' caseClause* defaultClause? caseClause* '}' + // caseBlock: '{' leftCases=caseClauses? defaultClause? rightCases=caseClauses? '}' @Override public Void visitCaseBlock(CaseBlockContext stsCaseBlock) { if (!doNeededIndent()) { @@ -1114,7 +1114,18 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append("{\n"); indentIncrement(); - visitChildren(stsCaseBlock); + if (stsCaseBlock.leftCases != null) { + visitCaseClauses(stsCaseBlock.leftCases); + } + + DefaultClauseContext stsDefaultClause = stsCaseBlock.defaultClause(); + if (stsDefaultClause != null) { + visitDefaultClause(stsDefaultClause); + } + + if (stsCaseBlock.rightCases != null) { + visitCaseClauses(stsCaseBlock.rightCases); + } indentDecrement(); sb.append(indentCurrent).append("}\n"); @@ -1122,6 +1133,17 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } + // caseClauses: caseClause+ + @Override + public Void visitCaseClauses(CaseClausesContext stsCaseClauses) { + List stsCaseClauseList = stsCaseClauses.caseClause(); + for (CaseClauseContext stsCaseClause : stsCaseClauseList) { + visitCaseClause(stsCaseClause); + } + + return null; + } + // caseClause: Case singleExpression ':' statement* @Override public Void visitCaseClause(CaseClauseContext stsCaseClause) { diff --git a/migrator/test/java/switch_statement.java b/migrator/test/java/switch_statement.java index 31e61720d..650307f9e 100644 --- a/migrator/test/java/switch_statement.java +++ b/migrator/test/java/switch_statement.java @@ -108,6 +108,18 @@ public class switch_statement { System.out.println("Falling through both case and default clauses"); break; } + + // Fall-through + switch (9) { + case 1: + System.out.println("In case 1: Falling through to default case"); + default: + System.out.println("In default case"); + break; + case 2: + System.out.println("In case 2"); + break; + } } public static void SwitchWithLocalDeclarations() { diff --git a/migrator/test/java/switch_statement.java.sts b/migrator/test/java/switch_statement.java.sts index 9c40fe12f..0e10a1c58 100644 --- a/migrator/test/java/switch_statement.java.sts +++ b/migrator/test/java/switch_statement.java.sts @@ -99,6 +99,17 @@ export open class switch_statement { break; } + switch (9) { + case 1: + System.out.println("In case 1: Falling through to default case"); + default: + System.out.println("In default case"); + break; + case 2: + System.out.println("In case 2"); + break; + } + } public static SwitchWithLocalDeclarations(): void { let i : int = 10; @@ -233,4 +244,4 @@ export open class switch_statement { } } - \ No newline at end of file + -- Gitee From dac70fefecb6d507811d314698207fa49b72c123 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Tue, 9 Aug 2022 14:41:55 +0300 Subject: [PATCH 04/60] Implemented translation of class literals. Also changes to STS grammar to allow underscores in numeric literals, and a number of fixes to translation of those literals. Added a test to cover all of the changes above. Change-Id: Ica33d0999a2f2212bc6e9c7109e94e93eb6dcdc9 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 34 ++++++++++- .../ohos/migrator/staticTS/NodeBuilder.java | 24 ++++++-- .../migrator/staticTS/parser/StaticTSLexer.g4 | 30 +++++++--- migrator/test/java/literals.java | 58 +++++++++++++++++++ migrator/test/java/literals.java.sts | 50 ++++++++++++++++ 5 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 migrator/test/java/literals.java create mode 100755 migrator/test/java/literals.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 293691e69..71c072839 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -826,9 +826,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(); @@ -838,8 +839,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // ArrayTypeContext - popCurrent(); // PrimaryTypeContext + if (needPrimaryType) popCurrent(); // PrimaryTypeContext return false; } @@ -1733,12 +1734,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 b2bc65cb6..e2b3f8c7c 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -200,16 +200,28 @@ public class NodeBuilder { LiteralContext stsLiteral = new LiteralContext(null, 0); CommonToken token; + // parse string representation to create appropriate token - if (value.startsWith("0b")) { + // Ignore suffices (d, f, l) that Java allows for numeric literals + if (value.endsWith("f") || value.endsWith("F") || + 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 { 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 705a2583c..b0ba23ccc 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 000000000..a49ec627e --- /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_A; + 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 000000000..34c2abd0d --- /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_A; + 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; + } +} + -- Gitee From 32a0543e7bf4368d5c02acf9c5e48e6f0c889574 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Tue, 9 Aug 2022 17:40:18 +0300 Subject: [PATCH 05/60] Minor fix to translation of numeric literals: Don't chop off terminating F in hexadecimal literals (was being taken for the f suffix earlier). Change-Id: I712151db5b5d88d9c6b9fe0e339886e2778b6eec Signed-off-by: Mikhail Velikanov --- .../src/com/ohos/migrator/staticTS/NodeBuilder.java | 10 +++++++--- migrator/test/java/literals.java | 2 +- migrator/test/java/literals.java.sts | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index e2b3f8c7c..5c0c2c337 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -202,9 +202,10 @@ public class NodeBuilder { CommonToken token; // parse string representation to create appropriate token - // Ignore suffices (d, f, l) that Java allows for numeric literals - if (value.endsWith("f") || value.endsWith("F") || - value.endsWith("d") || value.endsWith("D") || + // 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); } @@ -222,6 +223,9 @@ public class NodeBuilder { token = new CommonToken(StaticTSParser.OctalIntegerLiteral, value); } 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/test/java/literals.java b/migrator/test/java/literals.java index a49ec627e..5c8c11a6b 100644 --- a/migrator/test/java/literals.java +++ b/migrator/test/java/literals.java @@ -21,7 +21,7 @@ class literals { byte b = 0; byte b2 = 1_0_2; short s = 0x1; - short s2 = 0X1_A; + short s2 = 0X1_F; int i = 02; int i2 = 03_4_56; long l = 0b11L; diff --git a/migrator/test/java/literals.java.sts b/migrator/test/java/literals.java.sts index 34c2abd0d..3e3d7934d 100755 --- a/migrator/test/java/literals.java.sts +++ b/migrator/test/java/literals.java.sts @@ -20,7 +20,7 @@ open class literals { let b : byte = 0; let b2 : byte = 1_0_2; let s : short = 0x1; - let s2 : short = 0X1_A; + let s2 : short = 0X1_F; let i : int = 0o2; let i2 : int = 0o3_4_56; let l : long = 0b11; -- Gitee From 63a665e2d73e84c0e1eaba68148c270e999b07db Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 10 Aug 2022 14:28:27 +0300 Subject: [PATCH 06/60] Implemented translation of intersection types. Added a test to cover the changes above. Change-Id: Idfb2061e77bce95f36f8a676c54f385712a8d538 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 13 ++++++- migrator/test/java/intersection-type.java | 35 ++++++++++++++++++ migrator/test/java/intersection-type.java.sts | 37 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 migrator/test/java/intersection-type.java create mode 100755 migrator/test/java/intersection-type.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 71c072839..9e801b19f 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -853,7 +853,18 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(IntersectionType javaIntersectionType) { - // TODO: + boolean needPrimaryType = isInPrimaryTypeContext(); + if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + pushCurrent(new IntersectionTypeContext(stsCurrent, 0)); + + List javaTypeList = javaIntersectionType.types(); + for (Type javaType : javaTypeList) + javaType.accept(this); + + popCurrent(); // IntersectionTypeContext + + if (needPrimaryType) popCurrent(); // PrimaryTypeContext return false; } diff --git a/migrator/test/java/intersection-type.java b/migrator/test/java/intersection-type.java new file mode 100644 index 000000000..a1bdbbe67 --- /dev/null +++ b/migrator/test/java/intersection-type.java @@ -0,0 +1,35 @@ +/* + * 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 intersection_type { + public void bar(auxilliary arg) { + Runnable r = (Runnable & Something)arg; + r.run(); + + Something s = (Something & Runnable)arg; + s.foo(); + } +} + +class auxilliary implements Runnable, Something { + public void run() { } + public void foo() { } +} + +interface Something { + void foo(); +} diff --git a/migrator/test/java/intersection-type.java.sts b/migrator/test/java/intersection-type.java.sts new file mode 100755 index 000000000..96a82304a --- /dev/null +++ b/migrator/test/java/intersection-type.java.sts @@ -0,0 +1,37 @@ +/* + * 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 intersection_type { + public open bar(arg : auxilliary): void { + let r : Runnable = arg as (Runnable & Something); + r.run(); + let s : Something = arg as (Something & Runnable); + s.foo(); + } +} + +open class auxilliary implements Runnable, Something { + public open run(): void { + } + public open foo(): void { + } +} + +interface Something { + foo(): void ; +} + -- Gitee From 02890d86576ebad78d2360f571723eae93a48f43 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 3 Aug 2022 17:17:16 +0300 Subject: [PATCH 07/60] Enum translation (incomplete). Also minor bugfix and housekeeping in JavaTransformer code. Changes to tests to account for all of the above. Change-Id: I244038b63e07240aed4a882cab6385a07a50c487 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 262 ++++++++++++++---- .../staticTS/writer/StaticTSWriter.java | 58 ++-- .../test/java/class_instance_creation.java | 6 + .../java/class_instance_creation.java.sts | 9 + .../java/enum_with_class_behavior.java.sts | 69 ++++- migrator/test/java/method_invocation.java.sts | 8 +- migrator/test/java/test_enum.java.sts | 80 ++++-- 7 files changed, 360 insertions(+), 132 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 9e801b19f..f6ea9ddf8 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,8 +43,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; + private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; + private static int countStmtTotal = 0; private static int countExprTotal = 0; private static int countExprTransformed = 0; @@ -187,14 +190,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - private void translateNonAccessModifiers(FieldDeclaration javaFieldDecl) { - int javaModifiers = javaFieldDecl.getModifiers(); - - // A field may not have Abstract modifier. - if ((javaModifiers & Modifier.STATIC) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); - if ((javaModifiers & Modifier.FINAL) == 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Open)); - } - private void translateNonAccessModifiers(TypeDeclaration javaTypeDeclaration) { int javaModifiers = javaTypeDeclaration.getModifiers(); @@ -214,6 +209,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return true; } + for (ITypeBinding javaInterface : javaClassBinding.getInterfaces()) { + if (doesOverride(javaInterface, javaCheckedMethod)) + return true; + } + ITypeBinding javaSuperClassBinding = javaClassBinding.getSuperclass(); if (javaSuperClassBinding != null) return doesOverride(javaSuperClassBinding, javaCheckedMethod); @@ -241,15 +241,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if ((javaModifiers & Modifier.STATIC) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); if ((javaModifiers & Modifier.NATIVE) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Native)); } - - private void translateNonAccessModifiers(EnumDeclaration javaEnumDeclaration) { - // TODO: Check and correct to apply only enum related/valid modifiers. - int javaModifiers = javaEnumDeclaration.getModifiers(); - if ((javaModifiers & Modifier.ABSTRACT) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Abstract)); - if ((javaModifiers & Modifier.STATIC) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); - if ((javaModifiers & Modifier.FINAL) == 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Open)); - } - + // Java tree: // TypeDeclaration: // A type declaration is the union of a class declaration and an interface declaration. // ClassDeclaration @@ -269,7 +261,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // { { InterfaceBodyDeclaration | ; } } // // STS tree for interface: - // TopLevelElementContext + // topDeclarationContext // InterfaceDeclarationContext // TerminalNode // TerminalNode @@ -280,8 +272,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // // STS src: class TestClassB extends TestClassA implements TestInterfaceA, TestInterfaceB {} // Resulting tree: - // TopLevelElementContext | ClassMemberContext | InterfaceMemberContext - // TerminalNode ? (for TopLevelElementContext) + // topDeclarationContext | ClassMemberContext | InterfaceMemberContext + // TerminalNode ? (for topDeclarationContext) // | AccessibilityModifierContext? (for ClassMemberContext or InterfaceMemberContext) // ClassDeclarationContext // TerminalNode @@ -571,20 +563,27 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(stsClassOrInterField); - // Non-access modifiers and field name. - translateNonAccessModifiers(javaFieldDecl); + // Non-access modifiers + if ((javaMods & Modifier.STATIC) != 0) + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + // Note: Java allows final fields declared without initializer (to be initialized in ctor). + // STS doesn't allow constant fields without initializer, therefore the fields above will + // be translated without const modifier. ParserRuleContext stsVarOrConstDecl; - if ((javaMods & Modifier.FINAL) != 0 || !isInClassContext) { + Expression javaFragmentInit = javaVarDeclFragment.getInitializer(); + if (((javaMods & Modifier.FINAL) != 0 && javaFragmentInit != null) || !isInClassContext) { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Const)); stsVarOrConstDecl = new ConstantDeclarationContext(stsCurrent, 0); } else stsVarOrConstDecl = new VariableDeclarationContext(stsCurrent, 0); + // Field name pushCurrent(stsVarOrConstDecl); stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaVarDeclFragment.getName())); + // Field type pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); javaFieldDecl.getType().accept(this); @@ -594,11 +593,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeAnnotationContext - Expression javaInitializer = javaVarDeclFragment.getInitializer(); - if (javaInitializer != null) { + // Field initializer, if any + if (javaFragmentInit != null) { pushCurrent(new InitializerContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitializer.accept(this); + javaFragmentInit.accept(this); popCurrent(); // InitializerContext } @@ -1422,6 +1421,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // NOTE: All Java enums are translated into STS classes because of + // built-in methods values() and valueOf() available to the former! + // // Java tree: // EnumDeclaration: // [ Javadoc ] { ExtendedModifier } enum Identifier @@ -1432,55 +1434,207 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // } // // STS tree: - // TopLevelElementContext | ClassMemberContext | InterfaceMemberContext - // TerminalNode ? (for TopLevelElementContext) + // TopDeclarationContext | ClassMemberContext | InterfaceMemberContext + // TerminalNode ? (for TopDeclarationContext) // | AccessibilityModifierContext? (for ClassMemberContext or InterfaceMemberContext) - // EnumDeclarationContext - // Enum Identifier OpenBrace enumBody CloseBrace + // ClassDeclarationContext + // TerminalNode + // Identifier + // ClassExtendsClauseContext + // TerminalNode + // TypeReferenceContext + // QualifiedNameContext + // TerminalNode + // ImplementsClauseContext + // TerminalNode + // InterfaceTypeListContext + // TypeReferenceContext + // QualifiedNameContext + // TerminalNode + // TerminalNode <,> + // TypeReferenceContext + // QualifiedNameContext + // TerminalNode + // ClassBodyContext @Override public boolean visit(EnumDeclaration javaEnumDeclaration) { // Create appropriate member context to put declaration into. - pushCurrent(createMemberContextWithAccessModifier(javaEnumDeclaration.getModifiers())); - pushCurrent(new EnumDeclarationContext(stsCurrent, 0)); + int javaEnumMods = javaEnumDeclaration.getModifiers(); + pushCurrent(createMemberContextWithAccessModifier(javaEnumMods)); + + // Create class declaration context + ClassDeclarationContext stsClassDecl = new ClassDeclarationContext(stsCurrent, 0); + pushCurrent(stsClassDecl); + + // Set static modifier as necessary. + if (stsCurrent.getParent().getRuleIndex() != StaticTSParser.RULE_topDeclaration) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + } + + // Add class keyword and enum name + SimpleName javaEnumName = javaEnumDeclaration.getName(); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Class)); + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumName)); + + // Add extends clause. + createEnumExtendsClause(javaEnumName.getIdentifier()); - // Add remaining (non-access) modifiers and enum keyword. - translateNonAccessModifiers(javaEnumDeclaration); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Enum)); + // Add implements clause, if necessary + translateSuperInterfaceTypes(javaEnumDeclaration.superInterfaceTypes()); - // Enum name - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumDeclaration.getName())); + pushCurrent(new ClassBodyContext(stsCurrent, 0)); + + // Translate enum constants. + // If any of the constants contain anonymous class body (e.g., extend enum type), + // add open modifier to the resulting class. + boolean needOpen = false; + List javaEnumConstNames = new ArrayList<>(); + List javaEnumConstants = javaEnumDeclaration.enumConstants(); + for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { + if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBrace)); + // Pass enum name to enum constant node before visiting it + // as we'll need it to create appropriate initializers. + javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); - pushCurrent(new EnumBodyContext(stsCurrent, 0)); + // Store enum constant name in a list - we'll need it later to generate + // built-in values() method + javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); - // It looks for the transpiler there is no need to insert in the tree Comma terminal nodes. - // The writer adds them to the output without looking for them in the input tree. - List constants = javaEnumDeclaration.enumConstants(); - for(EnumConstantDeclaration javaEnumConst : constants) { javaEnumConst.accept(this); } + if (needOpen) { + stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); + } - popCurrent(); // EnumBodyContext + // Translate body declarations (ctors, methods, nested types, and fields). + List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); + for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { + javaEnumBodyDecl.accept(this); + } - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBrace)); + // TODO: valueOf(), toString() and ordinal() methods! + createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); - popCurrent(); // EnumDeclarationContext - popCurrent(); // stsMemberContext + popCurrent(); // ClassBodyContext + popCurrent(); // stsClassDecl + popCurrent(); // member context return false; } + private void createEnumExtendsClause(String javaEnumName) { + // Note: A Java enum extends Enum class. + pushCurrent(new ClassExtendsClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Extends)); + pushCurrent(NodeBuilder.typeReference("Enum")); + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount()-1); + pushCurrent((TypeReferencePartContext)lastChild, false); + pushCurrent(new TypeArgumentsContext(stsCurrent, 0)); + pushCurrent(new TypeArgumentListContext(stsCurrent, 0)); + pushCurrent(new TypeArgumentContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumName)).setParent(stsCurrent); + popCurrent(); // TypeArgumentContext + popCurrent(); // TypeArgumentListContext + popCurrent(); // TypeArgumentsContext + popCurrent(); // (TypeReferencePartContext)lastChild + popCurrent(); // TypeReferenceContext + popCurrent(); // ClassExtendsClauseContext + } + + private void createEnumValuesMethod(String javaEnumTypeName, List javaEnumConstNames) { + // Create class member context and add public modifier + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PUBLIC)); + + // Create class declaration context and add static modifier + pushCurrent(new ClassMethodDeclarationContext(stsCurrent, 0)); + pushCurrent(new ClassMethodWithBodyContext((ClassMethodDeclarationContext)stsCurrent)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + + // Add method name and signature + stsCurrent.addChild(NodeBuilder.terminalIdentifier("values")); + pushCurrent(new SignatureContext(stsCurrent, 0)); + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); + popCurrent(); // ArrayTypeContext + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + popCurrent(); // SignatureContext + + // Add function body + pushCurrent(new BlockContext(stsCurrent, 0)); + pushStatement(new ReturnStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Return)); + pushCurrent(new ArrayLiteralExpressionContext(pushSingleExpression())); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + for (String javaEnumConstName : javaEnumConstNames) { + stsCurrent.addChild(NodeBuilder.identifierExpression(javaEnumConstName)).setParent(stsCurrent); + } + popCurrent(); // ExpressionSequenceContext + popSingleExpression(); // ArrayLiteralExpressionContext + popStatement(); // ReturnStatementContext + popCurrent(); // BlockContext + + popCurrent(); // ClassMethodWithBodyContext + popCurrent(); // ClassMethodDeclarationContext + popCurrent(); // ClassMemberContext + } @Override public boolean visit(EnumConstantDeclaration javaEnumConstant) { - pushCurrent(new EnumMemberContext(stsCurrent, 0)); + // Create class member context and add public modifier + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PUBLIC)); - // Enum constant name + // Create class field declaration context and add static and const modifiers + pushCurrent(new ClassFieldDeclarationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Const)); + + // Create constant declaration context and add enum constant name and type + pushCurrent(new ConstantDeclarationContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumConstant.getName())); + String javaEnumTypeName = (String)javaEnumConstant.getProperty(ENUM_TYPE_NAME); + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotation - // TODO: Initializer + // Add initializer to constant declaration context + pushCurrent(new InitializerContext(stsCurrent, 0)); + pushCurrent(new NewClassExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); - popCurrent(); // EnumMemberContext + // Process ctor arguments, if any + List javaEnumConstArgs = javaEnumConstant.arguments(); + if (javaEnumConstArgs != null && !javaEnumConstArgs.isEmpty()) { + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + for (Expression javaEnumConstArg : javaEnumConstArgs) { + javaEnumConstArg.accept(this); + } + popCurrent(); // ExpressionSequenceContext + popCurrent(); // ArgumentsContext + } + + // Process anonymous class body, if any + AnonymousClassDeclaration javaEnumConstClassBody = javaEnumConstant.getAnonymousClassDeclaration(); + if (javaEnumConstClassBody != null) { + javaEnumConstClassBody.accept(this); + } + + popSingleExpression(); // NewClassExpressionContext + popCurrent(); // InitializerContext + + popCurrent(); // ConstantDeclarationContext + popCurrent(); // ClassFieldDeclarationContext + popCurrent(); // ClassMemberContext return false; } @@ -1595,7 +1749,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // | VariableDeclarationStatement // VariableDeclarationStatement: { ExtendedModifier } Type VariableDeclarationFragment { , VariableDeclarationFragment } ; // STS tree: - // topLevelElement: Export? + // topDeclaration: Export? // | variableStatement // variableStatement: ((Let variableDeclarationList) | (Const constantDeclarationList)) SemiColon // variableDeclarationList: @@ -2056,7 +2210,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(AnonymousClassDeclaration javaAnonymousClassDeclaration) { pushCurrent(new ClassBodyContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBrace)).setParent(stsCurrent); List javaBodyDeclarations = javaAnonymousClassDeclaration.bodyDeclarations(); assert (javaBodyDeclarations != null); @@ -2064,7 +2217,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaBodyDeclaration.accept(this); } - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBrace)).setParent(stsCurrent); popCurrent(); // ClassBodyContext return false; } @@ -2490,8 +2642,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // ThisExpression: // [ ClassName . ] this // STS tree: - // singleExpression: - // | (typeReference Dot)? This # ThisExpression @Override public boolean visit(ThisExpression javaThisExpr) { pushCurrent(new ThisExpressionContext(pushSingleExpression())); diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 22fe22fe8..d12f99258 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -131,13 +131,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // typeParameterList: typeParameter (',' typeParameter)*; @Override public Void visitTypeParameterList(TypeParameterListContext stsTypeParameterList) { + int i = 0; for (TypeParameterContext stsTypeParameter : stsTypeParameterList.typeParameter()) { + if (i > 0) sb.append(", "); visitTypeParameter(stsTypeParameter); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", "; - return null; } @@ -197,13 +197,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // typeArgumentList: typeArgument (',' typeArgument)* @Override public Void visitTypeArgumentList(TypeArgumentListContext stsTypeArgumentList) { + int i = 0; for (TypeArgumentContext stsTypeArgument : stsTypeArgumentList.typeArgument()) { + if (i > 0) sb.append(", "); visitTypeArgument(stsTypeArgument); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", ". - return null; } @@ -302,12 +302,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // qualifiedName: Identifier (Dot Identifier)* @Override public Void visitQualifiedName(QualifiedNameContext stsQualName) { + int i = 0; for (TerminalNode identifier : stsQualName.Identifier()) { - sb.append(identifier.getText()).append('.'); + sb.append(identifier.getText()); + if (i > 0) sb.append('.'); + ++i; } - sb.setLength(sb.length() - 1); // Cut off the ending extra '.' - return null; } @@ -566,13 +567,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // classOrInterfaceTypeList: typeReference (',' typeReference)* @Override public Void visitInterfaceTypeList(InterfaceTypeListContext stsClassOrInterfaceTypeList) { + int i = 0; for (TypeReferenceContext stsTypeReference : stsClassOrInterfaceTypeList.typeReference()) { + if (i > 0) sb.append(", "); visitTypeReference(stsTypeReference); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", " - return null; } @@ -792,26 +793,25 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // variableDeclarationList: variableDeclaration (',' variableDeclaration)* @Override public Void visitVariableDeclarationList(VariableDeclarationListContext stsVariableDeclarationList) { + int i = 0; for (VariableDeclarationContext stsVariableDeclaration : stsVariableDeclarationList.variableDeclaration()) { + if (i > 0) sb.append(", "); visitVariableDeclaration(stsVariableDeclaration); - sb.append(", "); + ++i; } - - sb.setLength(sb.length() - 2); // Cut off the ending extra ", " - return null; } // constantDeclarationList: constantDeclaration (',' constantDeclaration)* @Override public Void visitConstantDeclarationList(ConstantDeclarationListContext stsConstantDeclarationList) { + int i = 0; for (ConstantDeclarationContext stsConstantDeclaration : stsConstantDeclarationList.constantDeclaration()) { + if (i > 0) sb.append(", "); visitConstantDeclaration(stsConstantDeclaration); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", " - return null; } @@ -971,14 +971,14 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // expressionSequence: singleExpression (',' singleExpression)* @Override public Void visitExpressionSequence(ExpressionSequenceContext stsExpressionSequence) { + int i = 0; for (SingleExpressionContext stsExpression : stsExpressionSequence.singleExpression()) { + if (i > 0) sb.append(", "); stsExpression.accept(this); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off trailing ", " - - return null; + return null; } // | For '(' Let Identifier typeAnnotation? Of singleExpression ')' (statement | block) # ForInOfStatement @@ -1315,7 +1315,11 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitChildren(stsClassBody); indentDecrement(); - sb.append(indentCurrent).append("}\n\n"); + sb.append(indentCurrent).append("}"); + + // Don't start new line if this class body is a part of a object creation expression + if (!(stsClassBody.getParent() instanceof NewClassExpressionContext)) + sb.append("\n\n"); return null; } @@ -1421,12 +1425,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { List stsParameters = stsParameterList.parameter(); if (stsParameters != null) { + int i = 0; for (ParameterContext stsParameter : stsParameters) { + if (i > 0) sb.append(", "); visitParameter(stsParameter); - sb.append(", "); + ++i; } - - sb.setLength(sb.length() - 2); // Cut off trailing ", " } VariadicParameterContext stsVariadicParameter = stsParameterList.variadicParameter(); diff --git a/migrator/test/java/class_instance_creation.java b/migrator/test/java/class_instance_creation.java index 223ddcc5a..53d1eb020 100644 --- a/migrator/test/java/class_instance_creation.java +++ b/migrator/test/java/class_instance_creation.java @@ -20,7 +20,13 @@ class class_instance_creation { class_instance_creation() {} class_instance_creation(String s, double d) {} + public void foo() { } + static class_instance_creation inst1 = new class_instance_creation(); static class_instance_creation inst2 = new class_instance_creation(3); static class_instance_creation inst3 = new class_instance_creation("ss", 7.8); + static class_instance_creation inst4 = new class_instance_creation(3) { + private int f; + public void foo() { f = 2; } + }; } diff --git a/migrator/test/java/class_instance_creation.java.sts b/migrator/test/java/class_instance_creation.java.sts index 2dec21a27..73b567831 100644 --- a/migrator/test/java/class_instance_creation.java.sts +++ b/migrator/test/java/class_instance_creation.java.sts @@ -24,8 +24,17 @@ open class class_instance_creation { constructor(s : String, d : double) { } + public open foo(): void { + } + static inst1 : class_instance_creation = new class_instance_creation(); static inst2 : class_instance_creation = new class_instance_creation(3); static inst3 : class_instance_creation = new class_instance_creation("ss", 7.8); + static inst4 : class_instance_creation = new class_instance_creation(3) { + private f : int ; + public override foo(): void { + f = 2; + } + }; } diff --git a/migrator/test/java/enum_with_class_behavior.java.sts b/migrator/test/java/enum_with_class_behavior.java.sts index 63344485c..d47fe7b36 100644 --- a/migrator/test/java/enum_with_class_behavior.java.sts +++ b/migrator/test/java/enum_with_class_behavior.java.sts @@ -18,19 +18,60 @@ interface IOperation { apply(a : int, b : int): int ; } -enum ArithmeticOperation { - PLUS, - MINUS, - MULTIPLY, - DIVIDE +open class ArithmeticOperation extends Enum implements IOperation { + public static const PLUS : ArithmeticOperation = new ArithmeticOperation { + public override apply(a : int, b : int): int { + return a + b; + } + }; + public static const MINUS : ArithmeticOperation = new ArithmeticOperation { + public override apply(a : int, b : int): int { + return a - b; + } + }; + public static const MULTIPLY : ArithmeticOperation = new ArithmeticOperation { + public override apply(a : int, b : int): int { + return a * b; + } + }; + public static const DIVIDE : ArithmeticOperation = new ArithmeticOperation { + public override apply(a : int, b : int): int { + return a / b; + } + }; + public static values(): ArithmeticOperation[] { + return [PLUS, MINUS, MULTIPLY, DIVIDE]; + } } -enum Planet { - MERCURY, - VENUS, - EARTH, - MARS, - JUPITER, - SATURN, - URANUS, - NEPTUNE +class Planet extends Enum { + public static const MERCURY : Planet = new Planet(3.303e+23, 2.4397e6); + public static const VENUS : Planet = new Planet(4.869e+24, 6.0518e6); + public static const EARTH : Planet = new Planet(5.976e+24, 6.37814e6); + public static const MARS : Planet = new Planet(6.421e+23, 3.3972e6); + public static const JUPITER : Planet = new Planet(1.9e+27, 7.1492e7); + public static const SATURN : Planet = new Planet(5.688e+26, 6.0268e7); + public static const URANUS : Planet = new Planet(8.686e+25, 2.5559e7); + public static const NEPTUNE : Planet = new Planet(1.024e+26, 2.4746e7); + + private mass : double ; + private radius : double ; + + constructor(mass : double, radius : double) { + this.mass = mass; + this.radius = radius; + } + + public static const G : double = 6.67300E-11; + + open surfaceGravity(): double { + return G * mass / (radius * radius); + } + + open surfaceWeight(otherMass : double): double { + return otherMass * surfaceGravity(); + } + + public static values(): Planet[] { + return [MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE]; + } } diff --git a/migrator/test/java/method_invocation.java.sts b/migrator/test/java/method_invocation.java.sts index d0197e84a..681a206d0 100644 --- a/migrator/test/java/method_invocation.java.sts +++ b/migrator/test/java/method_invocation.java.sts @@ -28,9 +28,7 @@ open class SubClass1 extends SuperClass { public open run(): void { SubClass1.super.foo(); } - } - -; + }; } interface SuperInterface { @@ -53,9 +51,7 @@ open class SubClass3 implements SuperInterface { tweak : Runnable = new Runnable() { public open run(): void { } - } - -; + }; } open class Doubler { diff --git a/migrator/test/java/test_enum.java.sts b/migrator/test/java/test_enum.java.sts index 05aaf180d..9958c48d3 100644 --- a/migrator/test/java/test_enum.java.sts +++ b/migrator/test/java/test_enum.java.sts @@ -14,41 +14,63 @@ */ package com.ohos.migrator.test.java; -export enum test_enum { - +export class test_enum extends Enum { + public static values(): test_enum[] { + return []; + } } -enum Planet { - MERCURY, - VENUS, - EARTH, - MARS, - JUPITER, - SATURN, - URANUS, - NEPTUNE +class Planet extends Enum { + public static const MERCURY : Planet = new Planet; + public static const VENUS : Planet = new Planet; + public static const EARTH : Planet = new Planet; + public static const MARS : Planet = new Planet; + public static const JUPITER : Planet = new Planet; + public static const SATURN : Planet = new Planet; + public static const URANUS : Planet = new Planet; + public static const NEPTUNE : Planet = new Planet; + + public static values(): Planet[] { + return [MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE]; + } } open class NestedEnums { - private enum Colors { - RED, - GREEN, - BLUE + private static class Colors extends Enum { + public static const RED : Colors = new Colors; + public static const GREEN : Colors = new Colors; + public static const BLUE : Colors = new Colors; + + public static values(): Colors[] { + return [RED, GREEN, BLUE]; + } } - protected enum Size { - SMALL, - MEDIUM, - LARGE + protected static class Size extends Enum { + public static const SMALL : Size = new Size; + public static const MEDIUM : Size = new Size; + public static const LARGE : Size = new Size; + + public static values(): Size[] { + return [SMALL, MEDIUM, LARGE]; + } } - public enum Direction { - NORTH, - EAST, - SOUTH, - WEST + public static class Direction extends Enum { + public static const NORTH : Direction = new Direction; + public static const EAST : Direction = new Direction; + public static const SOUTH : Direction = new Direction; + public static const WEST : Direction = new Direction; + + public static values(): Direction[] { + return [NORTH, EAST, SOUTH, WEST]; + } } - enum Operator { - PLUS, - MINUS, - MULTIPLY, - DIVIDE + static class Operator extends Enum { + public static const PLUS : Operator = new Operator; + public static const MINUS : Operator = new Operator; + public static const MULTIPLY : Operator = new Operator; + public static const DIVIDE : Operator = new Operator; + + public static values(): Operator[] { + return [PLUS, MINUS, MULTIPLY, DIVIDE]; + } } } -- Gitee From 6f892f0372d0cf5260aa551b1626d63b9f451980 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Thu, 4 Aug 2022 15:19:32 +0300 Subject: [PATCH 08/60] Enum translation: Implemented valueOf method and updates to tests to cover these changes. Also minor fix to error processing. Change-Id: I4278b38afc634c2f05559edb301cfb70c9d93517 Signed-off-by: Mikhail Velikanov --- .../com/ohos/migrator/AbstractTranspiler.java | 7 + .../ohos/migrator/java/JavaTransformer.java | 122 ++++++++++++++++-- .../java/enum_with_class_behavior.java.sts | 12 ++ migrator/test/java/test_enum.java.sts | 37 ++++++ 4 files changed, 170 insertions(+), 8 deletions(-) diff --git a/migrator/src/com/ohos/migrator/AbstractTranspiler.java b/migrator/src/com/ohos/migrator/AbstractTranspiler.java index 015b99104..f727ac86d 100644 --- a/migrator/src/com/ohos/migrator/AbstractTranspiler.java +++ b/migrator/src/com/ohos/migrator/AbstractTranspiler.java @@ -70,6 +70,13 @@ public abstract class AbstractTranspiler implements Transpiler { if (strictMode) return transpileResult; } catch (Exception e) { + StringBuilder sb = new StringBuilder(e.getClass().getName()); + sb.append(" at:\n"); + + for (StackTraceElement ste : e.getStackTrace()) + sb.append(ste.toString()).append("\n"); + + errorList.add(new TranspileException(ResultCode.InputError, sb.toString())); transpileResult = ResultCode.majorValue(ResultCode.InputError, transpileResult); if (strictMode) return transpileResult; } diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index f6ea9ddf8..8b553e030 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1513,8 +1513,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaEnumBodyDecl.accept(this); } - // TODO: valueOf(), toString() and ordinal() methods! - createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); + // TODO: toString() and ordinal() methods! + String javaEnumTypeName = javaEnumDeclaration.getName().getIdentifier(); + createEnumValuesMethod(javaEnumTypeName, javaEnumConstNames); + createEnumValueOfMethod(javaEnumTypeName); popCurrent(); // ClassBodyContext popCurrent(); // stsClassDecl @@ -1542,15 +1544,29 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ClassExtendsClauseContext } - private void createEnumValuesMethod(String javaEnumTypeName, List javaEnumConstNames) { + private void pushEnumBuiltinMethod() { // Create class member context and add public modifier pushCurrent(new ClassMemberContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PUBLIC)); - // Create class declaration context and add static modifier + // Create class method declaration context and add static modifier pushCurrent(new ClassMethodDeclarationContext(stsCurrent, 0)); pushCurrent(new ClassMethodWithBodyContext((ClassMethodDeclarationContext)stsCurrent)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + } + + private void popEnumBuiltinMethod() { + popCurrent(); // ClassMethodWithBodyContext + popCurrent(); // ClassMethodDeclarationContext + popCurrent(); // ClassMemberContext + } + + // Generates the following method + // public static values() : [] { + // return [ , , ... ]; + // } + private void createEnumValuesMethod(String javaEnumTypeName, List javaEnumConstNames) { + pushEnumBuiltinMethod(); // Add method name and signature stsCurrent.addChild(NodeBuilder.terminalIdentifier("values")); @@ -1566,7 +1582,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeAnnotationContext popCurrent(); // SignatureContext - // Add function body + // Add method body + // return [ enum_constant1, enum_constant2, ... ]; pushCurrent(new BlockContext(stsCurrent, 0)); pushStatement(new ReturnStatementContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Return)); @@ -1580,9 +1597,98 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); // ReturnStatementContext popCurrent(); // BlockContext - popCurrent(); // ClassMethodWithBodyContext - popCurrent(); // ClassMethodDeclarationContext - popCurrent(); // ClassMemberContext + popEnumBuiltinMethod(); + } + + // Generates the following method: + // public static valueOf(String name) : { + // for (let value : of values()) { + // if (name == value.toString()) return value; + // } + // return null; + // } + private void createEnumValueOfMethod(String javaEnumTypeName) { + pushEnumBuiltinMethod(); + + // Add method name and signature + stsCurrent.addChild(NodeBuilder.terminalIdentifier("valueOf")); + pushCurrent(new SignatureContext(stsCurrent, 0)); + pushCurrent(new ParameterListContext(stsCurrent, 0)); + pushCurrent(new ParameterContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("name")); + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference("String")).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + popCurrent(); // ParameterContext + popCurrent(); // ParameterListContext + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + popCurrent(); // SignatureContext + + // Add method body + // for (let value : of values()) { + pushCurrent(new BlockContext(stsCurrent, 0)); + pushCurrent(new ForOfStatementContext(pushIterationStatement())); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.For)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Let)); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("value")); + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Of)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.identifierExpression("values")).setParent(stsCurrent); + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + popCurrent(); // ArgumentsContext + popSingleExpression(); // CallExpressionContext + pushStatement(new BlockContext(stsCurrent, 0)); + + // if (name == value.toString()) return value; + IfStatementContext stsIfStmt = new IfStatementContext(stsCurrent, 0); + pushStatement(stsIfStmt); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.If)); + pushCurrent(new EqualityExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.identifierExpression("name")).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Equals)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.identifierExpression("value")).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("toString")); + popSingleExpression(); // MemberAccessExpressionContext + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + popCurrent(); // ArgumentsContext + popSingleExpression(); // CallExpressionContext + popSingleExpression(); // EqualityExpressionContext + pushStatement(new ReturnStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Return)); + stsCurrent.addChild(NodeBuilder.identifierExpression("value")).setParent(stsCurrent); + popStatement(); // ReturnStatementContext + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + assert(lastChild instanceof StatementContext); + stsIfStmt.ifStmt = (StatementContext)lastChild; + popStatement(); // IfStatementContext + + // close off for-of statement + popStatement(); // BlockContext + popIterationStatement(); // ForOfStatementContext + + // return null; + pushStatement(new ReturnStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Return)); + stsCurrent.addChild(NodeBuilder.nullLiteral()).setParent(stsCurrent); + popStatement(); // ReturnStatementContext + + // close off method body + popCurrent(); // BlockContext + + popEnumBuiltinMethod(); } @Override public boolean visit(EnumConstantDeclaration javaEnumConstant) { diff --git a/migrator/test/java/enum_with_class_behavior.java.sts b/migrator/test/java/enum_with_class_behavior.java.sts index d47fe7b36..fe0a741d1 100644 --- a/migrator/test/java/enum_with_class_behavior.java.sts +++ b/migrator/test/java/enum_with_class_behavior.java.sts @@ -42,6 +42,12 @@ open class ArithmeticOperation extends Enum implements IOpe public static values(): ArithmeticOperation[] { return [PLUS, MINUS, MULTIPLY, DIVIDE]; } + public static valueOf(name : String): ArithmeticOperation { + for (let value : ArithmeticOperation of values()){ + if (name == value.toString()) return value; + } + return null; + } } class Planet extends Enum { public static const MERCURY : Planet = new Planet(3.303e+23, 2.4397e6); @@ -74,4 +80,10 @@ class Planet extends Enum { public static values(): Planet[] { return [MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE]; } + public static valueOf(name : String): Planet { + for (let value : Planet of values()){ + if (name == value.toString()) return value; + } + return null; + } } diff --git a/migrator/test/java/test_enum.java.sts b/migrator/test/java/test_enum.java.sts index 9958c48d3..e0893fd67 100644 --- a/migrator/test/java/test_enum.java.sts +++ b/migrator/test/java/test_enum.java.sts @@ -18,6 +18,13 @@ export class test_enum extends Enum { public static values(): test_enum[] { return []; } + public static valueOf(name : String): test_enum { + for (let value : test_enum of values()){ + if (name == value.toString()) return value; + } + return null; + } + } class Planet extends Enum { public static const MERCURY : Planet = new Planet; @@ -32,6 +39,12 @@ class Planet extends Enum { public static values(): Planet[] { return [MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE]; } + public static valueOf(name : String): Planet { + for (let value : Planet of values()){ + if (name == value.toString()) return value; + } + return null; + } } open class NestedEnums { private static class Colors extends Enum { @@ -42,6 +55,12 @@ open class NestedEnums { public static values(): Colors[] { return [RED, GREEN, BLUE]; } + public static valueOf(name : String): Colors { + for (let value : Colors of values()){ + if (name == value.toString()) return value; + } + return null; + } } protected static class Size extends Enum { public static const SMALL : Size = new Size; @@ -51,6 +70,12 @@ open class NestedEnums { public static values(): Size[] { return [SMALL, MEDIUM, LARGE]; } + public static valueOf(name : String): Size { + for (let value : Size of values()){ + if (name == value.toString()) return value; + } + return null; + } } public static class Direction extends Enum { public static const NORTH : Direction = new Direction; @@ -61,6 +86,12 @@ open class NestedEnums { public static values(): Direction[] { return [NORTH, EAST, SOUTH, WEST]; } + public static valueOf(name : String): Direction { + for (let value : Direction of values()){ + if (name == value.toString()) return value; + } + return null; + } } static class Operator extends Enum { public static const PLUS : Operator = new Operator; @@ -71,6 +102,12 @@ open class NestedEnums { public static values(): Operator[] { return [PLUS, MINUS, MULTIPLY, DIVIDE]; } + public static valueOf(name : String): Operator { + for (let value : Operator of values()){ + if (name == value.toString()) return value; + } + return null; + } } } -- Gitee From b3ca0441fb0847a43851cd6b5d067e9fa46cc5e6 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Thu, 4 Aug 2022 17:14:35 +0300 Subject: [PATCH 09/60] Minor refactoring of the code around enum translation. Change-Id: I017b70ce1ae1509c757ace4e5fb323d2ca63b938 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 29 +++-------------- .../ohos/migrator/staticTS/NodeBuilder.java | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 8b553e030..b1ce905af 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1571,15 +1571,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Add method name and signature stsCurrent.addChild(NodeBuilder.terminalIdentifier("values")); pushCurrent(new SignatureContext(stsCurrent, 0)); - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - pushCurrent(new ArrayTypeContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); - popCurrent(); // ArrayTypeContext - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext + ArrayTypeContext stsReturnType = NodeBuilder.arrayType(javaEnumTypeName, 1); + stsCurrent.addChild(NodeBuilder.typeAnnotation(stsReturnType)).setParent(stsCurrent); popCurrent(); // SignatureContext // Add method body @@ -1616,18 +1609,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ParameterListContext(stsCurrent, 0)); pushCurrent(new ParameterContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalIdentifier("name")); - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.typeReference("String")).setParent(stsCurrent); - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext + stsCurrent.addChild(NodeBuilder.typeAnnotation("String")).setParent(stsCurrent); popCurrent(); // ParameterContext popCurrent(); // ParameterListContext - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext + stsCurrent.addChild(NodeBuilder.typeAnnotation(javaEnumTypeName)).setParent(stsCurrent); popCurrent(); // SignatureContext // Add method body @@ -1637,11 +1622,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.For)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Let)); stsCurrent.addChild(NodeBuilder.terminalIdentifier("value")); - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext + stsCurrent.addChild(NodeBuilder.typeAnnotation(javaEnumTypeName)).setParent(stsCurrent); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Of)); pushCurrent(new CallExpressionContext(pushSingleExpression())); stsCurrent.addChild(NodeBuilder.identifierExpression("values")).setParent(stsCurrent); diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 5c0c2c337..077895650 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -336,4 +336,35 @@ public class NodeBuilder { stsArrayType.addChild(terminalNode(StaticTSParser.CloseBracket)); } } + + public static ArrayTypeContext arrayType(String elementTypeName, int dimensions) { + ArrayTypeContext stsArrayType = new ArrayTypeContext(null, 0); + stsArrayType.addChild(typeReference(elementTypeName)).setParent(stsArrayType); + for (int i = 0; i < dimensions; ++i) { + stsArrayType.addChild(terminalNode(StaticTSParser.OpenBracket)); + stsArrayType.addChild(terminalNode(StaticTSParser.CloseBracket)); + } + return stsArrayType; + } + + public static TypeAnnotationContext typeAnnotation(TypeReferenceContext stsTypeRef) { + TypeAnnotationContext stsTypeAnno = new TypeAnnotationContext(null, 0); + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsTypeAnno, 0); + stsPrimaryType.addChild(stsTypeRef).setParent(stsPrimaryType); + stsTypeAnno.addChild(stsPrimaryType).setParent(stsTypeAnno); + return stsTypeAnno; + } + + public static TypeAnnotationContext typeAnnotation(String stsTypeName) { + TypeReferenceContext stsTypeRef = typeReference(stsTypeName); + return typeAnnotation(stsTypeRef); + } + + public static TypeAnnotationContext typeAnnotation(ArrayTypeContext stsArrayType) { + TypeAnnotationContext stsTypeAnno = new TypeAnnotationContext(null, 0); + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsTypeAnno, 0); + stsPrimaryType.addChild(stsArrayType).setParent(stsPrimaryType); + stsTypeAnno.addChild(stsPrimaryType).setParent(stsTypeAnno); + return stsTypeAnno; + } } -- Gitee From 1f0cac380ad42b87f47fd6577d1c97378f0923ff Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 5 Aug 2022 12:48:09 +0300 Subject: [PATCH 10/60] Add declaration counts to metrics report. Change-Id: I4e85b31e55396dd8e2f67f8d7c94aa923f0402c5 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index b1ce905af..494b4b7c6 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -50,17 +50,30 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private static int countStmtTotal = 0; private static int countExprTotal = 0; + + private static int countDeclTotal = 0; private static int countExprTransformed = 0; private static int countStmtTransformed = 0; + private static int countDeclTransformed = 0; public static double getTransformationRate() { double result = 0.; + int normFactor = 0; - if (countStmtTotal > 0) result += countStmtTransformed / (double)countStmtTotal; - if (countExprTotal > 0) result += countExprTransformed / (double)countExprTotal; + if (countStmtTotal > 0) { + ++normFactor; + result += countStmtTransformed / (double)countStmtTotal; + } + if (countExprTotal > 0) { + ++normFactor; + result += countExprTransformed / (double)countExprTotal; + } + if (countDeclTotal > 0) { + ++normFactor; + result += countDeclTransformed / (double)countDeclTotal; + } - double normFactor = (countStmtTotal > 0 && countExprTotal > 0) ? 2. : 1.; - return result / normFactor; + return (normFactor > 0) ? result / (double)normFactor : 0.; } /** @@ -144,6 +157,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { ++countExprTotal; else if (node instanceof Statement) ++countStmtTotal; + else if (node instanceof BodyDeclaration + || node instanceof VariableDeclaration) + ++countDeclTotal; } }); @@ -347,6 +363,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // Interface/ClassDeclarationContext popCurrent(); // stsMemberContext + ++countDeclTransformed; return false; } @@ -606,6 +623,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // stsClassOrInterMember } + ++countDeclTransformed; return false; } @@ -1356,6 +1374,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // ClassMemberContext or InterfaceMemberContext + + ++countDeclTransformed; return false; } @@ -1418,6 +1438,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // RestFormalParameterContext | FormalParameterContext + ++countDeclTransformed; return false; } @@ -1522,6 +1543,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // stsClassDecl popCurrent(); // member context + ++countDeclTransformed; return false; } @@ -1723,6 +1745,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ClassFieldDeclarationContext popCurrent(); // ClassMemberContext + ++countDeclTransformed; return false; } @@ -1826,6 +1849,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // VarOrConstDeclaration + ++countDeclTransformed; // Each VariableDeclarationFragment is a separate declaration construct! } popCurrent(); // VarOrConstDeclarationList @@ -1983,6 +2007,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsInitStmts.addAll(stsBlock.statementOrLocalDeclaration()); } + ++countDeclTransformed; return false; } -- Gitee From 8571c14c2c5bd46b968209d8a989f7bb263ac859 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 5 Aug 2022 14:02:19 +0300 Subject: [PATCH 11/60] Don't re-compute reference source paths for JavaParser. Change-Id: I0758cf25ab1d5b3bf677988b30052f826dd1f968 Signed-off-by: Mikhail Velikanov --- .../src/com/ohos/migrator/java/JavaParser.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaParser.java b/migrator/src/com/ohos/migrator/java/JavaParser.java index 6ef82f258..5ecb4efc2 100644 --- a/migrator/src/com/ohos/migrator/java/JavaParser.java +++ b/migrator/src/com/ohos/migrator/java/JavaParser.java @@ -40,7 +40,7 @@ public class JavaParser { private File sourceFile; private static Map packagePaths = new HashMap<>(); - private String[] sourcepathEntries = null; + private static String[] sourcepathEntries = null; private String[] classpathEntries = null; /* @@ -60,7 +60,11 @@ public class JavaParser { */ public JavaParser(File sourceFile, List sourceFiles, List classpaths) throws IOException { this(sourceFile); - setSourcepathEntries(sourceFiles); + + // Compute reference source paths once + if (sourcepathEntries == null) + setSourcepathEntries(sourceFiles); + setClasspathEntries(classpaths); } @@ -73,7 +77,7 @@ public class JavaParser { this.source = source; } - private String getPackagePath(File file) { + private static String getPackagePath(File file) { // If already processed this file, return the result from cache. if (packagePaths.containsKey(file)) { return packagePaths.get(file); @@ -125,13 +129,10 @@ public class JavaParser { return packagePath; } - private void setSourcepathEntries(List sourceFiles) { + private static void setSourcepathEntries(List sourceFiles) { Set filePaths = new HashSet<>(); for (File file : sourceFiles) { - // Skip source file that is to be parsed currently. - if (file == this.sourceFile) continue; - // ASTParser accepts only directories where reference sources // are located. Thus, store the parent of each source file path. String pkg = getPackagePath(file); -- Gitee From b4fdfe98a6a6c3466a0b6cb287f7bbdc6c73fd1d Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 5 Aug 2022 17:36:14 +0300 Subject: [PATCH 12/60] Inject name and ordinal args into enum class ctor calls. Generate default enum class ctor if no explicit ctor exists. Change-Id: Ibc07d16cef715a2412a048b6399ca75c1798cdae Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 79 ++++++++++++++++--- .../ohos/migrator/staticTS/NodeBuilder.java | 26 ++++-- .../java/enum_with_class_behavior.java.sts | 27 ++++--- migrator/test/java/test_enum.java.sts | 62 +++++++++------ 4 files changed, 146 insertions(+), 48 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 494b4b7c6..3da2f2adf 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -48,6 +48,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; + private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; private static int countStmtTotal = 0; private static int countExprTotal = 0; @@ -689,7 +690,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { boolean needPrimaryType = isInPrimaryTypeContext(); if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - PredefinedTypeContext stsType = NodeBuilder.predefinedType(javaPrimitiveType); + PredefinedTypeContext stsType = NodeBuilder.predefinedType(javaPrimitiveType.getPrimitiveTypeCode()); stsCurrent.addChild(stsType).setParent(stsCurrent); if (needPrimaryType) popCurrent(); // PrimaryTypeContext @@ -1509,36 +1510,60 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // If any of the constants contain anonymous class body (e.g., extend enum type), // add open modifier to the resulting class. boolean needOpen = false; + int javaEnumConstOrdinal = 0; List javaEnumConstNames = new ArrayList<>(); List javaEnumConstants = javaEnumDeclaration.enumConstants(); for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; - // Pass enum name to enum constant node before visiting it + // Pass enum name and ordinal to enum constant node before visiting it // as we'll need it to create appropriate initializers. javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); + javaEnumConst.setProperty(ENUM_CONST_ORDINAL, String.valueOf(javaEnumConstOrdinal)); // Store enum constant name in a list - we'll need it later to generate // built-in values() method javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); javaEnumConst.accept(this); + ++javaEnumConstOrdinal; } if (needOpen) { stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); } // Translate body declarations (ctors, methods, nested types, and fields). + boolean hasCtors = false; List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { javaEnumBodyDecl.accept(this); + if (!hasCtors) { + if (javaEnumBodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION) { + MethodDeclaration javaEnumMethodDecl = (MethodDeclaration) javaEnumBodyDecl; + hasCtors = javaEnumMethodDecl.isConstructor(); + } + else { + hasCtors = javaEnumBodyDecl.getNodeType() == ASTNode.INITIALIZER; + } + } } - // TODO: toString() and ordinal() methods! + // Add values and valueOf built-in methods String javaEnumTypeName = javaEnumDeclaration.getName().getIdentifier(); createEnumValuesMethod(javaEnumTypeName, javaEnumConstNames); createEnumValueOfMethod(javaEnumTypeName); + // Add name and ordinal parameters to all ctors. + if (!hasCtors) { + // If no ctors present, generate default one with just the two parameters above, + // and a single super(name, ordinal) call in the body. + createEnumDefaultCtor(); + } + else { + // TODO: For all non-default ctors - if there is no call to another ctor in the body, + // generate super(name, ordinal) call, otherwise pass name and ordinal to existing ctor call. + } + popCurrent(); // ClassBodyContext popCurrent(); // stsClassDecl popCurrent(); // member context @@ -1547,6 +1572,37 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + private void createEnumDefaultCtor() { + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PRIVATE)).setParent(stsCurrent); + pushCurrent(new ConstructorDeclarationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Constructor)); + pushCurrent(new ParameterListContext(stsCurrent, 0)); + pushCurrent(new ParameterContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("name")); + stsCurrent.addChild(NodeBuilder.typeAnnotation("String")).setParent(stsCurrent); + popCurrent(); // ParameterContext + pushCurrent(new ParameterContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("ordinal")); + PredefinedTypeContext stsPredefType = NodeBuilder.predefinedType(PrimitiveType.INT); + stsCurrent.addChild(NodeBuilder.typeAnnotation(stsPredefType)).setParent(stsCurrent); + popCurrent(); // ParameterContext + popCurrent(); // ParameterListContext + pushCurrent(new ConstructorBodyContext(stsCurrent, 0)); + pushCurrent(new ConstructorCallContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Super)); + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.identifierExpression("name")).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.identifierExpression("ordinal")).setParent(stsCurrent); + popCurrent(); // ExpressionSequenceContext + popCurrent(); // ArgumentsContext + popCurrent(); // ConstructorCallContext + popCurrent(); // ConstructorBodyContext + popCurrent(); // ConstructorDeclarationContext + popCurrent(); // ClassMemberContext + } + private void createEnumExtendsClause(String javaEnumName) { // Note: A Java enum extends Enum class. pushCurrent(new ClassExtendsClauseContext(stsCurrent, 0)); @@ -1706,7 +1762,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Create constant declaration context and add enum constant name and type pushCurrent(new ConstantDeclarationContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumConstant.getName())); + String javaEnumConstName = javaEnumConstant.getName().getIdentifier(); + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumConstName)); String javaEnumTypeName = (String)javaEnumConstant.getProperty(ENUM_TYPE_NAME); pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); @@ -1720,17 +1777,21 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)); stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); - // Process ctor arguments, if any + // Process ctor arguments, if any. + // NOTE: Always insert name and ordinal as first two ctor arguments! List javaEnumConstArgs = javaEnumConstant.arguments(); + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.stringLiteral(javaEnumConstName)).setParent(stsCurrent); + String javaEnumConstOrdinal = (String)javaEnumConstant.getProperty(ENUM_CONST_ORDINAL); + stsCurrent.addChild(NodeBuilder.numericLiteral(javaEnumConstOrdinal)).setParent(stsCurrent); if (javaEnumConstArgs != null && !javaEnumConstArgs.isEmpty()) { - pushCurrent(new ArgumentsContext(stsCurrent, 0)); - pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); for (Expression javaEnumConstArg : javaEnumConstArgs) { javaEnumConstArg.accept(this); } - popCurrent(); // ExpressionSequenceContext - popCurrent(); // ArgumentsContext } + popCurrent(); // ExpressionSequenceContext + popCurrent(); // ArgumentsContext // Process anonymous class body, if any AnonymousClassDeclaration javaEnumConstClassBody = javaEnumConstant.getAnonymousClassDeclaration(); diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 077895650..0ca2a2b57 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -68,9 +68,8 @@ public class NodeBuilder { return qualifiedName(javaName.getFullyQualifiedName()); } - private static int stsTypeNameCode(PrimitiveType javaPrimitive) { + private static int stsTypeNameCode(PrimitiveType.Code javaPrimitiveTypeCode) { int stsTypeNameCode = -1; - PrimitiveType.Code javaTypeCode = javaPrimitive.getPrimitiveTypeCode(); if (javaTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; else if (javaTypeCode == PrimitiveType.BYTE) stsTypeNameCode = StaticTSParser.Byte; @@ -87,10 +86,10 @@ public class NodeBuilder { return stsTypeNameCode; } - public static PredefinedTypeContext predefinedType(PrimitiveType javaPrimitive) { + public static PredefinedTypeContext predefinedType(PrimitiveType.Code javaPrimitiveTypeCode) { // predefinedType -> TerminalNode PredefinedTypeContext stsPredefinedType = new PredefinedTypeContext(null, 0); - stsPredefinedType.addChild(terminalNode(stsTypeNameCode(javaPrimitive))); + stsPredefinedType.addChild(terminalNode(stsTypeNameCode(javaPrimitiveTypeCode))); return stsPredefinedType; } @@ -167,6 +166,10 @@ public class NodeBuilder { // singleExpression: | literal # LiteralExpression // literal: | CharLiteral public static SingleExpressionContext charLiteral(String value) { + // Add leading and/or terminating quotes if missing + if (!value.startsWith("'")) value = "'" + value; + if (!value.endsWith("'")) value += "'"; + SingleExpressionContext stsExpression = new SingleExpressionContext(null, 0); LiteralContext stsLiteral = new LiteralContext(null, 0); stsLiteral.addChild(new TerminalNodeImpl(new CommonToken(StaticTSParser.CharLiteral, value))); @@ -179,6 +182,11 @@ public class NodeBuilder { // singleExpression: | literal # LiteralExpression // literal: | StringLiteral public static SingleExpressionContext stringLiteral(String value) { + // Add leading and/or terminating quotes if missing + if (!value.startsWith("\"")) value = "\"" + value; + if (!value.endsWith("\"")) value += "\""; + + // TODO: Escape all unescaped characters SingleExpressionContext stsExpression = new SingleExpressionContext(null, 0); LiteralContext stsLiteral = new LiteralContext(null, 0); stsLiteral.addChild(new TerminalNodeImpl(new CommonToken(StaticTSParser.StringLiteral, value))); @@ -255,8 +263,9 @@ public class NodeBuilder { } public static TypeReferenceContext typeReference(PrimitiveType javaPrimitivetype) { + PrimitiveType.Code javaPrimitiveTypeCode = javaPrimitivetype.getPrimitiveTypeCode(); TypeReferenceContext stsTypeReference = new TypeReferenceContext(null, 0); - stsTypeReference.addChild(qualifiedName(stsName(stsTypeNameCode(javaPrimitivetype)))).setParent(stsTypeReference); + stsTypeReference.addChild(qualifiedName(stsName(stsTypeNameCode(javaPrimitiveTypeCode)))).setParent(stsTypeReference); return stsTypeReference; } public static TypeReferenceContext typeReference(String stsQualifierText, Name javaName) { @@ -360,6 +369,13 @@ public class NodeBuilder { return typeAnnotation(stsTypeRef); } + public static TypeAnnotationContext typeAnnotation(PredefinedTypeContext stsPredefType) { + TypeAnnotationContext stsTypeAnno = new TypeAnnotationContext(null, 0); + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsTypeAnno, 0); + stsPrimaryType.addChild(stsPredefType).setParent(stsPrimaryType); + stsTypeAnno.addChild(stsPrimaryType).setParent(stsTypeAnno); + return stsTypeAnno; + } public static TypeAnnotationContext typeAnnotation(ArrayTypeContext stsArrayType) { TypeAnnotationContext stsTypeAnno = new TypeAnnotationContext(null, 0); PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsTypeAnno, 0); diff --git a/migrator/test/java/enum_with_class_behavior.java.sts b/migrator/test/java/enum_with_class_behavior.java.sts index fe0a741d1..c90e6c465 100644 --- a/migrator/test/java/enum_with_class_behavior.java.sts +++ b/migrator/test/java/enum_with_class_behavior.java.sts @@ -19,22 +19,22 @@ interface IOperation { } open class ArithmeticOperation extends Enum implements IOperation { - public static const PLUS : ArithmeticOperation = new ArithmeticOperation { + public static const PLUS : ArithmeticOperation = new ArithmeticOperation("PLUS", 0) { public override apply(a : int, b : int): int { return a + b; } }; - public static const MINUS : ArithmeticOperation = new ArithmeticOperation { + public static const MINUS : ArithmeticOperation = new ArithmeticOperation("MINUS", 1) { public override apply(a : int, b : int): int { return a - b; } }; - public static const MULTIPLY : ArithmeticOperation = new ArithmeticOperation { + public static const MULTIPLY : ArithmeticOperation = new ArithmeticOperation("MULTIPLY", 2) { public override apply(a : int, b : int): int { return a * b; } }; - public static const DIVIDE : ArithmeticOperation = new ArithmeticOperation { + public static const DIVIDE : ArithmeticOperation = new ArithmeticOperation("DIVIDE", 3) { public override apply(a : int, b : int): int { return a / b; } @@ -48,16 +48,19 @@ open class ArithmeticOperation extends Enum implements IOpe } return null; } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } class Planet extends Enum { - public static const MERCURY : Planet = new Planet(3.303e+23, 2.4397e6); - public static const VENUS : Planet = new Planet(4.869e+24, 6.0518e6); - public static const EARTH : Planet = new Planet(5.976e+24, 6.37814e6); - public static const MARS : Planet = new Planet(6.421e+23, 3.3972e6); - public static const JUPITER : Planet = new Planet(1.9e+27, 7.1492e7); - public static const SATURN : Planet = new Planet(5.688e+26, 6.0268e7); - public static const URANUS : Planet = new Planet(8.686e+25, 2.5559e7); - public static const NEPTUNE : Planet = new Planet(1.024e+26, 2.4746e7); + public static const MERCURY : Planet = new Planet("MERCURY", 0, 3.303e+23, 2.4397e6); + public static const VENUS : Planet = new Planet("VENUS", 1, 4.869e+24, 6.0518e6); + public static const EARTH : Planet = new Planet("EARTH", 2, 5.976e+24, 6.37814e6); + public static const MARS : Planet = new Planet("MARS", 3, 6.421e+23, 3.3972e6); + public static const JUPITER : Planet = new Planet("JUPITER", 4, 1.9e+27, 7.1492e7); + public static const SATURN : Planet = new Planet("SATURN", 5, 5.688e+26, 6.0268e7); + public static const URANUS : Planet = new Planet("URANUS", 6, 8.686e+25, 2.5559e7); + public static const NEPTUNE : Planet = new Planet("NEPTUNE", 7, 1.024e+26, 2.4746e7); private mass : double ; private radius : double ; diff --git a/migrator/test/java/test_enum.java.sts b/migrator/test/java/test_enum.java.sts index e0893fd67..5f835b040 100644 --- a/migrator/test/java/test_enum.java.sts +++ b/migrator/test/java/test_enum.java.sts @@ -24,17 +24,20 @@ export class test_enum extends Enum { } return null; } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } class Planet extends Enum { - public static const MERCURY : Planet = new Planet; - public static const VENUS : Planet = new Planet; - public static const EARTH : Planet = new Planet; - public static const MARS : Planet = new Planet; - public static const JUPITER : Planet = new Planet; - public static const SATURN : Planet = new Planet; - public static const URANUS : Planet = new Planet; - public static const NEPTUNE : Planet = new Planet; + public static const MERCURY : Planet = new Planet("MERCURY", 0); + public static const VENUS : Planet = new Planet("VENUS", 1); + public static const EARTH : Planet = new Planet("EARTH", 2); + public static const MARS : Planet = new Planet("MARS", 3); + public static const JUPITER : Planet = new Planet("JUPITER", 4); + public static const SATURN : Planet = new Planet("SATURN", 5); + public static const URANUS : Planet = new Planet("URANUS", 6); + public static const NEPTUNE : Planet = new Planet("NEPTUNE", 7); public static values(): Planet[] { return [MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE]; @@ -45,12 +48,15 @@ class Planet extends Enum { } return null; } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } open class NestedEnums { private static class Colors extends Enum { - public static const RED : Colors = new Colors; - public static const GREEN : Colors = new Colors; - public static const BLUE : Colors = new Colors; + public static const RED : Colors = new Colors("RED", 0); + public static const GREEN : Colors = new Colors("GREEN", 1); + public static const BLUE : Colors = new Colors("BLUE", 2); public static values(): Colors[] { return [RED, GREEN, BLUE]; @@ -61,11 +67,14 @@ open class NestedEnums { } return null; } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } protected static class Size extends Enum { - public static const SMALL : Size = new Size; - public static const MEDIUM : Size = new Size; - public static const LARGE : Size = new Size; + public static const SMALL : Size = new Size("SMALL", 0); + public static const MEDIUM : Size = new Size("MEDIUM", 1); + public static const LARGE : Size = new Size("LARGE", 2); public static values(): Size[] { return [SMALL, MEDIUM, LARGE]; @@ -76,12 +85,15 @@ open class NestedEnums { } return null; } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } public static class Direction extends Enum { - public static const NORTH : Direction = new Direction; - public static const EAST : Direction = new Direction; - public static const SOUTH : Direction = new Direction; - public static const WEST : Direction = new Direction; + public static const NORTH : Direction = new Direction("NORTH", 0); + public static const EAST : Direction = new Direction("EAST", 1); + public static const SOUTH : Direction = new Direction("SOUTH", 2); + public static const WEST : Direction = new Direction("WEST", 3); public static values(): Direction[] { return [NORTH, EAST, SOUTH, WEST]; @@ -92,12 +104,15 @@ open class NestedEnums { } return null; } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } static class Operator extends Enum { - public static const PLUS : Operator = new Operator; - public static const MINUS : Operator = new Operator; - public static const MULTIPLY : Operator = new Operator; - public static const DIVIDE : Operator = new Operator; + public static const PLUS : Operator = new Operator("PLUS", 0); + public static const MINUS : Operator = new Operator("MINUS", 1); + public static const MULTIPLY : Operator = new Operator("MULTIPLY", 2); + public static const DIVIDE : Operator = new Operator("DIVIDE", 3); public static values(): Operator[] { return [PLUS, MINUS, MULTIPLY, DIVIDE]; @@ -108,6 +123,9 @@ open class NestedEnums { } return null; } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } } -- Gitee From 9b8576a4888fd1c5d18476a295c015ab1d1cc9c0 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Mon, 8 Aug 2022 17:14:09 +0300 Subject: [PATCH 13/60] Process explicit enum ctors. Also a to translation of instance initializers, namely creating default ctor if there are no explicit ctors, just an instance initializer (one or many). Updates to tests to cover all of the changes above. Change-Id: Id1db76398321c56e8ac2da5742fdcd5a2676ff29 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 125 ++++++++++++------ .../ohos/migrator/staticTS/NodeBuilder.java | 30 +++++ .../test/java/class_instance_initializer.java | 9 +- .../java/class_instance_initializer.java.sts | 7 + .../test/java/enum_with_class_behavior.java | 33 ++++- .../java/enum_with_class_behavior.java.sts | 41 +++++- 6 files changed, 194 insertions(+), 51 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 3da2f2adf..37113a63a 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -507,20 +507,41 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return stsMemberContext; } - private void addInstanceInitializersToCtors(TypeDeclaration javaTypeDeclaration) { + private void addInstanceInitializersToCtors(AbstractTypeDeclaration javaTypeDeclaration) { // Put statements from instance initializers into constructors which don't call // another constructor (i.e. don't have 'this()' call). - List stsInitStmts = (List) javaTypeDeclaration.getProperty(INSTANCE_INITIALIZER); + List stsInitStmts = (List)javaTypeDeclaration.getProperty(INSTANCE_INITIALIZER); if (stsCurrent instanceof ClassBodyContext && stsInitStmts != null && !stsInitStmts.isEmpty()) { ClassBodyContext stsClassBody = (ClassBodyContext) stsCurrent; + boolean needDefaultCtor = true; for (ClassMemberContext stsMember : stsClassBody.classMember()) { - addInstanceInitializersToCtor(stsMember.constructorDeclaration(), stsInitStmts); + ConstructorDeclarationContext stsCtorDecl = stsMember.constructorDeclaration(); + if (stsCtorDecl != null) { + addInstanceInitializersToCtor(stsCtorDecl, stsInitStmts); + needDefaultCtor = false; + } + } + + if (needDefaultCtor) { + // Create default ctor and add initializer statements to it + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PUBLIC)).setParent(stsCurrent); + + ConstructorDeclarationContext stsDefaultCtor = new ConstructorDeclarationContext(stsCurrent, 0); + pushCurrent(stsDefaultCtor); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Constructor)); + stsCurrent.addChild(new ConstructorBodyContext(stsCurrent, 0)).setParent(stsCurrent); + + popCurrent(); // stsDefaultCtor + popCurrent(); // ClassMemberContext + + addInstanceInitializersToCtor(stsDefaultCtor, stsInitStmts); } } } - - private void addInstanceInitializersToCtor(ConstructorDeclarationContext stsCtorDecl, List stsInitStmts) { + private void addInstanceInitializersToCtor(ConstructorDeclarationContext stsCtorDecl, List stsInitStmts) { // Sanity check. if (stsCtorDecl == null) return; @@ -1542,9 +1563,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { MethodDeclaration javaEnumMethodDecl = (MethodDeclaration) javaEnumBodyDecl; hasCtors = javaEnumMethodDecl.isConstructor(); } - else { - hasCtors = javaEnumBodyDecl.getNodeType() == ASTNode.INITIALIZER; - } } } @@ -1560,10 +1578,23 @@ public class JavaTransformer extends ASTVisitor implements Transformer { createEnumDefaultCtor(); } else { - // TODO: For all non-default ctors - if there is no call to another ctor in the body, + // For all non-default ctors - if there is no call to another ctor in the body, // generate super(name, ordinal) call, otherwise pass name and ordinal to existing ctor call. + ClassBodyContext stsEnumClassBody = (ClassBodyContext)stsCurrent; + for (ClassMemberContext stsEnumClassMember : stsEnumClassBody.classMember()) { + ConstructorDeclarationContext stsEnumCtor = stsEnumClassMember.constructorDeclaration(); + if (stsEnumCtor != null) { + modifyEnumCtor(stsEnumCtor); + } + } } + // Process instance initializers, if any. + // NOTE: This has to happen here, after default ctor is generated if necessary, + // (see above), as default ctor of enum class is different from the one that + // addInstanceInitializersToCtors can create. + addInstanceInitializersToCtors(javaEnumDeclaration); + popCurrent(); // ClassBodyContext popCurrent(); // stsClassDecl popCurrent(); // member context @@ -1571,38 +1602,62 @@ public class JavaTransformer extends ASTVisitor implements Transformer { ++countDeclTransformed; return false; } - private void createEnumDefaultCtor() { pushCurrent(new ClassMemberContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PRIVATE)).setParent(stsCurrent); pushCurrent(new ConstructorDeclarationContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Constructor)); pushCurrent(new ParameterListContext(stsCurrent, 0)); - pushCurrent(new ParameterContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalIdentifier("name")); - stsCurrent.addChild(NodeBuilder.typeAnnotation("String")).setParent(stsCurrent); - popCurrent(); // ParameterContext - pushCurrent(new ParameterContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalIdentifier("ordinal")); - PredefinedTypeContext stsPredefType = NodeBuilder.predefinedType(PrimitiveType.INT); - stsCurrent.addChild(NodeBuilder.typeAnnotation(stsPredefType)).setParent(stsCurrent); - popCurrent(); // ParameterContext + stsCurrent.addChild(NodeBuilder.parameter("name", "String")).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.parameter("ordinal", PrimitiveType.INT)).setParent(stsCurrent); popCurrent(); // ParameterListContext pushCurrent(new ConstructorBodyContext(stsCurrent, 0)); - pushCurrent(new ConstructorCallContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Super)); - pushCurrent(new ArgumentsContext(stsCurrent, 0)); - pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.identifierExpression("name")).setParent(stsCurrent); - stsCurrent.addChild(NodeBuilder.identifierExpression("ordinal")).setParent(stsCurrent); - popCurrent(); // ExpressionSequenceContext - popCurrent(); // ArgumentsContext - popCurrent(); // ConstructorCallContext + stsCurrent.addChild(NodeBuilder.ctorCall(true, "name", "ordinal")).setParent(stsCurrent); popCurrent(); // ConstructorBodyContext popCurrent(); // ConstructorDeclarationContext popCurrent(); // ClassMemberContext } + private void modifyEnumCtor(ConstructorDeclarationContext stsEnumCtor) { + // Get parameter list or create if there isn't one + ParameterListContext stsEnumCtorParams = stsEnumCtor.parameterList(); + if (stsEnumCtorParams == null) { + stsEnumCtorParams = new ParameterListContext(stsEnumCtor, 0); + stsEnumCtor.addChild(stsEnumCtorParams).setParent(stsEnumCtor); + } + + // Inject name and ordinal parameters + ParameterContext stsEnumCtorParam = NodeBuilder.parameter("name", "String"); + stsEnumCtorParams.children.add(0, stsEnumCtorParam); + stsEnumCtorParam.setParent(stsEnumCtorParams); + stsEnumCtorParam = NodeBuilder.parameter("ordinal", PrimitiveType.INT); + stsEnumCtorParams.children.add(1, stsEnumCtorParam); + stsEnumCtorParam.setParent(stsEnumCtorParams); + + ConstructorBodyContext stsEnumCtorBody = stsEnumCtor.constructorBody(); + ConstructorCallContext stsEnumCtorCall = stsEnumCtorBody.getRuleContext(ConstructorCallContext.class, 0); + if (stsEnumCtorCall == null) { + // Create super(name, ordinal) call + stsEnumCtorBody.addChild(NodeBuilder.ctorCall(true, "name", "ordinal")).setParent(stsEnumCtorBody); + } + else { + // Pass name and ordinal parameters to ctor call + ArgumentsContext stsEnumCtorCallArgs = stsEnumCtorCall.arguments(); + ExpressionSequenceContext stsExprSeq = stsEnumCtorCallArgs.expressionSequence(); + if (stsExprSeq == null) { + // Create expression sequence node, if necessary + stsExprSeq = new ExpressionSequenceContext(stsEnumCtorCallArgs, 0); + stsEnumCtorCallArgs.addChild(stsExprSeq).setParent(stsEnumCtorCallArgs); + } + + SingleExpressionContext stsEnumCtorCallArg = NodeBuilder.identifierExpression("name"); + stsExprSeq.children.add(0, stsEnumCtorCallArg); + stsEnumCtorCallArg.setParent(stsExprSeq); + stsEnumCtorCallArg = NodeBuilder.identifierExpression("ordinal"); + stsExprSeq.children.add(1, stsEnumCtorCallArg); + stsEnumCtorCallArg.setParent(stsExprSeq); + } + } private void createEnumExtendsClause(String javaEnumName) { // Note: A Java enum extends Enum class. pushCurrent(new ClassExtendsClauseContext(stsCurrent, 0)); @@ -1621,7 +1676,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeReferenceContext popCurrent(); // ClassExtendsClauseContext } - private void pushEnumBuiltinMethod() { // Create class member context and add public modifier pushCurrent(new ClassMemberContext(stsCurrent, 0)); @@ -1632,7 +1686,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ClassMethodWithBodyContext((ClassMethodDeclarationContext)stsCurrent)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); } - private void popEnumBuiltinMethod() { popCurrent(); // ClassMethodWithBodyContext popCurrent(); // ClassMethodDeclarationContext @@ -1685,10 +1738,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalIdentifier("valueOf")); pushCurrent(new SignatureContext(stsCurrent, 0)); pushCurrent(new ParameterListContext(stsCurrent, 0)); - pushCurrent(new ParameterContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalIdentifier("name")); - stsCurrent.addChild(NodeBuilder.typeAnnotation("String")).setParent(stsCurrent); - popCurrent(); // ParameterContext + stsCurrent.addChild(NodeBuilder.parameter("name", "String")).setParent(stsCurrent); popCurrent(); // ParameterListContext stsCurrent.addChild(NodeBuilder.typeAnnotation(javaEnumTypeName)).setParent(stsCurrent); popCurrent(); // SignatureContext @@ -2044,13 +2094,12 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // StaticTS doesn't have syntax for separate instance initializer blocks. // We gather all statements from such blocks in class declaration and place // at the beginning of all constructor's bodies that don't call another constructor. - - TypeDeclaration javaTypeDecl = (TypeDeclaration) javaInitializer.getParent(); - List stsInitStmts = (List) javaTypeDecl.getProperty(INSTANCE_INITIALIZER); + ASTNode javaInitParent = javaInitializer.getParent(); + List stsInitStmts = (List) javaInitParent.getProperty(INSTANCE_INITIALIZER); if (stsInitStmts == null) { stsInitStmts = new ArrayList<>(); - javaTypeDecl.setProperty(INSTANCE_INITIALIZER, stsInitStmts); + javaInitParent.setProperty(INSTANCE_INITIALIZER, stsInitStmts); } // Use dummy block here to gather translated statements. Do not diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 0ca2a2b57..1fe86be47 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -383,4 +383,34 @@ public class NodeBuilder { stsTypeAnno.addChild(stsPrimaryType).setParent(stsTypeAnno); return stsTypeAnno; } + + public static ParameterContext parameter(String stsParamName, String stsParamType) { + ParameterContext stsParam = new ParameterContext(null, 0); + stsParam.addChild(terminalIdentifier(stsParamName)); + stsParam.addChild(typeAnnotation(stsParamType)).setParent(stsParam); + return stsParam; + } + + public static ParameterContext parameter(String stsParamName, PrimitiveType.Code javaPrimitiveTypeCode) { + ParameterContext stsParam = new ParameterContext(null, 0); + stsParam.addChild(terminalIdentifier(stsParamName)); + stsParam.addChild(typeAnnotation(predefinedType(javaPrimitiveTypeCode))).setParent(stsParam); + return stsParam; + } + + public static ConstructorCallContext ctorCall(boolean isSuperCall, String... stsArgNames) { + ConstructorCallContext stsSuperCtorCall = new ConstructorCallContext(null, 0); + stsSuperCtorCall.addChild(terminalNode(isSuperCall ? StaticTSParser.Super : StaticTSParser.This)); + + ArgumentsContext stsSuperCtorCallArgs = new ArgumentsContext(stsSuperCtorCall, 0); + stsSuperCtorCall.addChild(stsSuperCtorCallArgs).setParent(stsSuperCtorCall); + ExpressionSequenceContext stsExprSeq = new ExpressionSequenceContext(stsSuperCtorCallArgs, 0); + stsSuperCtorCallArgs.addChild(stsExprSeq).setParent(stsSuperCtorCallArgs); + + for (String stsArgName : stsArgNames) { + stsExprSeq.addChild(identifierExpression(stsArgName)).setParent(stsExprSeq); + } + + return stsSuperCtorCall; + } } diff --git a/migrator/test/java/class_instance_initializer.java b/migrator/test/java/class_instance_initializer.java index 1279d786e..959ad31af 100644 --- a/migrator/test/java/class_instance_initializer.java +++ b/migrator/test/java/class_instance_initializer.java @@ -76,4 +76,11 @@ class B extends A { c = 500; d = 600; } -} \ No newline at end of file +} + +// instance initializer without ctors +class C { + String foo; + + { foo = "bar"; } +} diff --git a/migrator/test/java/class_instance_initializer.java.sts b/migrator/test/java/class_instance_initializer.java.sts index 298d22cea..c77a40cc6 100644 --- a/migrator/test/java/class_instance_initializer.java.sts +++ b/migrator/test/java/class_instance_initializer.java.sts @@ -65,3 +65,10 @@ open class B extends A { } +open class C { + foo : String ; + + public constructor() { + foo = "bar"; + } +} diff --git a/migrator/test/java/enum_with_class_behavior.java b/migrator/test/java/enum_with_class_behavior.java index a2524adc9..2331696ad 100644 --- a/migrator/test/java/enum_with_class_behavior.java +++ b/migrator/test/java/enum_with_class_behavior.java @@ -36,7 +36,13 @@ enum ArithmeticOperation implements IOperation { DIVIDE { @Override public int apply(int a, int b) { return a / b; } - } + }; + + // tests enum instance initializer translation + // super(name, ordinal) call should be inserted + // into resulting ctor! + private String foo; + { foo = "bar"; } } // Enum declaration with type members (ctor, methods, etc). @@ -46,17 +52,30 @@ enum Planet { VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6), - JUPITER (1.9e+27, 7.1492e7), - SATURN (5.688e+26, 6.0268e7), - URANUS (8.686e+25, 2.5559e7), - NEPTUNE (1.024e+26, 2.4746e7); + JUPITER (1.9e+27, 7.1492e7, PlanetType.GAS), + SATURN (5.688e+26, 6.0268e7, PlanetType.GAS), + URANUS (8.686e+25, 2.5559e7, PlanetType.ICE), + NEPTUNE (1.024e+26, 2.4746e7, PlanetType.ICE); + + enum PlanetType { + ROCK, + GAS, + ICE + } private final double mass; // in kilograms private final double radius; // in meters + private final PlanetType type; - Planet(double mass, double radius) { + Planet(double mass, double radius, PlanetType type) { this.mass = mass; this.radius = radius; + this.type = type; + } + + Planet(double mass, double radius) { + // No super(name, ordinal) call in translation here! + this(mass, radius, PlanetType.ROCK); } // universal gravitational constant (m3 kg-1 s-2) @@ -69,4 +88,4 @@ enum Planet { double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } -} \ No newline at end of file +} diff --git a/migrator/test/java/enum_with_class_behavior.java.sts b/migrator/test/java/enum_with_class_behavior.java.sts index c90e6c465..6fab978ac 100644 --- a/migrator/test/java/enum_with_class_behavior.java.sts +++ b/migrator/test/java/enum_with_class_behavior.java.sts @@ -39,6 +39,9 @@ open class ArithmeticOperation extends Enum implements IOpe return a / b; } }; + + private foo : String ; + public static values(): ArithmeticOperation[] { return [PLUS, MINUS, MULTIPLY, DIVIDE]; } @@ -48,8 +51,10 @@ open class ArithmeticOperation extends Enum implements IOpe } return null; } + private constructor(name : String, ordinal : int) { super(name, ordinal); + foo = "bar"; } } class Planet extends Enum { @@ -57,17 +62,43 @@ class Planet extends Enum { public static const VENUS : Planet = new Planet("VENUS", 1, 4.869e+24, 6.0518e6); public static const EARTH : Planet = new Planet("EARTH", 2, 5.976e+24, 6.37814e6); public static const MARS : Planet = new Planet("MARS", 3, 6.421e+23, 3.3972e6); - public static const JUPITER : Planet = new Planet("JUPITER", 4, 1.9e+27, 7.1492e7); - public static const SATURN : Planet = new Planet("SATURN", 5, 5.688e+26, 6.0268e7); - public static const URANUS : Planet = new Planet("URANUS", 6, 8.686e+25, 2.5559e7); - public static const NEPTUNE : Planet = new Planet("NEPTUNE", 7, 1.024e+26, 2.4746e7); + public static const JUPITER : Planet = new Planet("JUPITER", 4, 1.9e+27, 7.1492e7, PlanetType.GAS); + public static const SATURN : Planet = new Planet("SATURN", 5, 5.688e+26, 6.0268e7, PlanetType.GAS); + public static const URANUS : Planet = new Planet("URANUS", 6, 8.686e+25, 2.5559e7, PlanetType.ICE); + public static const NEPTUNE : Planet = new Planet("NEPTUNE", 7, 1.024e+26, 2.4746e7, PlanetType.ICE); + + static class PlanetType extends Enum { + public static const ROCK : PlanetType = new PlanetType("ROCK", 0); + public static const GAS : PlanetType = new PlanetType("GAS", 1); + public static const ICE : PlanetType = new PlanetType("ICE", 2); + + public static values(): PlanetType[] { + return [ROCK, GAS, ICE]; + } + public static valueOf(name : String): PlanetType { + for (let value : PlanetType of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + } private mass : double ; private radius : double ; + private type : PlanetType ; - constructor(mass : double, radius : double) { + constructor(name : String, ordinal : int, mass : double, radius : double, type : PlanetType) { + super(name, ordinal); this.mass = mass; this.radius = radius; + this.type = type; + } + + constructor(name : String, ordinal : int, mass : double, radius : double) { + this(name, ordinal, mass, radius, PlanetType.ROCK); } public static const G : double = 6.67300E-11; -- Gitee From 582d4ef5c2b8c44156e6f0db74374ec659f793a3 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 10 Aug 2022 17:39:52 +0300 Subject: [PATCH 14/60] Minor change to the test validating switch statement translation to account for re-implemented enum translation. Change-Id: Ibe389e6fa584eaed12196c2c8f063881f5f541fb Signed-off-by: Mikhail Velikanov --- migrator/test/java/switch_statement.java.sts | 22 ++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/migrator/test/java/switch_statement.java.sts b/migrator/test/java/switch_statement.java.sts index 0e10a1c58..36e61cd3b 100644 --- a/migrator/test/java/switch_statement.java.sts +++ b/migrator/test/java/switch_statement.java.sts @@ -223,11 +223,25 @@ export open class switch_statement { } } - enum Color { - Red, - Green, - Blue + + static class Color extends Enum { + public static const Red : Color = new Color("Red", 0); + public static const Green : Color = new Color("Green", 1); + public static const Blue : Color = new Color("Blue", 2); + public static values(): Color[] { + return [Red, Green, Blue]; + } + public static valueOf(name : String): Color { + for (let value : Color of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } + private static SwitchWithEnumValues(): void { let color : Color = Color.Green; switch (color) { -- Gitee From 65edd46a61c2af0fb7795ded0e602dd458cb7227 Mon Sep 17 00:00:00 2001 From: Artem Udovichenko Date: Mon, 25 Jul 2022 16:11:08 +0300 Subject: [PATCH 15/60] Remove --run-gc-in-place in tests262 Change-Id: I17dcf15df44549244c1a3e385545ed4bf3dacba9 Signed-off-by: Artem Udovichenko --- test/runner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/runner.py b/test/runner.py index c6e542bd7..f31d80116 100755 --- a/test/runner.py +++ b/test/runner.py @@ -76,7 +76,7 @@ def get_args(): '--update', action='store_true', dest='update', default=False, help='update skiplist') parser.add_argument( - '--no-run-gc-in-place', action='store_true', dest='no_gip', default=False, + '--run-gc-in-place', action='store_true', dest='run_gc_in_place', default=False, help='enable --run-gc-in-place mode') parser.add_argument( '--filter', '-f', action='store', dest='filter', @@ -487,7 +487,7 @@ class Test262Runner(Runner): '--gc-type=%s' % args.gc_type, ] - if not args.no_gip: + if args.run_gc_in_place: self.runtime_args += ['--run-gc-in-place'] if args.aot: @@ -502,7 +502,7 @@ class Test262Runner(Runner): '--gc-type=%s' % args.gc_type, ] - if not args.no_gip: + if args.run_gc_in_place: self.aot_args += ['--run-gc-in-place'] self.aot_args += args.aot_args -- Gitee From 0452da4b02929c0be980cd37937259e770e2fa4b Mon Sep 17 00:00:00 2001 From: Artem Udovichenko Date: Tue, 9 Aug 2022 12:06:46 +0300 Subject: [PATCH 16/60] Disable tracking reclaimed objects for G1 while runing test262 --- test/runner.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/runner.py b/test/runner.py index f31d80116..c0e04a08c 100755 --- a/test/runner.py +++ b/test/runner.py @@ -489,6 +489,10 @@ class Test262Runner(Runner): if args.run_gc_in_place: self.runtime_args += ['--run-gc-in-place'] + if args.gc_type == "g1-gc": + # Workaround. If don't specify this option G1 may access a deleted class while + # iterating over all objects in a region. + self.runtime_args += ['--g1-track-freed-objects=false'] if args.aot: self.arkaot = path.join(args.build_dir, 'bin', 'ark_aot') -- Gitee From b8f46f88ca4f384be378c34fb8328fd34bafdc7c Mon Sep 17 00:00:00 2001 From: Igor Rossinski Date: Tue, 9 Aug 2022 18:19:13 +0300 Subject: [PATCH 17/60] Translation of 'While' and 'Do-While' statements Signed-off-by: Igor Rossinski --- .../ohos/migrator/java/JavaTransformer.java | 47 ++++++++++++++++++ .../staticTS/writer/StaticTSWriter.java | 4 +- migrator/test/java/do_statement.java | 47 ++++++++++++++++++ migrator/test/java/do_statement.java.sts | 49 +++++++++++++++++++ migrator/test/java/empty_statement.java.sts | 8 +++ migrator/test/java/while_statement.java | 46 +++++++++++++++++ migrator/test/java/while_statement.java.sts | 44 +++++++++++++++++ 7 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 migrator/test/java/do_statement.java create mode 100644 migrator/test/java/do_statement.java.sts create mode 100644 migrator/test/java/while_statement.java create mode 100644 migrator/test/java/while_statement.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 37113a63a..178bda085 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -2042,6 +2042,53 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + @Override + public boolean visit(WhileStatement javaWhileStmt) { + IterationStatementContext stsIterStmt = new IterationStatementContext(stsCurrent, 0); + WhileStatementContext stsWhileStmt = new WhileStatementContext(stsIterStmt); + pushStatement(stsIterStmt); + pushCurrent(stsWhileStmt); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.While)); + Expression javaExpr = javaWhileStmt.getExpression(); + assert(javaExpr != null); + javaExpr.accept(this); + + Statement javaLoopBody = javaWhileStmt.getBody(); + assert(javaLoopBody != null); + javaLoopBody.accept(this); + + popCurrent(); + popStatement(); + return false; + } + + + @Override + public boolean visit(DoStatement javaDoStmt) { + IterationStatementContext stsIterStmt = new IterationStatementContext(stsCurrent, 0); + DoStatementContext stsDoStmt = new DoStatementContext(stsIterStmt); + pushStatement(stsIterStmt); + pushCurrent(stsDoStmt); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Do)); + + Statement javaLoopBody = javaDoStmt.getBody(); + assert(javaLoopBody != null); + javaLoopBody.accept(this); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.While)); + + Expression javaExpr = javaDoStmt.getExpression(); + assert(javaExpr != null); + javaExpr.accept(this); + + popCurrent(); + popStatement(); + return false; + } + + // Java tree: // Initializer: // [ static ] Block diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index d12f99258..1436d4ab3 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -890,11 +890,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { @Override public Void visitDoStatement(DoStatementContext stsDoStatement) { doNeededIndent(); - sb.append(stsDoStatement.Do().getText()); + sb.append(stsDoStatement.Do().getText() + "\n"); + indentIncrement(); StatementContext stsStmt = stsDoStatement.statement(); assert(stsStmt != null); visitStatement(stsStmt); + indentDecrement(); sb.append(indentCurrent).append(stsDoStatement.While().getText()).append('('); diff --git a/migrator/test/java/do_statement.java b/migrator/test/java/do_statement.java new file mode 100644 index 000000000..1e24c4c23 --- /dev/null +++ b/migrator/test/java/do_statement.java @@ -0,0 +1,47 @@ +/* + * 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 WhileStatements { + public static void Test() { + final boolean Flag = true; + int i = 0; + int j = 0; + + do break; while (Flag); + + do { + break; + } while( Flag ); + + do { + i++; + if (i == 2) continue; + if (i == 5) break; + } while ( i < 10 ); + + outerLoop: + do { + + innerLoop: + do { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + while ( j < 5 ); + } while ( i < 5 ); + } +} \ No newline at end of file diff --git a/migrator/test/java/do_statement.java.sts b/migrator/test/java/do_statement.java.sts new file mode 100644 index 000000000..1bf68b3ac --- /dev/null +++ b/migrator/test/java/do_statement.java.sts @@ -0,0 +1,49 @@ +/* + * 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 WhileStatements { + public static Test(): void { + const Flag : boolean = true; + let i : int = 0; + let j : int = 0; + do + break; + while(Flag); + do + { + break; + } + while(Flag); + do + { + i++; + if (i == 2) continue; + if (i == 5) break; + } + while(i < 10); + outerLoop: do + { + innerLoop: do + { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + while(j < 5); + } + while(i < 5); + } +} + diff --git a/migrator/test/java/empty_statement.java.sts b/migrator/test/java/empty_statement.java.sts index efe573a47..66c256492 100644 --- a/migrator/test/java/empty_statement.java.sts +++ b/migrator/test/java/empty_statement.java.sts @@ -19,6 +19,13 @@ open class empty_statement { public open Test(): void { a = 10; let i : int = 0; + while(i < 2) + { + } + do + { + } + while(i > 3); for (; i < 10; ++i) { } for (let s : int = 1; s < 2; ++s) { @@ -36,3 +43,4 @@ open class empty_statement { public open Run(): void { } } + diff --git a/migrator/test/java/while_statement.java b/migrator/test/java/while_statement.java new file mode 100644 index 000000000..a02725b36 --- /dev/null +++ b/migrator/test/java/while_statement.java @@ -0,0 +1,46 @@ +/* + * 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 WhileStatements { + public static void Test() { + final boolean Flag = true; + int i = 0; + int j = 0; + + while (Flag) break; + + while (Flag) { + break; + } + + while ( i< 10 ) { + i++; + if (i == 2) continue; + if (i == 5) break; + } + + outerLoop: + while (i < 5) { + + innerLoop: + while ( j < 5 ) { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + } + } +} \ No newline at end of file diff --git a/migrator/test/java/while_statement.java.sts b/migrator/test/java/while_statement.java.sts new file mode 100644 index 000000000..1e95cf586 --- /dev/null +++ b/migrator/test/java/while_statement.java.sts @@ -0,0 +1,44 @@ +/* + * 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 WhileStatements { + public static Test(): void { + const Flag : boolean = true; + let i : int = 0; + let j : int = 0; + while(Flag) + break; + while(Flag) + { + break; + } + while(i < 10) + { + i++; + if (i == 2) continue; + if (i == 5) break; + } + outerLoop: while(i < 5) + { + innerLoop: while(j < 5) + { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + } + } +} + -- Gitee From 31fda3fd288be980de92acb8111ef1d142bf818e Mon Sep 17 00:00:00 2001 From: Igor Rossinski Date: Thu, 11 Aug 2022 11:57:58 +0300 Subject: [PATCH 18/60] some improvement of 'while' and 'do' statements translation Signed-off-by: Igor Rossinski --- .../ohos/migrator/java/JavaTransformer.java | 17 +++------- .../staticTS/writer/StaticTSWriter.java | 2 -- migrator/test/java/do_statement.java | 4 +-- migrator/test/java/do_statement.java.sts | 32 +++++++++---------- migrator/test/java/empty_statement.java.sts | 4 +-- migrator/test/java/while_statement.java | 4 +-- migrator/test/java/while_statement.java.sts | 2 +- 7 files changed, 27 insertions(+), 38 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 178bda085..95feb5dcb 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -2044,10 +2044,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(WhileStatement javaWhileStmt) { - IterationStatementContext stsIterStmt = new IterationStatementContext(stsCurrent, 0); - WhileStatementContext stsWhileStmt = new WhileStatementContext(stsIterStmt); - pushStatement(stsIterStmt); - pushCurrent(stsWhileStmt); + pushCurrent(new WhileStatementContext(pushIterationStatement())); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.While)); Expression javaExpr = javaWhileStmt.getExpression(); @@ -2058,19 +2055,14 @@ public class JavaTransformer extends ASTVisitor implements Transformer { assert(javaLoopBody != null); javaLoopBody.accept(this); - popCurrent(); - popStatement(); + popIterationStatement(); // WhileStatementContext return false; } @Override public boolean visit(DoStatement javaDoStmt) { - IterationStatementContext stsIterStmt = new IterationStatementContext(stsCurrent, 0); - DoStatementContext stsDoStmt = new DoStatementContext(stsIterStmt); - pushStatement(stsIterStmt); - pushCurrent(stsDoStmt); - + pushCurrent(new DoStatementContext(pushIterationStatement())); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Do)); Statement javaLoopBody = javaDoStmt.getBody(); @@ -2083,8 +2075,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { assert(javaExpr != null); javaExpr.accept(this); - popCurrent(); - popStatement(); + popIterationStatement(); // DoStatementContext 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 1436d4ab3..9c6d3b406 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -892,11 +892,9 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { doNeededIndent(); sb.append(stsDoStatement.Do().getText() + "\n"); - indentIncrement(); StatementContext stsStmt = stsDoStatement.statement(); assert(stsStmt != null); visitStatement(stsStmt); - indentDecrement(); sb.append(indentCurrent).append(stsDoStatement.While().getText()).append('('); diff --git a/migrator/test/java/do_statement.java b/migrator/test/java/do_statement.java index 1e24c4c23..831fe0021 100644 --- a/migrator/test/java/do_statement.java +++ b/migrator/test/java/do_statement.java @@ -15,7 +15,7 @@ package com.ohos.migrator.test.java; -class WhileStatements { +class do_statement { public static void Test() { final boolean Flag = true; int i = 0; @@ -44,4 +44,4 @@ class WhileStatements { while ( j < 5 ); } while ( i < 5 ); } -} \ No newline at end of file +} diff --git a/migrator/test/java/do_statement.java.sts b/migrator/test/java/do_statement.java.sts index 1bf68b3ac..081747e64 100644 --- a/migrator/test/java/do_statement.java.sts +++ b/migrator/test/java/do_statement.java.sts @@ -14,35 +14,35 @@ */ package com.ohos.migrator.test.java; -open class WhileStatements { +open class do_statement { public static Test(): void { const Flag : boolean = true; let i : int = 0; let j : int = 0; do - break; + break; while(Flag); do - { - break; - } + { + break; + } while(Flag); do - { - i++; - if (i == 2) continue; - if (i == 5) break; - } + { + i++; + if (i == 2) continue; + if (i == 5) break; + } while(i < 10); outerLoop: do + { + innerLoop: do { - innerLoop: do - { - if (j == 2) continue innerLoop; - if (i * j == 20) break outerLoop; - } - while(j < 5); + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; } + while(j < 5); + } while(i < 5); } } diff --git a/migrator/test/java/empty_statement.java.sts b/migrator/test/java/empty_statement.java.sts index 66c256492..4423bbee9 100644 --- a/migrator/test/java/empty_statement.java.sts +++ b/migrator/test/java/empty_statement.java.sts @@ -23,8 +23,8 @@ open class empty_statement { { } do - { - } + { + } while(i > 3); for (; i < 10; ++i) { } diff --git a/migrator/test/java/while_statement.java b/migrator/test/java/while_statement.java index a02725b36..3915019cf 100644 --- a/migrator/test/java/while_statement.java +++ b/migrator/test/java/while_statement.java @@ -15,7 +15,7 @@ package com.ohos.migrator.test.java; -class WhileStatements { +class while_statement { public static void Test() { final boolean Flag = true; int i = 0; @@ -43,4 +43,4 @@ class WhileStatements { } } } -} \ No newline at end of file +} diff --git a/migrator/test/java/while_statement.java.sts b/migrator/test/java/while_statement.java.sts index 1e95cf586..aa29799b7 100644 --- a/migrator/test/java/while_statement.java.sts +++ b/migrator/test/java/while_statement.java.sts @@ -14,7 +14,7 @@ */ package com.ohos.migrator.test.java; -open class WhileStatements { +open class while_statement { public static Test(): void { const Flag : boolean = true; let i : int = 0; -- Gitee From 1ab903c19bf73346d672d208a858ce86dbb583de Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Thu, 11 Aug 2022 14:27:38 +0300 Subject: [PATCH 19/60] By default, don't terminate translation on Java syntax or semantic errors, simply report them. Also don't check syntax of resulting STS code by default. Do both of the above if in strict mode (-s or -strict command line switch). Do STS syntax check after translation if explcitly requested (-T or -check-sts-syntax command line switch). Also extended metrics computation to cover translation of types. Change-Id: I9991f07ef6830c2615876576614627c69ca45034 Signed-off-by: Mikhail Velikanov --- .../com/ohos/migrator/AbstractTranspiler.java | 11 ++---- migrator/src/com/ohos/migrator/Main.java | 14 +++++--- .../src/com/ohos/migrator/TestRunner.java | 2 +- .../com/ohos/migrator/java/JavaParser.java | 27 ++++++++++++--- .../migrator/java/JavaParserException.java | 8 ++--- .../ohos/migrator/java/JavaTransformer.java | 34 +++++++++++++++++-- 6 files changed, 69 insertions(+), 27 deletions(-) diff --git a/migrator/src/com/ohos/migrator/AbstractTranspiler.java b/migrator/src/com/ohos/migrator/AbstractTranspiler.java index f727ac86d..196df0c8a 100644 --- a/migrator/src/com/ohos/migrator/AbstractTranspiler.java +++ b/migrator/src/com/ohos/migrator/AbstractTranspiler.java @@ -36,14 +36,7 @@ public abstract class AbstractTranspiler implements Transpiler { protected List libFiles; protected List outFiles; protected List errorList; - private String outDir = null; - - protected boolean strictMode = false; - public void setStrictMode(boolean mode) { - strictMode = mode; - } - public AbstractTranspiler(List src, List libs, String outDir) { sourceFiles = src; libFiles = libs; @@ -67,7 +60,7 @@ public abstract class AbstractTranspiler implements Transpiler { } catch (TranspileException e) { errorList.add(e); transpileResult = ResultCode.majorValue(e.getResult(), transpileResult); - if (strictMode) return transpileResult; + if (Main.isStrictMode()) return transpileResult; } catch (Exception e) { StringBuilder sb = new StringBuilder(e.getClass().getName()); @@ -78,7 +71,7 @@ public abstract class AbstractTranspiler implements Transpiler { errorList.add(new TranspileException(ResultCode.InputError, sb.toString())); transpileResult = ResultCode.majorValue(ResultCode.InputError, transpileResult); - if (strictMode) return transpileResult; + if (Main.isStrictMode()) return transpileResult; } } diff --git a/migrator/src/com/ohos/migrator/Main.java b/migrator/src/com/ohos/migrator/Main.java index 6cad99455..4f8e16954 100644 --- a/migrator/src/com/ohos/migrator/Main.java +++ b/migrator/src/com/ohos/migrator/Main.java @@ -65,6 +65,9 @@ public class Main { public static boolean hasErrors() { return !errorList.isEmpty(); } + public static void addError(ResultCode code, String message) { + errorList.add(new TranspileException(code, message)); + } public static void main(String[] args) { final Options options = new Options(); @@ -74,7 +77,7 @@ public class Main { options.addOption(new Option("o","outdir",true,"Specify where to place generated source files")); options.addOption(new Option("nowarn","nowarn",false,"Generate no warnings")); options.addOption(new Option("Werror","Werror",false,"Treate warnings as errors")); - options.addOption(new Option("strict","strict",false,"Terminate transpile process after first error occurs")); + options.addOption(new Option("s","strict",false,"Terminate transpile process after first error occurs")); options.addOption(new Option("l","libs",true, "List of libraries separate with commas")); options.addOption(new Option("T","check-sts-syntax",false,"Check syntactical correctness of StaticTS sources")); options.addOption(new Option("R", "conversion-rate", false, "Report conversion rate")); @@ -145,7 +148,7 @@ public class Main { } } - if (needStsSyntaxCheck) { + if (needStsSyntaxCheck && !stsSources.isEmpty()) { ResultCode code = checkSTSSyntax(stsSources); finish(code); } @@ -184,7 +187,6 @@ public class Main { System.out.println("Transpiling " + javaSources.size() + " Java files."); JavaTranspiler javaTranspiler = new JavaTranspiler(javaSources, jarLibs, outDir); - if(isStrictMode()) javaTranspiler.setStrictMode(true); resultCode = javaTranspiler.transpile(); outFiles.addAll(javaTranspiler.getOutFiles()); errorList.addAll(javaTranspiler.getErrorList()); @@ -214,7 +216,11 @@ public class Main { // Check syntax of all STS files produced. // NOTE: This is for development process only, probably to be removed afterwards. - resultCode = ResultCode.majorValue(checkSTSSyntax(outFiles), resultCode); + // NOTE: We now ignore Java syntax and semantic errors by default, + // so don't check STS syntax by default, either. + if (isStrictMode() || needStsSyntaxCheck) + resultCode = ResultCode.majorValue(checkSTSSyntax(outFiles), resultCode); + finish(resultCode); } catch (UnrecognizedOptionException e) { diff --git a/migrator/src/com/ohos/migrator/TestRunner.java b/migrator/src/com/ohos/migrator/TestRunner.java index 69e59aad6..2d0af0e7d 100644 --- a/migrator/src/com/ohos/migrator/TestRunner.java +++ b/migrator/src/com/ohos/migrator/TestRunner.java @@ -63,7 +63,7 @@ public class TestRunner { String testFilePath = new File(testDir, testFile).getPath(); System.out.println("Running test " + testFile); - String[] mainArgs = new String[] {"-verbose", "-o", testResultDir.getPath(), testFilePath}; + String[] mainArgs = new String[] {"-verbose", "-s", "-o", testResultDir.getPath(), testFilePath}; Main.runTests(mainArgs); File resultFile = new File(testResultDir, testFile + Main.STS_EXT); diff --git a/migrator/src/com/ohos/migrator/java/JavaParser.java b/migrator/src/com/ohos/migrator/java/JavaParser.java index 5ecb4efc2..f2cc113e4 100644 --- a/migrator/src/com/ohos/migrator/java/JavaParser.java +++ b/migrator/src/com/ohos/migrator/java/JavaParser.java @@ -16,6 +16,7 @@ package com.ohos.migrator.java; import com.ohos.migrator.Main; +import com.ohos.migrator.ResultCode; import com.ohos.migrator.util.FileUtils; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.compiler.IProblem; @@ -53,7 +54,7 @@ public class JavaParser { /** * Create a Java parser. * - * @param fileToParse Java source file to be parsed. + * @param sourceFile Java source file to be parsed. * @param sourceFiles List of Java source files whose paths will be used to configure * parser's 'sourcepaths' setting. * @param classpaths List of paths to jar files or directories with '.class' files. @@ -197,12 +198,28 @@ public class JavaParser { CompilationUnit cu = (CompilationUnit) parser.createAST(null); if (cu == null) throw new JavaParserException("unknown Java parsing error"); - // Problems contains both warnings and errors. Don't throw the exception when there are only warnings. - for (IProblem problems : cu.getProblems()) { - if (problems.isError()) - throw new JavaParserException(cu.getProblems()); + // In strict mode, terminate on syntax or semantic errors; + // otherwise, report them and continue. + for (IProblem problem : cu.getProblems()) { + if (problem.isError()) { + if (Main.isStrictMode()) + throw new JavaParserException(cu.getProblems()); + else + Main.addError(ResultCode.ParseError, buildErrorMessage(problem)); + } } return cu; } + + public static String buildErrorMessage(IProblem problem) { + StringBuilder sb = new StringBuilder(); + int lineNumber = problem.getSourceLineNumber(); + String fileName = String.valueOf(problem.getOriginatingFileName()); + + String pos = fileName + "(" + lineNumber + "): "; + sb.append(pos).append(problem.getMessage()); + + return sb.toString(); + } } diff --git a/migrator/src/com/ohos/migrator/java/JavaParserException.java b/migrator/src/com/ohos/migrator/java/JavaParserException.java index e0411fb27..8dad5a2bc 100644 --- a/migrator/src/com/ohos/migrator/java/JavaParserException.java +++ b/migrator/src/com/ohos/migrator/java/JavaParserException.java @@ -18,20 +18,18 @@ package com.ohos.migrator.java; import org.eclipse.jdt.core.compiler.IProblem; public class JavaParserException extends Exception { - private static String buildErrorMessage(IProblem[] parseProblems) { StringBuilder sb = new StringBuilder(); for (IProblem problem: parseProblems) { - String pos = new String(problem.getOriginatingFileName()) + "(" + problem.getSourceLineNumber() + "): "; - sb.append(pos + problem.getMessage()).append('\n'); + if (problem.isError()) + sb.append(JavaParser.buildErrorMessage(problem)).append("\n"); } + return sb.toString(); } - public JavaParserException(IProblem[] parseProblems) { this(buildErrorMessage(parseProblems)); } - public JavaParserException(String s) { super(s); } diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 95feb5dcb..dcb833e3b 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -49,14 +49,16 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; + private static int countStmtTotal = 0; 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 countDeclTransformed = 0; + private static int countTypeTransformed = 0; + public static double getTransformationRate() { double result = 0.; int normFactor = 0; @@ -73,6 +75,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { ++normFactor; result += countDeclTransformed / (double)countDeclTotal; } + if (countTypeTotal > 0) { + ++normFactor; + result += countTypeTransformed / (double)countTypeTotal; + } return (normFactor > 0) ? result / (double)normFactor : 0.; } @@ -159,8 +165,13 @@ public class JavaTransformer extends ASTVisitor implements Transformer { else if (node instanceof Statement) ++countStmtTotal; else if (node instanceof BodyDeclaration - || node instanceof VariableDeclaration) + || 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; } }); @@ -204,6 +215,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // PackageDeclarationContext + ++countDeclTransformed; return false; } @@ -672,6 +684,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ImportStatementContext + ++countDeclTransformed; return false; } @@ -716,6 +729,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext + ++countTypeTransformed; return false; } @@ -736,6 +750,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext + ++countTypeTransformed; return false; } @@ -771,6 +786,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsTypeRef.addChild(stsTypeRefPart).setParent(stsTypeRef); if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -794,6 +811,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext + ++countTypeTransformed; return false; } @@ -840,6 +858,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -860,6 +880,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // WildcardTypeContext + + ++countTypeTransformed; return false; } @@ -880,6 +902,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ArrayTypeContext if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -904,6 +928,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // IntersectionTypeContext if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -2478,6 +2504,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // ClassBodyContext + + ++countDeclTransformed; return false; } -- Gitee From f75a66499c2cd55d33e1d3a6a3178ba81db98067 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Thu, 11 Aug 2022 15:26:42 +0300 Subject: [PATCH 20/60] Minor fix to translation of type parameters to avoid ClassCastException. Change-Id: I30b3e01b8b58a6eaa5b6dc003ab67d94481ac62f Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index dcb833e3b..bb8cdf678 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -270,7 +270,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if ((javaModifiers & Modifier.STATIC) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); if ((javaModifiers & Modifier.NATIVE) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Native)); } - + // Java tree: // TypeDeclaration: // A type declaration is the union of a class declaration and an interface declaration. // ClassDeclaration @@ -1270,8 +1270,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // typeParameterList: typeParameter (Comma typeParameter)* pushCurrent(new TypeParameterListContext(stsCurrent, 0)); - for (TypeParameter javaTypeParameter : javaTypeParameters) { - javaTypeParameter.accept(this); + for (TypeParameter javaTypeParam : javaTypeParameters) { + javaTypeParam.accept(this); // Note: TerminalToken (Comma) is not added to the tree. Check if it works OK. } -- Gitee From b0a1abec169cd615ba9123bc190f07832f6d6896 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Thu, 11 Aug 2022 15:50:48 +0300 Subject: [PATCH 21/60] Minor fix to translation of method declaration modifiers. Also updates to tests to account for the changes above. Change-Id: I88cf3c6e2445d1f2527f7bb8e7b984cb0ef62cfe Signed-off-by: Mikhail Velikanov --- .../src/com/ohos/migrator/java/JavaTransformer.java | 11 ++++++----- migrator/test/java/intersection-type.java.sts | 4 ++-- migrator/test/java/method_invocation.java.sts | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index bb8cdf678..cea6c4b77 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -233,9 +233,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private boolean doesOverride(ITypeBinding javaClassBinding, IMethodBinding javaCheckedMethod) { if (javaClassBinding != null) { - for (IMethodBinding javaMethod : javaClassBinding.getDeclaredMethods()) { - if (javaCheckedMethod.overrides(javaMethod)) - return true; + if (!javaClassBinding.isEqualTo(javaCheckedMethod.getDeclaringClass())) { + for (IMethodBinding javaMethod : javaClassBinding.getDeclaredMethods()) { + if (javaCheckedMethod.overrides(javaMethod)) + return true; + } } for (ITypeBinding javaInterface : javaClassBinding.getInterfaces()) { @@ -260,8 +262,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { else if ((javaModifiers & Modifier.FINAL) == 0) { // If the input (java) method is not final then output (STS) method has to be either Open or Override IMethodBinding javaMethodBinding = javaMethodDeclaration.resolveBinding(); - IMethodBinding javaDeclarationBinding = javaMethodBinding.getMethodDeclaration(); - if (doesOverride(javaDeclarationBinding.getDeclaringClass().getSuperclass(), javaDeclarationBinding)) + if (javaMethodBinding != null && doesOverride(javaMethodBinding.getDeclaringClass(), javaMethodBinding)) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Override)); else if ((javaModifiers & Modifier.STATIC) == 0 && (javaModifiers & Modifier.PRIVATE) == 0 && isInClassContext) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Open)); diff --git a/migrator/test/java/intersection-type.java.sts b/migrator/test/java/intersection-type.java.sts index 96a82304a..dea5be549 100755 --- a/migrator/test/java/intersection-type.java.sts +++ b/migrator/test/java/intersection-type.java.sts @@ -25,9 +25,9 @@ open class intersection_type { } open class auxilliary implements Runnable, Something { - public open run(): void { + public override run(): void { } - public open foo(): void { + public override foo(): void { } } diff --git a/migrator/test/java/method_invocation.java.sts b/migrator/test/java/method_invocation.java.sts index 681a206d0..b7b1808fb 100644 --- a/migrator/test/java/method_invocation.java.sts +++ b/migrator/test/java/method_invocation.java.sts @@ -25,7 +25,7 @@ open class SubClass1 extends SuperClass { override foo(): void { } tweak : Runnable = new Runnable() { - public open run(): void { + public override run(): void { SubClass1.super.foo(); } }; @@ -38,7 +38,7 @@ interface SuperInterface { } open class SubClass2 implements SuperInterface { - public open foo(): void { + public override foo(): void { } open tweak(): void { SuperInterface.super.foo(); @@ -46,10 +46,10 @@ open class SubClass2 implements SuperInterface { } open class SubClass3 implements SuperInterface { - public open foo(): void { + public override foo(): void { } tweak : Runnable = new Runnable() { - public open run(): void { + public override run(): void { } }; } -- Gitee From 8ac0c35e0ccea3d2c7435464cf63b4e5a21a5fe9 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 12 Aug 2022 14:24:14 +0300 Subject: [PATCH 22/60] Minor fix to two failing tests. Change-Id: Ic26ca91f309e5ae2bc1e28f7fa9dd1442d41c074 Signed-off-by: Mikhail Velikanov --- migrator/test/java/do_statement.java.sts | 12 ++++++------ migrator/test/java/while_statement.java.sts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/migrator/test/java/do_statement.java.sts b/migrator/test/java/do_statement.java.sts index 081747e64..180672704 100644 --- a/migrator/test/java/do_statement.java.sts +++ b/migrator/test/java/do_statement.java.sts @@ -20,26 +20,26 @@ open class do_statement { let i : int = 0; let j : int = 0; do - break; + break; while(Flag); do { - break; + break; } while(Flag); do { i++; - if (i == 2) continue; - if (i == 5) break; + if (i == 2) continue; + if (i == 5) break; } while(i < 10); outerLoop: do { innerLoop: do { - if (j == 2) continue innerLoop; - if (i * j == 20) break outerLoop; + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; } while(j < 5); } diff --git a/migrator/test/java/while_statement.java.sts b/migrator/test/java/while_statement.java.sts index aa29799b7..53b82645a 100644 --- a/migrator/test/java/while_statement.java.sts +++ b/migrator/test/java/while_statement.java.sts @@ -20,23 +20,23 @@ open class while_statement { let i : int = 0; let j : int = 0; while(Flag) - break; + break; while(Flag) { - break; + break; } while(i < 10) { i++; - if (i == 2) continue; - if (i == 5) break; + if (i == 2) continue; + if (i == 5) break; } outerLoop: while(i < 5) { innerLoop: while(j < 5) { - if (j == 2) continue innerLoop; - if (i * j == 20) break outerLoop; + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; } } } -- Gitee From edf65f947675c4c1a44d02c97d322d94842344bb Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 12 Aug 2022 14:36:07 +0300 Subject: [PATCH 23/60] Emit dummy calls for as yet untranslated Java constructs. The original syntax of these constructs is placed inside emitted calls for reference. This is done to avoid emitting invalid STS ASTs that cause exceptions in StaticTSWriter. Change-Id: I1d2b361dbdc3e54f032fa2fb85f649a1b4b9a187 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 178 +++++++++++------- .../ohos/migrator/staticTS/NodeBuilder.java | 30 ++- .../staticTS/writer/StaticTSWriter.java | 17 +- 3 files changed, 151 insertions(+), 74 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index cea6c4b77..d72259fd9 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -2717,46 +2717,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: - // Annotation: - // NormalAnnotation - // MarkerAnnotation - // SingleMemberAnnotation - // SingleMemberAnnotation: - // @ TypeName ( Expression ) - // STS tree: - // TODO: - @Override - public boolean visit(NormalAnnotation javaAnnotation) { - // TODO: - return super.visit(javaAnnotation); - } - - @Override - public boolean visit(MarkerAnnotation javaAnnotation) { - // TODO: - return super.visit(javaAnnotation); - } - - @Override - public boolean visit(SingleMemberAnnotation javaAnnotation) { - // TODO: - return super.visit(javaAnnotation); - } - - // Java tree: - // CreationReference: - // Type :: - // [ < Type { , Type } > ] - // new - // STS tree: - // TODO: - @Override - public boolean visit(CreationReference javaCreationRef) { - // TODO: - return super.visit(javaCreationRef); - } - // Java tree: // FieldAccess: // Expression . Identifier @@ -2826,20 +2786,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: - // LambdaExpression: - // Identifier -> Body - // ( [ Identifier { , Identifier } ] ) -> Body - // ( [ FormalParameter { , FormalParameter } ] ) -> Body - // STS tree: - // singleExpression: - // : OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression - @Override - public boolean visit(LambdaExpression javaLambdaExpr) { - // TODO: - return false; - } - // Java tree: // MethodInvocation: // [ Expression . ] @@ -2916,17 +2862,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: - // SuperMethodReference: - // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier - // STS tree: - // TODO: lambda ? - @Override - public boolean visit(SuperMethodReference javaSuperMethodReference) { - // TODO: implement - return false; - } - // Java tree: // ThisExpression: // [ ClassName . ] this @@ -3402,17 +3337,116 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // AST nodes yet to be translated + // + + // Java tree: + // LambdaExpression: + // Identifier -> Body + // ( [ Identifier { , Identifier } ] ) -> Body + // ( [ FormalParameter { , FormalParameter } ] ) -> Body + // STS tree: + // singleExpression: + // : OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + @Override + public boolean visit(LambdaExpression javaLambdaExpr) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaLambdaExpr)).setParent(stsCurrent); + + return false; + } + + // Java tree: + // CreationReference: + // Type :: + // [ < Type { , Type } > ] + // new + // STS tree: + // TODO: + @Override + public boolean visit(CreationReference javaCreationRef) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaCreationRef)).setParent(stsCurrent); + + return false; + } + + // Java tree: + // SuperMethodReference: + // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier + // STS tree: + // TODO: lambda ? + @Override + public boolean visit(SuperMethodReference javaSuperMethodReference) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaSuperMethodReference)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(TypeMethodReference javaTypeMethodRef) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaTypeMethodRef)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(ExpressionMethodReference javaExprMethodRef) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaExprMethodRef)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(TryStatement javaTryStatement) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaTryStatement)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(ThrowStatement javaThrowStatement) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaThrowStatement)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(SynchronizedStatement javaSynchrStmt) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaSynchrStmt)).setParent(stsCurrent); + + return false; + } + // The list of not yet translated Java Expressions: - // Expression: - // Annotation, - //?? CaseDefaultExpression, // CreationReference, // InstanceofExpression, // LambdaExpression, - //? MethodReference, - //? Pattern, // SuperMethodReference, - // SwitchExpression, - // TypeLiteral, // TypeMethodReference + // TryStatement + // SynchronizedStatement + // ThrowStatement } diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 1fe86be47..27aeea68d 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -31,7 +31,6 @@ public class NodeBuilder { public static TerminalNode terminalNode(int type) { return new TerminalNodeImpl(new CommonToken(type, stsName(type))); } - public static String stsName(int type) { // Antlr store all literal names wrapped into single quotes. Like: "'&='", "'^='", "'|='", "'=>'", "'null'", null, // "'do'", "'instanceof'", "'typeof'", "'case'", @@ -53,6 +52,9 @@ public class NodeBuilder { return new TerminalNodeImpl(new CommonToken(StaticTSParser.Identifier, identifier)); } + public static TerminalNode multiLineComment(String comment) { + return new TerminalNodeImpl(new CommonToken(StaticTSParser.MultiLineComment, comment)); + } public static TerminalNode terminalIdentifier(SimpleName name) { return terminalIdentifier(name.getIdentifier()); } @@ -413,4 +415,30 @@ public class NodeBuilder { return stsSuperCtorCall; } + + public static SingleExpressionContext untranslatedExpression(ASTNode node) { + SingleExpressionContext stsExpression = new SingleExpressionContext(null, 0); + CallExpressionContext stsCallExpression = new CallExpressionContext(stsExpression); + stsExpression.addChild(stsCallExpression).setParent(stsExpression); + + SingleExpressionContext stsIdentifier = identifierExpression("__untranslated_expression"); + stsCallExpression.addChild(stsIdentifier).setParent(stsCallExpression); + + ArgumentsContext stsArguments = new ArgumentsContext(stsCallExpression, 0); + stsCallExpression.addChild(stsArguments).setParent(stsCallExpression); + + stsArguments.addChild(multiLineComment("/*" + node.toString() + "*/")); + + return stsExpression; + } + + public static StatementContext untranslatedStatement(ASTNode node) { + StatementContext stsStatement = new StatementContext(null, 0); + ExpressionStatementContext stsExprStatement = new ExpressionStatementContext(stsStatement, 0); + stsStatement.addChild(stsExprStatement).setParent(stsStatement); + + stsExprStatement.addChild(untranslatedExpression(node)).setParent(stsExprStatement); + + return stsStatement; + } } diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 9c6d3b406..745e8c61d 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -22,6 +22,7 @@ import com.ohos.migrator.staticTS.parser.StaticTSParserBaseVisitor; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import java.io.FileWriter; @@ -1520,13 +1521,27 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append('('); ExpressionSequenceContext stsArgumentList = stsArguments.expressionSequence(); - if (stsArgumentList != null) visitExpressionSequence(stsArgumentList); + if (stsArgumentList != null) + visitExpressionSequence(stsArgumentList); + else if (stsArguments.getChildCount() > 0) + visitChildren(stsArguments); sb.append(')'); return null; } + @Override + public Void visitTerminal(TerminalNode stsTerminal) { + int stsTerminalCode = stsTerminal.getSymbol().getType(); + if (stsTerminalCode == StaticTSLexer.MultiLineComment || + stsTerminalCode == StaticTSLexer.SingleLineComment) { + sb.append(stsTerminal.getText()); + } + + return null; + } + // | singleExpression Instanceof singleExpression # InstanceofExpression @Override public Void visitInstanceofExpression(InstanceofExpressionContext stsInstanceofExpression) { -- Gitee From 73d74dbb9b0bbcc1fe063f8af00f3ea931cfa0bd Mon Sep 17 00:00:00 2001 From: Vsevolod Pukhov Date: Fri, 29 Jul 2022 14:33:27 +0300 Subject: [PATCH 24/60] Clear test262skiplist-compiler-arm64 Signed-off-by: Vsevolod Pukhov --- test/test262skiplist-compiler-arm64.txt | 388 ------------------------ 1 file changed, 388 deletions(-) diff --git a/test/test262skiplist-compiler-arm64.txt b/test/test262skiplist-compiler-arm64.txt index cf29d31b0..e69de29bb 100644 --- a/test/test262skiplist-compiler-arm64.txt +++ b/test/test262skiplist-compiler-arm64.txt @@ -1,388 +0,0 @@ -annexB/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js -built-ins/Array/prototype/reduce/15.4.4.21-1-11.js -built-ins/Array/prototype/reduce/15.4.4.21-1-12.js -built-ins/Array/prototype/reduce/15.4.4.21-1-14.js -built-ins/Array/prototype/reduce/15.4.4.21-1-3.js -built-ins/Array/prototype/reduce/15.4.4.21-1-4.js -built-ins/Array/prototype/reduce/15.4.4.21-1-5.js -built-ins/Array/prototype/reduce/15.4.4.21-1-6.js -built-ins/Array/prototype/reduce/15.4.4.21-1-7.js -built-ins/Array/prototype/reduce/15.4.4.21-1-8.js -built-ins/Array/prototype/reduce/15.4.4.21-1-9.js -built-ins/Array/prototype/reduce/15.4.4.21-10-1.js -built-ins/Array/prototype/reduce/15.4.4.21-10-2.js -built-ins/Array/prototype/reduce/15.4.4.21-10-4.js -built-ins/Array/prototype/reduce/15.4.4.21-10-5.js -built-ins/Array/prototype/reduce/15.4.4.21-10-6.js -built-ins/Array/prototype/reduce/15.4.4.21-10-7.js -built-ins/Array/prototype/reduce/15.4.4.21-10-8.js -built-ins/Array/prototype/reduce/15.4.4.21-2-1.js -built-ins/Array/prototype/reduce/15.4.4.21-2-10.js -built-ins/Array/prototype/reduce/15.4.4.21-2-17.js -built-ins/Array/prototype/reduce/15.4.4.21-2-18.js -built-ins/Array/prototype/reduce/15.4.4.21-2-19.js -built-ins/Array/prototype/reduce/15.4.4.21-2-2.js -built-ins/Array/prototype/reduce/15.4.4.21-2-3.js -built-ins/Array/prototype/reduce/15.4.4.21-2-4.js -built-ins/Array/prototype/reduce/15.4.4.21-2-5.js -built-ins/Array/prototype/reduce/15.4.4.21-2-6.js -built-ins/Array/prototype/reduce/15.4.4.21-2-7.js -built-ins/Array/prototype/reduce/15.4.4.21-2-8.js -built-ins/Array/prototype/reduce/15.4.4.21-2-9.js -built-ins/Array/prototype/reduce/15.4.4.21-3-11.js -built-ins/Array/prototype/reduce/15.4.4.21-3-13.js -built-ins/Array/prototype/reduce/15.4.4.21-3-15.js -built-ins/Array/prototype/reduce/15.4.4.21-3-16.js -built-ins/Array/prototype/reduce/15.4.4.21-3-17.js -built-ins/Array/prototype/reduce/15.4.4.21-3-19.js -built-ins/Array/prototype/reduce/15.4.4.21-3-2.js -built-ins/Array/prototype/reduce/15.4.4.21-3-20.js -built-ins/Array/prototype/reduce/15.4.4.21-3-21.js -built-ins/Array/prototype/reduce/15.4.4.21-3-23.js -built-ins/Array/prototype/reduce/15.4.4.21-3-24.js -built-ins/Array/prototype/reduce/15.4.4.21-3-6.js -built-ins/Array/prototype/reduce/15.4.4.21-4-12.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-2.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-3.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-1.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-10.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-11.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-12.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-13.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-14.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-15.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-16.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-17.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-18.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-19.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-2.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-20.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-21.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-22.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-25.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-26.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-27.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-28.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-29.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-3.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-30.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-31.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-4.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-5.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-6.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-7.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-8.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-3.js -built-ins/Array/prototype/reduce/15.4.4.21-9-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-6.js -built-ins/Array/prototype/reduce/15.4.4.21-9-7.js -built-ins/Array/prototype/reduce/15.4.4.21-9-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-11.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-12.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-13.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-14.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-15.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-16.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-17.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-18.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-19.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-20.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-21.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-22.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-23.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-24.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-25.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-26.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-27.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-28.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-29.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-3.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-5.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-6.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-7.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-8.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-11.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-12.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-13.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-14.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-15.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-16.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-17.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-18.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-19.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-20.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-21.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-22.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-25.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-26.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-27.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-28.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-29.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-3.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-30.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-31.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-32.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-33.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-5.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-6.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-7.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-8.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-11.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-13.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-16.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-17.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-19.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-20.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-21.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-22.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-23.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-24.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-25.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-26.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-27.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-28.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-29.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-30.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-31.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-32.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-33.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-34.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-35.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-37.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-4-s.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-5.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-8.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-23.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-24.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-4-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-30.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-31.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-23.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-24.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-30.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-31.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-32.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-33.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-23.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-24.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-30.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-31.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-32.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-33.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-34.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-35.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-37.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-4-s.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-9.js -built-ins/Array/prototype/sort/stability-11-elements.js -built-ins/Array/prototype/sort/stability-5-elements.js -built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js -built-ins/Proxy/set/call-parameters-prototype-index.js -built-ins/Proxy/set/call-parameters-prototype.js -built-ins/Proxy/set/call-parameters.js -built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js -built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js -built-ins/Proxy/set/return-true-target-property-is-not-configurable.js -built-ins/Proxy/set/return-true-target-property-is-not-writable.js -built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js -built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.js -built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js -built-ins/TypedArray/prototype/copyWithin/negative-out-of-bounds-end.js -built-ins/TypedArray/prototype/copyWithin/negative-out-of-bounds-target.js -built-ins/TypedArray/prototype/fill/coerced-indexes.js -built-ins/TypedArray/prototype/fill/fill-values-conversion-operations.js -built-ins/TypedArray/prototype/join/custom-separator-result-from-tostring-on-each-value.js -built-ins/TypedArray/prototype/reduce/callbackfn-return-does-not-change-instance.js -built-ins/TypedArray/prototype/reduce/get-length-uses-internal-arraylength.js -built-ins/TypedArray/prototype/reduce/result-is-last-callbackfn-return.js -built-ins/TypedArray/prototype/reduce/result-of-any-type.js -built-ins/TypedArray/prototype/reduceRight/callbackfn-return-does-not-change-instance.js -built-ins/TypedArray/prototype/reduceRight/get-length-uses-internal-arraylength.js -built-ins/TypedArray/prototype/reduceRight/result-is-last-callbackfn-return.js -built-ins/TypedArray/prototype/reduceRight/result-of-any-type.js -built-ins/TypedArray/prototype/set/array-arg-offset-tointeger.js -built-ins/TypedArray/prototype/set/array-arg-set-values.js -built-ins/TypedArray/prototype/set/array-arg-src-tonumber-value-conversions.js -built-ins/TypedArray/prototype/set/typedarray-arg-offset-tointeger.js -built-ins/TypedArray/prototype/set/typedarray-arg-set-values-diff-buffer-other-type.js -built-ins/TypedArray/prototype/slice/results-with-same-length.js -built-ins/TypedArray/prototype/slice/tointeger-end.js -built-ins/TypedArray/prototype/some/returns-false-if-every-cb-returns-false.js -built-ins/TypedArray/prototype/subarray/results-with-different-length.js -built-ins/TypedArray/prototype/subarray/tointeger-begin.js -built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-not-canonical-index.js -built-ins/TypedArrayConstructors/internals/Set/key-is-not-canonical-index.js -language/expressions/bitwise-not/S9.5_A2.2_T2.js -language/types/reference/put-value-prop-base-primitive.js \ No newline at end of file -- Gitee From 130d71717b597261c8e41bf150c79de625f5fd45 Mon Sep 17 00:00:00 2001 From: Vsevolod Pukhov Date: Mon, 15 Aug 2022 18:38:19 +0300 Subject: [PATCH 25/60] Cleanup test262 runner Signed-off-by: Vsevolod Pukhov --- test/runner.py | 43 +++++++------------------ test/test262skiplist-compiler-arm64.txt | 0 2 files changed, 11 insertions(+), 32 deletions(-) delete mode 100644 test/test262skiplist-compiler-arm64.txt diff --git a/test/runner.py b/test/runner.py index c0e04a08c..2c1a05b25 100755 --- a/test/runner.py +++ b/test/runner.py @@ -101,9 +101,6 @@ def get_args(): parser.add_argument( '--jit', action='store_true', dest='jit', default=False, help='use JIT in interpreter') - parser.add_argument( - '--arm64-compiler-skip', action='store_true', dest='arm64_compiler_skip', default=False, - help='use skiplist for tests failing on aarch64 in AOT or JIT mode') parser.add_argument( '--arm64-qemu', action='store_true', dest='arm64_qemu', default=False, help='launch all binaries in qemu aarch64') @@ -133,8 +130,11 @@ class Test: self.skipped = None self.reproduce = "" - def log_cmd(self, cmd): - self.reproduce += "\n" + ' '.join(cmd) + def log_cmd(self, cmd, verbose=False): + cmd_str = ' '.join(cmd) + self.reproduce += "\n" + cmd_str + if verbose: + print(cmd_str, file=sys.stderr) def run(self, runner): cmd = runner.cmd_prefix + [runner.es2panda, "--dump-ast"] @@ -202,11 +202,7 @@ class Test262Test(Test): cmd.append(self.path) - self.log_cmd(cmd) - - if runner.args.verbose: - print('Run es2panda: %s' % ' '.join(cmd), file=sys.stderr) - + self.log_cmd(cmd, runner.args.verbose) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=runner.cmd_env) @@ -235,19 +231,13 @@ class Test262Test(Test): return self if runner.args.aot: - cmd = runner.cmd_prefix + [runner.arkaot] - cmd.extend(runner.aot_args) - cmd.extend(['--paoc-panda-files', test_abc]) - cmd.extend(['--paoc-output', test_an]) + cmd = runner.cmd_prefix + [runner.arkaot] + runner.aot_args + cmd.extend(['--paoc-panda-files', test_abc, '--paoc-output', test_an]) if os.path.isfile(test_an): os.remove(test_an) - self.log_cmd(cmd) - - if runner.args.verbose: - print('Run ark_aot: %s' % ' '.join(cmd), file=sys.stderr) - + self.log_cmd(cmd, runner.args.verbose) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=runner.cmd_env) @@ -266,12 +256,7 @@ class Test262Test(Test): self.error = err.decode("utf-8", errors="ignore") return self - cmd = runner.cmd_prefix + [runner.runtime] - - if runner.args.verbose: - print('Run aot for arm64: %s' % ' '.join(cmd), file=sys.stderr) - - cmd.extend(runner.runtime_args) + cmd = runner.cmd_prefix + [runner.runtime] + runner.runtime_args if runner.args.aot: cmd.extend(['--aot-files', test_an]) @@ -283,11 +268,7 @@ class Test262Test(Test): cmd.extend([test_abc, "_GLOBAL::func_main_0"]) - self.log_cmd(cmd) - - if runner.args.verbose: - print('Run ark: %s' % ' '.join(cmd), file=sys.stderr) - + self.log_cmd(cmd, runner.args.verbose) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=runner.cmd_env) @@ -522,8 +503,6 @@ class Test262Runner(Runner): if args.bco: self.skiplist_bco_name = "test262skiplist-bco.txt" - if args.arm64_compiler_skip: - self.skiplist_name_list.append("test262skiplist-compiler-arm64.txt") self.tmp_dir = path.join(path.sep, 'tmp', 'panda', 'test262') os.makedirs(self.tmp_dir, exist_ok=True) diff --git a/test/test262skiplist-compiler-arm64.txt b/test/test262skiplist-compiler-arm64.txt deleted file mode 100644 index e69de29bb..000000000 -- Gitee From a94718c6c09a299a477c9a3521536b800a98a6cb Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Fri, 5 Aug 2022 16:29:37 +0300 Subject: [PATCH 26/60] ExpressionMethodReference translation is implemented. A few bugs in generics translation are fixed. Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 145 ++++++++++++++++-- 1 file changed, 135 insertions(+), 10 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index d72259fd9..d73882daa 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -3400,16 +3400,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - @Override - public boolean visit(ExpressionMethodReference javaExprMethodRef) { - // TODO: To be implemented - // Emit __untranslated_expression call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaExprMethodRef)).setParent(stsCurrent); - - return false; - } - @Override public boolean visit(TryStatement javaTryStatement) { // TODO: To be implemented @@ -3436,6 +3426,141 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Emit __untranslated_statement call with commented-out original syntax as argument for now. // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaSynchrStmt)).setParent(stsCurrent); + return false; + } + + // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier + // STS tree: + // singleExpression: + // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // lambdaBody: singleExpression | block; + @Override + public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { + pushCurrent(new LambdaExpressionContext(pushSingleExpression())); + + javaExpressionMethodReference.getExpression().accept(this); + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + stsCurrent.removeLastChild(); + assert(lastChild instanceof SingleExpressionContext); + SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; + + // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); + // parameterList: parameter... + pushCurrent(new ParameterListContext(stsCurrent, 0)); + // parameter: Identifier typeAnnotation + pushCurrent(new ParameterContext(stsCurrent, 0)); + + // TODO: Check if the fixed object name used here may cause a names conflict. + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. + assert (stsTypeExpr.getChildCount() == 1); + ParseTree stsNode = stsTypeExpr.getChild(0); + if (stsNode instanceof IdentifierExpressionContext) { + String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); + stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); + } + else { + // TODO: May it ever happens? + assert false; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + popCurrent(); // ParameterContext + popCurrent(); // ParameterListContext + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. + + IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); + ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + if (javaReturnType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaReturnType.isEnum()) { + // TODO: + } else if (javaReturnType.isArray()) { + // TODO: + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + + ITypeBinding javaElementType = javaReturnType.getElementType(); + if (javaElementType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaElementType.isClass() || javaElementType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaElementType.isEnum()) { + // TODO: + } else { + // Is this ever can be in case of array type? + assert false; + } + + int numDims = javaReturnType.getDimensions(); + for (int i = 0; i < numDims; ++i) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); + } + + popCurrent(); // ArrayTypeContext + } else { + assert false : "Need implementation of the translation"; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + // TODO: translation of type arguments. +// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); +// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { +// translateTypeArgumens(javaTypeArguments); +// } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); + // lambdaBody: singleExpression | block + // Use here + // singleExpression: + // | singleExpression typeArguments? arguments # CallExpression + // to produce object_arg.method_name() + pushCurrent(new LambdaBodyContext(stsCurrent, 0)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + + // | singleExpression Dot identifier # MemberAccessExpression + pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); + // singleExpression + // | Identifier IdentifierExpression + pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); + popSingleExpression(); // IdentifierExpressionContext + + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); + popSingleExpression(); // MemberAccessExpressionContext + + //translateTypeArguments(javaMethodInvocation.typeArguments()); + //translateArguments(javaMethodInvocation.arguments()); + stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. + + popSingleExpression(); // CallExpressionContext + popCurrent(); // LambdaBodyContext + popSingleExpression(); // LambdaExpressionContext + + ++countExprTransformed; return false; } -- Gitee From 82bb882f2dcb30abe72aceefc13407082821810d Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Fri, 26 Aug 2022 14:46:51 +0300 Subject: [PATCH 27/60] Post merge fix. Change-Id: Ice2b97d7236369f3688e3eef74f3ecf3aa724b6d Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 136 ------------------ .../ohos/migrator/staticTS/NodeBuilder.java | 2 +- 2 files changed, 1 insertion(+), 137 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index d73882daa..35db56619 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -3429,142 +3429,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier - // STS tree: - // singleExpression: - // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression - // lambdaBody: singleExpression | block; - @Override - public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { - pushCurrent(new LambdaExpressionContext(pushSingleExpression())); - - javaExpressionMethodReference.getExpression().accept(this); - ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); - stsCurrent.removeLastChild(); - assert(lastChild instanceof SingleExpressionContext); - SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; - - // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); - // parameterList: parameter... - pushCurrent(new ParameterListContext(stsCurrent, 0)); - // parameter: Identifier typeAnnotation - pushCurrent(new ParameterContext(stsCurrent, 0)); - - // TODO: Check if the fixed object name used here may cause a names conflict. - stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier - - // typeAnnotation: Colon primaryType - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); - // primaryType: predefinedType | typeReference | arrayType - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - - // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. - assert (stsTypeExpr.getChildCount() == 1); - ParseTree stsNode = stsTypeExpr.getChild(0); - if (stsNode instanceof IdentifierExpressionContext) { - String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); - stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); - } - else { - // TODO: May it ever happens? - assert false; - } - - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext - - popCurrent(); // ParameterContext - popCurrent(); // ParameterListContext - - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. - - IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); - ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); - - // typeAnnotation: Colon primaryType - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); - // primaryType: predefinedType | typeReference | arrayType - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - if (javaReturnType.isPrimitive()) { - stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); - } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { - stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); - } - else if (javaReturnType.isEnum()) { - // TODO: - } else if (javaReturnType.isArray()) { - // TODO: - pushCurrent(new ArrayTypeContext(stsCurrent, 0)); - - ITypeBinding javaElementType = javaReturnType.getElementType(); - if (javaElementType.isPrimitive()) { - stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); - } else if (javaElementType.isClass() || javaElementType.isInterface()) { - stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); - } - else if (javaElementType.isEnum()) { - // TODO: - } else { - // Is this ever can be in case of array type? - assert false; - } - - int numDims = javaReturnType.getDimensions(); - for (int i = 0; i < numDims; ++i) { - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); - } - - popCurrent(); // ArrayTypeContext - } else { - assert false : "Need implementation of the translation"; - } - - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext - - // TODO: translation of type arguments. -// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); -// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { -// translateTypeArgumens(javaTypeArguments); -// } - - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); - // lambdaBody: singleExpression | block - // Use here - // singleExpression: - // | singleExpression typeArguments? arguments # CallExpression - // to produce object_arg.method_name() - pushCurrent(new LambdaBodyContext(stsCurrent, 0)); - pushCurrent(new CallExpressionContext(pushSingleExpression())); - - // | singleExpression Dot identifier # MemberAccessExpression - pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); - // singleExpression - // | Identifier IdentifierExpression - pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); - stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); - popSingleExpression(); // IdentifierExpressionContext - - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); - popSingleExpression(); // MemberAccessExpressionContext - - //translateTypeArguments(javaMethodInvocation.typeArguments()); - //translateArguments(javaMethodInvocation.arguments()); - stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. - - popSingleExpression(); // CallExpressionContext - popCurrent(); // LambdaBodyContext - popSingleExpression(); // LambdaExpressionContext - - ++countExprTransformed; - - return false; - } - // The list of not yet translated Java Expressions: // CreationReference, // InstanceofExpression, diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 27aeea68d..bf23f1007 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -70,7 +70,7 @@ public class NodeBuilder { return qualifiedName(javaName.getFullyQualifiedName()); } - private static int stsTypeNameCode(PrimitiveType.Code javaPrimitiveTypeCode) { + private static int stsTypeNameCode(PrimitiveType.Code javaTypeCode) { int stsTypeNameCode = -1; if (javaTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; -- Gitee From 41613f4d33d769580a03efe1f8b409415efb1a3b Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 25 Jul 2022 19:44:01 +0300 Subject: [PATCH 28/60] Switch statement + local type declaration. Change-Id: I341d05705db6c87ef7c0ac4c732e43e9382dabe2 Signed-off-by: Evgeniy Okolnov --- .../com/ohos/migrator/java/JavaTransformer.java | 1 + .../migrator/staticTS/parser/StaticTSParser.g4 | 6 +----- .../migrator/staticTS/writer/StaticTSWriter.java | 15 ++------------- migrator/test/java/switch_statement.java.sts | 3 +-- 4 files changed, 5 insertions(+), 20 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 35db56619..3f952673d 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 30cfd3fdc..75c6218a7 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -373,11 +373,7 @@ switchStatement ; caseBlock - : OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace - ; - -caseClauses - : caseClause+ + : OpenBrace caseClause* defaultClause? caseClause* CloseBrace ; caseClause diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 745e8c61d..3c442b510 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1105,7 +1105,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // caseBlock: '{' leftCases=caseClauses? defaultClause? rightCases=caseClauses? '}' + // caseBlock: '{' caseClause* defaultClause? caseClause* '}' @Override public Void visitCaseBlock(CaseBlockContext stsCaseBlock) { if (!doNeededIndent()) { @@ -1115,18 +1115,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append("{\n"); indentIncrement(); - if (stsCaseBlock.leftCases != null) { - visitCaseClauses(stsCaseBlock.leftCases); - } - - DefaultClauseContext stsDefaultClause = stsCaseBlock.defaultClause(); - if (stsDefaultClause != null) { - visitDefaultClause(stsDefaultClause); - } - - if (stsCaseBlock.rightCases != null) { - visitCaseClauses(stsCaseBlock.rightCases); - } + visitChildren(stsCaseBlock); indentDecrement(); sb.append(indentCurrent).append("}\n"); diff --git a/migrator/test/java/switch_statement.java.sts b/migrator/test/java/switch_statement.java.sts index 36e61cd3b..cebe6f6a9 100644 --- a/migrator/test/java/switch_statement.java.sts +++ b/migrator/test/java/switch_statement.java.sts @@ -11,7 +11,7 @@ * 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; @@ -258,4 +258,3 @@ export open class switch_statement { } } - -- Gitee From 9693be72dd219babfeb7c40caae4e758d00adbf2 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 10 Aug 2022 14:28:27 +0300 Subject: [PATCH 29/60] Implemented translation of intersection types. Added a test to cover the changes above. Change-Id: Idfb2061e77bce95f36f8a676c54f385712a8d538 Signed-off-by: Mikhail Velikanov --- migrator/test/java/intersection-type.java.sts | 1 - 1 file changed, 1 deletion(-) mode change 100755 => 100644 migrator/test/java/intersection-type.java.sts diff --git a/migrator/test/java/intersection-type.java.sts b/migrator/test/java/intersection-type.java.sts old mode 100755 new mode 100644 index dea5be549..b8150eca6 --- a/migrator/test/java/intersection-type.java.sts +++ b/migrator/test/java/intersection-type.java.sts @@ -34,4 +34,3 @@ open class auxilliary implements Runnable, Something { interface Something { foo(): void ; } - -- Gitee From c263df189986a98d794762845f95a3745140eb38 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 3 Aug 2022 17:17:16 +0300 Subject: [PATCH 30/60] Enum translation (incomplete). Also minor bugfix and housekeeping in JavaTransformer code. Changes to tests to account for all of the above. Change-Id: I244038b63e07240aed4a882cab6385a07a50c487 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 44 +++++++++++++++++++ .../java/enum_with_class_behavior.java.sts | 2 +- migrator/test/java/test_enum.java.sts | 1 - 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 3f952673d..7a07ab247 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; @@ -246,6 +247,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return true; } + for (ITypeBinding javaInterface : javaClassBinding.getInterfaces()) { + if (doesOverride(javaInterface, javaCheckedMethod)) + return true; + } + ITypeBinding javaSuperClassBinding = javaClassBinding.getSuperclass(); if (javaSuperClassBinding != null) return doesOverride(javaSuperClassBinding, javaCheckedMethod); @@ -1555,6 +1561,44 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ClassBodyContext(stsCurrent, 0)); + // Translate enum constants. + // If any of the constants contain anonymous class body (e.g., extend enum type), + // add open modifier to the resulting class. + boolean needOpen = false; + List javaEnumConstNames = new ArrayList<>(); + List javaEnumConstants = javaEnumDeclaration.enumConstants(); + for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { + if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; + + // Pass enum name to enum constant node before visiting it + // as we'll need it to create appropriate initializers. + javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); + + // Store enum constant name in a list - we'll need it later to generate + // built-in values() method + javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); + + javaEnumConst.accept(this); + } + if (needOpen) { + stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); + } + + // Translate body declarations (ctors, methods, nested types, and fields). + List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); + for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { + javaEnumBodyDecl.accept(this); + } + + // TODO: valueOf(), toString() and ordinal() methods! + createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); + + popCurrent(); // ClassBodyContext + popCurrent(); // stsClassDecl + popCurrent(); // member context + + pushCurrent(new ClassBodyContext(stsCurrent, 0)); + // Translate enum constants. // If any of the constants contain anonymous class body (e.g., extend enum type), // add open modifier to the resulting class. diff --git a/migrator/test/java/enum_with_class_behavior.java.sts b/migrator/test/java/enum_with_class_behavior.java.sts index 6fab978ac..cc2c3c814 100644 --- a/migrator/test/java/enum_with_class_behavior.java.sts +++ b/migrator/test/java/enum_with_class_behavior.java.sts @@ -55,7 +55,7 @@ open class ArithmeticOperation extends Enum implements IOpe private constructor(name : String, ordinal : int) { super(name, ordinal); foo = "bar"; - } + } } class Planet extends Enum { public static const MERCURY : Planet = new Planet("MERCURY", 0, 3.303e+23, 2.4397e6); diff --git a/migrator/test/java/test_enum.java.sts b/migrator/test/java/test_enum.java.sts index 5f835b040..d4789956f 100644 --- a/migrator/test/java/test_enum.java.sts +++ b/migrator/test/java/test_enum.java.sts @@ -128,4 +128,3 @@ open class NestedEnums { } } } - -- Gitee From 01fba08bc9e58f599de2f5735a84f8a5c9afd7d6 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 5 Aug 2022 17:36:14 +0300 Subject: [PATCH 31/60] Inject name and ordinal args into enum class ctor calls. Generate default enum class ctor if no explicit ctor exists. Change-Id: Ibc07d16cef715a2412a048b6399ca75c1798cdae Signed-off-by: Mikhail Velikanov --- .../com/ohos/migrator/java/JavaTransformer.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 7a07ab247..3eb2aed58 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1565,29 +1565,42 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // If any of the constants contain anonymous class body (e.g., extend enum type), // add open modifier to the resulting class. boolean needOpen = false; + int javaEnumConstOrdinal = 0; List javaEnumConstNames = new ArrayList<>(); List javaEnumConstants = javaEnumDeclaration.enumConstants(); for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; - // Pass enum name to enum constant node before visiting it + // Pass enum name and ordinal to enum constant node before visiting it // as we'll need it to create appropriate initializers. javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); + javaEnumConst.setProperty(ENUM_CONST_ORDINAL, String.valueOf(javaEnumConstOrdinal)); // Store enum constant name in a list - we'll need it later to generate // built-in values() method javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); javaEnumConst.accept(this); + ++javaEnumConstOrdinal; } if (needOpen) { stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); } // Translate body declarations (ctors, methods, nested types, and fields). + boolean hasCtors = false; List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { javaEnumBodyDecl.accept(this); + if (!hasCtors) { + if (javaEnumBodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION) { + MethodDeclaration javaEnumMethodDecl = (MethodDeclaration) javaEnumBodyDecl; + hasCtors = javaEnumMethodDecl.isConstructor(); + } + else { + hasCtors = javaEnumBodyDecl.getNodeType() == ASTNode.INITIALIZER; + } + } } // TODO: valueOf(), toString() and ordinal() methods! -- Gitee From 9220442bbd0abeed997d4ded4a657c6891cb0089 Mon Sep 17 00:00:00 2001 From: Ilya Trubachev Date: Thu, 18 Aug 2022 19:30:32 +0300 Subject: [PATCH 32/60] clang tidy 1 Signed-off-by: Ilya Trubachev --- compiler/core/emitter.cpp | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/core/emitter.cpp b/compiler/core/emitter.cpp index 6e617cb41..2b724b665 100644 --- a/compiler/core/emitter.cpp +++ b/compiler/core/emitter.cpp @@ -85,56 +85,56 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) switch (tag) { case ir::LiteralTag::BOOLEAN: { - valueLit.tag_ = panda::panda_file::LiteralTag::BOOL; - valueLit.value_ = literal->GetBoolean(); + valueLit.tag = panda::panda_file::LiteralTag::BOOL; + valueLit.value = literal->GetBoolean(); break; } case ir::LiteralTag::INTEGER: { - valueLit.tag_ = panda::panda_file::LiteralTag::INTEGER; - valueLit.value_ = literal->GetInt(); + valueLit.tag = panda::panda_file::LiteralTag::INTEGER; + valueLit.value = literal->GetInt(); break; } case ir::LiteralTag::DOUBLE: { - valueLit.tag_ = panda::panda_file::LiteralTag::DOUBLE; - valueLit.value_ = literal->GetDouble(); + valueLit.tag = panda::panda_file::LiteralTag::DOUBLE; + valueLit.value = literal->GetDouble(); break; } case ir::LiteralTag::STRING: { - valueLit.tag_ = panda::panda_file::LiteralTag::STRING; - valueLit.value_ = literal->GetString().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::STRING; + valueLit.value = literal->GetString().Mutf8(); break; } case ir::LiteralTag::ACCESSOR: { - valueLit.tag_ = panda::panda_file::LiteralTag::ACCESSOR; - valueLit.value_ = static_cast(0); + valueLit.tag = panda::panda_file::LiteralTag::ACCESSOR; + valueLit.value = static_cast(0); break; } case ir::LiteralTag::METHOD: { - valueLit.tag_ = panda::panda_file::LiteralTag::METHOD; - valueLit.value_ = literal->GetMethod().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::METHOD; + valueLit.value = literal->GetMethod().Mutf8(); break; } case ir::LiteralTag::GENERATOR_METHOD: { - valueLit.tag_ = panda::panda_file::LiteralTag::GENERATORMETHOD; - valueLit.value_ = literal->GetMethod().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::GENERATORMETHOD; + valueLit.value = literal->GetMethod().Mutf8(); break; } case ir::LiteralTag::ASYNC_GENERATOR_METHOD: { - valueLit.tag_ = panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD; - valueLit.value_ = literal->GetMethod().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD; + valueLit.value = literal->GetMethod().Mutf8(); break; } case ir::LiteralTag::NULL_VALUE: { - valueLit.tag_ = panda::panda_file::LiteralTag::NULLVALUE; - valueLit.value_ = static_cast(0); + valueLit.tag = panda::panda_file::LiteralTag::NULLVALUE; + valueLit.value = static_cast(0); break; } default: break; } - tagLit.tag_ = panda::panda_file::LiteralTag::TAGVALUE; - tagLit.value_ = static_cast(valueLit.tag_); + tagLit.tag = panda::panda_file::LiteralTag::TAGVALUE; + tagLit.value = static_cast(valueLit.tag); array.emplace_back(tagLit); array.emplace_back(valueLit); -- Gitee From 07fc938fe36315001ed8ecb6ad095a57d7a47c83 Mon Sep 17 00:00:00 2001 From: vagin ivan Date: Tue, 16 Aug 2022 19:38:14 +0300 Subject: [PATCH 33/60] Added irtoc interpreter mode to test262 runner Signed-off-by: vagin ivan --- test/runner.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/runner.py b/test/runner.py index 2c1a05b25..d46ba19c8 100755 --- a/test/runner.py +++ b/test/runner.py @@ -101,6 +101,12 @@ def get_args(): parser.add_argument( '--jit', action='store_true', dest='jit', default=False, help='use JIT in interpreter') + parser.add_argument( + '--irtoc', action='store_true', dest='irtoc', default=False, + help='use irtoc in interpreter') + parser.add_argument( + '--arm64-compiler-skip', action='store_true', dest='arm64_compiler_skip', default=False, + help='use skiplist for tests failing on aarch64 in AOT or JIT mode') parser.add_argument( '--arm64-qemu', action='store_true', dest='arm64_qemu', default=False, help='launch all binaries in qemu aarch64') @@ -266,6 +272,9 @@ class Test262Test(Test): else: cmd.extend(['--compiler-enable-jit=false']) + if runner.args.irtoc: + cmd.extend(['--interpreter-type=irtoc']) + cmd.extend([test_abc, "_GLOBAL::func_main_0"]) self.log_cmd(cmd, runner.args.verbose) -- Gitee From d70290a615eb1d45ea314564084f965045371f4f Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Thu, 25 Aug 2022 14:28:01 +0300 Subject: [PATCH 34/60] - Translation of lambda expressions. - Revise translation of shift operator to avoid token collision in ANTLR grammar due to the ambiguity between '>>' token and multiple closing triangle brackets (for type arguments). - Fix translation of array types for method's parameters. Change-Id: I449596e7f1b46eb0e0a72aed7013c272fec5c5b3 Signed-off-by: Evgeniy Okolnov --- .../ohos/migrator/java/JavaTransformer.java | 162 +++++++++++++++--- .../ohos/migrator/staticTS/NodeBuilder.java | 20 +++ .../migrator/staticTS/parser/StaticTSLexer.g4 | 3 - .../staticTS/parser/StaticTSParser.g4 | 8 +- .../staticTS/writer/StaticTSWriter.java | 9 +- migrator/test/java/array_creation.java.sts | 2 +- migrator/test/java/inferred_types.java | 60 +++++++ migrator/test/java/inferred_types.java.sts | 90 ++++++++++ migrator/test/java/lambda_expr.java | 49 ++++++ migrator/test/java/lambda_expr.java.sts | 52 ++++++ 10 files changed, 419 insertions(+), 36 deletions(-) create mode 100644 migrator/test/java/inferred_types.java create mode 100644 migrator/test/java/inferred_types.java.sts create mode 100644 migrator/test/java/lambda_expr.java create mode 100644 migrator/test/java/lambda_expr.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 3eb2aed58..4b6682a35 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -941,6 +941,26 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + private void translateType(ITypeBinding javaType) { + boolean needPrimaryType = isInPrimaryTypeContext(); + if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + // NOTE: Method "ITypeBinding.getQualifiedName()" constructs fully-qualified name + // of the corresponding type, including its generic part, array brackets, etc., + // and returns it as a string value. Using this method, we can avoid constructing + // entire STS tree for the corresponding type, simply making an identifier token + // with string value of type's fully-qualified name and wrapping it with a single + // TypeReferenceContext node. + // + // See the following link for details: + // https://help.eclipse.org/latest/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ITypeBinding.html#getQualifiedName() + + TypeReferenceContext stsTypeRef = NodeBuilder.typeReference(javaType.getQualifiedName()); + stsCurrent.addChild(stsTypeRef).setParent(stsCurrent); + + if (needPrimaryType) popCurrent(); // PrimaryTypeContext + } + // Java tree: // Expression: NullLiteral // STS tree: @@ -1040,9 +1060,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { else if (javaOp == InfixExpression.Operator.REMAINDER) stsOperator = StaticTSParser.Modulus; else if (javaOp == InfixExpression.Operator.PLUS) stsOperator = StaticTSParser.Plus; else if (javaOp == InfixExpression.Operator.MINUS) stsOperator = StaticTSParser.Minus; - else if (javaOp == InfixExpression.Operator.LEFT_SHIFT) stsOperator = StaticTSParser.LeftShiftArithmetic; - else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED) stsOperator = StaticTSParser.RightShiftArithmetic; - else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED) stsOperator = StaticTSParser.RightShiftLogical; else if (javaOp == InfixExpression.Operator.LESS) stsOperator = StaticTSParser.LessThan; else if (javaOp == InfixExpression.Operator.GREATER) stsOperator = StaticTSParser.MoreThan; else if (javaOp == InfixExpression.Operator.LESS_EQUALS) stsOperator = StaticTSParser.LessThanEquals; @@ -1060,6 +1077,19 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return stsOperator; } + private ParseTree createStsInfixOperator(InfixExpression.Operator javaOp) { + if (isShiftOperator(javaOp)) + return NodeBuilder.shiftOperator(javaOp); + else + return NodeBuilder.terminalNode(stsOperatorType(javaOp)); + } + + private boolean isShiftOperator(InfixExpression.Operator javaInfixOp) { + return javaInfixOp == InfixExpression.Operator.LEFT_SHIFT + || javaInfixOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED + || javaInfixOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED; + } + private ParserRuleContext createStsInfixExpression(SingleExpressionContext stsSingleExpression, InfixExpression javaInfixExpression) { InfixExpression.Operator javaOp = javaInfixExpression.getOperator(); @@ -1067,7 +1097,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return new MultiplicativeExpressionContext(stsSingleExpression); else if (javaOp == InfixExpression.Operator.PLUS || javaOp == InfixExpression.Operator.MINUS) return new AdditiveExpressionContext(stsSingleExpression); - else if (javaOp == InfixExpression.Operator.LEFT_SHIFT || javaOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED || javaOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED) + else if (isShiftOperator(javaOp)) return new BitShiftExpressionContext(stsSingleExpression); else if (javaOp == InfixExpression.Operator.LESS || javaOp == InfixExpression.Operator.GREATER || javaOp == InfixExpression.Operator.LESS_EQUALS || javaOp == InfixExpression.Operator.GREATER_EQUALS) return new RelationalExpressionContext(stsSingleExpression); @@ -1107,11 +1137,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(InfixExpression javaInfixExpression) { pushCurrent(createStsInfixExpression(pushSingleExpression(), javaInfixExpression)); - - int stsOpType = stsOperatorType(javaInfixExpression.getOperator()); + InfixExpression.Operator javaOp = javaInfixExpression.getOperator(); javaInfixExpression.getLeftOperand().accept(this); - stsCurrent.addChild(NodeBuilder.terminalNode(stsOpType)).setParent(stsCurrent); + stsCurrent.addAnyChild(createStsInfixOperator(javaOp)).setParent(stsCurrent); javaInfixExpression.getRightOperand().accept(this); popSingleExpression(); // InfixExpression @@ -1126,7 +1155,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(createStsInfixExpression(pushSingleExpression(), javaInfixExpression)); stsCurrent.addChild(stsLeftOperand).setParent(stsCurrent); - stsCurrent.addChild(NodeBuilder.terminalNode(stsOpType)).setParent(stsCurrent); + stsCurrent.addAnyChild(createStsInfixOperator(javaOp)).setParent(stsCurrent); javaRightExpression.accept(this); popSingleExpression(); // InfixExpression @@ -1312,16 +1341,16 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // OpenParen parameterList? CloseParen // parameterList: parameter (Comma parameter)* (Comma variadicParameter)? | variadicParameter - private void createStsParameterList(List javaParameters) { - // OpenParen formalParameterList? CloseParen + private void createStsParameterList(List javaParameters) { + // OpenParen parameterList? CloseParen stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)).setParent(stsCurrent); assert(javaParameters != null); if (!javaParameters.isEmpty()) { pushCurrent(new ParameterListContext(stsCurrent, 0)); - for (SingleVariableDeclaration javaSingleVariableDeclaration : javaParameters) { - javaSingleVariableDeclaration.accept(this); + for (VariableDeclaration javaVariableDeclaration : javaParameters) { + javaVariableDeclaration.accept(this); } popCurrent(); // ParameterListContext @@ -1351,13 +1380,19 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // ( Block | ; ) // STS tree: // interfaceMember: methodSignature SemiColon #InterfaceMethod - // classMember: constructorDeclaration | classMethodDeclaration | other alternatives are not relevant for this visitor. - // constructorDeclaration: Constructor OpenParen formalParameterList? CloseParen OpenBrace functionBody CloseBrace + // classMember: + // accessibilityModifier? + // ( + // constructorDeclaration + // | classMethodDeclaration + // | other alternatives are not relevant for this visitor. + // ) + // constructorDeclaration: Constructor OpenParen parameterList? CloseParen constructorBody + // constructorBody: OpenBrace constructorCall? statementOrLocalDeclaration* CloseBrace // classMethodDeclaration - // : accessibilityModifier? (Static | Override | Open)? methodSignature OpenBrace functionBody CloseBrace #ClassMethodWithBody - // | Abstract accessibilityModifier? methodSignature SemiColon #AbstractClassMethod - // methodSignature: Identifier callSignature - // callSignature: typeParameters? OpenParen formalParameterList? CloseParen typeAnnotation + // : (Static | Override | Open)? Identifier signature block #ClassMethodWithBody + // | (Abstract | Static? Native | Native Static)? Identifier signature SemiColon #AbstractOrNativeClassMethod + // signature: typeParameters? OpenParen parameterList? CloseParen typeAnnotation @Override public boolean visit(MethodDeclaration javaMethodDeclaration) { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; @@ -1381,7 +1416,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ConstructorDeclarationContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Constructor)).setParent(stsCurrent); - // STS: OpenParen formalParameterList? CloseParen + // STS: OpenParen parameterList? CloseParen createStsParameterList(javaMethodDeclaration.parameters()); } else { // A regular method (not a constructor). @@ -1446,7 +1481,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS: typeParameters: LessThan typeParameterList? MoreThan createStsTypeParameters(javaMethodDeclaration.typeParameters()); - // STS: OpenParen formalParameterList? CloseParen + // STS: OpenParen parameterList? CloseParen createStsParameterList(javaMethodDeclaration.parameters()); // typeAnnotation @@ -1463,9 +1498,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Java tree: // SingleVariableDeclaration: { ExtendedModifier } Type {Annotation} [ ... ] Identifier { Dimension } [ = Expression ] // STS tree for formal parameter: - // formalParameter: Identifier typeAnnotation + // parameter: Identifier typeAnnotation // or - // restFormalParameter: Ellipsis Identifier typeAnnotation + // variadicParameter: Ellipsis Identifier typeAnnotation @Override public boolean visit(SingleVariableDeclaration javaSingleVariableDeclaration) { if (javaSingleVariableDeclaration.isVarargs()) { @@ -1481,8 +1516,13 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaSingleVariableDeclaration.getName())); + // Parameter type pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); javaSingleVariableDeclaration.getType().accept(this); + + int extraDims = javaSingleVariableDeclaration.getExtraDimensions(); + if (extraDims > 0) NodeBuilder.addExtraDimensions(stsCurrent, extraDims); + popCurrent(); // TypeAnnotationContext // TODO: { Dimension } @@ -1492,7 +1532,36 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // if (javaExpression != null) { // } - popCurrent(); // RestFormalParameterContext | FormalParameterContext + popCurrent(); // ParameterContext | VariadicParameterContext + + ++countDeclTransformed; + return false; + } + + // Java tree: + // VariableDeclarationFragment: + // Identifier { Dimension } [ = Expression ] + // STS tree for formal parameter: + // parameter: + // Identifier typeAnnotation + @Override + public boolean visit(VariableDeclarationFragment javaVariableDeclarationFragment) { + // Here, VariableDeclarationFragment node represents lambda's parameter + // with omitted parameter type. + + pushCurrent(new ParameterContext(stsCurrent, 0)); + + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaVariableDeclarationFragment.getName())); + + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + IVariableBinding variableBinding = javaVariableDeclarationFragment.resolveBinding(); + translateType(variableBinding.getType()); + popCurrent(); // TypeAnnotationContext + + // Note: no need to process the "{ Dimension }" part, as the extra dimensions + // of the declaration are covered by "translateType(ITypeBinding)" call. + + popCurrent(); // ParameterContext ++countDeclTransformed; return false; @@ -3403,16 +3472,53 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Identifier -> Body // ( [ Identifier { , Identifier } ] ) -> Body // ( [ FormalParameter { , FormalParameter } ] ) -> Body + // Body: + // Expression + // Block // STS tree: // singleExpression: - // : OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // lambdaBody + // : singleExpression + // | block @Override public boolean visit(LambdaExpression javaLambdaExpr) { - // TODO: To be implemented - // Emit __untranslated_expression call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaLambdaExpr)).setParent(stsCurrent); + pushCurrent(new LambdaExpressionContext(pushSingleExpression())); + + createStsParameterList(javaLambdaExpr.parameters()); + + IMethodBinding lambdaMethod = javaLambdaExpr.resolveMethodBinding(); + + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + translateType(lambdaMethod.getReturnType()); + popCurrent(); // TypeAnnotationContext + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); + + pushCurrent(new LambdaBodyContext(stsCurrent, 0)); + ASTNode javaBody = javaLambdaExpr.getBody(); + + if (javaBody instanceof Expression) { + javaBody.accept(this); + } else { + // Better this than calling javaBody.accept(this) here + // as visit(Block) will call pushStatement() which will + // add StatementContext node which isn't needed here. + pushCurrent(new BlockContext(stsCurrent, 0)); + + Block javaBlock = (Block) javaBody; + List javaBlockStmts = javaBlock.statements(); + for (Statement javaStmt : javaBlockStmts) { + javaStmt.accept(this); + } + popCurrent(); // BlockContext + } + popCurrent(); // LambdaBodyContext + + popSingleExpression(); // LambdaExpressionContext + + ++countExprTransformed; return false; } diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index bf23f1007..5b4d9fe62 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -441,4 +441,24 @@ public class NodeBuilder { return stsStatement; } + + public static ShiftOperatorContext shiftOperator(InfixExpression.Operator javaOp) { + ShiftOperatorContext stsShiftOp = new ShiftOperatorContext(null, 0); + + if (javaOp == InfixExpression.Operator.LEFT_SHIFT) { + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.LessThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.LessThan)); + } + else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED) { + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + } + else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED) { + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + } + + return stsShiftOp; + } } diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 index b0ba23ccc..f0b60c9fa 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 @@ -46,9 +46,6 @@ Not: '!'; Multiply: '*'; Divide: '/'; Modulus: '%'; -RightShiftArithmetic: '>>'; -LeftShiftArithmetic: '<<'; -RightShiftLogical: '>>>'; LessThan: '<'; MoreThan: '>'; LessThanEquals: '<='; diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 75c6218a7..5009e8b90 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -422,7 +422,7 @@ singleExpression | Not singleExpression # NotExpression | singleExpression (Multiply | Divide | Modulus) singleExpression # MultiplicativeExpression | singleExpression (Plus | Minus) singleExpression # AdditiveExpression - | singleExpression (LeftShiftArithmetic | RightShiftArithmetic | RightShiftLogical) singleExpression # BitShiftExpression + | singleExpression shiftOperator singleExpression # BitShiftExpression | singleExpression (LessThan | MoreThan | LessThanEquals | GreaterThanEquals) singleExpression # RelationalExpression | singleExpression Instanceof primaryType # InstanceofExpression | singleExpression (Equals | NotEquals) singleExpression # EqualityExpression @@ -444,6 +444,12 @@ singleExpression | singleExpression As (intersectionType | primaryType) # CastExpression ; +shiftOperator + : first=LessThan second=LessThan {$first.index + 1 == $second.index}? + | first=MoreThan second=MoreThan {$first.index + 1 == $second.index}? + | first=MoreThan second=MoreThan third=MoreThan {$first.index + 1 == $second.index && $second.index + 1 == $third.index}? + ; + lambdaBody : singleExpression | block diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 3c442b510..efbf6ffcd 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1702,10 +1702,10 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // | singleExpression ('<<' | '>>' | '>>>') singleExpression # BitShiftExpression + // | singleExpression ('<' '<' | '>' '>' | '>' '>' '>') singleExpression # BitShiftExpression @Override public Void visitBitShiftExpression(BitShiftExpressionContext stsBitShiftExpression) { - String op = stsBitShiftExpression.getChild(1).getText(); + String op = stsBitShiftExpression.shiftOperator().getText(); binaryOperatorWrite(op, stsBitShiftExpression.singleExpression()); return null; } @@ -1806,7 +1806,10 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { @Override public Void visitLambdaExpression(LambdaExpressionContext stsLambdaExpression) { sb.append('('); - visitParameterList(stsLambdaExpression.parameterList()); + ParameterListContext stsParameterList = stsLambdaExpression.parameterList(); + if (stsParameterList != null) { + visitParameterList(stsParameterList); + } sb.append(')'); visitTypeAnnotation(stsLambdaExpression.typeAnnotation()); diff --git a/migrator/test/java/array_creation.java.sts b/migrator/test/java/array_creation.java.sts index 7a386f7a0..6267de618 100644 --- a/migrator/test/java/array_creation.java.sts +++ b/migrator/test/java/array_creation.java.sts @@ -18,7 +18,7 @@ package com.ohos.migrator.test.java; export open class array_creation { private const b1 : byte[] = new byte[8]; private const c1 : char[] = ['a', 'b', 'c']; - private foo(c2 : char): void { + private foo(c2 : char[]): void { } public open bar(): void { foo(['g', 'k', 'h']); diff --git a/migrator/test/java/inferred_types.java b/migrator/test/java/inferred_types.java new file mode 100644 index 000000000..89e76bdea --- /dev/null +++ b/migrator/test/java/inferred_types.java @@ -0,0 +1,60 @@ +/* + * 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.tests.java; + +import java.util.List; + +class Main { + // Java language allows to omit return/parameter types for lambda expression. + // These types are then inferred by the compiler. + // This test covers all kinds of types that can be inferred by compiler + + class C {} + enum E {} + interface IPrimitiveTypes { void M(int i, boolean b, char c); } // Void, primitive types + interface IClassTypes { IPrimitiveTypes M(C c, String s, E e); } // Class, Interface, Enum + interface IArrays { int[] M(String[] sArray, IPrimitiveTypes[][] iArray, E[] eArray[]); } // Arrays + interface IParametrizedTypes { List M(List list, List listOfArrays, List> listOfLists[]); } // Parametrized type, Raw type + interface IWildcards { List M(List listExtends, List listSuper); } // Wildcards + interface IGeneric { T M(List list); } // Generic interface (parametrized types, type variables, wildcards, etc.) + + static class OuterClass { + class InnerClass { + void M(T t) { + IGeneric l = (list) -> list.get(0); // Generic functional interface parametrized with type variable + } + } + } + interface IInnerOuter { + int M(OuterClass>.InnerClass inner); // Nested type (with parametrized type) + } + + void Test() { + IPrimitiveTypes l1 = (i, b, c) -> { }; // Void, primitive types + IClassTypes l2 = (c, s, e) -> l1; // Class, Interface, Enum + IArrays l3 = (sArray, iArray, eArray) -> new int[5]; // Arrays + IParametrizedTypes l4 = (list, listOfArrays, ListOfLists) -> list; // Parametrized type, Raw type + IWildcards l5 = (listExtends, listSuper) -> listExtends; // Wildcards + + // Generic functional interface + IGeneric l6 = (list) -> list.get(0); // parametrized with explicit type + IGeneric l7 = (list) -> list.get(0); // parametrized with wildcard + IGeneric l8 = (list) -> list.get(0); // parametrized with wildcard with bound + IGeneric l9 = (list) -> list.get(0); // parametrized with wildcard with bound + + IInnerOuter l10 = (inner) -> 0; // Nested type (with parametrized type) + } +} \ No newline at end of file diff --git a/migrator/test/java/inferred_types.java.sts b/migrator/test/java/inferred_types.java.sts new file mode 100644 index 000000000..eea79cb1d --- /dev/null +++ b/migrator/test/java/inferred_types.java.sts @@ -0,0 +1,90 @@ +/* + * 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.tests.java; + +import java.util.List; +open class Main { + open class C { + } + + static class E extends Enum { + public static values(): E[] { + return []; + } + public static valueOf(name : String): E { + for (let value : E of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + + } + + interface IPrimitiveTypes { + M(i : int, b : boolean, c : char): void ; + } + + interface IClassTypes { + M(c : C, s : String, e : E): IPrimitiveTypes ; + } + + interface IArrays { + M(sArray : String[], iArray : IPrimitiveTypes[][], eArray : E[][]): int[] ; + } + + interface IParametrizedTypes { + M(list : List, listOfArrays : List, listOfLists : List>[]): List ; + } + + interface IWildcards { + M(listExtends : List, listSuper : List): List ; + } + + interface IGeneric { + M(list : List): T ; + } + + static open class OuterClass { + open class InnerClass { + open M(t : T): void { + let l : IGeneric = (list : java.util.List): T =>list.get(0); + } + } + + } + + interface IInnerOuter { + M(inner : OuterClass>.InnerClass): int ; + } + + open Test(): void { + let l1 : IPrimitiveTypes = (i : int, b : boolean, c : char): void => { + } +; + let l2 : IClassTypes = (c : com.ohos.migrator.tests.java.Main.C, s : java.lang.String, e : com.ohos.migrator.tests.java.Main.E): com.ohos.migrator.tests.java.Main.IPrimitiveTypes =>l1; + let l3 : IArrays = (sArray : java.lang.String[], iArray : com.ohos.migrator.tests.java.Main.IPrimitiveTypes[][], eArray : com.ohos.migrator.tests.java.Main.E[][]): int[] =>new int[5]; + let l4 : IParametrizedTypes = (list : java.util.List, listOfArrays : java.util.List, ListOfLists : java.util.List>[]): java.util.List =>list; + let l5 : IWildcards = (listExtends : java.util.List, listSuper : java.util.List): java.util.List =>listExtends; + let l6 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l7 : IGeneric = (list : java.util.List): java.lang.Object =>list.get(0); + let l8 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l9 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l10 : IInnerOuter = (inner : com.ohos.migrator.tests.java.Main.OuterClass>.InnerClass): int =>0; + } +} + \ No newline at end of file diff --git a/migrator/test/java/lambda_expr.java b/migrator/test/java/lambda_expr.java new file mode 100644 index 000000000..d24e1a349 --- /dev/null +++ b/migrator/test/java/lambda_expr.java @@ -0,0 +1,49 @@ +/* + * 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.tests.java; + +class Main { + + interface I1 { void M(); } + interface I2 { int M(boolean b); } + interface I3 { int M(int i, String s); } + + void Test() { + I1 i1 = () -> { }; + i1.M(); + + I2 i2 = x -> !x ? 1 : 2; + int i = i2.M(true); + + I2 i2_2 = getLambda(); + i2_2.M(false); + + PassLambdaByParam((x1, x2) -> x2.contains("x") ? x1 : 0); + } + + I2 getLambda() { + return (boolean b) -> { + if (b) + return 10; + else + return 20; + }; + } + + int PassLambdaByParam(I3 i3) { + return i3.M(10, "Text"); + } +} \ No newline at end of file diff --git a/migrator/test/java/lambda_expr.java.sts b/migrator/test/java/lambda_expr.java.sts new file mode 100644 index 000000000..604fe6764 --- /dev/null +++ b/migrator/test/java/lambda_expr.java.sts @@ -0,0 +1,52 @@ +/* + * 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.tests.java; + +open class Main { + interface I1 { + M(): void ; + } + + interface I2 { + M(b : boolean): int ; + } + + interface I3 { + M(i : int, s : String): int ; + } + + open Test(): void { + let i1 : I1 = (): void => { + } +; + i1.M(); + let i2 : I2 = (x : boolean): int =>!x ? 1 : 2; + let i : int = i2.M(true); + let i2_2 : I2 = getLambda(); + i2_2.M(false); + PassLambdaByParam((x1 : int, x2 : java.lang.String): int =>x2.contains("x") ? x1 : 0); + } + open getLambda(): I2 { + return (b : boolean): int => { + if (b) return 10; + else return 20; + } +; + } + open PassLambdaByParam(i3 : I3): int { + return i3.M(10, "Text"); + } +} + \ No newline at end of file -- Gitee From a279eb0ae2455e60eda757c04cff1d996577337e Mon Sep 17 00:00:00 2001 From: mwx1193402 Date: Wed, 24 Aug 2022 14:46:19 +0300 Subject: [PATCH 35/60] PR for clang-tidy check bytecode_optimizer Signed-off-by: mwx1193402 --- aot/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aot/main.cpp b/aot/main.cpp index 8dbd68097..79c919ecd 100644 --- a/aot/main.cpp +++ b/aot/main.cpp @@ -67,7 +67,7 @@ static int GenerateProgram(panda::pandasm::Program *prog, const std::string &out return 1; } - panda::bytecodeopt::options.SetOptLevel(optLevel); + panda::bytecodeopt::OPTIONS.SetOptLevel(optLevel); panda::bytecodeopt::OptimizeBytecode(prog, mapsp, output, true, true); } #endif -- Gitee From 215169c2f64b84ad6fc024d71bde70943b4a77b5 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Fri, 5 Aug 2022 16:29:37 +0300 Subject: [PATCH 36/60] ExpressionMethodReference translation is implemented. A few bugs in generics translation are fixed. Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 4b6682a35..1e3b2458d 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -3514,8 +3514,143 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // BlockContext } + popCurrent(); // LambdaBodyContext + popSingleExpression(); // LambdaExpressionContext + + ++countExprTransformed; + return false; + } + + // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier + // STS tree: + // singleExpression: + // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // lambdaBody: singleExpression | block; + @Override + public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { + pushCurrent(new LambdaExpressionContext(pushSingleExpression())); + + javaExpressionMethodReference.getExpression().accept(this); + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + stsCurrent.removeLastChild(); + assert(lastChild instanceof SingleExpressionContext); + SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; + + // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); + // parameterList: parameter... + pushCurrent(new ParameterListContext(stsCurrent, 0)); + // parameter: Identifier typeAnnotation + pushCurrent(new ParameterContext(stsCurrent, 0)); + + // TODO: Check if the fixed object name used here may cause a names conflict. + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. + assert (stsTypeExpr.getChildCount() == 1); + ParseTree stsNode = stsTypeExpr.getChild(0); + if (stsNode instanceof IdentifierExpressionContext) { + String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); + stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); + } + else { + // TODO: May it ever happens? + assert false; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + popCurrent(); // ParameterContext + popCurrent(); // ParameterListContext + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. + + IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); + ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + if (javaReturnType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaReturnType.isEnum()) { + // TODO: + } else if (javaReturnType.isArray()) { + // TODO: + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + + ITypeBinding javaElementType = javaReturnType.getElementType(); + if (javaElementType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaElementType.isClass() || javaElementType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaElementType.isEnum()) { + // TODO: + } else { + // Is this ever can be in case of array type? + assert false; + } + + int numDims = javaReturnType.getDimensions(); + for (int i = 0; i < numDims; ++i) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); + } + + popCurrent(); // ArrayTypeContext + } else { + assert false : "Need implementation of the translation"; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + // TODO: translation of type arguments. +// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); +// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { +// translateTypeArgumens(javaTypeArguments); +// } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); + // lambdaBody: singleExpression | block + // Use here + // singleExpression: + // | singleExpression typeArguments? arguments # CallExpression + // to produce object_arg.method_name() + pushCurrent(new LambdaBodyContext(stsCurrent, 0)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + + // | singleExpression Dot identifier # MemberAccessExpression + pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); + // singleExpression + // | Identifier IdentifierExpression + pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); + popSingleExpression(); // IdentifierExpressionContext + + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); + popSingleExpression(); // MemberAccessExpressionContext + + //translateTypeArguments(javaMethodInvocation.typeArguments()); + //translateArguments(javaMethodInvocation.arguments()); + stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. + + popSingleExpression(); // CallExpressionContext + popCurrent(); // LambdaBodyContext popSingleExpression(); // LambdaExpressionContext ++countExprTransformed; -- Gitee From fec604cbcd3ec3abdfdb97c792f8a537271db6df Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 25 Jul 2022 19:44:01 +0300 Subject: [PATCH 37/60] Switch statement + local type declaration. Change-Id: I341d05705db6c87ef7c0ac4c732e43e9382dabe2 Signed-off-by: Evgeniy Okolnov --- .../ohos/migrator/java/JavaTransformer.java | 273 +++++++++++++++++- 1 file changed, 270 insertions(+), 3 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 1e3b2458d..61c363bbe 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; @@ -3674,6 +3675,21 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // TypeDeclarationStatement: + // TypeDeclaration + // EnumDeclaration + // STS tree: + // statementOrLocalDeclaration: + // | classDeclaration + // | enumDeclaration + @Override + public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { + javaTypeDeclarationStmt.getDeclaration().accept(this); + + ++countStmtTransformed; + return false; + } + // Java tree: // SuperMethodReference: // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier @@ -3689,6 +3705,87 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // switch ( Expression ) + // { { SwitchCase | Statement } } + // SwitchCase: + // case Expression : + // default : + // STS tree: + // switchStatement: + // switch OpenParen singleExpression CloseParen caseBlock + // caseBlock: + // OpenBrace caseClause* defaultClause? caseClause* CloseBrace + // caseClause: + // case singleExpression ':' statement* + // defaultClause: + // default ':' statement* + @Override + public boolean visit(SwitchStatement javaSwitchStmt) { + SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); + pushStatement(stsSwitch); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); + + javaSwitchStmt.getExpression().accept(this); + + CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); + pushCurrent(stsCaseBlock); + + List javaVariablesToMove = new ArrayList<>(); + SwitchCase javaCurrentSwitchCase = null; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { + javaCurrentSwitchCase = (SwitchCase) javaStmt; + } + else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { + wrapCaseClauseStatementsWithBlock(); + } + else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { + processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, + javaSwitchStmt, javaVariablesToMove); + + // We've already processed variable declaration, proceed to the next statement. + continue; + } + + javaStmt.accept(this); + } + + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + popCurrent(); // CaseBlockContext + popStatement(); // SwitchStatementContext + + // Move variable declarations in front of switch statement, and enclose both + // declarations and switch with additional block. + if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { + // Remove switch statement from current STS node. + stsCurrent.removeLastChild(); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + + for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { + VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); + + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); + popStatement(); // VariableOrConstantDeclarationContext + } + + pushStatement(stsSwitch); + popStatement(); // SwitchContext + + popStatement(); // BlockContext + } + + ++countStmtTransformed; + + return false; + } + @Override public boolean visit(TypeMethodReference javaTypeMethodRef) { // TODO: To be implemented @@ -3728,13 +3825,183 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + public boolean visit(SwitchCase javaSwitchCase) { + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + if (javaSwitchCase.isDefault()) { + pushCurrent(new DefaultClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); + } else { + pushCurrent(new CaseClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); + javaSwitchCase.getExpression().accept(this); + } + + // SwitchCase is treated as Statement node, thus increment the count. + ++countStmtTransformed; + return false; + } + + private void popCaseClauseIfNeeded() { + // Check if we need to pop additional block added as work around to add + // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() + // method for details). + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) { + popStatement(); // BlockContext + } + + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause + || stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause) { + popCurrent(); // CaseClauseContext | DefaultClauseContext + } + } + + private void wrapCaseClauseStatementsWithBlock() { + // In StaticTS, CaseClause may contain only statements, and is not allowed to + // have local declarations. In contrast, Java permits to have local declarations + // in case clause scope, so when encounter one, wrap up all statements in case clause + // with additional block as a workaround, (since block can have local declarations). + + // Check if already inserted additional block. + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) + return; + + assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || + stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; + + List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); + stsCurrent.children.removeAll(stsCaseStmts); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + for (StatementContext stsStmt : stsCaseStmts) { + StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); + stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); + stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); + } + } + + + private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, + SwitchStatement javaSwitchStmt, List javaVariablesToMove) { + // Java permits to declare local variables in switch scope. Such variables exist + // in all following case clauses. In StaticTS, case clauses don't have a common + // scope, and allow only statements, not declarations. To work around this, we + // have to track whether a particular local variable has been referenced in another + // case clause and, in such case, move declaration of that variable in front of + // switch statement, additionally enclosing both variable declaration and switch + // statement, so that variables are only visible in context of switch statement. + + List javaVarFragments = javaVarDeclStmt.fragments(); + for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { + if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { + javaVariablesToMove.add(javaVarFragment); + + // Since evaluation of initializer expression can cause side effects, + // in order to preserve the behaviour and result of program, all + // expressions must evaluate in the same order as before. For that + // purpose, we move the variable declaration without initializer part + // and replace initialization with simple assignment. + Expression javaInitExpr = javaVarFragment.getInitializer(); + if (javaInitExpr != null) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); + + javaVarFragment.getName().accept(this); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitExpr.accept(this); + + popSingleExpression(); // AssignmentExpressionContext; + popStatement(); // ExpressionStatementContext + } + } else { + wrapCaseClauseStatementsWithBlock(); + + // For variables, that don't need to be moved, emit single variable + // declaration here to preserve the correct order of evaluation of + // initializer expressions (including assignments emitted for variables + // that are moved). + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); + popStatement(); // VariableOrConstantDeclarationContext + } + } + + ++countStmtTransformed; + } + + private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, + SwitchStatement javaSwitchStmt) { + IVariableBinding javaVarBinding = javaVarDecl.resolveBinding(); + + ASTVisitor localVarUsageLookupVisitor = new ASTVisitor() { + boolean done = false; + int nestedSwitchCount = 0; + SwitchCase currentSwitchCase = null; + + @Override + public boolean preVisit2(ASTNode javaNode) { + // This line will prevent from visiting further AST nodes, + // once we are done with the work. + return !done; + } + + @Override + public boolean visit(SimpleName javaName) { + IBinding binding = javaName.resolveBinding(); + + if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { + javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); + done = true; + } + + return false; + } + + @Override + public boolean visit(VariableDeclarationFragment javaVarDeclFragment) { + // Do NOT visit declaration of the variable that we are looking up. + return javaVarDeclFragment != javaVarDecl; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Do not change currentSwitchCase when visiting nested switch statements. + if (nestedSwitchCount == 0) { + currentSwitchCase = javaSwitchCase; + } + + return false; + } + + @Override + public boolean visit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount++; + return true; + } + + @Override + public void endVisit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount--; + } + }; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + javaStmt.accept(localVarUsageLookupVisitor); + + if (javaVarDecl.getProperty(USED_IN_ANOTHER_CASE_CLAUSE) != null) + return true; + } + + return false; + } + // The list of not yet translated Java Expressions: // CreationReference, // InstanceofExpression, // LambdaExpression, // SuperMethodReference, // TypeMethodReference - // TryStatement - // SynchronizedStatement - // ThrowStatement } -- Gitee From 6de84c55eac4d051516f21d97f0d9841076e31de Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 10 Aug 2022 14:28:27 +0300 Subject: [PATCH 38/60] Implemented translation of intersection types. Added a test to cover the changes above. Change-Id: Idfb2061e77bce95f36f8a676c54f385712a8d538 Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 2 -- migrator/test/java/intersection-type.java.sts | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 61c363bbe..c7e2497a0 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -937,8 +937,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // IntersectionTypeContext if (needPrimaryType) popCurrent(); // PrimaryTypeContext - - ++countTypeTransformed; return false; } diff --git a/migrator/test/java/intersection-type.java.sts b/migrator/test/java/intersection-type.java.sts index b8150eca6..be025281d 100644 --- a/migrator/test/java/intersection-type.java.sts +++ b/migrator/test/java/intersection-type.java.sts @@ -25,9 +25,9 @@ open class intersection_type { } open class auxilliary implements Runnable, Something { - public override run(): void { + public open run(): void { } - public override foo(): void { + public open foo(): void { } } -- Gitee From df447a0198716e4fa021850c1c90391d2428fe73 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 3 Aug 2022 17:17:16 +0300 Subject: [PATCH 39/60] Enum translation (incomplete). Also minor bugfix and housekeeping in JavaTransformer code. Changes to tests to account for all of the above. Change-Id: I244038b63e07240aed4a882cab6385a07a50c487 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 86 ++++++++++--------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index c7e2497a0..ab1f4c73e 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; @@ -1537,6 +1538,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // NOTE: All Java enums are translated into STS classes because of + // built-in methods values() and valueOf() available to the former! + // // Java tree: // VariableDeclarationFragment: // Identifier { Dimension } [ = Expression ] @@ -1629,6 +1633,44 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ClassBodyContext(stsCurrent, 0)); + // Translate enum constants. + // If any of the constants contain anonymous class body (e.g., extend enum type), + // add open modifier to the resulting class. + boolean needOpen = false; + List javaEnumConstNames = new ArrayList<>(); + List javaEnumConstants = javaEnumDeclaration.enumConstants(); + for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { + if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; + + // Pass enum name to enum constant node before visiting it + // as we'll need it to create appropriate initializers. + javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); + + // Store enum constant name in a list - we'll need it later to generate + // built-in values() method + javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); + + javaEnumConst.accept(this); + } + if (needOpen) { + stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); + } + + // Translate body declarations (ctors, methods, nested types, and fields). + List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); + for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { + javaEnumBodyDecl.accept(this); + } + + // TODO: valueOf(), toString() and ordinal() methods! + createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); + + popCurrent(); // ClassBodyContext + popCurrent(); // stsClassDecl + popCurrent(); // member context + + pushCurrent(new ClassBodyContext(stsCurrent, 0)); + // Translate enum constants. // If any of the constants contain anonymous class body (e.g., extend enum type), // add open modifier to the resulting class. @@ -1755,6 +1797,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { ++countDeclTransformed; return false; } + private void createEnumDefaultCtor() { pushCurrent(new ClassMemberContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PRIVATE)).setParent(stsCurrent); @@ -1771,46 +1814,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ClassMemberContext } - private void modifyEnumCtor(ConstructorDeclarationContext stsEnumCtor) { - // Get parameter list or create if there isn't one - ParameterListContext stsEnumCtorParams = stsEnumCtor.parameterList(); - if (stsEnumCtorParams == null) { - stsEnumCtorParams = new ParameterListContext(stsEnumCtor, 0); - stsEnumCtor.addChild(stsEnumCtorParams).setParent(stsEnumCtor); - } - - // Inject name and ordinal parameters - ParameterContext stsEnumCtorParam = NodeBuilder.parameter("name", "String"); - stsEnumCtorParams.children.add(0, stsEnumCtorParam); - stsEnumCtorParam.setParent(stsEnumCtorParams); - stsEnumCtorParam = NodeBuilder.parameter("ordinal", PrimitiveType.INT); - stsEnumCtorParams.children.add(1, stsEnumCtorParam); - stsEnumCtorParam.setParent(stsEnumCtorParams); - - ConstructorBodyContext stsEnumCtorBody = stsEnumCtor.constructorBody(); - ConstructorCallContext stsEnumCtorCall = stsEnumCtorBody.getRuleContext(ConstructorCallContext.class, 0); - if (stsEnumCtorCall == null) { - // Create super(name, ordinal) call - stsEnumCtorBody.addChild(NodeBuilder.ctorCall(true, "name", "ordinal")).setParent(stsEnumCtorBody); - } - else { - // Pass name and ordinal parameters to ctor call - ArgumentsContext stsEnumCtorCallArgs = stsEnumCtorCall.arguments(); - ExpressionSequenceContext stsExprSeq = stsEnumCtorCallArgs.expressionSequence(); - if (stsExprSeq == null) { - // Create expression sequence node, if necessary - stsExprSeq = new ExpressionSequenceContext(stsEnumCtorCallArgs, 0); - stsEnumCtorCallArgs.addChild(stsExprSeq).setParent(stsEnumCtorCallArgs); - } - - SingleExpressionContext stsEnumCtorCallArg = NodeBuilder.identifierExpression("name"); - stsExprSeq.children.add(0, stsEnumCtorCallArg); - stsEnumCtorCallArg.setParent(stsExprSeq); - stsEnumCtorCallArg = NodeBuilder.identifierExpression("ordinal"); - stsExprSeq.children.add(1, stsEnumCtorCallArg); - stsEnumCtorCallArg.setParent(stsExprSeq); - } - } private void createEnumExtendsClause(String javaEnumName) { // Note: A Java enum extends Enum class. pushCurrent(new ClassExtendsClauseContext(stsCurrent, 0)); @@ -1829,6 +1832,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeReferenceContext popCurrent(); // ClassExtendsClauseContext } + private void pushEnumBuiltinMethod() { // Create class member context and add public modifier pushCurrent(new ClassMemberContext(stsCurrent, 0)); @@ -1839,6 +1843,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ClassMethodWithBodyContext((ClassMethodDeclarationContext)stsCurrent)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); } + private void popEnumBuiltinMethod() { popCurrent(); // ClassMethodWithBodyContext popCurrent(); // ClassMethodDeclarationContext @@ -1952,6 +1957,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popEnumBuiltinMethod(); } + @Override public boolean visit(EnumConstantDeclaration javaEnumConstant) { // Create class member context and add public modifier -- Gitee From 5409547004bda2b88dd36b86ad9fda8a63891f7f Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 5 Aug 2022 17:36:14 +0300 Subject: [PATCH 40/60] Inject name and ordinal args into enum class ctor calls. Generate default enum class ctor if no explicit ctor exists. Change-Id: Ibc07d16cef715a2412a048b6399ca75c1798cdae Signed-off-by: Mikhail Velikanov --- .../com/ohos/migrator/java/JavaTransformer.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index ab1f4c73e..dfede6203 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1637,29 +1637,42 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // If any of the constants contain anonymous class body (e.g., extend enum type), // add open modifier to the resulting class. boolean needOpen = false; + int javaEnumConstOrdinal = 0; List javaEnumConstNames = new ArrayList<>(); List javaEnumConstants = javaEnumDeclaration.enumConstants(); for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; - // Pass enum name to enum constant node before visiting it + // Pass enum name and ordinal to enum constant node before visiting it // as we'll need it to create appropriate initializers. javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); + javaEnumConst.setProperty(ENUM_CONST_ORDINAL, String.valueOf(javaEnumConstOrdinal)); // Store enum constant name in a list - we'll need it later to generate // built-in values() method javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); javaEnumConst.accept(this); + ++javaEnumConstOrdinal; } if (needOpen) { stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); } // Translate body declarations (ctors, methods, nested types, and fields). + boolean hasCtors = false; List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { javaEnumBodyDecl.accept(this); + if (!hasCtors) { + if (javaEnumBodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION) { + MethodDeclaration javaEnumMethodDecl = (MethodDeclaration) javaEnumBodyDecl; + hasCtors = javaEnumMethodDecl.isConstructor(); + } + else { + hasCtors = javaEnumBodyDecl.getNodeType() == ASTNode.INITIALIZER; + } + } } // TODO: valueOf(), toString() and ordinal() methods! @@ -1957,7 +1970,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popEnumBuiltinMethod(); } - + @Override public boolean visit(EnumConstantDeclaration javaEnumConstant) { // Create class member context and add public modifier -- Gitee From 82cc530085d5ce26af184bf3ea69a716ef9648f7 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 12 Aug 2022 14:36:07 +0300 Subject: [PATCH 41/60] Emit dummy calls for as yet untranslated Java constructs. The original syntax of these constructs is placed inside emitted calls for reference. This is done to avoid emitting invalid STS ASTs that cause exceptions in StaticTSWriter. Change-Id: I1d2b361dbdc3e54f032fa2fb85f649a1b4b9a187 Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index dfede6203..dbe4e3fb1 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -4021,4 +4021,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // LambdaExpression, // SuperMethodReference, // TypeMethodReference + // TryStatement + // SynchronizedStatement + // ThrowStatement } -- Gitee From 021ff820cb74284b8621b9790fc5bdef6a5fcafb Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Fri, 5 Aug 2022 16:29:37 +0300 Subject: [PATCH 42/60] ExpressionMethodReference translation is implemented. A few bugs in generics translation are fixed. Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index dbe4e3fb1..53e874925 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -4015,6 +4015,142 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier + // STS tree: + // singleExpression: + // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // lambdaBody: singleExpression | block; + @Override + public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { + pushCurrent(new LambdaExpressionContext(pushSingleExpression())); + + javaExpressionMethodReference.getExpression().accept(this); + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + stsCurrent.removeLastChild(); + assert(lastChild instanceof SingleExpressionContext); + SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; + + // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); + // parameterList: parameter... + pushCurrent(new ParameterListContext(stsCurrent, 0)); + // parameter: Identifier typeAnnotation + pushCurrent(new ParameterContext(stsCurrent, 0)); + + // TODO: Check if the fixed object name used here may cause a names conflict. + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. + assert (stsTypeExpr.getChildCount() == 1); + ParseTree stsNode = stsTypeExpr.getChild(0); + if (stsNode instanceof IdentifierExpressionContext) { + String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); + stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); + } + else { + // TODO: May it ever happens? + assert false; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + popCurrent(); // ParameterContext + popCurrent(); // ParameterListContext + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. + + IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); + ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + if (javaReturnType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaReturnType.isEnum()) { + // TODO: + } else if (javaReturnType.isArray()) { + // TODO: + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + + ITypeBinding javaElementType = javaReturnType.getElementType(); + if (javaElementType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaElementType.isClass() || javaElementType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaElementType.isEnum()) { + // TODO: + } else { + // Is this ever can be in case of array type? + assert false; + } + + int numDims = javaReturnType.getDimensions(); + for (int i = 0; i < numDims; ++i) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); + } + + popCurrent(); // ArrayTypeContext + } else { + assert false : "Need implementation of the translation"; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + // TODO: translation of type arguments. +// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); +// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { +// translateTypeArgumens(javaTypeArguments); +// } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); + // lambdaBody: singleExpression | block + // Use here + // singleExpression: + // | singleExpression typeArguments? arguments # CallExpression + // to produce object_arg.method_name() + pushCurrent(new LambdaBodyContext(stsCurrent, 0)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + + // | singleExpression Dot identifier # MemberAccessExpression + pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); + // singleExpression + // | Identifier IdentifierExpression + pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); + popSingleExpression(); // IdentifierExpressionContext + + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); + popSingleExpression(); // MemberAccessExpressionContext + + //translateTypeArguments(javaMethodInvocation.typeArguments()); + //translateArguments(javaMethodInvocation.arguments()); + stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. + + popSingleExpression(); // CallExpressionContext + popCurrent(); // LambdaBodyContext + popSingleExpression(); // LambdaExpressionContext + + ++countExprTransformed; + + return false; + } + // The list of not yet translated Java Expressions: // CreationReference, // InstanceofExpression, -- Gitee From e9a04bf1f159d752ae30a226225f741858f6fa61 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Mon, 29 Aug 2022 13:01:35 +0300 Subject: [PATCH 43/60] Just comments are corrected in the code Change-Id: I4b71e1d484c268e75e1e6b7c47b7ab7a2764e3d5 Signed-off-by: Alexander Pavlyuk --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 2 -- migrator/test/java/generic_class_1.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 53e874925..06f052138 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -4153,8 +4153,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // The list of not yet translated Java Expressions: // CreationReference, - // InstanceofExpression, - // LambdaExpression, // SuperMethodReference, // TypeMethodReference // TryStatement diff --git a/migrator/test/java/generic_class_1.java b/migrator/test/java/generic_class_1.java index 838e687d1..1b15fde1e 100644 --- a/migrator/test/java/generic_class_1.java +++ b/migrator/test/java/generic_class_1.java @@ -25,4 +25,4 @@ class ReprChange, S extends ConvertibleTo> { T t; void set(S s) { t = s.convert(); } S get() { return t.convert(); } -} \ No newline at end of file + } \ No newline at end of file -- Gitee From 8be4840b9ef62903e266d2b94f2f3584ea4a8fc1 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Mon, 29 Aug 2022 15:30:14 +0300 Subject: [PATCH 44/60] Post merge fix 1 Change-Id: Ifd0cf93b777a2bb49e1f185261a7e02460db4849 Signed-off-by: Alexander Pavlyuk --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 06f052138..ea5328a06 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -46,10 +46,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; - private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; - - private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; - private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; -- Gitee From e5af4da44f02000855b3b5c2dbace3936e5e9296 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Tue, 30 Aug 2022 15:27:33 +0300 Subject: [PATCH 45/60] Post merge fix 3 Change-Id: I5f7fe841cadeb90dc4b8a4fa8ced3d20a4f57c0a Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 460 ++---------------- .../ohos/migrator/staticTS/NodeBuilder.java | 29 +- .../staticTS/parser/StaticTSParser.g4 | 6 +- .../staticTS/writer/StaticTSWriter.java | 25 +- migrator/test/java/generic_class_1.java.sts | 3 +- migrator/test/java/generic_class_2.java.sts | 11 +- migrator/test/java/generic_class_3.java.sts | 4 +- migrator/test/java/intersection-type.java.sts | 4 +- 8 files changed, 93 insertions(+), 449 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index ea5328a06..8163ecdb9 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -245,11 +245,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return true; } - for (ITypeBinding javaInterface : javaClassBinding.getInterfaces()) { - if (doesOverride(javaInterface, javaCheckedMethod)) - return true; - } - ITypeBinding javaSuperClassBinding = javaClassBinding.getSuperclass(); if (javaSuperClassBinding != null) return doesOverride(javaSuperClassBinding, javaCheckedMethod); @@ -493,7 +488,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ConstraintContext } - popCurrent(); // TypeParameterContext return false; } @@ -833,7 +827,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeArgumentListContext popCurrent(); // TypeArgumentsContext - } @Override @@ -934,6 +927,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // IntersectionTypeContext if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -1823,6 +1818,47 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ClassMemberContext } + private void modifyEnumCtor(ConstructorDeclarationContext stsEnumCtor) { + // Get parameter list or create if there isn't one + ParameterListContext stsEnumCtorParams = stsEnumCtor.parameterList(); + if (stsEnumCtorParams == null) { + stsEnumCtorParams = new ParameterListContext(stsEnumCtor, 0); + stsEnumCtor.addChild(stsEnumCtorParams).setParent(stsEnumCtor); + } + + // Inject name and ordinal parameters + ParameterContext stsEnumCtorParam = NodeBuilder.parameter("name", "String"); + stsEnumCtorParams.children.add(0, stsEnumCtorParam); + stsEnumCtorParam.setParent(stsEnumCtorParams); + stsEnumCtorParam = NodeBuilder.parameter("ordinal", PrimitiveType.INT); + stsEnumCtorParams.children.add(1, stsEnumCtorParam); + stsEnumCtorParam.setParent(stsEnumCtorParams); + + ConstructorBodyContext stsEnumCtorBody = stsEnumCtor.constructorBody(); + ConstructorCallContext stsEnumCtorCall = stsEnumCtorBody.getRuleContext(ConstructorCallContext.class, 0); + if (stsEnumCtorCall == null) { + // Create super(name, ordinal) call + stsEnumCtorBody.addChild(NodeBuilder.ctorCall(true, "name", "ordinal")).setParent(stsEnumCtorBody); + } + else { + // Pass name and ordinal parameters to ctor call + ArgumentsContext stsEnumCtorCallArgs = stsEnumCtorCall.arguments(); + ExpressionSequenceContext stsExprSeq = stsEnumCtorCallArgs.expressionSequence(); + if (stsExprSeq == null) { + // Create expression sequence node, if necessary + stsExprSeq = new ExpressionSequenceContext(stsEnumCtorCallArgs, 0); + stsEnumCtorCallArgs.addChild(stsExprSeq).setParent(stsEnumCtorCallArgs); + } + + SingleExpressionContext stsEnumCtorCallArg = NodeBuilder.identifierExpression("name"); + stsExprSeq.children.add(0, stsEnumCtorCallArg); + stsEnumCtorCallArg.setParent(stsExprSeq); + stsEnumCtorCallArg = NodeBuilder.identifierExpression("ordinal"); + stsExprSeq.children.add(1, stsEnumCtorCallArg); + stsEnumCtorCallArg.setParent(stsExprSeq); + } + } + private void createEnumExtendsClause(String javaEnumName) { // Note: A Java enum extends Enum class. pushCurrent(new ClassExtendsClauseContext(stsCurrent, 0)); @@ -2883,7 +2919,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Dot Identifier # MemberAccessExpression - // where the next singleExpression is + // where the next singleExpresion is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(SuperFieldAccess javaSuperFieldAccess) { @@ -2911,7 +2947,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Instanceof primaryType # instanceofExpression - // where the next singleExpression is + // where the next singleExpresion is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(InstanceofExpression javaInstanceofExpr) { @@ -3370,6 +3406,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // statement, so that variables are only visible in context of switch statement. List javaVarFragments = javaVarDeclStmt.fragments(); + for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { javaVariablesToMove.add(javaVarFragment); @@ -3688,21 +3725,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // TypeDeclarationStatement: - // TypeDeclaration - // EnumDeclaration - // STS tree: - // statementOrLocalDeclaration: - // | classDeclaration - // | enumDeclaration - @Override - public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { - javaTypeDeclarationStmt.getDeclaration().accept(this); - - ++countStmtTransformed; - return false; - } - // Java tree: // SuperMethodReference: // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier @@ -3718,87 +3740,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // switch ( Expression ) - // { { SwitchCase | Statement } } - // SwitchCase: - // case Expression : - // default : - // STS tree: - // switchStatement: - // switch OpenParen singleExpression CloseParen caseBlock - // caseBlock: - // OpenBrace caseClause* defaultClause? caseClause* CloseBrace - // caseClause: - // case singleExpression ':' statement* - // defaultClause: - // default ':' statement* - @Override - public boolean visit(SwitchStatement javaSwitchStmt) { - SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); - pushStatement(stsSwitch); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); - - javaSwitchStmt.getExpression().accept(this); - - CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); - pushCurrent(stsCaseBlock); - - List javaVariablesToMove = new ArrayList<>(); - SwitchCase javaCurrentSwitchCase = null; - - List javaStmts = javaSwitchStmt.statements(); - for (Statement javaStmt : javaStmts) { - if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { - javaCurrentSwitchCase = (SwitchCase) javaStmt; - } - else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { - wrapCaseClauseStatementsWithBlock(); - } - else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { - processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, - javaSwitchStmt, javaVariablesToMove); - - // We've already processed variable declaration, proceed to the next statement. - continue; - } - - javaStmt.accept(this); - } - - // Close the last case clause. - popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext - - popCurrent(); // CaseBlockContext - popStatement(); // SwitchStatementContext - - // Move variable declarations in front of switch statement, and enclose both - // declarations and switch with additional block. - if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { - // Remove switch statement from current STS node. - stsCurrent.removeLastChild(); - - BlockContext stsBlock = new BlockContext(stsCurrent, 0); - pushStatement(stsBlock); - - for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { - VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); - - pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); - popStatement(); // VariableOrConstantDeclarationContext - } - - pushStatement(stsSwitch); - popStatement(); // SwitchContext - - popStatement(); // BlockContext - } - - ++countStmtTransformed; - - return false; - } - @Override public boolean visit(TypeMethodReference javaTypeMethodRef) { // TODO: To be implemented @@ -3838,315 +3779,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - public boolean visit(SwitchCase javaSwitchCase) { - // Close the last case clause. - popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext - - if (javaSwitchCase.isDefault()) { - pushCurrent(new DefaultClauseContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); - } else { - pushCurrent(new CaseClauseContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); - javaSwitchCase.getExpression().accept(this); - } - - // SwitchCase is treated as Statement node, thus increment the count. - ++countStmtTransformed; - return false; - } - - private void popCaseClauseIfNeeded() { - // Check if we need to pop additional block added as work around to add - // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() - // method for details). - if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) { - popStatement(); // BlockContext - } - - if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause - || stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause) { - popCurrent(); // CaseClauseContext | DefaultClauseContext - } - } - - private void wrapCaseClauseStatementsWithBlock() { - // In StaticTS, CaseClause may contain only statements, and is not allowed to - // have local declarations. In contrast, Java permits to have local declarations - // in case clause scope, so when encounter one, wrap up all statements in case clause - // with additional block as a workaround, (since block can have local declarations). - - // Check if already inserted additional block. - if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) - return; - - assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || - stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; - - List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); - stsCurrent.children.removeAll(stsCaseStmts); - - BlockContext stsBlock = new BlockContext(stsCurrent, 0); - pushStatement(stsBlock); - for (StatementContext stsStmt : stsCaseStmts) { - StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); - stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); - stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); - } - } - - - private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, - SwitchStatement javaSwitchStmt, List javaVariablesToMove) { - // Java permits to declare local variables in switch scope. Such variables exist - // in all following case clauses. In StaticTS, case clauses don't have a common - // scope, and allow only statements, not declarations. To work around this, we - // have to track whether a particular local variable has been referenced in another - // case clause and, in such case, move declaration of that variable in front of - // switch statement, additionally enclosing both variable declaration and switch - // statement, so that variables are only visible in context of switch statement. - - List javaVarFragments = javaVarDeclStmt.fragments(); - for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { - if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { - javaVariablesToMove.add(javaVarFragment); - - // Since evaluation of initializer expression can cause side effects, - // in order to preserve the behaviour and result of program, all - // expressions must evaluate in the same order as before. For that - // purpose, we move the variable declaration without initializer part - // and replace initialization with simple assignment. - Expression javaInitExpr = javaVarFragment.getInitializer(); - if (javaInitExpr != null) { - pushStatement(new ExpressionStatementContext(stsCurrent, 0)); - pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); - - javaVarFragment.getName().accept(this); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitExpr.accept(this); - - popSingleExpression(); // AssignmentExpressionContext; - popStatement(); // ExpressionStatementContext - } - } else { - wrapCaseClauseStatementsWithBlock(); - - // For variables, that don't need to be moved, emit single variable - // declaration here to preserve the correct order of evaluation of - // initializer expressions (including assignments emitted for variables - // that are moved). - pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); - popStatement(); // VariableOrConstantDeclarationContext - } - } - - ++countStmtTransformed; - } - - private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, - SwitchStatement javaSwitchStmt) { - IVariableBinding javaVarBinding = javaVarDecl.resolveBinding(); - - ASTVisitor localVarUsageLookupVisitor = new ASTVisitor() { - boolean done = false; - int nestedSwitchCount = 0; - SwitchCase currentSwitchCase = null; - - @Override - public boolean preVisit2(ASTNode javaNode) { - // This line will prevent from visiting further AST nodes, - // once we are done with the work. - return !done; - } - - @Override - public boolean visit(SimpleName javaName) { - IBinding binding = javaName.resolveBinding(); - - if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { - javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); - done = true; - } - - return false; - } - - @Override - public boolean visit(VariableDeclarationFragment javaVarDeclFragment) { - // Do NOT visit declaration of the variable that we are looking up. - return javaVarDeclFragment != javaVarDecl; - } - - @Override - public boolean visit(SwitchCase javaSwitchCase) { - // Do not change currentSwitchCase when visiting nested switch statements. - if (nestedSwitchCount == 0) { - currentSwitchCase = javaSwitchCase; - } - - return false; - } - - @Override - public boolean visit(SwitchStatement javaSwitchStatement) { - nestedSwitchCount++; - return true; - } - - @Override - public void endVisit(SwitchStatement javaSwitchStatement) { - nestedSwitchCount--; - } - }; - - List javaStmts = javaSwitchStmt.statements(); - for (Statement javaStmt : javaStmts) { - javaStmt.accept(localVarUsageLookupVisitor); - - if (javaVarDecl.getProperty(USED_IN_ANOTHER_CASE_CLAUSE) != null) - return true; - } - - return false; - } - - // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier - // STS tree: - // singleExpression: - // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression - // lambdaBody: singleExpression | block; - @Override - public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { - pushCurrent(new LambdaExpressionContext(pushSingleExpression())); - - javaExpressionMethodReference.getExpression().accept(this); - ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); - stsCurrent.removeLastChild(); - assert(lastChild instanceof SingleExpressionContext); - SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; - - // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); - // parameterList: parameter... - pushCurrent(new ParameterListContext(stsCurrent, 0)); - // parameter: Identifier typeAnnotation - pushCurrent(new ParameterContext(stsCurrent, 0)); - - // TODO: Check if the fixed object name used here may cause a names conflict. - stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier - - // typeAnnotation: Colon primaryType - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); - // primaryType: predefinedType | typeReference | arrayType - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - - // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. - assert (stsTypeExpr.getChildCount() == 1); - ParseTree stsNode = stsTypeExpr.getChild(0); - if (stsNode instanceof IdentifierExpressionContext) { - String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); - stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); - } - else { - // TODO: May it ever happens? - assert false; - } - - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext - - popCurrent(); // ParameterContext - popCurrent(); // ParameterListContext - - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. - - IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); - ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); - - // typeAnnotation: Colon primaryType - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); - // primaryType: predefinedType | typeReference | arrayType - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - if (javaReturnType.isPrimitive()) { - stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); - } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { - stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); - } - else if (javaReturnType.isEnum()) { - // TODO: - } else if (javaReturnType.isArray()) { - // TODO: - pushCurrent(new ArrayTypeContext(stsCurrent, 0)); - - ITypeBinding javaElementType = javaReturnType.getElementType(); - if (javaElementType.isPrimitive()) { - stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); - } else if (javaElementType.isClass() || javaElementType.isInterface()) { - stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); - } - else if (javaElementType.isEnum()) { - // TODO: - } else { - // Is this ever can be in case of array type? - assert false; - } - - int numDims = javaReturnType.getDimensions(); - for (int i = 0; i < numDims; ++i) { - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); - } - - popCurrent(); // ArrayTypeContext - } else { - assert false : "Need implementation of the translation"; - } - - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext - - // TODO: translation of type arguments. -// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); -// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { -// translateTypeArgumens(javaTypeArguments); -// } - - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); - // lambdaBody: singleExpression | block - // Use here - // singleExpression: - // | singleExpression typeArguments? arguments # CallExpression - // to produce object_arg.method_name() - pushCurrent(new LambdaBodyContext(stsCurrent, 0)); - pushCurrent(new CallExpressionContext(pushSingleExpression())); - - // | singleExpression Dot identifier # MemberAccessExpression - pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); - // singleExpression - // | Identifier IdentifierExpression - pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); - stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); - popSingleExpression(); // IdentifierExpressionContext - - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); - popSingleExpression(); // MemberAccessExpressionContext - - //translateTypeArguments(javaMethodInvocation.typeArguments()); - //translateArguments(javaMethodInvocation.arguments()); - stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. - - popSingleExpression(); // CallExpressionContext - popCurrent(); // LambdaBodyContext - popSingleExpression(); // LambdaExpressionContext - - ++countExprTransformed; - - return false; - } - // The list of not yet translated Java Expressions: // CreationReference, // SuperMethodReference, diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 5b4d9fe62..c02eb1037 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -70,18 +70,27 @@ public class NodeBuilder { return qualifiedName(javaName.getFullyQualifiedName()); } - private static int stsTypeNameCode(PrimitiveType.Code javaTypeCode) { + private static int stsTypeNameCode(PrimitiveType.Code javaPrimitiveTypeCode) { int stsTypeNameCode = -1; - if (javaTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; - else if (javaTypeCode == PrimitiveType.BYTE) stsTypeNameCode = StaticTSParser.Byte; - else if (javaTypeCode == PrimitiveType.CHAR) stsTypeNameCode = StaticTSParser.Char; - else if (javaTypeCode == PrimitiveType.INT) stsTypeNameCode = StaticTSParser.Int; - else if (javaTypeCode == PrimitiveType.DOUBLE) stsTypeNameCode = StaticTSParser.Double; - else if (javaTypeCode == PrimitiveType.FLOAT) stsTypeNameCode = StaticTSParser.Float; - else if (javaTypeCode == PrimitiveType.LONG) stsTypeNameCode = StaticTSParser.Long; - else if (javaTypeCode == PrimitiveType.SHORT) stsTypeNameCode = StaticTSParser.Short; - else if (javaTypeCode == PrimitiveType.VOID) stsTypeNameCode = StaticTSParser.Void; + if (javaPrimitiveTypeCode == PrimitiveType.BOOLEAN) + stsTypeNameCode = StaticTSParser.Boolean; + else if (javaPrimitiveTypeCode == PrimitiveType.BYTE) + stsTypeNameCode = StaticTSParser.Byte; + else if (javaPrimitiveTypeCode == PrimitiveType.CHAR) + stsTypeNameCode = StaticTSParser.Char; + else if (javaPrimitiveTypeCode == PrimitiveType.INT) + stsTypeNameCode = StaticTSParser.Int; + else if (javaPrimitiveTypeCode == PrimitiveType.DOUBLE) + stsTypeNameCode = StaticTSParser.Double; + else if (javaPrimitiveTypeCode == PrimitiveType.FLOAT) + stsTypeNameCode = StaticTSParser.Float; + else if (javaPrimitiveTypeCode == PrimitiveType.LONG) + stsTypeNameCode = StaticTSParser.Long; + else if (javaPrimitiveTypeCode == PrimitiveType.SHORT) + stsTypeNameCode = StaticTSParser.Short; + else if (javaPrimitiveTypeCode == PrimitiveType.VOID) + stsTypeNameCode = StaticTSParser.Void; else assert false : "Unknown type"; diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 5009e8b90..de2cf22ee 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -373,7 +373,11 @@ switchStatement ; caseBlock - : OpenBrace caseClause* defaultClause? caseClause* CloseBrace + : OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace + ; + +caseClauses + : caseClause+ ; caseClause diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index efbf6ffcd..dcf7ceed6 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -119,12 +119,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeParameterList(stsTypeParameterList); } - if (sb.charAt(sb.length()-1) == '>') { - sb.append(" >"); - } - else { sb.append('>'); - } return null; } @@ -185,12 +180,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeArgumentList(stsTypeArgumentList); } - if (sb.charAt(sb.length()-1) == '>') { - sb.append(" >"); - } - else { sb.append('>'); - } return null; } @@ -1105,7 +1095,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // caseBlock: '{' caseClause* defaultClause? caseClause* '}' + // caseBlock: '{' leftCases=caseClauses? defaultClause? rightCases=caseClauses? '}' @Override public Void visitCaseBlock(CaseBlockContext stsCaseBlock) { if (!doNeededIndent()) { @@ -1115,7 +1105,18 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append("{\n"); indentIncrement(); - visitChildren(stsCaseBlock); + if (stsCaseBlock.leftCases != null) { + visitCaseClauses(stsCaseBlock.leftCases); + } + + DefaultClauseContext stsDefaultClause = stsCaseBlock.defaultClause(); + if (stsDefaultClause != null) { + visitDefaultClause(stsDefaultClause); + } + + if (stsCaseBlock.rightCases != null) { + visitCaseClauses(stsCaseBlock.rightCases); + } indentDecrement(); sb.append(indentCurrent).append("}\n"); diff --git a/migrator/test/java/generic_class_1.java.sts b/migrator/test/java/generic_class_1.java.sts index a49c7758f..192ed6b39 100644 --- a/migrator/test/java/generic_class_1.java.sts +++ b/migrator/test/java/generic_class_1.java.sts @@ -12,14 +12,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.ohos.migrator.test.java; interface ConvertibleTo { convert(): T ; } -open class ReprChange, S extends ConvertibleTo > { +open class ReprChange, S extends ConvertibleTo> { t : T ; open set(s : S): void { t = s.convert(); diff --git a/migrator/test/java/generic_class_2.java.sts b/migrator/test/java/generic_class_2.java.sts index 6331c3e71..1bd7124f4 100644 --- a/migrator/test/java/generic_class_2.java.sts +++ b/migrator/test/java/generic_class_2.java.sts @@ -11,8 +11,7 @@ * 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 Seq { @@ -31,13 +30,13 @@ open class Seq { return tail == null; } open class Zipper { - open zip(that : Seq): Seq > { + open zip(that : Seq): Seq> { if (isEmpty() || that.isEmpty()) { - return new Seq >(); + return new Seq>(); } else { let tailZipper : Seq.Zipper = new Zipper(); - return new Seq >(new Pair(head, that.head), tailZipper.zip(that.tail)); + return new Seq>(new Pair(head, that.head), tailZipper.zip(that.tail)); } } } @@ -59,7 +58,7 @@ open class Test { 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 combined : Seq > = zipper.zip(nums); + let combined : Seq> = zipper.zip(nums); } } diff --git a/migrator/test/java/generic_class_3.java.sts b/migrator/test/java/generic_class_3.java.sts index 0f3b3f74c..57906a9f8 100644 --- a/migrator/test/java/generic_class_3.java.sts +++ b/migrator/test/java/generic_class_3.java.sts @@ -11,7 +11,7 @@ * 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; @@ -47,7 +47,7 @@ open class C { } open class Main { - public static main(args : String): void { + public static main(args : String[]): void { let c : C = new C(); c.test1(); c.test2(); diff --git a/migrator/test/java/intersection-type.java.sts b/migrator/test/java/intersection-type.java.sts index be025281d..b8150eca6 100644 --- a/migrator/test/java/intersection-type.java.sts +++ b/migrator/test/java/intersection-type.java.sts @@ -25,9 +25,9 @@ open class intersection_type { } open class auxilliary implements Runnable, Something { - public open run(): void { + public override run(): void { } - public open foo(): void { + public override foo(): void { } } -- Gitee From f237ea97197ec310f9d08f32de9eb367a79a6028 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Tue, 30 Aug 2022 15:55:22 +0300 Subject: [PATCH 46/60] Post merge fix 4 Change-Id: I8d7977e88c594949f3a2335e3e4c0ba98f078c75 Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 237 ------------------ 1 file changed, 237 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 8163ecdb9..2d358978c 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1650,108 +1650,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); } - // Translate body declarations (ctors, methods, nested types, and fields). - boolean hasCtors = false; - List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); - for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { - javaEnumBodyDecl.accept(this); - if (!hasCtors) { - if (javaEnumBodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION) { - MethodDeclaration javaEnumMethodDecl = (MethodDeclaration) javaEnumBodyDecl; - hasCtors = javaEnumMethodDecl.isConstructor(); - } - else { - hasCtors = javaEnumBodyDecl.getNodeType() == ASTNode.INITIALIZER; - } - } - } - - // TODO: valueOf(), toString() and ordinal() methods! - createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); - - popCurrent(); // ClassBodyContext - popCurrent(); // stsClassDecl - popCurrent(); // member context - - pushCurrent(new ClassBodyContext(stsCurrent, 0)); - - // Translate enum constants. - // If any of the constants contain anonymous class body (e.g., extend enum type), - // add open modifier to the resulting class. - boolean needOpen = false; - int javaEnumConstOrdinal = 0; - List javaEnumConstNames = new ArrayList<>(); - List javaEnumConstants = javaEnumDeclaration.enumConstants(); - for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { - if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; - - // Pass enum name and ordinal to enum constant node before visiting it - // as we'll need it to create appropriate initializers. - javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); - javaEnumConst.setProperty(ENUM_CONST_ORDINAL, String.valueOf(javaEnumConstOrdinal)); - - // Store enum constant name in a list - we'll need it later to generate - // built-in values() method - javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); - - javaEnumConst.accept(this); - ++javaEnumConstOrdinal; - } - if (needOpen) { - stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); - } - - // Translate body declarations (ctors, methods, nested types, and fields). - boolean hasCtors = false; - List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); - for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { - javaEnumBodyDecl.accept(this); - if (!hasCtors) { - if (javaEnumBodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION) { - MethodDeclaration javaEnumMethodDecl = (MethodDeclaration) javaEnumBodyDecl; - hasCtors = javaEnumMethodDecl.isConstructor(); - } - else { - hasCtors = javaEnumBodyDecl.getNodeType() == ASTNode.INITIALIZER; - } - } - } - - // TODO: valueOf(), toString() and ordinal() methods! - createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); - - popCurrent(); // ClassBodyContext - popCurrent(); // stsClassDecl - popCurrent(); // member context - - pushCurrent(new ClassBodyContext(stsCurrent, 0)); - - // Translate enum constants. - // If any of the constants contain anonymous class body (e.g., extend enum type), - // add open modifier to the resulting class. - boolean needOpen = false; - int javaEnumConstOrdinal = 0; - List javaEnumConstNames = new ArrayList<>(); - List javaEnumConstants = javaEnumDeclaration.enumConstants(); - for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { - if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; - - // Pass enum name and ordinal to enum constant node before visiting it - // as we'll need it to create appropriate initializers. - javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); - javaEnumConst.setProperty(ENUM_CONST_ORDINAL, String.valueOf(javaEnumConstOrdinal)); - - // Store enum constant name in a list - we'll need it later to generate - // built-in values() method - javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); - - javaEnumConst.accept(this); - ++javaEnumConstOrdinal; - } - if (needOpen) { - stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); - } - // Translate body declarations (ctors, methods, nested types, and fields). boolean hasCtors = false; List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); @@ -3060,141 +2958,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } // Java tree: - // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier - // STS tree: - // singleExpression: - // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression - // lambdaBody: singleExpression | block; - @Override - public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { - pushCurrent(new LambdaExpressionContext(pushSingleExpression())); - - javaExpressionMethodReference.getExpression().accept(this); - ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); - stsCurrent.removeLastChild(); - assert(lastChild instanceof SingleExpressionContext); - SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; - - // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); - // parameterList: parameter... - pushCurrent(new ParameterListContext(stsCurrent, 0)); - // parameter: Identifier typeAnnotation - pushCurrent(new ParameterContext(stsCurrent, 0)); - - // TODO: Check if the fixed object name used here may cause a names conflict. - stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier - - // typeAnnotation: Colon primaryType - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); - // primaryType: predefinedType | typeReference | arrayType - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - - // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. - assert (stsTypeExpr.getChildCount() == 1); - ParseTree stsNode = stsTypeExpr.getChild(0); - if (stsNode instanceof IdentifierExpressionContext) { - String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); - stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); - } - else { - // TODO: May it ever happens? - assert false; - } - - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext - - popCurrent(); // ParameterContext - popCurrent(); // ParameterListContext - - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. - - IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); - ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); - - // typeAnnotation: Colon primaryType - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); - // primaryType: predefinedType | typeReference | arrayType - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - if (javaReturnType.isPrimitive()) { - stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); - } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { - stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); - } - else if (javaReturnType.isEnum()) { - // TODO: - } else if (javaReturnType.isArray()) { - // TODO: - pushCurrent(new ArrayTypeContext(stsCurrent, 0)); - - ITypeBinding javaElementType = javaReturnType.getElementType(); - if (javaElementType.isPrimitive()) { - stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); - } else if (javaElementType.isClass() || javaElementType.isInterface()) { - stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); - } - else if (javaElementType.isEnum()) { - // TODO: - } else { - // Is this ever can be in case of array type? - assert false; - } - - int numDims = javaReturnType.getDimensions(); - for (int i = 0; i < numDims; ++i) { - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); - } - - popCurrent(); // ArrayTypeContext - } else { - assert false : "Need implementation of the translation"; - } - - popCurrent(); // PrimaryTypeContext - popCurrent(); // TypeAnnotationContext - - // TODO: translation of type arguments. -// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); -// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { -// translateTypeArgumens(javaTypeArguments); -// } - - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); - // lambdaBody: singleExpression | block - // Use here - // singleExpression: - // | singleExpression typeArguments? arguments # CallExpression - // to produce object_arg.method_name() - pushCurrent(new LambdaBodyContext(stsCurrent, 0)); - pushCurrent(new CallExpressionContext(pushSingleExpression())); - - // | singleExpression Dot identifier # MemberAccessExpression - pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); - // singleExpression - // | Identifier IdentifierExpression - pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); - stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); - popSingleExpression(); // IdentifierExpressionContext - - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); - popSingleExpression(); // MemberAccessExpressionContext - - //translateTypeArguments(javaMethodInvocation.typeArguments()); - //translateArguments(javaMethodInvocation.arguments()); - stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. - - popSingleExpression(); // CallExpressionContext - popCurrent(); // LambdaBodyContext - popSingleExpression(); // LambdaExpressionContext - - ++countExprTransformed; - return false; - } - // TypeDeclarationStatement: // TypeDeclaration // EnumDeclaration -- Gitee From d36665cb0c1c5081a373c6a8388656dd251ac94a Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 25 Jul 2022 19:44:01 +0300 Subject: [PATCH 47/60] Switch statement + local type declaration. Change-Id: I341d05705db6c87ef7c0ac4c732e43e9382dabe2 Signed-off-by: Evgeniy Okolnov --- .../com/ohos/migrator/java/JavaTransformer.java | 1 + .../migrator/staticTS/parser/StaticTSParser.g4 | 6 +----- .../migrator/staticTS/writer/StaticTSWriter.java | 15 ++------------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 2d358978c..5f310a79f 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index de2cf22ee..5009e8b90 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -373,11 +373,7 @@ switchStatement ; caseBlock - : OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace - ; - -caseClauses - : caseClause+ + : OpenBrace caseClause* defaultClause? caseClause* CloseBrace ; caseClause diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index dcf7ceed6..3c056881d 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1095,7 +1095,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // caseBlock: '{' leftCases=caseClauses? defaultClause? rightCases=caseClauses? '}' + // caseBlock: '{' caseClause* defaultClause? caseClause* '}' @Override public Void visitCaseBlock(CaseBlockContext stsCaseBlock) { if (!doNeededIndent()) { @@ -1105,18 +1105,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append("{\n"); indentIncrement(); - if (stsCaseBlock.leftCases != null) { - visitCaseClauses(stsCaseBlock.leftCases); - } - - DefaultClauseContext stsDefaultClause = stsCaseBlock.defaultClause(); - if (stsDefaultClause != null) { - visitDefaultClause(stsDefaultClause); - } - - if (stsCaseBlock.rightCases != null) { - visitCaseClauses(stsCaseBlock.rightCases); - } + visitChildren(stsCaseBlock); indentDecrement(); sb.append(indentCurrent).append("}\n"); -- Gitee From 2575649707cff1b18b8534b1b26dbcb46b683d6c Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 3 Aug 2022 17:17:16 +0300 Subject: [PATCH 48/60] Enum translation (incomplete). Also minor bugfix and housekeeping in JavaTransformer code. Changes to tests to account for all of the above. Change-Id: I244038b63e07240aed4a882cab6385a07a50c487 Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 5f310a79f..0a87a9fac 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,14 +43,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; - private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; - private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; - private static int countStmtTotal = 0; private static int countExprTotal = 0; private static int countDeclTotal = 0; @@ -246,6 +243,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return true; } + for (ITypeBinding javaInterface : javaClassBinding.getInterfaces()) { + if (doesOverride(javaInterface, javaCheckedMethod)) + return true; + } + ITypeBinding javaSuperClassBinding = javaClassBinding.getSuperclass(); if (javaSuperClassBinding != null) return doesOverride(javaSuperClassBinding, javaCheckedMethod); -- Gitee From 2ebf26a05ee5f0a055bd1b36d41a2be6b4c21eac Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Fri, 5 Aug 2022 17:36:14 +0300 Subject: [PATCH 49/60] Inject name and ordinal args into enum class ctor calls. Generate default enum class ctor if no explicit ctor exists. Change-Id: Ibc07d16cef715a2412a048b6399ca75c1798cdae Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 0a87a9fac..ab9620e56 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -48,6 +48,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; + private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; private static int countStmtTotal = 0; private static int countExprTotal = 0; private static int countDeclTotal = 0; -- Gitee From a79c231cf4ed286d91dec30a4e598aca9044a2c6 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Fri, 5 Aug 2022 16:29:37 +0300 Subject: [PATCH 50/60] ExpressionMethodReference translation is implemented. A few bugs in generics translation are fixed. Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 4 +-- .../ohos/migrator/staticTS/NodeBuilder.java | 27 +++++++------------ .../staticTS/writer/StaticTSWriter.java | 10 +++++++ migrator/test/java/generic_class_1.java | 4 +-- migrator/test/java/generic_class_1.java.sts | 1 - migrator/test/java/generic_class_2.java.sts | 3 +-- migrator/test/java/generic_class_3.java.sts | 3 +-- 7 files changed, 25 insertions(+), 27 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index ab9620e56..578c54855 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -2821,7 +2821,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Dot Identifier # MemberAccessExpression - // where the next singleExpresion is + // where the next singleExpression is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(SuperFieldAccess javaSuperFieldAccess) { @@ -2849,7 +2849,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Instanceof primaryType # instanceofExpression - // where the next singleExpresion is + // where the next singleExpression is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(InstanceofExpression javaInstanceofExpr) { diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index c02eb1037..51b6c3160 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -73,24 +73,15 @@ public class NodeBuilder { private static int stsTypeNameCode(PrimitiveType.Code javaPrimitiveTypeCode) { int stsTypeNameCode = -1; - if (javaPrimitiveTypeCode == PrimitiveType.BOOLEAN) - stsTypeNameCode = StaticTSParser.Boolean; - else if (javaPrimitiveTypeCode == PrimitiveType.BYTE) - stsTypeNameCode = StaticTSParser.Byte; - else if (javaPrimitiveTypeCode == PrimitiveType.CHAR) - stsTypeNameCode = StaticTSParser.Char; - else if (javaPrimitiveTypeCode == PrimitiveType.INT) - stsTypeNameCode = StaticTSParser.Int; - else if (javaPrimitiveTypeCode == PrimitiveType.DOUBLE) - stsTypeNameCode = StaticTSParser.Double; - else if (javaPrimitiveTypeCode == PrimitiveType.FLOAT) - stsTypeNameCode = StaticTSParser.Float; - else if (javaPrimitiveTypeCode == PrimitiveType.LONG) - stsTypeNameCode = StaticTSParser.Long; - else if (javaPrimitiveTypeCode == PrimitiveType.SHORT) - stsTypeNameCode = StaticTSParser.Short; - else if (javaPrimitiveTypeCode == PrimitiveType.VOID) - stsTypeNameCode = StaticTSParser.Void; + if (javaTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; + else if (javaTypeCode == PrimitiveType.BYTE) stsTypeNameCode = StaticTSParser.Byte; + else if (javaTypeCode == PrimitiveType.CHAR) stsTypeNameCode = StaticTSParser.Char; + else if (javaTypeCode == PrimitiveType.INT) stsTypeNameCode = StaticTSParser.Int; + else if (javaTypeCode == PrimitiveType.DOUBLE) stsTypeNameCode = StaticTSParser.Double; + else if (javaTypeCode == PrimitiveType.FLOAT) stsTypeNameCode = StaticTSParser.Float; + else if (javaTypeCode == PrimitiveType.LONG) stsTypeNameCode = StaticTSParser.Long; + else if (javaTypeCode == PrimitiveType.SHORT) stsTypeNameCode = StaticTSParser.Short; + else if (javaTypeCode == PrimitiveType.VOID) stsTypeNameCode = StaticTSParser.Void; else assert false : "Unknown type"; diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 3c056881d..efbf6ffcd 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -119,7 +119,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeParameterList(stsTypeParameterList); } + if (sb.charAt(sb.length()-1) == '>') { + sb.append(" >"); + } + else { sb.append('>'); + } return null; } @@ -180,7 +185,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeArgumentList(stsTypeArgumentList); } + if (sb.charAt(sb.length()-1) == '>') { + sb.append(" >"); + } + else { sb.append('>'); + } return null; } diff --git a/migrator/test/java/generic_class_1.java b/migrator/test/java/generic_class_1.java index 1b15fde1e..d84732865 100644 --- a/migrator/test/java/generic_class_1.java +++ b/migrator/test/java/generic_class_1.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.ohos.migrator.test.java; +package com.ohos.migrator.test.java; // Java specification Example 8.1.2-1. Mutually Recursive Type Variable Bounds: @@ -25,4 +25,4 @@ class ReprChange, S extends ConvertibleTo> { T t; void set(S s) { t = s.convert(); } S get() { return t.convert(); } - } \ No newline at end of file + } diff --git a/migrator/test/java/generic_class_1.java.sts b/migrator/test/java/generic_class_1.java.sts index 192ed6b39..797cf4735 100644 --- a/migrator/test/java/generic_class_1.java.sts +++ b/migrator/test/java/generic_class_1.java.sts @@ -27,4 +27,3 @@ open class ReprChange, S extends ConvertibleTo> { return t.convert(); } } - diff --git a/migrator/test/java/generic_class_2.java.sts b/migrator/test/java/generic_class_2.java.sts index 1bd7124f4..cad39bcf5 100644 --- a/migrator/test/java/generic_class_2.java.sts +++ b/migrator/test/java/generic_class_2.java.sts @@ -11,7 +11,7 @@ * 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 Seq { @@ -61,4 +61,3 @@ open class Test { let combined : Seq> = zipper.zip(nums); } } - diff --git a/migrator/test/java/generic_class_3.java.sts b/migrator/test/java/generic_class_3.java.sts index 57906a9f8..716211aab 100644 --- a/migrator/test/java/generic_class_3.java.sts +++ b/migrator/test/java/generic_class_3.java.sts @@ -11,7 +11,7 @@ * 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; @@ -53,4 +53,3 @@ open class Main { c.test2(); } } - -- Gitee From 864af640cb086741b638dc35ed36d48588a50484 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 25 Jul 2022 19:44:01 +0300 Subject: [PATCH 51/60] Switch statement + local type declaration. Change-Id: I341d05705db6c87ef7c0ac4c732e43e9382dabe2 Signed-off-by: Evgeniy Okolnov --- .../ohos/migrator/java/JavaTransformer.java | 173 +++++++++++++++--- 1 file changed, 152 insertions(+), 21 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 578c54855..dfd11b2bf 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; @@ -3493,27 +3494,102 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } // Java tree: - // SuperMethodReference: - // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier + // switch ( Expression ) + // { { SwitchCase | Statement } } + // SwitchCase: + // case Expression : + // default : // STS tree: - // TODO: lambda ? + // switchStatement: + // switch OpenParen singleExpression CloseParen caseBlock + // caseBlock: + // OpenBrace caseClause* defaultClause? caseClause* CloseBrace + // caseClause: + // case singleExpression ':' statement* + // defaultClause: + // default ':' statement* @Override - public boolean visit(SuperMethodReference javaSuperMethodReference) { - // TODO: To be implemented - // Emit __untranslated_expression call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaSuperMethodReference)).setParent(stsCurrent); + public boolean visit(SwitchStatement javaSwitchStmt) { + SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); + pushStatement(stsSwitch); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); + javaSwitchStmt.getExpression().accept(this); + + CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); + pushCurrent(stsCaseBlock); + + List javaVariablesToMove = new ArrayList<>(); + SwitchCase javaCurrentSwitchCase = null; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { + javaCurrentSwitchCase = (SwitchCase) javaStmt; + } + else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { + wrapCaseClauseStatementsWithBlock(); + } + else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { + processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, + javaSwitchStmt, javaVariablesToMove); + + // We've already processed variable declaration, proceed to the next statement. + continue; + } + + javaStmt.accept(this); + } + + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + popCurrent(); // CaseBlockContext + popStatement(); // SwitchStatementContext + + // Move variable declarations in front of switch statement, and enclose both + // declarations and switch with additional block. + if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { + // Remove switch statement from current STS node. + stsCurrent.removeLastChild(); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + + for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { + VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); + + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); + popStatement(); // VariableOrConstantDeclarationContext + } + + pushStatement(stsSwitch); + popStatement(); // SwitchContext + + popStatement(); // BlockContext + } + + ++countStmtTransformed; return false; } @Override - public boolean visit(TypeMethodReference javaTypeMethodRef) { - // TODO: To be implemented - // Emit __untranslated_expression call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaTypeMethodRef)).setParent(stsCurrent); + public boolean visit(SwitchCase javaSwitchCase) { + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + if (javaSwitchCase.isDefault()) { + pushCurrent(new DefaultClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); + } else { + pushCurrent(new CaseClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); + javaSwitchCase.getExpression().accept(this); + } + // SwitchCase is treated as Statement node, thus increment the count. + ++countStmtTransformed; return false; } @@ -3524,17 +3600,72 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaTryStatement)).setParent(stsCurrent); - return false; + // Check if already inserted additional block. + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) + return; + + assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || + stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; + + List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); + stsCurrent.children.removeAll(stsCaseStmts); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + for (StatementContext stsStmt : stsCaseStmts) { + StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); + stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); + stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); + } } - @Override - public boolean visit(ThrowStatement javaThrowStatement) { - // TODO: To be implemented - // Emit __untranslated_statement call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaThrowStatement)).setParent(stsCurrent); - return false; + private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, + SwitchStatement javaSwitchStmt, List javaVariablesToMove) { + // Java permits to declare local variables in switch scope. Such variables exist + // in all following case clauses. In StaticTS, case clauses don't have a common + // scope, and allow only statements, not declarations. To work around this, we + // have to track whether a particular local variable has been referenced in another + // case clause and, in such case, move declaration of that variable in front of + // switch statement, additionally enclosing both variable declaration and switch + // statement, so that variables are only visible in context of switch statement. + + List javaVarFragments = javaVarDeclStmt.fragments(); + for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { + if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { + javaVariablesToMove.add(javaVarFragment); + + // Since evaluation of initializer expression can cause side effects, + // in order to preserve the behaviour and result of program, all + // expressions must evaluate in the same order as before. For that + // purpose, we move the variable declaration without initializer part + // and replace initialization with simple assignment. + Expression javaInitExpr = javaVarFragment.getInitializer(); + if (javaInitExpr != null) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); + + javaVarFragment.getName().accept(this); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitExpr.accept(this); + + popSingleExpression(); // AssignmentExpressionContext; + popStatement(); // ExpressionStatementContext + } + } else { + wrapCaseClauseStatementsWithBlock(); + + // For variables, that don't need to be moved, emit single variable + // declaration here to preserve the correct order of evaluation of + // initializer expressions (including assignments emitted for variables + // that are moved). + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); + popStatement(); // VariableOrConstantDeclarationContext + } + } + + ++countStmtTransformed; } @Override -- Gitee From 9dff90f4d72a3b3329569dc282c91cc6f78331f9 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 3 Aug 2022 17:17:16 +0300 Subject: [PATCH 52/60] Enum translation (incomplete). Also minor bugfix and housekeeping in JavaTransformer code. Changes to tests to account for all of the above. Change-Id: I244038b63e07240aed4a882cab6385a07a50c487 Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index dfd11b2bf..a3efbff5a 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,7 +43,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; - private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; -- Gitee From d127b303576c5f8205cb84d61d9d3427ab7347d7 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Fri, 26 Aug 2022 14:46:51 +0300 Subject: [PATCH 53/60] Post merge fix. Change-Id: Ice2b97d7236369f3688e3eef74f3ecf3aa724b6d Signed-off-by: Alexander Pavlyuk --- migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 51b6c3160..5b4d9fe62 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -70,7 +70,7 @@ public class NodeBuilder { return qualifiedName(javaName.getFullyQualifiedName()); } - private static int stsTypeNameCode(PrimitiveType.Code javaPrimitiveTypeCode) { + private static int stsTypeNameCode(PrimitiveType.Code javaTypeCode) { int stsTypeNameCode = -1; if (javaTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; -- Gitee From 7412ae9eb8af1b7f950a9b1002a7c70ce96f84bf Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 25 Jul 2022 19:44:01 +0300 Subject: [PATCH 54/60] Switch statement + local type declaration. Change-Id: I341d05705db6c87ef7c0ac4c732e43e9382dabe2 Signed-off-by: Evgeniy Okolnov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index a3efbff5a..dfd11b2bf 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; -- Gitee From eb56fac3f6f4bd96b62c20bc16ba0571e58a3caf Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 3 Aug 2022 17:17:16 +0300 Subject: [PATCH 55/60] Enum translation (incomplete). Also minor bugfix and housekeeping in JavaTransformer code. Changes to tests to account for all of the above. Change-Id: I244038b63e07240aed4a882cab6385a07a50c487 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index dfd11b2bf..11dafc10e 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; @@ -1629,6 +1630,44 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ClassBodyContext(stsCurrent, 0)); + // Translate enum constants. + // If any of the constants contain anonymous class body (e.g., extend enum type), + // add open modifier to the resulting class. + boolean needOpen = false; + List javaEnumConstNames = new ArrayList<>(); + List javaEnumConstants = javaEnumDeclaration.enumConstants(); + for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { + if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; + + // Pass enum name to enum constant node before visiting it + // as we'll need it to create appropriate initializers. + javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); + + // Store enum constant name in a list - we'll need it later to generate + // built-in values() method + javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); + + javaEnumConst.accept(this); + } + if (needOpen) { + stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); + } + + // Translate body declarations (ctors, methods, nested types, and fields). + List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); + for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { + javaEnumBodyDecl.accept(this); + } + + // TODO: valueOf(), toString() and ordinal() methods! + createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); + + popCurrent(); // ClassBodyContext + popCurrent(); // stsClassDecl + popCurrent(); // member context + + pushCurrent(new ClassBodyContext(stsCurrent, 0)); + // Translate enum constants. // If any of the constants contain anonymous class body (e.g., extend enum type), // add open modifier to the resulting class. -- Gitee From f394469a7b1f21454c52e16c278db35c7d134a07 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 25 Jul 2022 19:44:01 +0300 Subject: [PATCH 56/60] Switch statement + local type declaration. Change-Id: I341d05705db6c87ef7c0ac4c732e43e9382dabe2 Signed-off-by: Evgeniy Okolnov --- .../ohos/migrator/java/JavaTransformer.java | 273 +++++++++++++++++- 1 file changed, 270 insertions(+), 3 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 11dafc10e..fa20bd5ea 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; @@ -3532,6 +3533,21 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // TypeDeclarationStatement: + // TypeDeclaration + // EnumDeclaration + // STS tree: + // statementOrLocalDeclaration: + // | classDeclaration + // | enumDeclaration + @Override + public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { + javaTypeDeclarationStmt.getDeclaration().accept(this); + + ++countStmtTransformed; + return false; + } + // Java tree: // switch ( Expression ) // { { SwitchCase | Statement } } @@ -3613,7 +3629,261 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // switch ( Expression ) + // { { SwitchCase | Statement } } + // SwitchCase: + // case Expression : + // default : + // STS tree: + // switchStatement: + // switch OpenParen singleExpression CloseParen caseBlock + // caseBlock: + // OpenBrace caseClause* defaultClause? caseClause* CloseBrace + // caseClause: + // case singleExpression ':' statement* + // defaultClause: + // default ':' statement* @Override + public boolean visit(SwitchStatement javaSwitchStmt) { + SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); + pushStatement(stsSwitch); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); + + javaSwitchStmt.getExpression().accept(this); + + CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); + pushCurrent(stsCaseBlock); + + List javaVariablesToMove = new ArrayList<>(); + SwitchCase javaCurrentSwitchCase = null; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { + javaCurrentSwitchCase = (SwitchCase) javaStmt; + } + else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { + wrapCaseClauseStatementsWithBlock(); + } + else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { + processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, + javaSwitchStmt, javaVariablesToMove); + + // We've already processed variable declaration, proceed to the next statement. + continue; + } + + javaStmt.accept(this); + } + + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + popCurrent(); // CaseBlockContext + popStatement(); // SwitchStatementContext + + // Move variable declarations in front of switch statement, and enclose both + // declarations and switch with additional block. + if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { + // Remove switch statement from current STS node. + stsCurrent.removeLastChild(); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + + for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { + VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); + + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); + popStatement(); // VariableOrConstantDeclarationContext + } + + pushStatement(stsSwitch); + popStatement(); // SwitchContext + + popStatement(); // BlockContext + } + + ++countStmtTransformed; + + return false; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + if (javaSwitchCase.isDefault()) { + pushCurrent(new DefaultClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); + } else { + pushCurrent(new CaseClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); + javaSwitchCase.getExpression().accept(this); + } + + // SwitchCase is treated as Statement node, thus increment the count. + ++countStmtTransformed; + return false; + } + + private void popCaseClauseIfNeeded() { + // Check if we need to pop additional block added as work around to add + // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() + // method for details). + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) { + popStatement(); // BlockContext + } + + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause + || stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause) { + popCurrent(); // CaseClauseContext | DefaultClauseContext + } + } + + private void wrapCaseClauseStatementsWithBlock() { + // In StaticTS, CaseClause may contain only statements, and is not allowed to + // have local declarations. In contrast, Java permits to have local declarations + // in case clause scope, so when encounter one, wrap up all statements in case clause + // with additional block as a workaround, (since block can have local declarations). + + // Check if already inserted additional block. + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) + return; + + assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || + stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; + + List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); + stsCurrent.children.removeAll(stsCaseStmts); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + for (StatementContext stsStmt : stsCaseStmts) { + StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); + stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); + stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); + } + } + + + private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, + SwitchStatement javaSwitchStmt, List javaVariablesToMove) { + // Java permits to declare local variables in switch scope. Such variables exist + // in all following case clauses. In StaticTS, case clauses don't have a common + // scope, and allow only statements, not declarations. To work around this, we + // have to track whether a particular local variable has been referenced in another + // case clause and, in such case, move declaration of that variable in front of + // switch statement, additionally enclosing both variable declaration and switch + // statement, so that variables are only visible in context of switch statement. + + List javaVarFragments = javaVarDeclStmt.fragments(); + for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { + if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { + javaVariablesToMove.add(javaVarFragment); + + // Since evaluation of initializer expression can cause side effects, + // in order to preserve the behaviour and result of program, all + // expressions must evaluate in the same order as before. For that + // purpose, we move the variable declaration without initializer part + // and replace initialization with simple assignment. + Expression javaInitExpr = javaVarFragment.getInitializer(); + if (javaInitExpr != null) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); + + javaVarFragment.getName().accept(this); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitExpr.accept(this); + + popSingleExpression(); // AssignmentExpressionContext; + popStatement(); // ExpressionStatementContext + } + } else { + wrapCaseClauseStatementsWithBlock(); + + // For variables, that don't need to be moved, emit single variable + // declaration here to preserve the correct order of evaluation of + // initializer expressions (including assignments emitted for variables + // that are moved). + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); + popStatement(); // VariableOrConstantDeclarationContext + } + } + + ++countStmtTransformed; + } + + private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, + SwitchStatement javaSwitchStmt) { + IVariableBinding javaVarBinding = javaVarDecl.resolveBinding(); + + ASTVisitor localVarUsageLookupVisitor = new ASTVisitor() { + boolean done = false; + int nestedSwitchCount = 0; + SwitchCase currentSwitchCase = null; + + @Override + public boolean preVisit2(ASTNode javaNode) { + // This line will prevent from visiting further AST nodes, + // once we are done with the work. + return !done; + } + + @Override + public boolean visit(SimpleName javaName) { + IBinding binding = javaName.resolveBinding(); + + if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { + javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); + done = true; + } + + return false; + } + + @Override + public boolean visit(VariableDeclarationFragment javaVarDeclFragment) { + // Do NOT visit declaration of the variable that we are looking up. + return javaVarDeclFragment != javaVarDecl; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Do not change currentSwitchCase when visiting nested switch statements. + if (nestedSwitchCount == 0) { + currentSwitchCase = javaSwitchCase; + } + + return false; + } + + @Override + public boolean visit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount++; + return true; + } + + @Override + public void endVisit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount--; + } + }; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + javaStmt.accept(localVarUsageLookupVisitor); + + if (javaVarDecl.getProperty(USED_IN_ANOTHER_CASE_CLAUSE) != null) + return true; + } + + return false; + } + public boolean visit(SwitchCase javaSwitchCase) { // Close the last case clause. popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext @@ -3720,7 +3990,4 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // CreationReference, // SuperMethodReference, // TypeMethodReference - // TryStatement - // SynchronizedStatement - // ThrowStatement } -- Gitee From ab41933de07fccc60920d514cb969920789c07ca Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 3 Aug 2022 17:17:16 +0300 Subject: [PATCH 57/60] Enum translation (incomplete). Also minor bugfix and housekeeping in JavaTransformer code. Changes to tests to account for all of the above. Change-Id: I244038b63e07240aed4a882cab6385a07a50c487 Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index fa20bd5ea..097b2e9e3 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -43,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; -- Gitee From c3af7a7608c5b7df462ecaefaa68b01c3222dc17 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Tue, 30 Aug 2022 15:27:33 +0300 Subject: [PATCH 58/60] Post merge fix 3 Change-Id: I5f7fe841cadeb90dc4b8a4fa8ced3d20a4f57c0a Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 105 +----------------- .../ohos/migrator/staticTS/NodeBuilder.java | 29 +++-- .../staticTS/parser/StaticTSParser.g4 | 6 +- .../staticTS/writer/StaticTSWriter.java | 25 +++-- migrator/test/java/generic_class_3.java.sts | 2 +- 5 files changed, 40 insertions(+), 127 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 097b2e9e3..572d71c21 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -248,11 +248,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return true; } - for (ITypeBinding javaInterface : javaClassBinding.getInterfaces()) { - if (doesOverride(javaInterface, javaCheckedMethod)) - return true; - } - ITypeBinding javaSuperClassBinding = javaClassBinding.getSuperclass(); if (javaSuperClassBinding != null) return doesOverride(javaSuperClassBinding, javaCheckedMethod); @@ -2863,7 +2858,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Dot Identifier # MemberAccessExpression - // where the next singleExpression is + // where the next singleExpresion is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(SuperFieldAccess javaSuperFieldAccess) { @@ -2891,7 +2886,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // singleExpression: // | singleExpression Instanceof primaryType # instanceofExpression - // where the next singleExpression is + // where the next singleExpresion is // | (typeReference Dot)? Super # SuperExpression @Override public boolean visit(InstanceofExpression javaInstanceofExpr) { @@ -3534,21 +3529,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // TypeDeclarationStatement: - // TypeDeclaration - // EnumDeclaration - // STS tree: - // statementOrLocalDeclaration: - // | classDeclaration - // | enumDeclaration - @Override - public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { - javaTypeDeclarationStmt.getDeclaration().accept(this); - - ++countStmtTransformed; - return false; - } - // Java tree: // switch ( Expression ) // { { SwitchCase | Statement } } @@ -3630,87 +3610,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // switch ( Expression ) - // { { SwitchCase | Statement } } - // SwitchCase: - // case Expression : - // default : - // STS tree: - // switchStatement: - // switch OpenParen singleExpression CloseParen caseBlock - // caseBlock: - // OpenBrace caseClause* defaultClause? caseClause* CloseBrace - // caseClause: - // case singleExpression ':' statement* - // defaultClause: - // default ':' statement* - @Override - public boolean visit(SwitchStatement javaSwitchStmt) { - SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); - pushStatement(stsSwitch); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); - - javaSwitchStmt.getExpression().accept(this); - - CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); - pushCurrent(stsCaseBlock); - - List javaVariablesToMove = new ArrayList<>(); - SwitchCase javaCurrentSwitchCase = null; - - List javaStmts = javaSwitchStmt.statements(); - for (Statement javaStmt : javaStmts) { - if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { - javaCurrentSwitchCase = (SwitchCase) javaStmt; - } - else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { - wrapCaseClauseStatementsWithBlock(); - } - else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { - processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, - javaSwitchStmt, javaVariablesToMove); - - // We've already processed variable declaration, proceed to the next statement. - continue; - } - - javaStmt.accept(this); - } - - // Close the last case clause. - popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext - - popCurrent(); // CaseBlockContext - popStatement(); // SwitchStatementContext - - // Move variable declarations in front of switch statement, and enclose both - // declarations and switch with additional block. - if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { - // Remove switch statement from current STS node. - stsCurrent.removeLastChild(); - - BlockContext stsBlock = new BlockContext(stsCurrent, 0); - pushStatement(stsBlock); - - for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { - VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); - - pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); - popStatement(); // VariableOrConstantDeclarationContext - } - - pushStatement(stsSwitch); - popStatement(); // SwitchContext - - popStatement(); // BlockContext - } - - ++countStmtTransformed; - - return false; - } - @Override public boolean visit(SwitchCase javaSwitchCase) { // Close the last case clause. diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index 5b4d9fe62..c02eb1037 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -70,18 +70,27 @@ public class NodeBuilder { return qualifiedName(javaName.getFullyQualifiedName()); } - private static int stsTypeNameCode(PrimitiveType.Code javaTypeCode) { + private static int stsTypeNameCode(PrimitiveType.Code javaPrimitiveTypeCode) { int stsTypeNameCode = -1; - if (javaTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; - else if (javaTypeCode == PrimitiveType.BYTE) stsTypeNameCode = StaticTSParser.Byte; - else if (javaTypeCode == PrimitiveType.CHAR) stsTypeNameCode = StaticTSParser.Char; - else if (javaTypeCode == PrimitiveType.INT) stsTypeNameCode = StaticTSParser.Int; - else if (javaTypeCode == PrimitiveType.DOUBLE) stsTypeNameCode = StaticTSParser.Double; - else if (javaTypeCode == PrimitiveType.FLOAT) stsTypeNameCode = StaticTSParser.Float; - else if (javaTypeCode == PrimitiveType.LONG) stsTypeNameCode = StaticTSParser.Long; - else if (javaTypeCode == PrimitiveType.SHORT) stsTypeNameCode = StaticTSParser.Short; - else if (javaTypeCode == PrimitiveType.VOID) stsTypeNameCode = StaticTSParser.Void; + if (javaPrimitiveTypeCode == PrimitiveType.BOOLEAN) + stsTypeNameCode = StaticTSParser.Boolean; + else if (javaPrimitiveTypeCode == PrimitiveType.BYTE) + stsTypeNameCode = StaticTSParser.Byte; + else if (javaPrimitiveTypeCode == PrimitiveType.CHAR) + stsTypeNameCode = StaticTSParser.Char; + else if (javaPrimitiveTypeCode == PrimitiveType.INT) + stsTypeNameCode = StaticTSParser.Int; + else if (javaPrimitiveTypeCode == PrimitiveType.DOUBLE) + stsTypeNameCode = StaticTSParser.Double; + else if (javaPrimitiveTypeCode == PrimitiveType.FLOAT) + stsTypeNameCode = StaticTSParser.Float; + else if (javaPrimitiveTypeCode == PrimitiveType.LONG) + stsTypeNameCode = StaticTSParser.Long; + else if (javaPrimitiveTypeCode == PrimitiveType.SHORT) + stsTypeNameCode = StaticTSParser.Short; + else if (javaPrimitiveTypeCode == PrimitiveType.VOID) + stsTypeNameCode = StaticTSParser.Void; else assert false : "Unknown type"; diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 5009e8b90..de2cf22ee 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -373,7 +373,11 @@ switchStatement ; caseBlock - : OpenBrace caseClause* defaultClause? caseClause* CloseBrace + : OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace + ; + +caseClauses + : caseClause+ ; caseClause diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index efbf6ffcd..dcf7ceed6 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -119,12 +119,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeParameterList(stsTypeParameterList); } - if (sb.charAt(sb.length()-1) == '>') { - sb.append(" >"); - } - else { sb.append('>'); - } return null; } @@ -185,12 +180,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitTypeArgumentList(stsTypeArgumentList); } - if (sb.charAt(sb.length()-1) == '>') { - sb.append(" >"); - } - else { sb.append('>'); - } return null; } @@ -1105,7 +1095,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // caseBlock: '{' caseClause* defaultClause? caseClause* '}' + // caseBlock: '{' leftCases=caseClauses? defaultClause? rightCases=caseClauses? '}' @Override public Void visitCaseBlock(CaseBlockContext stsCaseBlock) { if (!doNeededIndent()) { @@ -1115,7 +1105,18 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append("{\n"); indentIncrement(); - visitChildren(stsCaseBlock); + if (stsCaseBlock.leftCases != null) { + visitCaseClauses(stsCaseBlock.leftCases); + } + + DefaultClauseContext stsDefaultClause = stsCaseBlock.defaultClause(); + if (stsDefaultClause != null) { + visitDefaultClause(stsDefaultClause); + } + + if (stsCaseBlock.rightCases != null) { + visitCaseClauses(stsCaseBlock.rightCases); + } indentDecrement(); sb.append(indentCurrent).append("}\n"); diff --git a/migrator/test/java/generic_class_3.java.sts b/migrator/test/java/generic_class_3.java.sts index 716211aab..99edd5ab4 100644 --- a/migrator/test/java/generic_class_3.java.sts +++ b/migrator/test/java/generic_class_3.java.sts @@ -11,7 +11,7 @@ * 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; -- Gitee From c74e5bc05538c19c82fef578da59b31933f9eb94 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Tue, 30 Aug 2022 16:56:16 +0300 Subject: [PATCH 59/60] Post merge fix 5 Change-Id: Ic3d3b718d2de2affdde00637ece623eac8983d73 Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 268 +++--------------- 1 file changed, 34 insertions(+), 234 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 572d71c21..04b40af22 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -53,6 +53,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; + private static int countStmtTotal = 0; private static int countExprTotal = 0; private static int countDeclTotal = 0; @@ -3530,257 +3531,56 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } // Java tree: - // switch ( Expression ) - // { { SwitchCase | Statement } } - // SwitchCase: - // case Expression : - // default : + // SuperMethodReference: + // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier // STS tree: - // switchStatement: - // switch OpenParen singleExpression CloseParen caseBlock - // caseBlock: - // OpenBrace caseClause* defaultClause? caseClause* CloseBrace - // caseClause: - // case singleExpression ':' statement* - // defaultClause: - // default ':' statement* + // TODO: lambda ? @Override - public boolean visit(SwitchStatement javaSwitchStmt) { - SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); - pushStatement(stsSwitch); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); - - javaSwitchStmt.getExpression().accept(this); - - CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); - pushCurrent(stsCaseBlock); - - List javaVariablesToMove = new ArrayList<>(); - SwitchCase javaCurrentSwitchCase = null; - - List javaStmts = javaSwitchStmt.statements(); - for (Statement javaStmt : javaStmts) { - if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { - javaCurrentSwitchCase = (SwitchCase) javaStmt; - } - else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { - wrapCaseClauseStatementsWithBlock(); - } - else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { - processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, - javaSwitchStmt, javaVariablesToMove); - - // We've already processed variable declaration, proceed to the next statement. - continue; - } - - javaStmt.accept(this); - } - - // Close the last case clause. - popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext - - popCurrent(); // CaseBlockContext - popStatement(); // SwitchStatementContext - - // Move variable declarations in front of switch statement, and enclose both - // declarations and switch with additional block. - if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { - // Remove switch statement from current STS node. - stsCurrent.removeLastChild(); - - BlockContext stsBlock = new BlockContext(stsCurrent, 0); - pushStatement(stsBlock); - - for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { - VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); - - pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType(), false); - popStatement(); // VariableOrConstantDeclarationContext - } - - pushStatement(stsSwitch); - popStatement(); // SwitchContext - - popStatement(); // BlockContext - } + public boolean visit(SuperMethodReference javaSuperMethodReference) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaSuperMethodReference)).setParent(stsCurrent); - ++countStmtTransformed; return false; } @Override - public boolean visit(SwitchCase javaSwitchCase) { - // Close the last case clause. - popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext - - if (javaSwitchCase.isDefault()) { - pushCurrent(new DefaultClauseContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); - } else { - pushCurrent(new CaseClauseContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); - javaSwitchCase.getExpression().accept(this); - } + public boolean visit(TypeMethodReference javaTypeMethodRef) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaTypeMethodRef)).setParent(stsCurrent); - // SwitchCase is treated as Statement node, thus increment the count. - ++countStmtTransformed; return false; } - private void popCaseClauseIfNeeded() { - // Check if we need to pop additional block added as work around to add - // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() - // method for details). - if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) { - popStatement(); // BlockContext - } - - if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause - || stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause) { - popCurrent(); // CaseClauseContext | DefaultClauseContext - } - } - - private void wrapCaseClauseStatementsWithBlock() { - // In StaticTS, CaseClause may contain only statements, and is not allowed to - // have local declarations. In contrast, Java permits to have local declarations - // in case clause scope, so when encounter one, wrap up all statements in case clause - // with additional block as a workaround, (since block can have local declarations). - - // Check if already inserted additional block. - if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) - return; - - assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || - stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; - - List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); - stsCurrent.children.removeAll(stsCaseStmts); + @Override + public boolean visit(TryStatement javaTryStatement) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaTryStatement)).setParent(stsCurrent); - BlockContext stsBlock = new BlockContext(stsCurrent, 0); - pushStatement(stsBlock); - for (StatementContext stsStmt : stsCaseStmts) { - StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); - stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); - stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); - } + return false; } + @Override + public boolean visit(ThrowStatement javaThrowStatement) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaThrowStatement)).setParent(stsCurrent); - private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, - SwitchStatement javaSwitchStmt, List javaVariablesToMove) { - // Java permits to declare local variables in switch scope. Such variables exist - // in all following case clauses. In StaticTS, case clauses don't have a common - // scope, and allow only statements, not declarations. To work around this, we - // have to track whether a particular local variable has been referenced in another - // case clause and, in such case, move declaration of that variable in front of - // switch statement, additionally enclosing both variable declaration and switch - // statement, so that variables are only visible in context of switch statement. - - List javaVarFragments = javaVarDeclStmt.fragments(); - for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { - if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { - javaVariablesToMove.add(javaVarFragment); - - // Since evaluation of initializer expression can cause side effects, - // in order to preserve the behaviour and result of program, all - // expressions must evaluate in the same order as before. For that - // purpose, we move the variable declaration without initializer part - // and replace initialization with simple assignment. - Expression javaInitExpr = javaVarFragment.getInitializer(); - if (javaInitExpr != null) { - pushStatement(new ExpressionStatementContext(stsCurrent, 0)); - pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); - - javaVarFragment.getName().accept(this); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitExpr.accept(this); - - popSingleExpression(); // AssignmentExpressionContext; - popStatement(); // ExpressionStatementContext - } - } else { - wrapCaseClauseStatementsWithBlock(); - - // For variables, that don't need to be moved, emit single variable - // declaration here to preserve the correct order of evaluation of - // initializer expressions (including assignments emitted for variables - // that are moved). - pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); - popStatement(); // VariableOrConstantDeclarationContext - } - } - - ++countStmtTransformed; + return false; } - private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, - SwitchStatement javaSwitchStmt) { - IVariableBinding javaVarBinding = javaVarDecl.resolveBinding(); - - ASTVisitor localVarUsageLookupVisitor = new ASTVisitor() { - boolean done = false; - int nestedSwitchCount = 0; - SwitchCase currentSwitchCase = null; - - @Override - public boolean preVisit2(ASTNode javaNode) { - // This line will prevent from visiting further AST nodes, - // once we are done with the work. - return !done; - } - - @Override - public boolean visit(SimpleName javaName) { - IBinding binding = javaName.resolveBinding(); - - if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { - javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); - done = true; - } - - return false; - } - - @Override - public boolean visit(VariableDeclarationFragment javaVarDeclFragment) { - // Do NOT visit declaration of the variable that we are looking up. - return javaVarDeclFragment != javaVarDecl; - } - - @Override - public boolean visit(SwitchCase javaSwitchCase) { - // Do not change currentSwitchCase when visiting nested switch statements. - if (nestedSwitchCount == 0) { - currentSwitchCase = javaSwitchCase; - } - - return false; - } - - @Override - public boolean visit(SwitchStatement javaSwitchStatement) { - nestedSwitchCount++; - return true; - } - - @Override - public void endVisit(SwitchStatement javaSwitchStatement) { - nestedSwitchCount--; - } - }; - - List javaStmts = javaSwitchStmt.statements(); - for (Statement javaStmt : javaStmts) { - javaStmt.accept(localVarUsageLookupVisitor); - - if (javaVarDecl.getProperty(USED_IN_ANOTHER_CASE_CLAUSE) != null) - return true; - } - + @Override + public boolean visit(SynchronizedStatement javaSynchrStmt) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaSynchrStmt)).setParent(stsCurrent); return false; } -- Gitee From 7b5ef0257005cd718c01db84a667830856064850 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Tue, 30 Aug 2022 17:09:55 +0300 Subject: [PATCH 60/60] Post merge fix 6 Change-Id: Ifa6da942c85987dcb7a8df9949507be6e6305a07 Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 144 ------------------ migrator/test/java/generic_class_1.java | 4 +- migrator/test/java/generic_class_1.java.sts | 1 + migrator/test/java/generic_class_2.java.sts | 3 +- migrator/test/java/generic_class_3.java.sts | 1 + 5 files changed, 6 insertions(+), 147 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 04b40af22..c5410ec75 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -46,10 +46,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; - private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; - - private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; - private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; @@ -1628,44 +1624,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ClassBodyContext(stsCurrent, 0)); - // Translate enum constants. - // If any of the constants contain anonymous class body (e.g., extend enum type), - // add open modifier to the resulting class. - boolean needOpen = false; - List javaEnumConstNames = new ArrayList<>(); - List javaEnumConstants = javaEnumDeclaration.enumConstants(); - for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { - if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; - - // Pass enum name to enum constant node before visiting it - // as we'll need it to create appropriate initializers. - javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); - - // Store enum constant name in a list - we'll need it later to generate - // built-in values() method - javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); - - javaEnumConst.accept(this); - } - if (needOpen) { - stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); - } - - // Translate body declarations (ctors, methods, nested types, and fields). - List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); - for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { - javaEnumBodyDecl.accept(this); - } - - // TODO: valueOf(), toString() and ordinal() methods! - createEnumValuesMethod(javaEnumDeclaration.getName().getIdentifier(), javaEnumConstNames); - - popCurrent(); // ClassBodyContext - popCurrent(); // stsClassDecl - popCurrent(); // member context - - pushCurrent(new ClassBodyContext(stsCurrent, 0)); - // Translate enum constants. // If any of the constants contain anonymous class body (e.g., extend enum type), // add open modifier to the resulting class. @@ -3584,108 +3542,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - public boolean visit(SwitchCase javaSwitchCase) { - // Close the last case clause. - popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext - - if (javaSwitchCase.isDefault()) { - pushCurrent(new DefaultClauseContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); - } else { - pushCurrent(new CaseClauseContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); - javaSwitchCase.getExpression().accept(this); - } - - // SwitchCase is treated as Statement node, thus increment the count. - ++countStmtTransformed; - return false; - } - - @Override - public boolean visit(TryStatement javaTryStatement) { - // TODO: To be implemented - // Emit __untranslated_statement call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaTryStatement)).setParent(stsCurrent); - - // Check if already inserted additional block. - if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) - return; - - assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || - stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; - - List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); - stsCurrent.children.removeAll(stsCaseStmts); - - BlockContext stsBlock = new BlockContext(stsCurrent, 0); - pushStatement(stsBlock); - for (StatementContext stsStmt : stsCaseStmts) { - StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); - stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); - stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); - } - } - - - private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, - SwitchStatement javaSwitchStmt, List javaVariablesToMove) { - // Java permits to declare local variables in switch scope. Such variables exist - // in all following case clauses. In StaticTS, case clauses don't have a common - // scope, and allow only statements, not declarations. To work around this, we - // have to track whether a particular local variable has been referenced in another - // case clause and, in such case, move declaration of that variable in front of - // switch statement, additionally enclosing both variable declaration and switch - // statement, so that variables are only visible in context of switch statement. - - List javaVarFragments = javaVarDeclStmt.fragments(); - for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { - if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { - javaVariablesToMove.add(javaVarFragment); - - // Since evaluation of initializer expression can cause side effects, - // in order to preserve the behaviour and result of program, all - // expressions must evaluate in the same order as before. For that - // purpose, we move the variable declaration without initializer part - // and replace initialization with simple assignment. - Expression javaInitExpr = javaVarFragment.getInitializer(); - if (javaInitExpr != null) { - pushStatement(new ExpressionStatementContext(stsCurrent, 0)); - pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); - - javaVarFragment.getName().accept(this); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitExpr.accept(this); - - popSingleExpression(); // AssignmentExpressionContext; - popStatement(); // ExpressionStatementContext - } - } else { - wrapCaseClauseStatementsWithBlock(); - - // For variables, that don't need to be moved, emit single variable - // declaration here to preserve the correct order of evaluation of - // initializer expressions (including assignments emitted for variables - // that are moved). - pushStatement(new VariableOrConstantDeclarationContext(null, 0)); - createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), new ArrayList() {{ add(javaVarFragment); }}, javaVarDeclStmt.getType()); - popStatement(); // VariableOrConstantDeclarationContext - } - } - - ++countStmtTransformed; - } - - @Override - public boolean visit(SynchronizedStatement javaSynchrStmt) { - // TODO: To be implemented - // Emit __untranslated_statement call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaSynchrStmt)).setParent(stsCurrent); - return false; - } - // The list of not yet translated Java Expressions: // CreationReference, // SuperMethodReference, diff --git a/migrator/test/java/generic_class_1.java b/migrator/test/java/generic_class_1.java index d84732865..1b15fde1e 100644 --- a/migrator/test/java/generic_class_1.java +++ b/migrator/test/java/generic_class_1.java @@ -13,7 +13,7 @@ * limitations under the License. */ -package com.ohos.migrator.test.java; +package com.ohos.migrator.test.java; // Java specification Example 8.1.2-1. Mutually Recursive Type Variable Bounds: @@ -25,4 +25,4 @@ class ReprChange, S extends ConvertibleTo> { T t; void set(S s) { t = s.convert(); } S get() { return t.convert(); } - } + } \ No newline at end of file diff --git a/migrator/test/java/generic_class_1.java.sts b/migrator/test/java/generic_class_1.java.sts index 797cf4735..192ed6b39 100644 --- a/migrator/test/java/generic_class_1.java.sts +++ b/migrator/test/java/generic_class_1.java.sts @@ -27,3 +27,4 @@ open class ReprChange, S extends ConvertibleTo> { return t.convert(); } } + diff --git a/migrator/test/java/generic_class_2.java.sts b/migrator/test/java/generic_class_2.java.sts index cad39bcf5..1bd7124f4 100644 --- a/migrator/test/java/generic_class_2.java.sts +++ b/migrator/test/java/generic_class_2.java.sts @@ -11,7 +11,7 @@ * 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 Seq { @@ -61,3 +61,4 @@ open class Test { let combined : Seq> = zipper.zip(nums); } } + diff --git a/migrator/test/java/generic_class_3.java.sts b/migrator/test/java/generic_class_3.java.sts index 99edd5ab4..57906a9f8 100644 --- a/migrator/test/java/generic_class_3.java.sts +++ b/migrator/test/java/generic_class_3.java.sts @@ -53,3 +53,4 @@ open class Main { c.test2(); } } + -- Gitee