From bc78fcb7ae0c1b8532081a9c45c63f16181dca1d Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Thu, 1 Sep 2022 17:30:14 +0300 Subject: [PATCH 01/13] Translation of generics Change-Id: Id6ce62ea5fbf5bc8b21c75a424d49fa5a945223d Signed-off-by: Alexander Pavlyuk --- .../ohos/migrator/java/JavaTransformer.java | 333 +++++++++++++----- .../ohos/migrator/staticTS/NodeBuilder.java | 29 ++ migrator/test/java/generic_class_1.java | 28 ++ migrator/test/java/generic_class_1.java.sts | 30 ++ migrator/test/java/generic_class_2.java | 57 +++ migrator/test/java/generic_class_2.java.sts | 64 ++++ 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 | 27 ++ migrator/test/java/generic_interface_3.java | 27 ++ .../test/java/generic_interface_3.java.skip | 0 .../test/java/generic_interface_3.java.sts | 11 + migrator/test/java/interface_nested.java.sts | 8 +- migrator/test/java/interface_public.java.sts | 8 +- migrator/test/java/test_interface.java.sts | 6 +- 20 files changed, 758 insertions(+), 100 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 create mode 100644 migrator/test/java/generic_interface_3.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index ff53eaf63..684078800 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -27,7 +27,6 @@ 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; @@ -271,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 @@ -290,52 +289,45 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // [ permits Type { , Type } ] // { { InterfaceBodyDeclaration | ; } } // - // STS tree for interface: + // STS tree for class declaration: + // topDeclarationContext + // Export? + // ClassDeclarationContext + // TermminalNode <(static? (abstract | open) | (abstract | open)? static)?> ? + // TerminalNode + // TerminalNode + // TypeParametersContext ? + // ClassExtendsClauseContext ? + // ImplementsClauseContext ? + // ClassBodyContext + // TerminalNode <{> + // ClassMemberContext * + // clinit = CclassInitializerContext ? + // ClassMemberContext * + // TerminalNode <}> + // STS tree for interface declaration: // topDeclarationContext + // Export? // InterfaceDeclarationContext + // TermminalNode ? // TerminalNode - // TerminalNode + // TerminalNode + // TypeParametersContext ? + // InterfaceExtendsClauseContext ? // TerminalNode <{> // InterfaceBodyContext // null // TerminalNode <}> // - // STS src: class TestClassB extends TestClassA implements TestInterfaceA, TestInterfaceB {} - // Resulting tree: - // topDeclarationContext | ClassMemberContext | InterfaceMemberContext - // TerminalNode ? (for topDeclarationContext) - // | AccessibilityModifierContext? (for ClassMemberContext or InterfaceMemberContext) - // ClassDeclarationContext - // TerminalNode - // ClassExtendsClauseContext - // TerminalNode - // TypeReferenceContext - // QualifiedNameContext - // TerminalNode - // ImplementsClauseContext - // TerminalNode - // InterfaceTypeListContext - // TypeReferenceContext - // QualifiedNameContext - // TerminalNode - // TerminalNode <,> - // TypeReferenceContext - // QualifiedNameContext - // TerminalNode - // ClassBodyContext @Override public boolean visit(TypeDeclaration javaTypeDeclaration) { // Create appropriate member context to put declaration into. int javaMods = javaTypeDeclaration.getModifiers(); - ParserRuleContext stsMemberContext = createMemberContextWithAccessModifier(javaMods); - pushCurrent(stsMemberContext); + pushCurrent(createDeclarationOrMemberContextWithAccessModifier(javaMods)); // Create class or interface declaration context and select appropriate keyword. - int terminalCode = StaticTSParser.Class; - if (javaTypeDeclaration.isInterface()) { pushCurrent(new InterfaceDeclarationContext(stsCurrent, 0)); - terminalCode = StaticTSParser.Interface; } else { pushCurrent(new ClassDeclarationContext(stsCurrent, 0)); @@ -343,24 +335,22 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Add remaining (non-access modifiers) and class/interface keyword. translateNonAccessModifiers(javaTypeDeclaration); - stsCurrent.addChild(NodeBuilder.terminalNode(terminalCode)); + stsCurrent.addChild(NodeBuilder.terminalNode(javaTypeDeclaration.isInterface() ? StaticTSParser.Interface : StaticTSParser.Class)); // The name of the type declared in this type declaration. stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaTypeDeclaration.getName())); translateTypeParameters(javaTypeDeclaration.typeParameters()); - - translateSuperclassType(javaTypeDeclaration.getSuperclassType()); - - translateSuperInterfaceTypes(javaTypeDeclaration.superInterfaceTypes()); - - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBrace)); // { + translateSuperclassType(javaTypeDeclaration.getSuperclassType()); // extends (not present for interface) + translateSuperInterfaceTypes(javaTypeDeclaration.superInterfaceTypes()); // implements (extends for interface) if (javaTypeDeclaration.isInterface()) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBrace)); // { pushCurrent(new InterfaceBodyContext(stsCurrent, 0)); } else { pushCurrent(new ClassBodyContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBrace)); // { } // All type members are represented as body declarations. @@ -371,11 +361,17 @@ public class JavaTransformer extends ASTVisitor implements Transformer { addInstanceInitializersToCtors(javaTypeDeclaration); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBrace)); // } + if (javaTypeDeclaration.isInterface()) { + popCurrent(); // InterfaceBodyContext + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBrace)); // } + } + else { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBrace)); // } + popCurrent(); // ClassBodyContext + } - popCurrent(); // Interface/ClassBodyContext popCurrent(); // Interface/ClassDeclarationContext - popCurrent(); // stsMemberContext + popCurrent(); // stsDeclarationOrMemberContext ++countDeclTransformed; return false; @@ -415,9 +411,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Extends)); } else { - pushCurrent(new ImplementsClauseContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Implements)); + pushCurrent(new ImplementsClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Implements)); } + pushCurrent(new InterfaceTypeListContext(stsCurrent, 0)); for (Type javaSuperInterfaceType : javaSuperInterfaceTypes) { @@ -442,25 +439,54 @@ 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)); 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 != null && !javaTypeBounds.isEmpty()) { + if (!javaTypeBounds.isEmpty()) { pushCurrent(new ConstraintContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Extends)); - boolean isIntersectionTypeBound = javaTypeBounds.size() > 1; - if (isIntersectionTypeBound) pushCurrent(new IntersectionTypeContext(stsCurrent, 0)); + 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); + } - for (Type javaTypeBound : javaTypeBounds) { - javaTypeBound.accept(this); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); + popCurrent(); // IntersectionTypeContext } - if (isIntersectionTypeBound) popCurrent(); // IntersectionTypeContext popCurrent(); // ConstraintContext } @@ -468,7 +494,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - private ParserRuleContext createMemberContextWithAccessModifier(int javaMods) { + private ParserRuleContext createDeclarationOrMemberContextWithAccessModifier(int javaMods) { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; boolean isInInterfaceContext = stsCurrent instanceof InterfaceBodyContext; @@ -485,11 +511,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Process access modifier. In top-level context, public translates to export, // everything else to none. In all other contexts, emit AccessibilityModifierContext. // NOTE: In all cases, resulting node should NOT be a child of declaration node! - if (isInClassContext) { + if (isInClassContext || isInInterfaceContext) { AccessibilityModifierContext stsAccessMod = NodeBuilder.accessibilityModifier(javaMods); - if (stsAccessMod != null) {//stsMemberContext = null; - stsMemberContext.addChild(stsAccessMod).setParent(stsMemberContext); - } + if (stsAccessMod != null) stsMemberContext.addChild(stsAccessMod).setParent(stsMemberContext); } else if ((javaMods & Modifier.PUBLIC) != 0) stsMemberContext.addChild(NodeBuilder.terminalNode(StaticTSParser.Export)); @@ -575,7 +599,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { List javaVarDeclFragments = javaFieldDecl.fragments(); for (VariableDeclarationFragment javaVarDeclFragment : javaVarDeclFragments) { - pushCurrent(createMemberContextWithAccessModifier(javaMods)); + pushCurrent(createDeclarationOrMemberContextWithAccessModifier(javaMods)); ParserRuleContext stsClassOrInterField = isInClassContext ? new ClassFieldDeclarationContext(stsCurrent, 0) : new InterfaceFieldContext((InterfaceMemberContext)stsCurrent); @@ -783,6 +807,20 @@ 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(); @@ -804,17 +842,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)); + translateTypeArgumens(javaTypeArgs); - for (Type javaTypeArg : javaTypeArgs) { - pushCurrent(new TypeArgumentContext(stsCurrent, 0)); - javaTypeArg.accept(this); - popCurrent(); // TypeArgumentContext - } - - popCurrent(); // TypeArgumentListContext - popCurrent(); // TypeArgumentsContext popCurrent(); // (TypeReferencePartContext)lastChild popCurrent(); // (TypeReferenceContext)lastChild } @@ -1352,7 +1381,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; assert(isInClassContext || (stsCurrent instanceof InterfaceBodyContext)); - pushCurrent(createMemberContextWithAccessModifier(javaMethodDeclaration.getModifiers())); + pushCurrent(createDeclarationOrMemberContextWithAccessModifier(javaMethodDeclaration.getModifiers())); Block javaBlock = javaMethodDeclaration.getBody(); if (javaMethodDeclaration.isConstructor()) { @@ -1468,6 +1497,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeAnnotationContext + // TODO: { Dimension } + //javaSingleVariableDeclaration. // TODO: [= Expression ] // Expression javaExpression = javaSingleVariableDeclaration.getInitializer(); // if (javaExpression != null) { @@ -1479,6 +1510,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 ] @@ -1547,7 +1581,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(EnumDeclaration javaEnumDeclaration) { // Create appropriate member context to put declaration into. int javaEnumMods = javaEnumDeclaration.getModifiers(); - pushCurrent(createMemberContextWithAccessModifier(javaEnumMods)); + pushCurrent(createDeclarationOrMemberContextWithAccessModifier(javaEnumMods)); // Create class declaration context ClassDeclarationContext stsClassDecl = new ClassDeclarationContext(stsCurrent, 0); @@ -1646,6 +1680,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); @@ -1702,6 +1737,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsEnumCtorCallArg.setParent(stsExprSeq); } } + private void createEnumExtendsClause(String javaEnumName) { // Note: A Java enum extends Enum class. pushCurrent(new ClassExtendsClauseContext(stsCurrent, 0)); @@ -1720,6 +1756,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)); @@ -1730,6 +1767,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 @@ -1843,6 +1881,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popEnumBuiltinMethod(); } + @Override public boolean visit(EnumConstantDeclaration javaEnumConstant) { // Create class member context and add public modifier @@ -2461,10 +2500,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaArrayInitializer.accept(this); } -// popSingleExpression(); // NewArrayExpression - - // TODO: Needs reworking. - // ++countExprTransformed. return false; } @@ -2564,7 +2599,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: // ForStatement: // for ( @@ -3116,6 +3150,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); @@ -3274,8 +3309,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; @@ -3324,16 +3494,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 @@ -3366,11 +3526,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // The list of not yet translated Java Expressions: // CreationReference, - //?? ExpressionMethodReference, - // LambdaExpression, // SuperMethodReference, // TypeMethodReference - // TryStatement - // SynchronizedStatement - // ThrowStatement -} \ No newline at end of file +} diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index ec7daf0ac..c02eb1037 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -104,6 +104,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/test/java/generic_class_1.java b/migrator/test/java/generic_class_1.java new file mode 100644 index 000000000..1b15fde1e --- /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..192ed6b39 --- /dev/null +++ b/migrator/test/java/generic_class_1.java.sts @@ -0,0 +1,30 @@ +/* + * 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..1bd7124f4 --- /dev/null +++ b/migrator/test/java/generic_class_2.java.sts @@ -0,0 +1,64 @@ +/* + * 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..57906a9f8 --- /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..9bd613d2f --- /dev/null +++ b/migrator/test/java/generic_interface_2.java.sts @@ -0,0 +1,27 @@ +/* + * 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 extends G1, G2 { +} + diff --git a/migrator/test/java/generic_interface_3.java b/migrator/test/java/generic_interface_3.java new file mode 100644 index 000000000..3aba8e60b --- /dev/null +++ b/migrator/test/java/generic_interface_3.java @@ -0,0 +1,27 @@ +/* + * 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; +import java.util.ArrayList; + +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 diff --git a/migrator/test/java/generic_interface_3.java.sts b/migrator/test/java/generic_interface_3.java.sts new file mode 100644 index 000000000..71faba01f --- /dev/null +++ b/migrator/test/java/generic_interface_3.java.sts @@ -0,0 +1,11 @@ +package com.ohos.migrator.test.java; + +import java.util.List; +import java.util.ArrayList; +interface ListFactory { + make(): List ; + lf : ListFactory = __untranslated_expression(/*ArrayList::new*/); + ls : List = lf.make(); + ln : List = lf.make(); +} + diff --git a/migrator/test/java/interface_nested.java.sts b/migrator/test/java/interface_nested.java.sts index 088e675be..fa47496ed 100644 --- a/migrator/test/java/interface_nested.java.sts +++ b/migrator/test/java/interface_nested.java.sts @@ -18,7 +18,7 @@ import java.util.List; import java.io.*; interface Test { Outtermethod(): void ; - open class A { + public open class A { i : int ; } @@ -27,10 +27,10 @@ interface Test { } interface innerInterface { - Innermethod(): int ; + public Innermethod(): int ; } - interface inner_A { + public interface inner_A { coeff(): double ; } @@ -44,7 +44,7 @@ open class TestClass implements Test.innerInterface, Test.inner_A { return 3.14; } public interface constants { - Pi(): double ; + public Pi(): double ; static E(): double { return 2.7828; } diff --git a/migrator/test/java/interface_public.java.sts b/migrator/test/java/interface_public.java.sts index 8e06462c9..ed8935485 100644 --- a/migrator/test/java/interface_public.java.sts +++ b/migrator/test/java/interface_public.java.sts @@ -18,14 +18,14 @@ import java.util.List; import java.io.*; export interface interface_public { i : int = 10; - pi : double = 3.1416; + public pi : double = 3.1416; foo(): void ; static foo(i : int): void { } - foo(b : boolean): void { + private foo(b : boolean): void { } - foo(s : String): void ; - static Pi(): double { + public foo(s : String): void ; + public static Pi(): double { return pi; } E(): double { diff --git a/migrator/test/java/test_interface.java.sts b/migrator/test/java/test_interface.java.sts index 1ad4abae3..0db0b8dd4 100644 --- a/migrator/test/java/test_interface.java.sts +++ b/migrator/test/java/test_interface.java.sts @@ -22,9 +22,9 @@ interface test_interface { foo(): void ; static foo(i : int): void { } - foo(b : boolean): void { + private foo(b : boolean): void { } - foo(s : String): void ; + public foo(s : String): void ; } interface iface_FP { @@ -32,6 +32,6 @@ interface iface_FP { } interface iface_C extends test_interface, iface_FP { - foo(d : double): void ; + public foo(d : double): void ; } -- Gitee From ed571b43f9ce764cb9f91e9d05677a2239b8759c Mon Sep 17 00:00:00 2001 From: Mikhail Sherstennikov Date: Tue, 2 Aug 2022 17:05:32 +0300 Subject: [PATCH 02/13] Support bytecode profiling Signed-off-by: Mikhail Sherstennikov --- aot/main.cpp | 5 +++++ compiler/templates/formats.h.erb | 2 ++ 2 files changed, 7 insertions(+) diff --git a/aot/main.cpp b/aot/main.cpp index 79c919ecd..c0eb079b2 100644 --- a/aot/main.cpp +++ b/aot/main.cpp @@ -76,6 +76,11 @@ static int GenerateProgram(panda::pandasm::Program *prog, const std::string &out es2panda::Compiler::DumpAsm(prog); } + if (!panda::pandasm::AsmEmitter::AssignProfileInfo(prog)) { + std::cerr << "AssignProfileInfo failed" << std::endl; + return 1; + } + if (!panda::pandasm::AsmEmitter::Emit(output, *prog, statp, mapsp, true)) { return 1; } diff --git a/compiler/templates/formats.h.erb b/compiler/templates/formats.h.erb index 71b9587a0..e1f189982 100644 --- a/compiler/templates/formats.h.erb +++ b/compiler/templates/formats.h.erb @@ -44,6 +44,8 @@ namespace panda::es2panda::compiler { % elsif op.id? % is_string_id = insn.properties.include? 'string_id' % return is_string_id ? "OperandKind::STRING_ID" : "OperandKind::ID" +% elsif op.prof? +% return "OperandKind::IMM" % else % return nil % end -- Gitee From 0385055dd4331b2d2f308fa82e7c58aba82632dd Mon Sep 17 00:00:00 2001 From: Petrov Igor Date: Thu, 11 Aug 2022 14:44:52 +0300 Subject: [PATCH 03/13] [MM] Enable Heap Verifier for tests262 Signed-off-by: Petrov Igor --- test/runner.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/runner.py b/test/runner.py index d46ba19c8..9a91161b8 100755 --- a/test/runner.py +++ b/test/runner.py @@ -92,6 +92,9 @@ def get_args(): dest='timeout', default=10, help='JS runtime timeout') parser.add_argument( '--gc-type', dest='gc_type', default="g1-gc", help='Type of garbage collector') + parser.add_argument( + '--heap-verifier', dest='heap_verifier', default="fail_on_verification", + help='Heap verifier options') parser.add_argument( '--aot', action='store_true', dest='aot', default=False, help='use AOT compilation') @@ -475,6 +478,7 @@ class Test262Runner(Runner): % args.build_dir, '--load-runtimes=ecmascript', '--gc-type=%s' % args.gc_type, + '--heap-verifier=%s' % args.heap_verifier ] if args.run_gc_in_place: @@ -494,6 +498,7 @@ class Test262Runner(Runner): % args.build_dir, '--load-runtimes=ecmascript', '--gc-type=%s' % args.gc_type, + '--heap-verifier=%s' % args.heap_verifier ] if args.run_gc_in_place: -- Gitee From dab4e82fbd156a8618b9cf260c0c0b12da51fe21 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Tue, 30 Aug 2022 15:05:04 +0300 Subject: [PATCH 04/13] Implemented translation of synchronized blocks. Defer statement is implemented in STS as part of the above. Added a test to validate translation of synchronized blocks. Change-Id: I22e6df938e3782de58518c02776d5a8ce90bcb25 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 49 +++++++++++++++++-- .../migrator/staticTS/parser/StaticTSLexer.g4 | 1 + .../staticTS/parser/StaticTSParser.g4 | 5 ++ .../staticTS/writer/StaticTSWriter.java | 10 ++++ migrator/test/java/synchronized_blocks.java | 27 ++++++++++ .../test/java/synchronized_blocks.java.sts | 34 +++++++++++++ 6 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 migrator/test/java/synchronized_blocks.java create mode 100644 migrator/test/java/synchronized_blocks.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 684078800..7aab8c98a 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1380,7 +1380,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(MethodDeclaration javaMethodDeclaration) { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; assert(isInClassContext || (stsCurrent instanceof InterfaceBodyContext)); - + pushCurrent(createDeclarationOrMemberContextWithAccessModifier(javaMethodDeclaration.getModifiers())); Block javaBlock = javaMethodDeclaration.getBody(); @@ -3514,16 +3514,55 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // Java: + // synchronized(X) { statements } + // + // STS: + // { Monitor.lock(X); defer Monitor.unlock(X); statements } @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); + pushStatement(new BlockContext(stsCurrent, 0)); + + // Add Monitor.lock call + Expression javaExpr = javaSynchrStmt.getExpression(); + createIntrinsicCall("MonitorEnter", javaExpr); + // Add deferred Monitor.unlock call + pushStatement(new DeferStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Defer)); + createIntrinsicCall("MonitorExit", javaExpr); + popStatement(); // DeferStatementContext + + // Translate block statements + List javaStmts = javaSynchrStmt.getBody().statements(); + for (Statement javaStmt : javaStmts) + javaStmt.accept(this); + + popStatement(); // BlockContext + + ++countStmtTransformed; return false; } + private void createIntrinsicCall(String name, Expression... args) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + + stsCurrent.addChild(NodeBuilder.identifierExpression(name)).setParent(stsCurrent); + + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + + for (Expression arg : args) + arg.accept(this); + + popCurrent(); // ExpressionSequenceContext + popCurrent(); // ArgumentsContext + + popSingleExpression(); // CallExpressionContext + popStatement(); // ExpressionStatementContext + } + // The list of not yet translated Java Expressions: // CreationReference, // SuperMethodReference, diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 index f0b60c9fa..d915ba7ca 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 @@ -126,6 +126,7 @@ If: 'if'; Throw: 'throw'; Of: 'of'; Try: 'try'; +Defer: 'defer'; From: 'from'; As: 'as'; diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index de2cf22ee..ca2f06803 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -326,6 +326,7 @@ statement | switchStatement | throwStatement | tryStatement + | deferStatement | expressionStatement ; @@ -404,6 +405,10 @@ finallyClause : Finally block ; +deferStatement + : Defer statement + ; + expressionStatement : {this.notOpenBraceAndNotFunction()}? singleExpression SemiColon? ; diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index dcf7ceed6..4e652d54f 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1856,4 +1856,14 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } + + @Override + public Void visitDeferStatement(DeferStatementContext stsDeferStmt) { + doNeededIndent(); + + sb.append(stsDeferStmt.Defer().getText()).append(' '); + stsDeferStmt.statement().accept(this); + + return null; + } } diff --git a/migrator/test/java/synchronized_blocks.java b/migrator/test/java/synchronized_blocks.java new file mode 100644 index 000000000..67ea454cc --- /dev/null +++ b/migrator/test/java/synchronized_blocks.java @@ -0,0 +1,27 @@ +/* + * 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 synchronized_blocks { + public static void main(String[] args) { + synchronized_blocks t = new synchronized_blocks(); + synchronized(t) { + synchronized(System.out) { + System.out.println("made it!"); + } + } + } +} diff --git a/migrator/test/java/synchronized_blocks.java.sts b/migrator/test/java/synchronized_blocks.java.sts new file mode 100644 index 000000000..9116b4b75 --- /dev/null +++ b/migrator/test/java/synchronized_blocks.java.sts @@ -0,0 +1,34 @@ +/* + * 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 synchronized_blocks { + public static main(args : String[]): void { + let t : synchronized_blocks = new synchronized_blocks(); + + { + MonitorEnter(t); + defer MonitorExit(t); + + { + MonitorEnter(System.out); + defer MonitorExit(System.out); + + System.out.println("made it!"); + } + } + } +} -- Gitee From aeb5bda249a1d023c9a8d154d31c80bc14e53eaf Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 31 Aug 2022 13:26:51 +0300 Subject: [PATCH 05/13] Implemented translation of synchronized methods. Added a test to validate the functionality above. Change-Id: I4912bc76b7c1b9685dd2b60b0a81536eba13f04e Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 61 +++++++++++++++++-- .../ohos/migrator/staticTS/NodeBuilder.java | 46 +++++++++++++- migrator/test/java/synchronized_methods.java | 35 +++++++++++ .../test/java/synchronized_methods.java.sts | 43 +++++++++++++ 4 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 migrator/test/java/synchronized_methods.java create mode 100644 migrator/test/java/synchronized_methods.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 7aab8c98a..5dc93c80c 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1381,7 +1381,16 @@ public class JavaTransformer extends ASTVisitor implements Transformer { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; assert(isInClassContext || (stsCurrent instanceof InterfaceBodyContext)); - pushCurrent(createDeclarationOrMemberContextWithAccessModifier(javaMethodDeclaration.getModifiers())); + // Get current enclosing context - we'll need it later if + // current method is synchronized (see below). Also store + // modifiers of the current method for the same reason. + // NOTE: This has to happen BEFORE any further pushCurrent + // or a similar call that changes the value of stsCurrent! + ParserRuleContext enclosingContext = stsCurrent.getParent(); + int javaMods = javaMethodDeclaration.getModifiers(); + + pushCurrent(createDeclarationOrMemberContextWithAccessModifier(javaMods)); + Block javaBlock = javaMethodDeclaration.getBody(); if (javaMethodDeclaration.isConstructor()) { @@ -1421,6 +1430,42 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new BlockContext(stsCurrent, 0)); } + // For synchronized methods, inject MonitorEnter and deferred MonitorExit calls + // in front of all other statements in the method body. The argument of both calls + // is 'this' for non-static methods and class literal of the enclosing class otherwise. + if ((javaMods & Modifier.SYNCHRONIZED) != 0) { + // Figure out enclosing class or interface name. In case we're in anonymous class + // instance creation context, leave it null - we won't need it as this context + // doesn't allow static methods for which we need the class or interface name. + String enclosingTypeName = null; + if (enclosingContext.getRuleIndex() == StaticTSParser.RULE_classDeclaration) + enclosingTypeName = ((ClassDeclarationContext)enclosingContext).Identifier().getText(); + else if (enclosingContext.getRuleIndex() == StaticTSParser.RULE_interfaceDeclaration) + enclosingTypeName = ((InterfaceDeclarationContext)enclosingContext).Identifier().getText(); + + // Add MonitorEnter call + // NOTE: The argument has to be added manually as we don't have it in Java AST. + CallExpressionContext stsMonitorEnterCall = createIntrinsicCall("MonitorEnter"); + SingleExpressionContext stsMonitorEnterCallArg = (javaMods & Modifier.STATIC) == 0 + ? NodeBuilder.thisExpression(null) + : NodeBuilder.classLiteral(enclosingTypeName); + NodeBuilder.addArgument(stsMonitorEnterCall, stsMonitorEnterCallArg); + + // Add deferred MonitorExit call + // NOTE: The argument has to be created again to keep STS AST structure valid + // and added manually as above. + pushStatement(new DeferStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Defer)); + + CallExpressionContext stsMonitorExitCall = createIntrinsicCall("MonitorExit"); + SingleExpressionContext stsMonitorExitCallArg = (javaMods & Modifier.STATIC) == 0 + ? NodeBuilder.thisExpression(null) + : NodeBuilder.classLiteral(enclosingTypeName); + NodeBuilder.addArgument(stsMonitorExitCall, stsMonitorExitCallArg); + + popStatement(); // DeferStatementContext + } + List javaBlockStmts = javaBlock.statements(); for (Statement javaStmt : javaBlockStmts) { javaStmt.accept(this); @@ -3518,16 +3563,16 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // synchronized(X) { statements } // // STS: - // { Monitor.lock(X); defer Monitor.unlock(X); statements } + // { MonitorEnter(X); defer MonitorExit(X); statements } @Override public boolean visit(SynchronizedStatement javaSynchrStmt) { pushStatement(new BlockContext(stsCurrent, 0)); - // Add Monitor.lock call + // Add MonitorEnter call Expression javaExpr = javaSynchrStmt.getExpression(); createIntrinsicCall("MonitorEnter", javaExpr); - // Add deferred Monitor.unlock call + // Add deferred MonitorExit call pushStatement(new DeferStatementContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Defer)); createIntrinsicCall("MonitorExit", javaExpr); @@ -3544,9 +3589,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - private void createIntrinsicCall(String name, Expression... args) { + private CallExpressionContext createIntrinsicCall(String name, Expression... args) { pushStatement(new ExpressionStatementContext(stsCurrent, 0)); - pushCurrent(new CallExpressionContext(pushSingleExpression())); + + CallExpressionContext stsCallExpr = new CallExpressionContext(pushSingleExpression()); + pushCurrent(stsCallExpr); stsCurrent.addChild(NodeBuilder.identifierExpression(name)).setParent(stsCurrent); @@ -3561,6 +3608,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // CallExpressionContext popStatement(); // ExpressionStatementContext + + return stsCallExpr; } // The list of not yet translated Java Expressions: diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index c02eb1037..cf24542e5 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -17,7 +17,6 @@ package com.ohos.migrator.staticTS; import com.ohos.migrator.staticTS.parser.StaticTSParser; import com.ohos.migrator.staticTS.parser.StaticTSParser.*; -import kotlin.jvm.internal.TypeReference; import org.antlr.v4.runtime.CommonToken; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Vocabulary; @@ -259,7 +258,7 @@ public class NodeBuilder { // SimpleType: { Annotation } TypeName // STS: // typeReference: typeReferencePart ('.' typeReferencePart)* - // typeReference: qualifiedName typeArguments? + // typeReferencePart: qualifiedName typeArguments? public static TypeReferenceContext typeReference(String typeName) { TypeReferenceContext stsTypeReference = new TypeReferenceContext(null, 0); TypeReferencePartContext stsTypeRefPart = typeReferencePart(typeName); @@ -470,4 +469,47 @@ public class NodeBuilder { return stsShiftOp; } + + public static void addArgument(CallExpressionContext stsCallExpr, SingleExpressionContext stsArg) { + ArgumentsContext stsArgs = stsCallExpr.arguments(); + if (stsArgs != null) { + ExpressionSequenceContext stsExprSeq = stsArgs.expressionSequence(); + if (stsExprSeq != null) { + stsExprSeq.addChild(stsArg).setParent(stsExprSeq); + } + } + } + + public static SingleExpressionContext thisExpression(TypeReferenceContext stsTypeRef) { + SingleExpressionContext stsSingleExpr = new SingleExpressionContext(null, 0); + ThisExpressionContext stsThisExpression = new ThisExpressionContext(stsSingleExpr); + stsSingleExpr.addChild(stsThisExpression).setParent(stsSingleExpr); + + if (stsTypeRef != null) { + stsThisExpression.addChild(stsTypeRef).setParent(stsThisExpression); + } + stsThisExpression.addChild(terminalNode(StaticTSParser.This)); + + return stsSingleExpr; + } + + public static SingleExpressionContext classLiteral(String className) { + // Sanity check + if (className == null) return null; + + SingleExpressionContext stsSingleExpr = new SingleExpressionContext(null, 0); + ClassLiteralExpressionContext stsClassLiteral = new ClassLiteralExpressionContext(stsSingleExpr); + stsSingleExpr.addChild(stsClassLiteral).setParent(stsSingleExpr); + + // NOTE: Class literal requires PrimaryTypeContext! + // | primaryType Dot Class # ClassLiteralExpression + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsClassLiteral, 0); + stsPrimaryType.addChild(typeReference(className)).setParent(stsPrimaryType); + stsClassLiteral.addChild(stsPrimaryType).setParent(stsClassLiteral); + + stsClassLiteral.addChild(terminalNode(StaticTSParser.Dot)); + stsClassLiteral.addChild(terminalNode(StaticTSParser.Class)); + + return stsSingleExpr; + } } diff --git a/migrator/test/java/synchronized_methods.java b/migrator/test/java/synchronized_methods.java new file mode 100644 index 000000000..5ade2cd3c --- /dev/null +++ b/migrator/test/java/synchronized_methods.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 synchronized_methods { + int count; + synchronized void bump() { + count++; + } + + static int classCount; + static synchronized void classBump() { + classCount++; + } + + public static void main(String[] args) { + synchronized_methods t = new synchronized_methods() { + private int anonCount; + public synchronized void bump() { anonCount++; } + }; + } +} diff --git a/migrator/test/java/synchronized_methods.java.sts b/migrator/test/java/synchronized_methods.java.sts new file mode 100644 index 000000000..b0de0936a --- /dev/null +++ b/migrator/test/java/synchronized_methods.java.sts @@ -0,0 +1,43 @@ +/* + * 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 synchronized_methods { + count : int ; + open bump(): void { + MonitorEnter(this); + defer MonitorExit(this); + count++; + } + + static classCount : int ; + static classBump(): void { + MonitorEnter(synchronized_methods.class); + defer MonitorExit(synchronized_methods.class); + classCount++; + } + + public static main(args : String[]): void { + let t : synchronized_methods = new synchronized_methods() { + private anonCount : int ; + public override bump(): void { + MonitorEnter(this); + defer MonitorExit(this); + anonCount++; + } + }; + } +} -- Gitee From a614652a7bdccced9195d51c7f3bfd3c1c0ed5b0 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Thu, 1 Sep 2022 12:27:45 +0300 Subject: [PATCH 06/13] Fixed possible NPEs in lambda translation. Added command-line option -noxrefs to avoid processing all input sources as source references (i.e. block resolution of crossreferences in input sources). The latter is needed to speedup processing of some benchmarks. Change-Id: I8b29d83f778960f522f1a87659e0436ae04b293c Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/Main.java | 5 +- .../com/ohos/migrator/java/JavaParser.java | 7 +- .../ohos/migrator/java/JavaTransformer.java | 66 +++++++++++++++++-- .../ohos/migrator/java/JavaTranspiler.java | 13 ++-- 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/migrator/src/com/ohos/migrator/Main.java b/migrator/src/com/ohos/migrator/Main.java index 5141f4c3d..cacf67668 100644 --- a/migrator/src/com/ohos/migrator/Main.java +++ b/migrator/src/com/ohos/migrator/Main.java @@ -84,7 +84,7 @@ public class Main { 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")); - + options.addOption(new Option("noxrefs", "noxrefs", false, "Don't resolve cross-references in the input source files")); options.addOption(new Option("verbose","verbose",false,"Prints extended diagnostic messages")); options.addOption(new Option("v","version",false,"Version information")); @@ -185,11 +185,12 @@ public class Main { double convRate = 0.; int numLanguages = 0; + boolean noxrefs = cmd.hasOption("noxrefs"); if (!javaSources.isEmpty()) { System.out.println("Transpiling " + javaSources.size() + " Java files."); - JavaTranspiler javaTranspiler = new JavaTranspiler(javaSources, jarLibs, outDir); + JavaTranspiler javaTranspiler = new JavaTranspiler(javaSources, jarLibs, outDir, noxrefs); resultCode = javaTranspiler.transpile(); outFiles.addAll(javaTranspiler.getOutFiles()); errorList.addAll(javaTranspiler.getErrorList()); diff --git a/migrator/src/com/ohos/migrator/java/JavaParser.java b/migrator/src/com/ohos/migrator/java/JavaParser.java index f2cc113e4..214f4c7cb 100644 --- a/migrator/src/com/ohos/migrator/java/JavaParser.java +++ b/migrator/src/com/ohos/migrator/java/JavaParser.java @@ -59,11 +59,12 @@ public class JavaParser { * parser's 'sourcepaths' setting. * @param classpaths List of paths to jar files or directories with '.class' files. */ - public JavaParser(File sourceFile, List sourceFiles, List classpaths) throws IOException { + public JavaParser(File sourceFile, List sourceFiles, List classpaths, boolean noxrefs) throws IOException { this(sourceFile); - // Compute reference source paths once - if (sourcepathEntries == null) + // Compute reference source paths once, unless + // explicitly prohibited by command-line option + if (!noxrefs && sourcepathEntries == null) setSourcepathEntries(sourceFiles); setClasspathEntries(classpaths); diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 5dc93c80c..869d995e6 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -15,6 +15,8 @@ package com.ohos.migrator.java; +import com.ohos.migrator.Main; +import com.ohos.migrator.ResultCode; import com.ohos.migrator.Transformer; import com.ohos.migrator.staticTS.NodeBuilder; import com.ohos.migrator.staticTS.parser.StaticTSParser; @@ -26,6 +28,7 @@ import org.antlr.v4.runtime.tree.TerminalNode; import org.eclipse.jdt.core.dom.*; import org.jetbrains.annotations.NotNull; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Stack; @@ -37,6 +40,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final CompilationUnit javaCU; private CompilationUnitContext stsCU; + private final File srcFile; private ParserRuleContext stsCurrent; private final Stack stsSaved = new Stack<>(); @@ -149,8 +153,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); // IterationStatement, StatementContext } - public JavaTransformer(CompilationUnit javaCU) { + public JavaTransformer(CompilationUnit javaCU, File srcFile) { this.javaCU = javaCU; + this.srcFile = srcFile; } public CompilationUnitContext transform() { @@ -172,6 +177,32 @@ public class JavaTransformer extends ASTVisitor implements Transformer { else if (node instanceof Type) ++countTypeTotal; } + + // TODO: Remove as translation of remaining Java AST nodes is implemented! + @Override + public boolean visit(TryStatement node) { + return false; + } + @Override + public boolean visit(ThrowStatement node) { + return false; + } + @Override + public boolean visit(ExpressionMethodReference node) { + return false; + } + @Override + public boolean visit(SuperMethodReference node) { + return false; + } + @Override + public boolean visit(TypeMethodReference node) { + return false; + } + @Override + public boolean visit(CreationReference node) { + return false; + } }); // Visit Java AST and construct StaticTS AST. @@ -1575,7 +1606,20 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); IVariableBinding variableBinding = javaVariableDeclarationFragment.resolveBinding(); - translateType(variableBinding.getType()); + + if (variableBinding != null) { + translateType(variableBinding.getType()); + } + else { + // Warn and emit __UnknownType__ as variable type + String loc = srcFile.getPath() + ":" + javaCU.getLineNumber(javaVariableDeclarationFragment.getStartPosition()); + Main.addError(ResultCode.TranspileError, "Failed to resolve lambda parameter at " + loc); + + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference("__UnknownType__")).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + } + popCurrent(); // TypeAnnotationContext // Note: no need to process the "{ Dimension }" part, as the extra dimensions @@ -3257,7 +3301,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(SimpleName javaName) { IBinding binding = javaName.resolveBinding(); - if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { + if (binding != null && binding.isEqualTo(javaVarBinding) && javaSwitchCase != currentSwitchCase) { javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); done = true; } @@ -3328,9 +3372,21 @@ public class JavaTransformer extends ASTVisitor implements Transformer { createStsParameterList(javaLambdaExpr.parameters()); IMethodBinding lambdaMethod = javaLambdaExpr.resolveMethodBinding(); - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - translateType(lambdaMethod.getReturnType()); + + if (lambdaMethod != null) { + translateType(lambdaMethod.getReturnType()); + } + else { + // Warn and emit __UnknownType__ as return type + String loc = srcFile.getPath() + ":" + javaCU.getLineNumber(javaLambdaExpr.getStartPosition()); + Main.addError(ResultCode.TranspileError, "Failed to resolve lambda expression at " + loc); + + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference("__UnknownType__")).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + } + popCurrent(); // TypeAnnotationContext stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); diff --git a/migrator/src/com/ohos/migrator/java/JavaTranspiler.java b/migrator/src/com/ohos/migrator/java/JavaTranspiler.java index 3d00af70e..0579956ee 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTranspiler.java +++ b/migrator/src/com/ohos/migrator/java/JavaTranspiler.java @@ -37,8 +37,11 @@ import java.util.List; */ public class JavaTranspiler extends AbstractTranspiler { - public JavaTranspiler(List src, List libs, String outDir) { + + private boolean noxrefs = false; + public JavaTranspiler(List src, List libs, String outDir, boolean noxrefs) { super(src, libs, outDir); + this.noxrefs = noxrefs; } @Override @@ -46,7 +49,7 @@ public class JavaTranspiler extends AbstractTranspiler { try { CompilationUnit javaCU = parse(srcFile); - CompilationUnitContext stsCU = transform(javaCU); + CompilationUnitContext stsCU = transform(javaCU, srcFile); write(stsCU, srcFile); } catch (IOException e) { @@ -57,12 +60,12 @@ public class JavaTranspiler extends AbstractTranspiler { } private CompilationUnit parse(File srcFile) throws IOException, JavaParserException { - JavaParser parser = new JavaParser(srcFile, sourceFiles, libFiles); + JavaParser parser = new JavaParser(srcFile, sourceFiles, libFiles, noxrefs); return parser.parse(); } - private CompilationUnitContext transform(CompilationUnit javaCU) { - JavaTransformer transformer = new JavaTransformer(javaCU); + private CompilationUnitContext transform(CompilationUnit javaCU, File srcFile) { + JavaTransformer transformer = new JavaTransformer(javaCU, srcFile); return transformer.transform(); } -- Gitee From 2f062d108d84bb5f5c6787bb66f55c72dd4d28ba Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Mon, 5 Sep 2022 13:13:06 +0300 Subject: [PATCH 07/13] Correction to interface translation Change-Id: I8218842f61683728f96a0795596d13644d174886 Signed-off-by: Alexander Pavlyuk --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 869d995e6..7ee2433a1 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -541,11 +541,15 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Process access modifier. In top-level context, public translates to export, // everything else to none. In all other contexts, emit AccessibilityModifierContext. - // NOTE: In all cases, resulting node should NOT be a child of declaration node! - if (isInClassContext || isInInterfaceContext) { + if (isInClassContext) { AccessibilityModifierContext stsAccessMod = NodeBuilder.accessibilityModifier(javaMods); if (stsAccessMod != null) stsMemberContext.addChild(stsAccessMod).setParent(stsMemberContext); } + else if (isInInterfaceContext) { + // Note: 'public' modifier is not permitted for interface's members. + AccessibilityModifierContext stsAccessMod = NodeBuilder.accessibilityModifier(javaMods & ~Modifier.PUBLIC); + if (stsAccessMod != null) stsMemberContext.addChild(stsAccessMod).setParent(stsMemberContext); + } else if ((javaMods & Modifier.PUBLIC) != 0) stsMemberContext.addChild(NodeBuilder.terminalNode(StaticTSParser.Export)); -- Gitee From 58e46e844c0c5495d7621b88fa31cd300067aeb3 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Mon, 5 Sep 2022 17:35:52 +0300 Subject: [PATCH 08/13] Correction of expected files in interface tests Change-Id: I35b712e423007ca580fcaad1004f263eeac815c6 Signed-off-by: Alexander Pavlyuk --- migrator/test/java/interface_nested.java.sts | 8 ++++---- migrator/test/java/interface_public.java.sts | 6 +++--- migrator/test/java/test_interface.java.sts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/migrator/test/java/interface_nested.java.sts b/migrator/test/java/interface_nested.java.sts index fa47496ed..088e675be 100644 --- a/migrator/test/java/interface_nested.java.sts +++ b/migrator/test/java/interface_nested.java.sts @@ -18,7 +18,7 @@ import java.util.List; import java.io.*; interface Test { Outtermethod(): void ; - public open class A { + open class A { i : int ; } @@ -27,10 +27,10 @@ interface Test { } interface innerInterface { - public Innermethod(): int ; + Innermethod(): int ; } - public interface inner_A { + interface inner_A { coeff(): double ; } @@ -44,7 +44,7 @@ open class TestClass implements Test.innerInterface, Test.inner_A { return 3.14; } public interface constants { - public Pi(): double ; + Pi(): double ; static E(): double { return 2.7828; } diff --git a/migrator/test/java/interface_public.java.sts b/migrator/test/java/interface_public.java.sts index ed8935485..06409cf69 100644 --- a/migrator/test/java/interface_public.java.sts +++ b/migrator/test/java/interface_public.java.sts @@ -18,14 +18,14 @@ import java.util.List; import java.io.*; export interface interface_public { i : int = 10; - public pi : double = 3.1416; + pi : double = 3.1416; foo(): void ; static foo(i : int): void { } private foo(b : boolean): void { } - public foo(s : String): void ; - public static Pi(): double { + foo(s : String): void ; + static Pi(): double { return pi; } E(): double { diff --git a/migrator/test/java/test_interface.java.sts b/migrator/test/java/test_interface.java.sts index 0db0b8dd4..d90b30942 100644 --- a/migrator/test/java/test_interface.java.sts +++ b/migrator/test/java/test_interface.java.sts @@ -24,7 +24,7 @@ interface test_interface { } private foo(b : boolean): void { } - public foo(s : String): void ; + foo(s : String): void ; } interface iface_FP { @@ -32,6 +32,6 @@ interface iface_FP { } interface iface_C extends test_interface, iface_FP { - public foo(d : double): void ; + foo(d : double): void ; } -- Gitee From dd4b0b279b4aa699b18b376f34b21a97988319ae Mon Sep 17 00:00:00 2001 From: Vsevolod Pukhov Date: Wed, 31 Aug 2022 18:04:38 +0300 Subject: [PATCH 09/13] Disable flaky test262 async*dflt-params-arg-val-not-undefined Signed-off-by: Vsevolod Pukhov --- test/test262skiplist-flaky.txt | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/test262skiplist-flaky.txt b/test/test262skiplist-flaky.txt index 424e218b2..eacb199cd 100644 --- a/test/test262skiplist-flaky.txt +++ b/test/test262skiplist-flaky.txt @@ -8,3 +8,38 @@ intl402/Locale/constructor-options-language-valid.js built-ins/TypedArray/prototype/filter/callbackfn-called-before-species.js # panda#6937 intl402/NumberFormat/test-option-currencyDisplay.js +# panda#9132 +language/statements/class/async-method-static/dflt-params-arg-val-not-undefined.js +language/statements/class/async-method-static/dflt-params-arg-val-undefined.js +language/statements/class/async-method/dflt-params-arg-val-not-undefined.js +language/statements/class/async-method/dflt-params-arg-val-undefined.js +language/statements/class/async-gen-method-static/dflt-params-arg-val-not-undefined.js +language/statements/class/async-gen-method-static/dflt-params-arg-val-undefined.js +language/statements/class/async-gen-method/dflt-params-arg-val-not-undefined.js +language/statements/class/async-gen-method/dflt-params-arg-val-undefined.js +language/statements/async-generator/dflt-params-arg-val-not-undefined.js +language/statements/async-generator/dflt-params-arg-val-undefined.js +language/statements/async-function/dflt-params-arg-val-not-undefined.js +language/statements/async-function/dflt-params-arg-val-undefined.js +language/expressions/class/async-method-static/dflt-params-arg-val-not-undefined.js +language/expressions/class/async-method-static/dflt-params-arg-val-undefined.js +language/expressions/class/async-method/dflt-params-arg-val-not-undefined.js +language/expressions/class/async-method/dflt-params-arg-val-undefined.js +language/expressions/class/async-gen-method-static/dflt-params-arg-val-not-undefined.js +language/expressions/class/async-gen-method-static/dflt-params-arg-val-undefined.js +language/expressions/class/async-gen-method/dflt-params-arg-val-not-undefined.js +language/expressions/class/async-gen-method/dflt-params-arg-val-undefined.js +language/expressions/object/method-definition/async-gen-meth-dflt-params-arg-val-not-undefined.js +language/expressions/object/method-definition/async-meth-dflt-params-arg-val-not-undefined.js +language/expressions/object/method-definition/async-meth-dflt-params-arg-val-undefined.js +language/expressions/object/method-definition/async-gen-meth-dflt-params-arg-val-undefined.js +language/expressions/async-generator/dflt-params-arg-val-not-undefined.js +language/expressions/async-generator/dflt-params-arg-val-undefined.js +language/expressions/async-generator/named-dflt-params-arg-val-not-undefined.js +language/expressions/async-generator/named-dflt-params-arg-val-undefined.js +language/expressions/async-arrow-function/dflt-params-arg-val-not-undefined.js +language/expressions/async-arrow-function/dflt-params-arg-val-undefined.js +language/expressions/async-function/nameless-dflt-params-arg-val-undefined.js +language/expressions/async-function/named-dflt-params-arg-val-not-undefined.js +language/expressions/async-function/nameless-dflt-params-arg-val-not-undefined.js +language/expressions/async-function/named-dflt-params-arg-val-undefined.js -- Gitee From cc7b12806910241631ed09877aec3902d01edaa6 Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Thu, 1 Sep 2022 17:30:14 +0300 Subject: [PATCH 10/13] Translation of generics Change-Id: Id6ce62ea5fbf5bc8b21c75a424d49fa5a945223d Signed-off-by: Alexander Pavlyuk --- migrator/test/java/interface_nested.java.sts | 8 ++++---- migrator/test/java/interface_public.java.sts | 6 +++--- migrator/test/java/test_interface.java.sts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/migrator/test/java/interface_nested.java.sts b/migrator/test/java/interface_nested.java.sts index 088e675be..fa47496ed 100644 --- a/migrator/test/java/interface_nested.java.sts +++ b/migrator/test/java/interface_nested.java.sts @@ -18,7 +18,7 @@ import java.util.List; import java.io.*; interface Test { Outtermethod(): void ; - open class A { + public open class A { i : int ; } @@ -27,10 +27,10 @@ interface Test { } interface innerInterface { - Innermethod(): int ; + public Innermethod(): int ; } - interface inner_A { + public interface inner_A { coeff(): double ; } @@ -44,7 +44,7 @@ open class TestClass implements Test.innerInterface, Test.inner_A { return 3.14; } public interface constants { - Pi(): double ; + public Pi(): double ; static E(): double { return 2.7828; } diff --git a/migrator/test/java/interface_public.java.sts b/migrator/test/java/interface_public.java.sts index 06409cf69..ed8935485 100644 --- a/migrator/test/java/interface_public.java.sts +++ b/migrator/test/java/interface_public.java.sts @@ -18,14 +18,14 @@ import java.util.List; import java.io.*; export interface interface_public { i : int = 10; - pi : double = 3.1416; + public pi : double = 3.1416; foo(): void ; static foo(i : int): void { } private foo(b : boolean): void { } - foo(s : String): void ; - static Pi(): double { + public foo(s : String): void ; + public static Pi(): double { return pi; } E(): double { diff --git a/migrator/test/java/test_interface.java.sts b/migrator/test/java/test_interface.java.sts index d90b30942..0db0b8dd4 100644 --- a/migrator/test/java/test_interface.java.sts +++ b/migrator/test/java/test_interface.java.sts @@ -24,7 +24,7 @@ interface test_interface { } private foo(b : boolean): void { } - foo(s : String): void ; + public foo(s : String): void ; } interface iface_FP { @@ -32,6 +32,6 @@ interface iface_FP { } interface iface_C extends test_interface, iface_FP { - foo(d : double): void ; + public foo(d : double): void ; } -- Gitee From c3318029754f07919725b18ea7cf802ff1b70239 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Tue, 30 Aug 2022 15:05:04 +0300 Subject: [PATCH 11/13] Implemented translation of synchronized blocks. Defer statement is implemented in STS as part of the above. Added a test to validate translation of synchronized blocks. Change-Id: I22e6df938e3782de58518c02776d5a8ce90bcb25 Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 7ee2433a1..05d6717af 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -3623,7 +3623,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // synchronized(X) { statements } // // STS: - // { MonitorEnter(X); defer MonitorExit(X); statements } + // { Monitor.lock(X); defer Monitor.unlock(X); statements } @Override public boolean visit(SynchronizedStatement javaSynchrStmt) { pushStatement(new BlockContext(stsCurrent, 0)); -- Gitee From d3460aae51111c41ca228421ad5b10dfd5fad447 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 31 Aug 2022 13:26:51 +0300 Subject: [PATCH 12/13] Implemented translation of synchronized methods. Added a test to validate the functionality above. Change-Id: I4912bc76b7c1b9685dd2b60b0a81536eba13f04e Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/java/JavaTransformer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 05d6717af..7ee2433a1 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -3623,7 +3623,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // synchronized(X) { statements } // // STS: - // { Monitor.lock(X); defer Monitor.unlock(X); statements } + // { MonitorEnter(X); defer MonitorExit(X); statements } @Override public boolean visit(SynchronizedStatement javaSynchrStmt) { pushStatement(new BlockContext(stsCurrent, 0)); -- Gitee From 8a643bbe2529d578a5abb4a9483dc97a525d851c Mon Sep 17 00:00:00 2001 From: Alexander Pavlyuk Date: Mon, 5 Sep 2022 17:59:20 +0300 Subject: [PATCH 13/13] Post merge update of expected files for interface tests Change-Id: I9fc8efdf9bf722926685a3446ffeee07de0770ed Signed-off-by: Alexander Pavlyuk --- migrator/test/java/interface_nested.java.sts | 8 ++++---- migrator/test/java/interface_public.java.sts | 6 +++--- migrator/test/java/test_interface.java.sts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/migrator/test/java/interface_nested.java.sts b/migrator/test/java/interface_nested.java.sts index fa47496ed..088e675be 100644 --- a/migrator/test/java/interface_nested.java.sts +++ b/migrator/test/java/interface_nested.java.sts @@ -18,7 +18,7 @@ import java.util.List; import java.io.*; interface Test { Outtermethod(): void ; - public open class A { + open class A { i : int ; } @@ -27,10 +27,10 @@ interface Test { } interface innerInterface { - public Innermethod(): int ; + Innermethod(): int ; } - public interface inner_A { + interface inner_A { coeff(): double ; } @@ -44,7 +44,7 @@ open class TestClass implements Test.innerInterface, Test.inner_A { return 3.14; } public interface constants { - public Pi(): double ; + Pi(): double ; static E(): double { return 2.7828; } diff --git a/migrator/test/java/interface_public.java.sts b/migrator/test/java/interface_public.java.sts index ed8935485..06409cf69 100644 --- a/migrator/test/java/interface_public.java.sts +++ b/migrator/test/java/interface_public.java.sts @@ -18,14 +18,14 @@ import java.util.List; import java.io.*; export interface interface_public { i : int = 10; - public pi : double = 3.1416; + pi : double = 3.1416; foo(): void ; static foo(i : int): void { } private foo(b : boolean): void { } - public foo(s : String): void ; - public static Pi(): double { + foo(s : String): void ; + static Pi(): double { return pi; } E(): double { diff --git a/migrator/test/java/test_interface.java.sts b/migrator/test/java/test_interface.java.sts index 0db0b8dd4..d90b30942 100644 --- a/migrator/test/java/test_interface.java.sts +++ b/migrator/test/java/test_interface.java.sts @@ -24,7 +24,7 @@ interface test_interface { } private foo(b : boolean): void { } - public foo(s : String): void ; + foo(s : String): void ; } interface iface_FP { @@ -32,6 +32,6 @@ interface iface_FP { } interface iface_C extends test_interface, iface_FP { - public foo(d : double): void ; + foo(d : double): void ; } -- Gitee