diff --git a/aot/main.cpp b/aot/main.cpp index 8dbd680977fa6e901ca1e41d7f6dbc8235458125..79c919ecdaf3a0cb19ae266134aed2727987ab4b 100644 --- a/aot/main.cpp +++ b/aot/main.cpp @@ -67,7 +67,7 @@ static int GenerateProgram(panda::pandasm::Program *prog, const std::string &out return 1; } - panda::bytecodeopt::options.SetOptLevel(optLevel); + panda::bytecodeopt::OPTIONS.SetOptLevel(optLevel); panda::bytecodeopt::OptimizeBytecode(prog, mapsp, output, true, true); } #endif diff --git a/compiler/core/emitter.cpp b/compiler/core/emitter.cpp index 6e617cb41f196d3b1ae3fdc361eed462f28af155..2b724b665be5597ada2fa28a41ebb8dcbbe3e8b7 100644 --- a/compiler/core/emitter.cpp +++ b/compiler/core/emitter.cpp @@ -85,56 +85,56 @@ void FunctionEmitter::GenBufferLiterals(const LiteralBuffer *buff) switch (tag) { case ir::LiteralTag::BOOLEAN: { - valueLit.tag_ = panda::panda_file::LiteralTag::BOOL; - valueLit.value_ = literal->GetBoolean(); + valueLit.tag = panda::panda_file::LiteralTag::BOOL; + valueLit.value = literal->GetBoolean(); break; } case ir::LiteralTag::INTEGER: { - valueLit.tag_ = panda::panda_file::LiteralTag::INTEGER; - valueLit.value_ = literal->GetInt(); + valueLit.tag = panda::panda_file::LiteralTag::INTEGER; + valueLit.value = literal->GetInt(); break; } case ir::LiteralTag::DOUBLE: { - valueLit.tag_ = panda::panda_file::LiteralTag::DOUBLE; - valueLit.value_ = literal->GetDouble(); + valueLit.tag = panda::panda_file::LiteralTag::DOUBLE; + valueLit.value = literal->GetDouble(); break; } case ir::LiteralTag::STRING: { - valueLit.tag_ = panda::panda_file::LiteralTag::STRING; - valueLit.value_ = literal->GetString().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::STRING; + valueLit.value = literal->GetString().Mutf8(); break; } case ir::LiteralTag::ACCESSOR: { - valueLit.tag_ = panda::panda_file::LiteralTag::ACCESSOR; - valueLit.value_ = static_cast(0); + valueLit.tag = panda::panda_file::LiteralTag::ACCESSOR; + valueLit.value = static_cast(0); break; } case ir::LiteralTag::METHOD: { - valueLit.tag_ = panda::panda_file::LiteralTag::METHOD; - valueLit.value_ = literal->GetMethod().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::METHOD; + valueLit.value = literal->GetMethod().Mutf8(); break; } case ir::LiteralTag::GENERATOR_METHOD: { - valueLit.tag_ = panda::panda_file::LiteralTag::GENERATORMETHOD; - valueLit.value_ = literal->GetMethod().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::GENERATORMETHOD; + valueLit.value = literal->GetMethod().Mutf8(); break; } case ir::LiteralTag::ASYNC_GENERATOR_METHOD: { - valueLit.tag_ = panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD; - valueLit.value_ = literal->GetMethod().Mutf8(); + valueLit.tag = panda::panda_file::LiteralTag::ASYNCGENERATORMETHOD; + valueLit.value = literal->GetMethod().Mutf8(); break; } case ir::LiteralTag::NULL_VALUE: { - valueLit.tag_ = panda::panda_file::LiteralTag::NULLVALUE; - valueLit.value_ = static_cast(0); + valueLit.tag = panda::panda_file::LiteralTag::NULLVALUE; + valueLit.value = static_cast(0); break; } default: break; } - tagLit.tag_ = panda::panda_file::LiteralTag::TAGVALUE; - tagLit.value_ = static_cast(valueLit.tag_); + tagLit.tag = panda::panda_file::LiteralTag::TAGVALUE; + tagLit.value = static_cast(valueLit.tag); array.emplace_back(tagLit); array.emplace_back(valueLit); diff --git a/migrator/src/com/ohos/migrator/AbstractTranspiler.java b/migrator/src/com/ohos/migrator/AbstractTranspiler.java index 015b991043de3de7b92f20d2b9d0bdd6d2d0789c..196df0c8aad94c6b10e877c6b0ddb4b767c0c075 100644 --- a/migrator/src/com/ohos/migrator/AbstractTranspiler.java +++ b/migrator/src/com/ohos/migrator/AbstractTranspiler.java @@ -36,14 +36,7 @@ public abstract class AbstractTranspiler implements Transpiler { protected List libFiles; protected List outFiles; protected List errorList; - private String outDir = null; - - protected boolean strictMode = false; - public void setStrictMode(boolean mode) { - strictMode = mode; - } - public AbstractTranspiler(List src, List libs, String outDir) { sourceFiles = src; libFiles = libs; @@ -67,11 +60,18 @@ public abstract class AbstractTranspiler implements Transpiler { } catch (TranspileException e) { errorList.add(e); transpileResult = ResultCode.majorValue(e.getResult(), transpileResult); - if (strictMode) return transpileResult; + if (Main.isStrictMode()) return transpileResult; } catch (Exception e) { + StringBuilder sb = new StringBuilder(e.getClass().getName()); + sb.append(" at:\n"); + + for (StackTraceElement ste : e.getStackTrace()) + sb.append(ste.toString()).append("\n"); + + errorList.add(new TranspileException(ResultCode.InputError, sb.toString())); transpileResult = ResultCode.majorValue(ResultCode.InputError, transpileResult); - if (strictMode) return transpileResult; + if (Main.isStrictMode()) return transpileResult; } } diff --git a/migrator/src/com/ohos/migrator/Main.java b/migrator/src/com/ohos/migrator/Main.java index 6cad994554787f4349c2d04cc5aa6c219eae38ff..4f8e169543d6e5570cde405c818c7d650c99d220 100644 --- a/migrator/src/com/ohos/migrator/Main.java +++ b/migrator/src/com/ohos/migrator/Main.java @@ -65,6 +65,9 @@ public class Main { public static boolean hasErrors() { return !errorList.isEmpty(); } + public static void addError(ResultCode code, String message) { + errorList.add(new TranspileException(code, message)); + } public static void main(String[] args) { final Options options = new Options(); @@ -74,7 +77,7 @@ public class Main { options.addOption(new Option("o","outdir",true,"Specify where to place generated source files")); options.addOption(new Option("nowarn","nowarn",false,"Generate no warnings")); options.addOption(new Option("Werror","Werror",false,"Treate warnings as errors")); - options.addOption(new Option("strict","strict",false,"Terminate transpile process after first error occurs")); + options.addOption(new Option("s","strict",false,"Terminate transpile process after first error occurs")); options.addOption(new Option("l","libs",true, "List of libraries separate with commas")); options.addOption(new Option("T","check-sts-syntax",false,"Check syntactical correctness of StaticTS sources")); options.addOption(new Option("R", "conversion-rate", false, "Report conversion rate")); @@ -145,7 +148,7 @@ public class Main { } } - if (needStsSyntaxCheck) { + if (needStsSyntaxCheck && !stsSources.isEmpty()) { ResultCode code = checkSTSSyntax(stsSources); finish(code); } @@ -184,7 +187,6 @@ public class Main { System.out.println("Transpiling " + javaSources.size() + " Java files."); JavaTranspiler javaTranspiler = new JavaTranspiler(javaSources, jarLibs, outDir); - if(isStrictMode()) javaTranspiler.setStrictMode(true); resultCode = javaTranspiler.transpile(); outFiles.addAll(javaTranspiler.getOutFiles()); errorList.addAll(javaTranspiler.getErrorList()); @@ -214,7 +216,11 @@ public class Main { // Check syntax of all STS files produced. // NOTE: This is for development process only, probably to be removed afterwards. - resultCode = ResultCode.majorValue(checkSTSSyntax(outFiles), resultCode); + // NOTE: We now ignore Java syntax and semantic errors by default, + // so don't check STS syntax by default, either. + if (isStrictMode() || needStsSyntaxCheck) + resultCode = ResultCode.majorValue(checkSTSSyntax(outFiles), resultCode); + finish(resultCode); } catch (UnrecognizedOptionException e) { diff --git a/migrator/src/com/ohos/migrator/TestRunner.java b/migrator/src/com/ohos/migrator/TestRunner.java index 69e59aad624c7caeaed606370d18970ba8e9aaec..2d0af0e7d531f22d3b80a4a491d06b2982db92d2 100644 --- a/migrator/src/com/ohos/migrator/TestRunner.java +++ b/migrator/src/com/ohos/migrator/TestRunner.java @@ -63,7 +63,7 @@ public class TestRunner { String testFilePath = new File(testDir, testFile).getPath(); System.out.println("Running test " + testFile); - String[] mainArgs = new String[] {"-verbose", "-o", testResultDir.getPath(), testFilePath}; + String[] mainArgs = new String[] {"-verbose", "-s", "-o", testResultDir.getPath(), testFilePath}; Main.runTests(mainArgs); File resultFile = new File(testResultDir, testFile + Main.STS_EXT); diff --git a/migrator/src/com/ohos/migrator/java/JavaParser.java b/migrator/src/com/ohos/migrator/java/JavaParser.java index 6ef82f25816ab0479827fcfb2522155c93c0ed4d..f2cc113e4c05ccc73b7a2b6bf91267d929720c46 100644 --- a/migrator/src/com/ohos/migrator/java/JavaParser.java +++ b/migrator/src/com/ohos/migrator/java/JavaParser.java @@ -16,6 +16,7 @@ package com.ohos.migrator.java; import com.ohos.migrator.Main; +import com.ohos.migrator.ResultCode; import com.ohos.migrator.util.FileUtils; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.compiler.IProblem; @@ -40,7 +41,7 @@ public class JavaParser { private File sourceFile; private static Map packagePaths = new HashMap<>(); - private String[] sourcepathEntries = null; + private static String[] sourcepathEntries = null; private String[] classpathEntries = null; /* @@ -53,14 +54,18 @@ public class JavaParser { /** * Create a Java parser. * - * @param fileToParse Java source file to be parsed. + * @param sourceFile Java source file to be parsed. * @param sourceFiles List of Java source files whose paths will be used to configure * parser's 'sourcepaths' setting. * @param classpaths List of paths to jar files or directories with '.class' files. */ public JavaParser(File sourceFile, List sourceFiles, List classpaths) throws IOException { this(sourceFile); - setSourcepathEntries(sourceFiles); + + // Compute reference source paths once + if (sourcepathEntries == null) + setSourcepathEntries(sourceFiles); + setClasspathEntries(classpaths); } @@ -73,7 +78,7 @@ public class JavaParser { this.source = source; } - private String getPackagePath(File file) { + private static String getPackagePath(File file) { // If already processed this file, return the result from cache. if (packagePaths.containsKey(file)) { return packagePaths.get(file); @@ -125,13 +130,10 @@ public class JavaParser { return packagePath; } - private void setSourcepathEntries(List sourceFiles) { + private static void setSourcepathEntries(List sourceFiles) { Set filePaths = new HashSet<>(); for (File file : sourceFiles) { - // Skip source file that is to be parsed currently. - if (file == this.sourceFile) continue; - // ASTParser accepts only directories where reference sources // are located. Thus, store the parent of each source file path. String pkg = getPackagePath(file); @@ -196,12 +198,28 @@ public class JavaParser { CompilationUnit cu = (CompilationUnit) parser.createAST(null); if (cu == null) throw new JavaParserException("unknown Java parsing error"); - // Problems contains both warnings and errors. Don't throw the exception when there are only warnings. - for (IProblem problems : cu.getProblems()) { - if (problems.isError()) - throw new JavaParserException(cu.getProblems()); + // In strict mode, terminate on syntax or semantic errors; + // otherwise, report them and continue. + for (IProblem problem : cu.getProblems()) { + if (problem.isError()) { + if (Main.isStrictMode()) + throw new JavaParserException(cu.getProblems()); + else + Main.addError(ResultCode.ParseError, buildErrorMessage(problem)); + } } return cu; } + + public static String buildErrorMessage(IProblem problem) { + StringBuilder sb = new StringBuilder(); + int lineNumber = problem.getSourceLineNumber(); + String fileName = String.valueOf(problem.getOriginatingFileName()); + + String pos = fileName + "(" + lineNumber + "): "; + sb.append(pos).append(problem.getMessage()); + + return sb.toString(); + } } diff --git a/migrator/src/com/ohos/migrator/java/JavaParserException.java b/migrator/src/com/ohos/migrator/java/JavaParserException.java index e0411fb275da06b23e366ab5e66cb3c69dc93170..8dad5a2bc25ffd6cf926f6273253ab6930dac448 100644 --- a/migrator/src/com/ohos/migrator/java/JavaParserException.java +++ b/migrator/src/com/ohos/migrator/java/JavaParserException.java @@ -18,20 +18,18 @@ package com.ohos.migrator.java; import org.eclipse.jdt.core.compiler.IProblem; public class JavaParserException extends Exception { - private static String buildErrorMessage(IProblem[] parseProblems) { StringBuilder sb = new StringBuilder(); for (IProblem problem: parseProblems) { - String pos = new String(problem.getOriginatingFileName()) + "(" + problem.getSourceLineNumber() + "): "; - sb.append(pos + problem.getMessage()).append('\n'); + if (problem.isError()) + sb.append(JavaParser.buildErrorMessage(problem)).append("\n"); } + return sb.toString(); } - public JavaParserException(IProblem[] parseProblems) { this(buildErrorMessage(parseProblems)); } - public JavaParserException(String s) { super(s); } diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index b0eb95d5a4462a485122bc9190497df411651e8c..c5410ec753db5d3eb81ea99ca12cabb42e5a2668 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -27,6 +27,7 @@ import org.eclipse.jdt.core.dom.*; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Stack; @@ -43,19 +44,43 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; + + private final String ENUM_TYPE_NAME = "ENUM_TYPE_NAME"; + + private final String ENUM_CONST_ORDINAL = "ENUM_CONST_ORDINAL"; + private static int countStmtTotal = 0; private static int countExprTotal = 0; + private static int countDeclTotal = 0; + private static int countTypeTotal = 0; private static int countExprTransformed = 0; private static int countStmtTransformed = 0; + private static int countDeclTransformed = 0; + private static int countTypeTransformed = 0; public static double getTransformationRate() { double result = 0.; + int normFactor = 0; - if (countStmtTotal > 0) result += countStmtTransformed / (double)countStmtTotal; - if (countExprTotal > 0) result += countExprTransformed / (double)countExprTotal; + if (countStmtTotal > 0) { + ++normFactor; + result += countStmtTransformed / (double)countStmtTotal; + } + if (countExprTotal > 0) { + ++normFactor; + result += countExprTransformed / (double)countExprTotal; + } + if (countDeclTotal > 0) { + ++normFactor; + result += countDeclTransformed / (double)countDeclTotal; + } + if (countTypeTotal > 0) { + ++normFactor; + result += countTypeTransformed / (double)countTypeTotal; + } - double normFactor = (countStmtTotal > 0 && countExprTotal > 0) ? 2. : 1.; - return result / normFactor; + return (normFactor > 0) ? result / (double)normFactor : 0.; } /** @@ -139,6 +164,14 @@ public class JavaTransformer extends ASTVisitor implements Transformer { ++countExprTotal; else if (node instanceof Statement) ++countStmtTotal; + else if (node instanceof BodyDeclaration + || node instanceof VariableDeclaration + || node.getNodeType() == ASTNode.ANONYMOUS_CLASS_DECLARATION + || node.getNodeType() == ASTNode.IMPORT_DECLARATION + || node.getNodeType() == ASTNode.PACKAGE_DECLARATION) + ++countDeclTotal; + else if (node instanceof Type) + ++countTypeTotal; } }); @@ -182,17 +215,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // PackageDeclarationContext + ++countDeclTransformed; return false; } - private void translateNonAccessModifiers(FieldDeclaration javaFieldDecl) { - int javaModifiers = javaFieldDecl.getModifiers(); - - // A field may not have Abstract modifier. - if ((javaModifiers & Modifier.STATIC) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); - if ((javaModifiers & Modifier.FINAL) == 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Open)); - } - private void translateNonAccessModifiers(TypeDeclaration javaTypeDeclaration) { int javaModifiers = javaTypeDeclaration.getModifiers(); @@ -207,8 +233,15 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private boolean doesOverride(ITypeBinding javaClassBinding, IMethodBinding javaCheckedMethod) { if (javaClassBinding != null) { - for (IMethodBinding javaMethod : javaClassBinding.getDeclaredMethods()) { - if (javaCheckedMethod.overrides(javaMethod)) + if (!javaClassBinding.isEqualTo(javaCheckedMethod.getDeclaringClass())) { + for (IMethodBinding javaMethod : javaClassBinding.getDeclaredMethods()) { + if (javaCheckedMethod.overrides(javaMethod)) + return true; + } + } + + for (ITypeBinding javaInterface : javaClassBinding.getInterfaces()) { + if (doesOverride(javaInterface, javaCheckedMethod)) return true; } @@ -229,8 +262,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { else if ((javaModifiers & Modifier.FINAL) == 0) { // If the input (java) method is not final then output (STS) method has to be either Open or Override IMethodBinding javaMethodBinding = javaMethodDeclaration.resolveBinding(); - IMethodBinding javaDeclarationBinding = javaMethodBinding.getMethodDeclaration(); - if (doesOverride(javaDeclarationBinding.getDeclaringClass().getSuperclass(), javaDeclarationBinding)) + if (javaMethodBinding != null && doesOverride(javaMethodBinding.getDeclaringClass(), javaMethodBinding)) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Override)); else if ((javaModifiers & Modifier.STATIC) == 0 && (javaModifiers & Modifier.PRIVATE) == 0 && isInClassContext) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Open)); @@ -240,14 +272,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if ((javaModifiers & Modifier.NATIVE) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Native)); } - private void translateNonAccessModifiers(EnumDeclaration javaEnumDeclaration) { - // TODO: Check and correct to apply only enum related/valid modifiers. - int javaModifiers = javaEnumDeclaration.getModifiers(); - if ((javaModifiers & Modifier.ABSTRACT) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Abstract)); - if ((javaModifiers & Modifier.STATIC) != 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); - if ((javaModifiers & Modifier.FINAL) == 0) stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Open)); - } - // Java tree: // TypeDeclaration: // A type declaration is the union of a class declaration and an interface declaration. // ClassDeclaration @@ -267,7 +291,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // { { InterfaceBodyDeclaration | ; } } // // STS tree for interface: - // TopLevelElementContext + // topDeclarationContext // InterfaceDeclarationContext // TerminalNode // TerminalNode @@ -278,8 +302,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // // STS src: class TestClassB extends TestClassA implements TestInterfaceA, TestInterfaceB {} // Resulting tree: - // TopLevelElementContext | ClassMemberContext | InterfaceMemberContext - // TerminalNode ? (for TopLevelElementContext) + // topDeclarationContext | ClassMemberContext | InterfaceMemberContext + // TerminalNode ? (for topDeclarationContext) // | AccessibilityModifierContext? (for ClassMemberContext or InterfaceMemberContext) // ClassDeclarationContext // TerminalNode @@ -353,6 +377,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // Interface/ClassDeclarationContext popCurrent(); // stsMemberContext + ++countDeclTransformed; return false; } @@ -412,13 +437,57 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeParametersContext } + // Java tree: + // TypeParameter: { ExtendedModifier } Identifier [ extends Type { & Type } ] + // STS tree: + // typeParameter: Identifier constraint?; + // constraint: Extends (typeReference | intersectionType); + // typeReference: typeReferencePart (Dot typeReferencePart)* + // typeReferencePart: qualifiedName typeArguments? + // typeArguments: LessThan typeArgumentList? MoreThan + // intersectionType: OpenParen typeReference (BitAnd typeReference)+ CloseParen @Override public boolean visit(TypeParameter javaTypeParameter) { pushCurrent(new TypeParameterContext(stsCurrent, 0)); - // TODO: Add constraints! stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaTypeParameter.getName())); + // TODO: Add constraints! + List javaModifiers = javaTypeParameter.modifiers(); + if (javaModifiers != null && !javaModifiers.isEmpty()) { + // TODO: Translate the modifiers. + } + + List javaTypeBounds = javaTypeParameter.typeBounds(); + if (!javaTypeBounds.isEmpty()) { + pushCurrent(new ConstraintContext(stsCurrent, 0)); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Extends)); + + if (javaTypeBounds.size() == 1) { + javaTypeBounds.get(0).accept(this); + } else { + pushCurrent(new IntersectionTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); + + boolean first = true; + for (Type javaType : javaTypeBounds) { + if (!first) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.BitAnd)); + } else { + first = false; + } + + javaType.accept(this); + } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); + popCurrent(); // IntersectionTypeContext + } + + popCurrent(); // ConstraintContext + } + popCurrent(); // TypeParameterContext return false; } @@ -432,6 +501,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsMemberContext = new ClassMemberContext(stsCurrent, 0); else if (isInInterfaceContext) stsMemberContext = new InterfaceMemberContext(stsCurrent, 0); + else if (stsCurrent instanceof BlockContext || stsCurrent instanceof ConstructorBodyContext) + stsMemberContext = new StatementOrLocalDeclarationContext(stsCurrent, 0); else stsMemberContext = new TopDeclarationContext(stsCurrent, 0); @@ -448,20 +519,41 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return stsMemberContext; } - private void addInstanceInitializersToCtors(TypeDeclaration javaTypeDeclaration) { + private void addInstanceInitializersToCtors(AbstractTypeDeclaration javaTypeDeclaration) { // Put statements from instance initializers into constructors which don't call // another constructor (i.e. don't have 'this()' call). - List stsInitStmts = (List) javaTypeDeclaration.getProperty(INSTANCE_INITIALIZER); + List stsInitStmts = (List)javaTypeDeclaration.getProperty(INSTANCE_INITIALIZER); if (stsCurrent instanceof ClassBodyContext && stsInitStmts != null && !stsInitStmts.isEmpty()) { ClassBodyContext stsClassBody = (ClassBodyContext) stsCurrent; + boolean needDefaultCtor = true; for (ClassMemberContext stsMember : stsClassBody.classMember()) { - addInstanceInitializersToCtor(stsMember.constructorDeclaration(), stsInitStmts); + ConstructorDeclarationContext stsCtorDecl = stsMember.constructorDeclaration(); + if (stsCtorDecl != null) { + addInstanceInitializersToCtor(stsCtorDecl, stsInitStmts); + needDefaultCtor = false; + } + } + + if (needDefaultCtor) { + // Create default ctor and add initializer statements to it + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PUBLIC)).setParent(stsCurrent); + + ConstructorDeclarationContext stsDefaultCtor = new ConstructorDeclarationContext(stsCurrent, 0); + pushCurrent(stsDefaultCtor); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Constructor)); + stsCurrent.addChild(new ConstructorBodyContext(stsCurrent, 0)).setParent(stsCurrent); + + popCurrent(); // stsDefaultCtor + popCurrent(); // ClassMemberContext + + addInstanceInitializersToCtor(stsDefaultCtor, stsInitStmts); } } } - - private void addInstanceInitializersToCtor(ConstructorDeclarationContext stsCtorDecl, List stsInitStmts) { + private void addInstanceInitializersToCtor(ConstructorDeclarationContext stsCtorDecl, List stsInitStmts) { // Sanity check. if (stsCtorDecl == null) return; @@ -522,20 +614,27 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(stsClassOrInterField); - // Non-access modifiers and field name. - translateNonAccessModifiers(javaFieldDecl); + // Non-access modifiers + if ((javaMods & Modifier.STATIC) != 0) + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + // Note: Java allows final fields declared without initializer (to be initialized in ctor). + // STS doesn't allow constant fields without initializer, therefore the fields above will + // be translated without const modifier. ParserRuleContext stsVarOrConstDecl; - if ((javaMods & Modifier.FINAL) != 0 || !isInClassContext) { + Expression javaFragmentInit = javaVarDeclFragment.getInitializer(); + if (((javaMods & Modifier.FINAL) != 0 && javaFragmentInit != null) || !isInClassContext) { stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Const)); stsVarOrConstDecl = new ConstantDeclarationContext(stsCurrent, 0); } else stsVarOrConstDecl = new VariableDeclarationContext(stsCurrent, 0); + // Field name pushCurrent(stsVarOrConstDecl); stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaVarDeclFragment.getName())); + // Field type pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); javaFieldDecl.getType().accept(this); @@ -545,11 +644,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // TypeAnnotationContext - Expression javaInitializer = javaVarDeclFragment.getInitializer(); - if (javaInitializer != null) { + // Field initializer, if any + if (javaFragmentInit != null) { pushCurrent(new InitializerContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitializer.accept(this); + javaFragmentInit.accept(this); popCurrent(); // InitializerContext } @@ -558,6 +657,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // stsClassOrInterMember } + ++countDeclTransformed; return false; } @@ -584,6 +684,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popCurrent(); // ImportStatementContext + ++countDeclTransformed; return false; } @@ -623,11 +724,12 @@ public class JavaTransformer extends ASTVisitor implements Transformer { boolean needPrimaryType = isInPrimaryTypeContext(); if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - PredefinedTypeContext stsType = NodeBuilder.predefinedType(javaPrimitiveType); + PredefinedTypeContext stsType = NodeBuilder.predefinedType(javaPrimitiveType.getPrimitiveTypeCode()); stsCurrent.addChild(stsType).setParent(stsCurrent); if (needPrimaryType) popCurrent(); // PrimaryTypeContext + ++countTypeTransformed; return false; } @@ -648,6 +750,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext + ++countTypeTransformed; return false; } @@ -683,6 +786,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsTypeRef.addChild(stsTypeRefPart).setParent(stsTypeRef); if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -706,9 +811,24 @@ public class JavaTransformer extends ASTVisitor implements Transformer { if (needPrimaryType) popCurrent(); // PrimaryTypeContext + ++countTypeTransformed; return false; } + private void translateTypeArgumens(List javaTypeArgs) { + pushCurrent(new TypeArgumentsContext(stsCurrent, 0)); + pushCurrent(new TypeArgumentListContext(stsCurrent, 0)); + + for (Type javaTypeArg : javaTypeArgs) { + pushCurrent(new TypeArgumentContext(stsCurrent, 0)); + javaTypeArg.accept(this); + popCurrent(); // TypeArgumentContext + } + + popCurrent(); // TypeArgumentListContext + popCurrent(); // TypeArgumentsContext + } + @Override public boolean visit(ParameterizedType javaParametrizedType) { boolean needPrimaryType = isInPrimaryTypeContext(); @@ -730,22 +850,15 @@ public class JavaTransformer extends ASTVisitor implements Transformer { assert(lastChild instanceof TypeReferencePartContext && lastChild.getChildCount() == 1); pushCurrent((TypeReferencePartContext)lastChild, false); - pushCurrent(new TypeArgumentsContext(stsCurrent, 0)); - pushCurrent(new TypeArgumentListContext(stsCurrent, 0)); - - for (Type javaTypeArg : javaTypeArgs) { - pushCurrent(new TypeArgumentContext(stsCurrent, 0)); - javaTypeArg.accept(this); - popCurrent(); // TypeArgumentContext - } + translateTypeArgumens(javaTypeArgs); - popCurrent(); // TypeArgumentListContext - popCurrent(); // TypeArgumentsContext popCurrent(); // (TypeReferencePartContext)lastChild popCurrent(); // (TypeReferenceContext)lastChild } if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -766,14 +879,17 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // WildcardTypeContext + + ++countTypeTransformed; return false; } @Override public boolean visit(ArrayType javaArrayType) { - pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); - pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + boolean needPrimaryType = isInPrimaryTypeContext(); + if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); javaArrayType.getElementType().accept(this); int numDims = javaArrayType.getDimensions(); @@ -783,8 +899,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // ArrayTypeContext - popCurrent(); // PrimaryTypeContext + if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } @@ -797,10 +915,43 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(IntersectionType javaIntersectionType) { - // TODO: + boolean needPrimaryType = isInPrimaryTypeContext(); + if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + pushCurrent(new IntersectionTypeContext(stsCurrent, 0)); + + List javaTypeList = javaIntersectionType.types(); + for (Type javaType : javaTypeList) + javaType.accept(this); + + popCurrent(); // IntersectionTypeContext + + if (needPrimaryType) popCurrent(); // PrimaryTypeContext + + ++countTypeTransformed; return false; } + private void translateType(ITypeBinding javaType) { + boolean needPrimaryType = isInPrimaryTypeContext(); + if (needPrimaryType) pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + // NOTE: Method "ITypeBinding.getQualifiedName()" constructs fully-qualified name + // of the corresponding type, including its generic part, array brackets, etc., + // and returns it as a string value. Using this method, we can avoid constructing + // entire STS tree for the corresponding type, simply making an identifier token + // with string value of type's fully-qualified name and wrapping it with a single + // TypeReferenceContext node. + // + // See the following link for details: + // https://help.eclipse.org/latest/topic/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/dom/ITypeBinding.html#getQualifiedName() + + TypeReferenceContext stsTypeRef = NodeBuilder.typeReference(javaType.getQualifiedName()); + stsCurrent.addChild(stsTypeRef).setParent(stsCurrent); + + if (needPrimaryType) popCurrent(); // PrimaryTypeContext + } + // Java tree: // Expression: NullLiteral // STS tree: @@ -900,9 +1051,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { else if (javaOp == InfixExpression.Operator.REMAINDER) stsOperator = StaticTSParser.Modulus; else if (javaOp == InfixExpression.Operator.PLUS) stsOperator = StaticTSParser.Plus; else if (javaOp == InfixExpression.Operator.MINUS) stsOperator = StaticTSParser.Minus; - else if (javaOp == InfixExpression.Operator.LEFT_SHIFT) stsOperator = StaticTSParser.LeftShiftArithmetic; - else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED) stsOperator = StaticTSParser.RightShiftArithmetic; - else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED) stsOperator = StaticTSParser.RightShiftLogical; else if (javaOp == InfixExpression.Operator.LESS) stsOperator = StaticTSParser.LessThan; else if (javaOp == InfixExpression.Operator.GREATER) stsOperator = StaticTSParser.MoreThan; else if (javaOp == InfixExpression.Operator.LESS_EQUALS) stsOperator = StaticTSParser.LessThanEquals; @@ -920,6 +1068,19 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return stsOperator; } + private ParseTree createStsInfixOperator(InfixExpression.Operator javaOp) { + if (isShiftOperator(javaOp)) + return NodeBuilder.shiftOperator(javaOp); + else + return NodeBuilder.terminalNode(stsOperatorType(javaOp)); + } + + private boolean isShiftOperator(InfixExpression.Operator javaInfixOp) { + return javaInfixOp == InfixExpression.Operator.LEFT_SHIFT + || javaInfixOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED + || javaInfixOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED; + } + private ParserRuleContext createStsInfixExpression(SingleExpressionContext stsSingleExpression, InfixExpression javaInfixExpression) { InfixExpression.Operator javaOp = javaInfixExpression.getOperator(); @@ -927,7 +1088,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return new MultiplicativeExpressionContext(stsSingleExpression); else if (javaOp == InfixExpression.Operator.PLUS || javaOp == InfixExpression.Operator.MINUS) return new AdditiveExpressionContext(stsSingleExpression); - else if (javaOp == InfixExpression.Operator.LEFT_SHIFT || javaOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED || javaOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED) + else if (isShiftOperator(javaOp)) return new BitShiftExpressionContext(stsSingleExpression); else if (javaOp == InfixExpression.Operator.LESS || javaOp == InfixExpression.Operator.GREATER || javaOp == InfixExpression.Operator.LESS_EQUALS || javaOp == InfixExpression.Operator.GREATER_EQUALS) return new RelationalExpressionContext(stsSingleExpression); @@ -967,11 +1128,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(InfixExpression javaInfixExpression) { pushCurrent(createStsInfixExpression(pushSingleExpression(), javaInfixExpression)); - - int stsOpType = stsOperatorType(javaInfixExpression.getOperator()); + InfixExpression.Operator javaOp = javaInfixExpression.getOperator(); javaInfixExpression.getLeftOperand().accept(this); - stsCurrent.addChild(NodeBuilder.terminalNode(stsOpType)).setParent(stsCurrent); + stsCurrent.addAnyChild(createStsInfixOperator(javaOp)).setParent(stsCurrent); javaInfixExpression.getRightOperand().accept(this); popSingleExpression(); // InfixExpression @@ -986,7 +1146,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(createStsInfixExpression(pushSingleExpression(), javaInfixExpression)); stsCurrent.addChild(stsLeftOperand).setParent(stsCurrent); - stsCurrent.addChild(NodeBuilder.terminalNode(stsOpType)).setParent(stsCurrent); + stsCurrent.addAnyChild(createStsInfixOperator(javaOp)).setParent(stsCurrent); javaRightExpression.accept(this); popSingleExpression(); // InfixExpression @@ -1128,7 +1288,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // typeParameters: LessThan typeParameterList? MoreThan // typeParameterList: typeParameter (Comma typeParameter)* - private void createStsTypeParameters(List javaTypeParameters) { + private void createStsTypeParameters(List javaTypeParameters) { assert(javaTypeParameters != null); if (!javaTypeParameters.isEmpty()) { @@ -1138,8 +1298,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // typeParameterList: typeParameter (Comma typeParameter)* pushCurrent(new TypeParameterListContext(stsCurrent, 0)); - for (Type javaType : javaTypeParameters) { - javaType.accept(this); + for (TypeParameter javaTypeParam : javaTypeParameters) { + javaTypeParam.accept(this); // Note: TerminalToken (Comma) is not added to the tree. Check if it works OK. } @@ -1172,16 +1332,16 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // OpenParen parameterList? CloseParen // parameterList: parameter (Comma parameter)* (Comma variadicParameter)? | variadicParameter - private void createStsParameterList(List javaParameters) { - // OpenParen formalParameterList? CloseParen + private void createStsParameterList(List javaParameters) { + // OpenParen parameterList? CloseParen stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)).setParent(stsCurrent); assert(javaParameters != null); if (!javaParameters.isEmpty()) { pushCurrent(new ParameterListContext(stsCurrent, 0)); - for (SingleVariableDeclaration javaSingleVariableDeclaration : javaParameters) { - javaSingleVariableDeclaration.accept(this); + for (VariableDeclaration javaVariableDeclaration : javaParameters) { + javaVariableDeclaration.accept(this); } popCurrent(); // ParameterListContext @@ -1211,13 +1371,19 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // ( Block | ; ) // STS tree: // interfaceMember: methodSignature SemiColon #InterfaceMethod - // classMember: constructorDeclaration | classMethodDeclaration | other alternatives are not relevant for this visitor. - // constructorDeclaration: Constructor OpenParen formalParameterList? CloseParen OpenBrace functionBody CloseBrace + // classMember: + // accessibilityModifier? + // ( + // constructorDeclaration + // | classMethodDeclaration + // | other alternatives are not relevant for this visitor. + // ) + // constructorDeclaration: Constructor OpenParen parameterList? CloseParen constructorBody + // constructorBody: OpenBrace constructorCall? statementOrLocalDeclaration* CloseBrace // classMethodDeclaration - // : accessibilityModifier? (Static | Override | Open)? methodSignature OpenBrace functionBody CloseBrace #ClassMethodWithBody - // | Abstract accessibilityModifier? methodSignature SemiColon #AbstractClassMethod - // methodSignature: Identifier callSignature - // callSignature: typeParameters? OpenParen formalParameterList? CloseParen typeAnnotation + // : (Static | Override | Open)? Identifier signature block #ClassMethodWithBody + // | (Abstract | Static? Native | Native Static)? Identifier signature SemiColon #AbstractOrNativeClassMethod + // signature: typeParameters? OpenParen parameterList? CloseParen typeAnnotation @Override public boolean visit(MethodDeclaration javaMethodDeclaration) { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; @@ -1241,7 +1407,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new ConstructorDeclarationContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Constructor)).setParent(stsCurrent); - // STS: OpenParen formalParameterList? CloseParen + // STS: OpenParen parameterList? CloseParen createStsParameterList(javaMethodDeclaration.parameters()); } else { // A regular method (not a constructor). @@ -1290,6 +1456,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } popCurrent(); // ClassMemberContext or InterfaceMemberContext + + ++countDeclTransformed; return false; } @@ -1304,7 +1472,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS: typeParameters: LessThan typeParameterList? MoreThan createStsTypeParameters(javaMethodDeclaration.typeParameters()); - // STS: OpenParen formalParameterList? CloseParen + // STS: OpenParen parameterList? CloseParen createStsParameterList(javaMethodDeclaration.parameters()); // typeAnnotation @@ -1321,9 +1489,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // Java tree: // SingleVariableDeclaration: { ExtendedModifier } Type {Annotation} [ ... ] Identifier { Dimension } [ = Expression ] // STS tree for formal parameter: - // formalParameter: Identifier typeAnnotation + // parameter: Identifier typeAnnotation // or - // restFormalParameter: Ellipsis Identifier typeAnnotation + // variadicParameter: Ellipsis Identifier typeAnnotation @Override public boolean visit(SingleVariableDeclaration javaSingleVariableDeclaration) { if (javaSingleVariableDeclaration.isVarargs()) { @@ -1339,22 +1507,63 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaSingleVariableDeclaration.getName())); + // Parameter type pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); javaSingleVariableDeclaration.getType().accept(this); + + int extraDims = javaSingleVariableDeclaration.getExtraDimensions(); + if (extraDims > 0) NodeBuilder.addExtraDimensions(stsCurrent, extraDims); + popCurrent(); // TypeAnnotationContext - // TODO: { Dimention } + // TODO: { Dimension } //javaSingleVariableDeclaration. // TODO: [= Expression ] // Expression javaExpression = javaSingleVariableDeclaration.getInitializer(); // if (javaExpression != null) { // } - popCurrent(); // RestFormalParameterContext | FormalParameterContext + popCurrent(); // ParameterContext | VariadicParameterContext + + ++countDeclTransformed; + 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 ] + // STS tree for formal parameter: + // parameter: + // Identifier typeAnnotation + @Override + public boolean visit(VariableDeclarationFragment javaVariableDeclarationFragment) { + // Here, VariableDeclarationFragment node represents lambda's parameter + // with omitted parameter type. + + pushCurrent(new ParameterContext(stsCurrent, 0)); + + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaVariableDeclarationFragment.getName())); + + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + IVariableBinding variableBinding = javaVariableDeclarationFragment.resolveBinding(); + translateType(variableBinding.getType()); + popCurrent(); // TypeAnnotationContext + + // Note: no need to process the "{ Dimension }" part, as the extra dimensions + // of the declaration are covered by "translateType(ITypeBinding)" call. + + popCurrent(); // ParameterContext + ++countDeclTransformed; return false; } + // NOTE: All Java enums are translated into STS classes because of + // built-in methods values() and valueOf() available to the former! + // // Java tree: // EnumDeclaration: // [ Javadoc ] { ExtendedModifier } enum Identifier @@ -1365,56 +1574,391 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // } // // STS tree: - // TopLevelElementContext | ClassMemberContext | InterfaceMemberContext - // TerminalNode ? (for TopLevelElementContext) + // TopDeclarationContext | ClassMemberContext | InterfaceMemberContext + // TerminalNode ? (for TopDeclarationContext) // | AccessibilityModifierContext? (for ClassMemberContext or InterfaceMemberContext) - // EnumDeclarationContext - // Enum Identifier OpenBrace enumBody CloseBrace + // ClassDeclarationContext + // TerminalNode + // Identifier + // ClassExtendsClauseContext + // TerminalNode + // TypeReferenceContext + // QualifiedNameContext + // TerminalNode + // ImplementsClauseContext + // TerminalNode + // InterfaceTypeListContext + // TypeReferenceContext + // QualifiedNameContext + // TerminalNode + // TerminalNode <,> + // TypeReferenceContext + // QualifiedNameContext + // TerminalNode + // ClassBodyContext @Override public boolean visit(EnumDeclaration javaEnumDeclaration) { // Create appropriate member context to put declaration into. - pushCurrent(createMemberContextWithAccessModifier(javaEnumDeclaration.getModifiers())); - pushCurrent(new EnumDeclarationContext(stsCurrent, 0)); + int javaEnumMods = javaEnumDeclaration.getModifiers(); + pushCurrent(createMemberContextWithAccessModifier(javaEnumMods)); + + // Create class declaration context + ClassDeclarationContext stsClassDecl = new ClassDeclarationContext(stsCurrent, 0); + pushCurrent(stsClassDecl); + + // Set static modifier as necessary. + if (stsCurrent.getParent().getRuleIndex() != StaticTSParser.RULE_topDeclaration) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + } + + // Add class keyword and enum name + SimpleName javaEnumName = javaEnumDeclaration.getName(); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Class)); + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumName)); - // Add remaining (non-access) modifiers and enum keyword. - translateNonAccessModifiers(javaEnumDeclaration); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Enum)); + // Add extends clause. + createEnumExtendsClause(javaEnumName.getIdentifier()); - // Enum name - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumDeclaration.getName())); + // Add implements clause, if necessary + translateSuperInterfaceTypes(javaEnumDeclaration.superInterfaceTypes()); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBrace)); + pushCurrent(new ClassBodyContext(stsCurrent, 0)); - pushCurrent(new EnumBodyContext(stsCurrent, 0)); + // Translate enum constants. + // If any of the constants contain anonymous class body (e.g., extend enum type), + // add open modifier to the resulting class. + boolean needOpen = false; + int javaEnumConstOrdinal = 0; + List javaEnumConstNames = new ArrayList<>(); + List javaEnumConstants = javaEnumDeclaration.enumConstants(); + for (EnumConstantDeclaration javaEnumConst : javaEnumConstants) { + if (!needOpen) needOpen = javaEnumConst.getAnonymousClassDeclaration() != null; + + // Pass enum name and ordinal to enum constant node before visiting it + // as we'll need it to create appropriate initializers. + javaEnumConst.setProperty(ENUM_TYPE_NAME, javaEnumName.getIdentifier()); + javaEnumConst.setProperty(ENUM_CONST_ORDINAL, String.valueOf(javaEnumConstOrdinal)); + + // Store enum constant name in a list - we'll need it later to generate + // built-in values() method + javaEnumConstNames.add(javaEnumConst.getName().getIdentifier()); - // It looks for the transpiler there is no need to insert in the tree Comma terminal nodes. - // The writer adds them to the output without looking for them in the input tree. - List constants = javaEnumDeclaration.enumConstants(); - for(EnumConstantDeclaration javaEnumConst : constants) { javaEnumConst.accept(this); + ++javaEnumConstOrdinal; + } + if (needOpen) { + stsClassDecl.children.add(0, NodeBuilder.terminalNode(StaticTSParser.Open)); } - popCurrent(); // EnumBodyContext + // Translate body declarations (ctors, methods, nested types, and fields). + boolean hasCtors = false; + List javaEnumBodyDecls = javaEnumDeclaration.bodyDeclarations(); + for (BodyDeclaration javaEnumBodyDecl : javaEnumBodyDecls) { + javaEnumBodyDecl.accept(this); + if (!hasCtors) { + if (javaEnumBodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION) { + MethodDeclaration javaEnumMethodDecl = (MethodDeclaration) javaEnumBodyDecl; + hasCtors = javaEnumMethodDecl.isConstructor(); + } + } + } - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBrace)); + // Add values and valueOf built-in methods + String javaEnumTypeName = javaEnumDeclaration.getName().getIdentifier(); + createEnumValuesMethod(javaEnumTypeName, javaEnumConstNames); + createEnumValueOfMethod(javaEnumTypeName); - popCurrent(); // EnumDeclarationContext - popCurrent(); // stsMemberContext + // Add name and ordinal parameters to all ctors. + if (!hasCtors) { + // If no ctors present, generate default one with just the two parameters above, + // and a single super(name, ordinal) call in the body. + createEnumDefaultCtor(); + } + else { + // For all non-default ctors - if there is no call to another ctor in the body, + // generate super(name, ordinal) call, otherwise pass name and ordinal to existing ctor call. + ClassBodyContext stsEnumClassBody = (ClassBodyContext)stsCurrent; + for (ClassMemberContext stsEnumClassMember : stsEnumClassBody.classMember()) { + ConstructorDeclarationContext stsEnumCtor = stsEnumClassMember.constructorDeclaration(); + if (stsEnumCtor != null) { + modifyEnumCtor(stsEnumCtor); + } + } + } + + // Process instance initializers, if any. + // NOTE: This has to happen here, after default ctor is generated if necessary, + // (see above), as default ctor of enum class is different from the one that + // addInstanceInitializersToCtors can create. + addInstanceInitializersToCtors(javaEnumDeclaration); + popCurrent(); // ClassBodyContext + popCurrent(); // stsClassDecl + popCurrent(); // member context + + ++countDeclTransformed; return false; } + private void createEnumDefaultCtor() { + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PRIVATE)).setParent(stsCurrent); + pushCurrent(new ConstructorDeclarationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Constructor)); + pushCurrent(new ParameterListContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.parameter("name", "String")).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.parameter("ordinal", PrimitiveType.INT)).setParent(stsCurrent); + popCurrent(); // ParameterListContext + pushCurrent(new ConstructorBodyContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.ctorCall(true, "name", "ordinal")).setParent(stsCurrent); + popCurrent(); // ConstructorBodyContext + popCurrent(); // ConstructorDeclarationContext + popCurrent(); // ClassMemberContext + } + + private void modifyEnumCtor(ConstructorDeclarationContext stsEnumCtor) { + // Get parameter list or create if there isn't one + ParameterListContext stsEnumCtorParams = stsEnumCtor.parameterList(); + if (stsEnumCtorParams == null) { + stsEnumCtorParams = new ParameterListContext(stsEnumCtor, 0); + stsEnumCtor.addChild(stsEnumCtorParams).setParent(stsEnumCtor); + } + + // Inject name and ordinal parameters + ParameterContext stsEnumCtorParam = NodeBuilder.parameter("name", "String"); + stsEnumCtorParams.children.add(0, stsEnumCtorParam); + stsEnumCtorParam.setParent(stsEnumCtorParams); + stsEnumCtorParam = NodeBuilder.parameter("ordinal", PrimitiveType.INT); + stsEnumCtorParams.children.add(1, stsEnumCtorParam); + stsEnumCtorParam.setParent(stsEnumCtorParams); + + ConstructorBodyContext stsEnumCtorBody = stsEnumCtor.constructorBody(); + ConstructorCallContext stsEnumCtorCall = stsEnumCtorBody.getRuleContext(ConstructorCallContext.class, 0); + if (stsEnumCtorCall == null) { + // Create super(name, ordinal) call + stsEnumCtorBody.addChild(NodeBuilder.ctorCall(true, "name", "ordinal")).setParent(stsEnumCtorBody); + } + else { + // Pass name and ordinal parameters to ctor call + ArgumentsContext stsEnumCtorCallArgs = stsEnumCtorCall.arguments(); + ExpressionSequenceContext stsExprSeq = stsEnumCtorCallArgs.expressionSequence(); + if (stsExprSeq == null) { + // Create expression sequence node, if necessary + stsExprSeq = new ExpressionSequenceContext(stsEnumCtorCallArgs, 0); + stsEnumCtorCallArgs.addChild(stsExprSeq).setParent(stsEnumCtorCallArgs); + } + + SingleExpressionContext stsEnumCtorCallArg = NodeBuilder.identifierExpression("name"); + stsExprSeq.children.add(0, stsEnumCtorCallArg); + stsEnumCtorCallArg.setParent(stsExprSeq); + stsEnumCtorCallArg = NodeBuilder.identifierExpression("ordinal"); + stsExprSeq.children.add(1, stsEnumCtorCallArg); + stsEnumCtorCallArg.setParent(stsExprSeq); + } + } + + private void createEnumExtendsClause(String javaEnumName) { + // Note: A Java enum extends Enum class. + pushCurrent(new ClassExtendsClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Extends)); + pushCurrent(NodeBuilder.typeReference("Enum")); + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount()-1); + pushCurrent((TypeReferencePartContext)lastChild, false); + pushCurrent(new TypeArgumentsContext(stsCurrent, 0)); + pushCurrent(new TypeArgumentListContext(stsCurrent, 0)); + pushCurrent(new TypeArgumentContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumName)).setParent(stsCurrent); + popCurrent(); // TypeArgumentContext + popCurrent(); // TypeArgumentListContext + popCurrent(); // TypeArgumentsContext + popCurrent(); // (TypeReferencePartContext)lastChild + popCurrent(); // TypeReferenceContext + popCurrent(); // ClassExtendsClauseContext + } + + private void pushEnumBuiltinMethod() { + // Create class member context and add public modifier + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PUBLIC)); + + // Create class method declaration context and add static modifier + pushCurrent(new ClassMethodDeclarationContext(stsCurrent, 0)); + pushCurrent(new ClassMethodWithBodyContext((ClassMethodDeclarationContext)stsCurrent)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + } + + private void popEnumBuiltinMethod() { + popCurrent(); // ClassMethodWithBodyContext + popCurrent(); // ClassMethodDeclarationContext + popCurrent(); // ClassMemberContext + } + + // Generates the following method + // public static values() : [] { + // return [ , , ... ]; + // } + private void createEnumValuesMethod(String javaEnumTypeName, List javaEnumConstNames) { + pushEnumBuiltinMethod(); + + // Add method name and signature + stsCurrent.addChild(NodeBuilder.terminalIdentifier("values")); + pushCurrent(new SignatureContext(stsCurrent, 0)); + ArrayTypeContext stsReturnType = NodeBuilder.arrayType(javaEnumTypeName, 1); + stsCurrent.addChild(NodeBuilder.typeAnnotation(stsReturnType)).setParent(stsCurrent); + popCurrent(); // SignatureContext + + // Add method body + // return [ enum_constant1, enum_constant2, ... ]; + pushCurrent(new BlockContext(stsCurrent, 0)); + pushStatement(new ReturnStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Return)); + pushCurrent(new ArrayLiteralExpressionContext(pushSingleExpression())); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + for (String javaEnumConstName : javaEnumConstNames) { + stsCurrent.addChild(NodeBuilder.identifierExpression(javaEnumConstName)).setParent(stsCurrent); + } + popCurrent(); // ExpressionSequenceContext + popSingleExpression(); // ArrayLiteralExpressionContext + popStatement(); // ReturnStatementContext + popCurrent(); // BlockContext + + popEnumBuiltinMethod(); + } + + // Generates the following method: + // public static valueOf(String name) : { + // for (let value : of values()) { + // if (name == value.toString()) return value; + // } + // return null; + // } + private void createEnumValueOfMethod(String javaEnumTypeName) { + pushEnumBuiltinMethod(); + + // Add method name and signature + stsCurrent.addChild(NodeBuilder.terminalIdentifier("valueOf")); + pushCurrent(new SignatureContext(stsCurrent, 0)); + pushCurrent(new ParameterListContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.parameter("name", "String")).setParent(stsCurrent); + popCurrent(); // ParameterListContext + stsCurrent.addChild(NodeBuilder.typeAnnotation(javaEnumTypeName)).setParent(stsCurrent); + popCurrent(); // SignatureContext + + // Add method body + // for (let value : of values()) { + pushCurrent(new BlockContext(stsCurrent, 0)); + pushCurrent(new ForOfStatementContext(pushIterationStatement())); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.For)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Let)); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("value")); + stsCurrent.addChild(NodeBuilder.typeAnnotation(javaEnumTypeName)).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Of)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.identifierExpression("values")).setParent(stsCurrent); + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + popCurrent(); // ArgumentsContext + popSingleExpression(); // CallExpressionContext + pushStatement(new BlockContext(stsCurrent, 0)); + + // if (name == value.toString()) return value; + IfStatementContext stsIfStmt = new IfStatementContext(stsCurrent, 0); + pushStatement(stsIfStmt); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.If)); + pushCurrent(new EqualityExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.identifierExpression("name")).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Equals)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.identifierExpression("value")).setParent(stsCurrent); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("toString")); + popSingleExpression(); // MemberAccessExpressionContext + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + popCurrent(); // ArgumentsContext + popSingleExpression(); // CallExpressionContext + popSingleExpression(); // EqualityExpressionContext + pushStatement(new ReturnStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Return)); + stsCurrent.addChild(NodeBuilder.identifierExpression("value")).setParent(stsCurrent); + popStatement(); // ReturnStatementContext + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + assert(lastChild instanceof StatementContext); + stsIfStmt.ifStmt = (StatementContext)lastChild; + popStatement(); // IfStatementContext + + // close off for-of statement + popStatement(); // BlockContext + popIterationStatement(); // ForOfStatementContext + + // return null; + pushStatement(new ReturnStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Return)); + stsCurrent.addChild(NodeBuilder.nullLiteral()).setParent(stsCurrent); + popStatement(); // ReturnStatementContext + + // close off method body + popCurrent(); // BlockContext + + popEnumBuiltinMethod(); + } + @Override public boolean visit(EnumConstantDeclaration javaEnumConstant) { - pushCurrent(new EnumMemberContext(stsCurrent, 0)); + // Create class member context and add public modifier + pushCurrent(new ClassMemberContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.accessibilityModifier(Modifier.PUBLIC)); + + // Create class field declaration context and add static and const modifiers + pushCurrent(new ClassFieldDeclarationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Static)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Const)); + + // Create constant declaration context and add enum constant name and type + pushCurrent(new ConstantDeclarationContext(stsCurrent, 0)); + String javaEnumConstName = javaEnumConstant.getName().getIdentifier(); + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumConstName)); + String javaEnumTypeName = (String)javaEnumConstant.getProperty(ENUM_TYPE_NAME); + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotation + + // Add initializer to constant declaration context + pushCurrent(new InitializerContext(stsCurrent, 0)); + pushCurrent(new NewClassExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.New)); + stsCurrent.addChild(NodeBuilder.typeReference(javaEnumTypeName)).setParent(stsCurrent); + + // Process ctor arguments, if any. + // NOTE: Always insert name and ordinal as first two ctor arguments! + List javaEnumConstArgs = javaEnumConstant.arguments(); + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.stringLiteral(javaEnumConstName)).setParent(stsCurrent); + String javaEnumConstOrdinal = (String)javaEnumConstant.getProperty(ENUM_CONST_ORDINAL); + stsCurrent.addChild(NodeBuilder.numericLiteral(javaEnumConstOrdinal)).setParent(stsCurrent); + if (javaEnumConstArgs != null && !javaEnumConstArgs.isEmpty()) { + for (Expression javaEnumConstArg : javaEnumConstArgs) { + javaEnumConstArg.accept(this); + } + } + popCurrent(); // ExpressionSequenceContext + popCurrent(); // ArgumentsContext - // Enum constant name - stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaEnumConstant.getName())); + // Process anonymous class body, if any + AnonymousClassDeclaration javaEnumConstClassBody = javaEnumConstant.getAnonymousClassDeclaration(); + if (javaEnumConstClassBody != null) { + javaEnumConstClassBody.accept(this); + } - // TODO: Initializer + popSingleExpression(); // NewClassExpressionContext + popCurrent(); // InitializerContext - popCurrent(); // EnumMemberContext + popCurrent(); // ConstantDeclarationContext + popCurrent(); // ClassFieldDeclarationContext + popCurrent(); // ClassMemberContext + ++countDeclTransformed; return false; } @@ -1490,6 +2034,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } private void createAndFillVarOrConstDeclarationList(int javaModifiers, List javaVarDeclFragments, Type javaType) { + createAndFillVarOrConstDeclarationList(javaModifiers, javaVarDeclFragments, javaType, true); + } + + private void createAndFillVarOrConstDeclarationList(int javaModifiers, List javaVarDeclFragments, Type javaType, boolean translateVarInitializers) { pushCurrent(createVarOrConstDeclarationList(javaModifiers)); for (VariableDeclarationFragment javaVarDeclFragment : javaVarDeclFragments) { @@ -1502,16 +2050,19 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaType.accept(this); popCurrent(); // TypeAnnotationContext - Expression javaInitializer = javaVarDeclFragment.getInitializer(); + if (translateVarInitializers) { + Expression javaInitializer = javaVarDeclFragment.getInitializer(); - if (javaInitializer != null) { - pushCurrent(new InitializerContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitializer.accept(this); - popCurrent(); // InitializerContext + if (javaInitializer != null) { + pushCurrent(new InitializerContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitializer.accept(this); + popCurrent(); // InitializerContext + } } popCurrent(); // VarOrConstDeclaration + ++countDeclTransformed; // Each VariableDeclarationFragment is a separate declaration construct! } popCurrent(); // VarOrConstDeclarationList @@ -1522,7 +2073,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // | VariableDeclarationStatement // VariableDeclarationStatement: { ExtendedModifier } Type VariableDeclarationFragment { , VariableDeclarationFragment } ; // STS tree: - // topLevelElement: Export? + // topDeclaration: Export? // | variableStatement // variableStatement: ((Let variableDeclarationList) | (Const constantDeclarationList)) SemiColon // variableDeclarationList: @@ -1593,6 +2144,44 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + @Override + public boolean visit(WhileStatement javaWhileStmt) { + pushCurrent(new WhileStatementContext(pushIterationStatement())); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.While)); + Expression javaExpr = javaWhileStmt.getExpression(); + assert(javaExpr != null); + javaExpr.accept(this); + + Statement javaLoopBody = javaWhileStmt.getBody(); + assert(javaLoopBody != null); + javaLoopBody.accept(this); + + popIterationStatement(); // WhileStatementContext + return false; + } + + + @Override + public boolean visit(DoStatement javaDoStmt) { + pushCurrent(new DoStatementContext(pushIterationStatement())); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Do)); + + Statement javaLoopBody = javaDoStmt.getBody(); + assert(javaLoopBody != null); + javaLoopBody.accept(this); + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.While)); + + Expression javaExpr = javaDoStmt.getExpression(); + assert(javaExpr != null); + javaExpr.accept(this); + + popIterationStatement(); // DoStatementContext + return false; + } + + // Java tree: // Initializer: // [ static ] Block @@ -1645,13 +2234,12 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // StaticTS doesn't have syntax for separate instance initializer blocks. // We gather all statements from such blocks in class declaration and place // at the beginning of all constructor's bodies that don't call another constructor. - - TypeDeclaration javaTypeDecl = (TypeDeclaration) javaInitializer.getParent(); - List stsInitStmts = (List) javaTypeDecl.getProperty(INSTANCE_INITIALIZER); + ASTNode javaInitParent = javaInitializer.getParent(); + List stsInitStmts = (List) javaInitParent.getProperty(INSTANCE_INITIALIZER); if (stsInitStmts == null) { stsInitStmts = new ArrayList<>(); - javaTypeDecl.setProperty(INSTANCE_INITIALIZER, stsInitStmts); + javaInitParent.setProperty(INSTANCE_INITIALIZER, stsInitStmts); } // Use dummy block here to gather translated statements. Do not @@ -1669,6 +2257,33 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsInitStmts.addAll(stsBlock.statementOrLocalDeclaration()); } + ++countDeclTransformed; + return false; + } + + // Java AST: + // TypeName {[ ]} . class + // NumericType {[ ]} . class + // boolean {[ ]} . class + // void . class + // STS AST: + // SingleExpressionContext + // ClassLiteralExpressionContext + // PrimaryTypeContext . class + @Override + public boolean visit(TypeLiteral node) { + pushCurrent(new ClassLiteralExpressionContext(pushSingleExpression())); + + // Translate type + node.getType().accept(this); + + // Add . and class tokens + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Dot)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Class)); + + popSingleExpression(); // ClassLiteralExpressionContext + + ++countExprTransformed; return false; } @@ -1678,6 +2293,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // STS tree: // expressionStatement: // singleExpression SemiColon? + @Override public boolean visit(ExpressionStatement javaExprStmt) { pushStatement(new ExpressionStatementContext(null, 0)); javaExprStmt.getExpression().accept(this); @@ -1903,10 +2519,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaArrayInitializer.accept(this); } -// popSingleExpression(); // NewArrayExpression - - // TODO: Needs reworking. - // ++countExprTransformed. return false; } @@ -1960,7 +2572,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { @Override public boolean visit(AnonymousClassDeclaration javaAnonymousClassDeclaration) { pushCurrent(new ClassBodyContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBrace)).setParent(stsCurrent); List javaBodyDeclarations = javaAnonymousClassDeclaration.bodyDeclarations(); assert (javaBodyDeclarations != null); @@ -1968,8 +2579,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaBodyDeclaration.accept(this); } - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBrace)).setParent(stsCurrent); popCurrent(); // ClassBodyContext + + ++countDeclTransformed; return false; } @@ -2006,7 +2618,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: // ForStatement: // for ( @@ -2182,48 +2793,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } // Java tree: - // Annotation: - // NormalAnnotation - // MarkerAnnotation - // SingleMemberAnnotation - // SingleMemberAnnotation: - // @ TypeName ( Expression ) - // STS tree: - // TODO: - @Override - public boolean visit(NormalAnnotation javaAnnotation) { - // TODO: - return super.visit(javaAnnotation); - } - - @Override - public boolean visit(MarkerAnnotation javaAnnotation) { - // TODO: - return super.visit(javaAnnotation); - } - - @Override - public boolean visit(SingleMemberAnnotation javaAnnotation) { - // TODO: - return super.visit(javaAnnotation); - } - - // Java tree: - // CreationReference: - // Type :: - // [ < Type { , Type } > ] - // new - // STS tree: - // TODO: - @Override - public boolean visit(CreationReference javaCreationRef) { - // TODO: - return super.visit(javaCreationRef); - } - - // Java tree: - // FieldAccess: - // Expression . Identifier + // FieldAccess: + // Expression . Identifier // STS tree: // singleExpression: // | singleExpression Dot Identifier # MemberAccessExpression @@ -2290,20 +2861,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: - // LambdaExpression: - // Identifier -> Body - // ( [ Identifier { , Identifier } ] ) -> Body - // ( [ FormalParameter { , FormalParameter } ] ) -> Body - // STS tree: - // singleExpression: - // : OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression - @Override - public boolean visit(LambdaExpression javaLambdaExpr) { - // TODO: - return false; - } - // Java tree: // MethodInvocation: // [ Expression . ] @@ -2380,23 +2937,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - // Java tree: - // SuperMethodReference: - // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier - // STS tree: - // TODO: lambda ? - @Override - public boolean visit(SuperMethodReference javaSuperMethodReference) { - // TODO: implement - return false; - } - // Java tree: // ThisExpression: // [ ClassName . ] this // STS tree: - // singleExpression: - // | (typeReference Dot)? This # ThisExpression @Override public boolean visit(ThisExpression javaThisExpr) { pushCurrent(new ThisExpressionContext(pushSingleExpression())); @@ -2413,18 +2957,593 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // Java tree: + // TypeDeclarationStatement: + // TypeDeclaration + // EnumDeclaration + // STS tree: + // statementOrLocalDeclaration: + // | classDeclaration + // | enumDeclaration + @Override + public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { + javaTypeDeclarationStmt.getDeclaration().accept(this); + + ++countStmtTransformed; + return false; + } + + // Java tree: + // switch ( Expression ) + // { { SwitchCase | Statement } } + // SwitchCase: + // case Expression : + // default : + // STS tree: + // switchStatement: + // switch OpenParen singleExpression CloseParen caseBlock + // caseBlock: + // OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace + // caseClauses: + // caseClause+ + // caseClause: + // case singleExpression ':' statement* + // defaultClause: + // default ':' statement* + @Override + public boolean visit(SwitchStatement javaSwitchStmt) { + SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); + pushStatement(stsSwitch); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); + + javaSwitchStmt.getExpression().accept(this); + + CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); + stsCaseBlock.leftCases = null; + stsCaseBlock.rightCases = null; + pushCurrent(stsCaseBlock); + + List javaVariablesToMove = new ArrayList<>(); + SwitchCase javaCurrentSwitchCase = null; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { + javaCurrentSwitchCase = (SwitchCase) javaStmt; + } + else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { + wrapCaseClauseStatementsWithBlock(); + } + else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { + processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, + javaSwitchStmt, javaVariablesToMove); + + // We've already processed variable declaration, proceed to the next statement. + continue; + } + + javaStmt.accept(this); + } + + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + // Create CaseClausesContext node and transfer all cases translated thus far to it. + // If we've seen default node, initialize rightCases field of CaseBlockContext node; + // otherwise, initialize leftCases field of CaseBlockContext node. + CaseClausesContext stsCaseClauses = createAndFillCaseClausesContext(stsCaseBlock); + if (stsCaseBlock.defaultClause() != null) { + stsCaseBlock.rightCases = stsCaseClauses; + } + else { + stsCaseBlock.leftCases = stsCaseClauses; + } + + popCurrent(); // CaseBlockContext + popStatement(); // SwitchStatementContext + + // Move variable declarations in front of switch statement, and enclose both + // declarations and switch with additional block. + if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { + // Remove switch statement from current STS node. + stsCurrent.removeLastChild(); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + + for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { + VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); + + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + + ArrayList declFragmentList = new ArrayList<>(); + declFragmentList.add(javaVarFragment); + + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), declFragmentList, javaVarDeclStmt.getType(), false); + popStatement(); // VariableOrConstantDeclarationContext + } + + pushStatement(stsSwitch); + popStatement(); // SwitchContext + + popStatement(); // BlockContext + } + + ++countStmtTransformed; + return false; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + assert(stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseBlock); + CaseBlockContext stsCaseBlock = (CaseBlockContext)stsCurrent; + + if (javaSwitchCase.isDefault()) { + // If any cases have been translated thus far, create CaseClauseContext node, + // transfer those cases to it, and initialize leftCases field of CaseBlockContext node. + stsCaseBlock.leftCases = createAndFillCaseClausesContext(stsCaseBlock); + + // Translate default clause + pushCurrent(new DefaultClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); + } + else { + pushCurrent(new CaseClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); + javaSwitchCase.getExpression().accept(this); + } + + // SwitchCase is treated as Statement node, thus increment the count. + ++countStmtTransformed; + return false; + } + + private CaseClausesContext createAndFillCaseClausesContext(CaseBlockContext stsCaseBlock) { + List stsCaseList = stsCaseBlock.getRuleContexts(CaseClauseContext.class); + CaseClausesContext stsCaseClauses = null; + + if (!stsCaseList.isEmpty()) { + stsCaseClauses = new CaseClausesContext(stsCurrent, 0); + for (CaseClauseContext stsCase : stsCaseList) { + stsCaseClauses.addChild(stsCase).setParent(stsCaseClauses); + } + stsCaseBlock.children.removeAll(stsCaseList); + + // Add CaseClauseContext node to CaseBlockContext + stsCaseBlock.addChild(stsCaseClauses).setParent(stsCaseBlock); + } + + return stsCaseClauses; + } + private void popCaseClauseIfNeeded() { + // Check if we need to pop additional block added as work around to add + // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() + // method for details). + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) { + popStatement(); // BlockContext + } + + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause + || stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause) { + popCurrent(); // CaseClauseContext | DefaultClauseContext + } + } + + private void wrapCaseClauseStatementsWithBlock() { + // In StaticTS, CaseClause may contain only statements, and is not allowed to + // have local declarations. In contrast, Java permits to have local declarations + // in case clause scope, so when encounter one, wrap up all statements in case clause + // with additional block as a workaround, (since block can have local declarations). + + // Check if already inserted additional block. + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) + return; + + assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || + stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; + + List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); + stsCurrent.children.removeAll(stsCaseStmts); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + for (StatementContext stsStmt : stsCaseStmts) { + StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); + stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); + stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); + } + } + + + private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, + SwitchStatement javaSwitchStmt, List javaVariablesToMove) { + // Java permits to declare local variables in switch scope. Such variables exist + // in all following case clauses. In StaticTS, case clauses don't have a common + // scope, and allow only statements, not declarations. To work around this, we + // have to track whether a particular local variable has been referenced in another + // case clause and, in such case, move declaration of that variable in front of + // switch statement, additionally enclosing both variable declaration and switch + // statement, so that variables are only visible in context of switch statement. + + List javaVarFragments = javaVarDeclStmt.fragments(); + + for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { + if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { + javaVariablesToMove.add(javaVarFragment); + + // Since evaluation of initializer expression can cause side effects, + // in order to preserve the behaviour and result of program, all + // expressions must evaluate in the same order as before. For that + // purpose, we move the variable declaration without initializer part + // and replace initialization with simple assignment. + Expression javaInitExpr = javaVarFragment.getInitializer(); + if (javaInitExpr != null) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); + + javaVarFragment.getName().accept(this); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitExpr.accept(this); + + popSingleExpression(); // AssignmentExpressionContext; + popStatement(); // ExpressionStatementContext + } + } else { + wrapCaseClauseStatementsWithBlock(); + + // For variables, that don't need to be moved, emit single variable + // declaration here to preserve the correct order of evaluation of + // initializer expressions (including assignments emitted for variables + // that are moved). + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + + ArrayList declFragmentList = new ArrayList<>(); + declFragmentList.add(javaVarFragment); + + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), declFragmentList, javaVarDeclStmt.getType()); + popStatement(); // VariableOrConstantDeclarationContext + } + } + + ++countStmtTransformed; + } + + private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, + SwitchStatement javaSwitchStmt) { + IVariableBinding javaVarBinding = javaVarDecl.resolveBinding(); + + ASTVisitor localVarUsageLookupVisitor = new ASTVisitor() { + boolean done = false; + int nestedSwitchCount = 0; + SwitchCase currentSwitchCase = null; + + @Override + public boolean preVisit2(ASTNode javaNode) { + // This line will prevent from visiting further AST nodes, + // once we are done with the work. + return !done; + } + + @Override + public boolean visit(SimpleName javaName) { + IBinding binding = javaName.resolveBinding(); + + if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { + javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); + done = true; + } + + return false; + } + + @Override + public boolean visit(VariableDeclarationFragment javaVarDeclFragment) { + // Do NOT visit declaration of the variable that we are looking up. + return javaVarDeclFragment != javaVarDecl; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Do not change currentSwitchCase when visiting nested switch statements. + if (nestedSwitchCount == 0) { + currentSwitchCase = javaSwitchCase; + } + + return false; + } + + @Override + public boolean visit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount++; + return true; + } + + @Override + public void endVisit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount--; + } + }; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + javaStmt.accept(localVarUsageLookupVisitor); + + if (javaVarDecl.getProperty(USED_IN_ANOTHER_CASE_CLAUSE) != null) + return true; + } + + return false; + } + + // AST nodes yet to be translated + // + + // Java tree: + // LambdaExpression: + // Identifier -> Body + // ( [ Identifier { , Identifier } ] ) -> Body + // ( [ FormalParameter { , FormalParameter } ] ) -> Body + // Body: + // Expression + // Block + // STS tree: + // singleExpression: + // OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // lambdaBody + // : singleExpression + // | block + @Override + public boolean visit(LambdaExpression javaLambdaExpr) { + pushCurrent(new LambdaExpressionContext(pushSingleExpression())); + + createStsParameterList(javaLambdaExpr.parameters()); + + IMethodBinding lambdaMethod = javaLambdaExpr.resolveMethodBinding(); + + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + translateType(lambdaMethod.getReturnType()); + popCurrent(); // TypeAnnotationContext + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); + + pushCurrent(new LambdaBodyContext(stsCurrent, 0)); + ASTNode javaBody = javaLambdaExpr.getBody(); + + if (javaBody instanceof Expression) { + javaBody.accept(this); + } else { + // Better this than calling javaBody.accept(this) here + // as visit(Block) will call pushStatement() which will + // add StatementContext node which isn't needed here. + pushCurrent(new BlockContext(stsCurrent, 0)); + + Block javaBlock = (Block) javaBody; + List javaBlockStmts = javaBlock.statements(); + for (Statement javaStmt : javaBlockStmts) { + javaStmt.accept(this); + } + + popCurrent(); // BlockContext + } + + popCurrent(); // LambdaBodyContext + popSingleExpression(); // LambdaExpressionContext + + ++countExprTransformed; + return false; + } + + // ExpressionMethodReference: Expression :: [ < Type { , Type } > ] Identifier + // STS tree: + // singleExpression: + // | OpenParen parameterList? CloseParen typeAnnotation Arrow lambdaBody # LambdaExpression + // lambdaBody: singleExpression | block; + @Override + public boolean visit(ExpressionMethodReference javaExpressionMethodReference) { + pushCurrent(new LambdaExpressionContext(pushSingleExpression())); + + javaExpressionMethodReference.getExpression().accept(this); + ParseTree lastChild = stsCurrent.getChild(stsCurrent.getChildCount() - 1); + stsCurrent.removeLastChild(); + assert(lastChild instanceof SingleExpressionContext); + SingleExpressionContext stsTypeExpr = (SingleExpressionContext)lastChild; + + // Form the list of parameters. It will contain one object of type defined by stsTypeExpr. + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenParen)); + // parameterList: parameter... + pushCurrent(new ParameterListContext(stsCurrent, 0)); + // parameter: Identifier typeAnnotation + pushCurrent(new ParameterContext(stsCurrent, 0)); + + // TODO: Check if the fixed object name used here may cause a names conflict. + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); // Identifier + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + + // Depending on type of stsTypeExpr create proper child for PrimaryTypeContext object. + assert (stsTypeExpr.getChildCount() == 1); + ParseTree stsNode = stsTypeExpr.getChild(0); + if (stsNode instanceof IdentifierExpressionContext) { + String typeName = ((IdentifierExpressionContext)stsNode).Identifier().getText(); + stsCurrent.addChild(NodeBuilder.typeReference(typeName)).setParent(stsCurrent); + } + else { + // TODO: May it ever happens? + assert false; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + popCurrent(); // ParameterContext + popCurrent(); // ParameterListContext + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseParen)); // End of parameters list. + + IMethodBinding javaMethodBinding = javaExpressionMethodReference.resolveMethodBinding(); + ITypeBinding javaReturnType = javaMethodBinding.getReturnType(); + + // typeAnnotation: Colon primaryType + pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Colon)); + // primaryType: predefinedType | typeReference | arrayType + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + if (javaReturnType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaReturnType.isClass() || javaReturnType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaReturnType.isEnum()) { + // TODO: + } else if (javaReturnType.isArray()) { + // TODO: + pushCurrent(new ArrayTypeContext(stsCurrent, 0)); + + ITypeBinding javaElementType = javaReturnType.getElementType(); + if (javaElementType.isPrimitive()) { + stsCurrent.addChild(NodeBuilder.predefinedType(javaReturnType)).setParent(stsCurrent); + } else if (javaElementType.isClass() || javaElementType.isInterface()) { + stsCurrent.addChild(NodeBuilder.typeReference(javaReturnType.getQualifiedName())).setParent(stsCurrent); + } + else if (javaElementType.isEnum()) { + // TODO: + } else { + // Is this ever can be in case of array type? + assert false; + } + + int numDims = javaReturnType.getDimensions(); + for (int i = 0; i < numDims; ++i) { + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.OpenBracket)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.CloseBracket)); + } + + popCurrent(); // ArrayTypeContext + } else { + assert false : "Need implementation of the translation"; + } + + popCurrent(); // PrimaryTypeContext + popCurrent(); // TypeAnnotationContext + + // TODO: translation of type arguments. +// List javaTypeArguments = javaExpressionMethodReference.typeArguments(); +// if (javaTypeArguments != null && !javaTypeArguments.isEmpty()) { +// translateTypeArgumens(javaTypeArguments); +// } + + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); + // lambdaBody: singleExpression | block + // Use here + // singleExpression: + // | singleExpression typeArguments? arguments # CallExpression + // to produce object_arg.method_name() + pushCurrent(new LambdaBodyContext(stsCurrent, 0)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + + // | singleExpression Dot identifier # MemberAccessExpression + pushCurrent(new MemberAccessExpressionContext(pushSingleExpression())); + // singleExpression + // | Identifier IdentifierExpression + pushCurrent(new IdentifierExpressionContext(pushSingleExpression())); + stsCurrent.addChild(NodeBuilder.terminalIdentifier("object_arg")); + popSingleExpression(); // IdentifierExpressionContext + + stsCurrent.addChild(NodeBuilder.terminalIdentifier(javaExpressionMethodReference.getName())); + popSingleExpression(); // MemberAccessExpressionContext + + //translateTypeArguments(javaMethodInvocation.typeArguments()); + //translateArguments(javaMethodInvocation.arguments()); + stsCurrent.addChild(new ArgumentsContext(stsCurrent, 0)); // Empty list of arguments. + + popSingleExpression(); // CallExpressionContext + popCurrent(); // LambdaBodyContext + popSingleExpression(); // LambdaExpressionContext + + ++countExprTransformed; + return false; + } + + // Java tree: + // CreationReference: + // Type :: + // [ < Type { , Type } > ] + // new + // STS tree: + // TODO: + @Override + public boolean visit(CreationReference javaCreationRef) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaCreationRef)).setParent(stsCurrent); + + return false; + } + + // Java tree: + // SuperMethodReference: + // [ ClassName . ] super :: [ < Type { , Type } > ] Identifier + // STS tree: + // TODO: lambda ? + @Override + public boolean visit(SuperMethodReference javaSuperMethodReference) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaSuperMethodReference)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(TypeMethodReference javaTypeMethodRef) { + // TODO: To be implemented + // Emit __untranslated_expression call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedExpression(javaTypeMethodRef)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(TryStatement javaTryStatement) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaTryStatement)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(ThrowStatement javaThrowStatement) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaThrowStatement)).setParent(stsCurrent); + + return false; + } + + @Override + public boolean visit(SynchronizedStatement javaSynchrStmt) { + // TODO: To be implemented + // Emit __untranslated_statement call with commented-out original syntax as argument for now. + // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. + stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaSynchrStmt)).setParent(stsCurrent); + return false; + } + // The list of not yet translated Java Expressions: - // Expression: - // Annotation, - //?? CaseDefaultExpression, // CreationReference, - //?? ExpressionMethodReference, - // InstanceofExpression, - // LambdaExpression, - //? MethodReference, - //? Pattern, // SuperMethodReference, - // SwitchExpression, - // TypeLiteral, // TypeMethodReference -} \ 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 65ca0b0afab8e7741f4ce6662fcc0f498fff7123..c02eb1037ab2fa88d80443036a70d93c9dbf877f 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -31,7 +31,6 @@ public class NodeBuilder { public static TerminalNode terminalNode(int type) { return new TerminalNodeImpl(new CommonToken(type, stsName(type))); } - public static String stsName(int type) { // Antlr store all literal names wrapped into single quotes. Like: "'&='", "'^='", "'|='", "'=>'", "'null'", null, // "'do'", "'instanceof'", "'typeof'", "'case'", @@ -49,10 +48,13 @@ public class NodeBuilder { return stsName; } - private static TerminalNode terminalIdentifier(String identifier) { + public static TerminalNode terminalIdentifier(String identifier) { return new TerminalNodeImpl(new CommonToken(StaticTSParser.Identifier, identifier)); } + public static TerminalNode multiLineComment(String comment) { + return new TerminalNodeImpl(new CommonToken(StaticTSParser.MultiLineComment, comment)); + } public static TerminalNode terminalIdentifier(SimpleName name) { return terminalIdentifier(name.getIdentifier()); } @@ -68,27 +70,26 @@ public class NodeBuilder { return qualifiedName(javaName.getFullyQualifiedName()); } - private static int stsTypeNameCode(PrimitiveType javaPrimitive) { + private static int stsTypeNameCode(PrimitiveType.Code javaPrimitiveTypeCode) { int stsTypeNameCode = -1; - PrimitiveType.Code javaTypeCode = javaPrimitive.getPrimitiveTypeCode(); - if (javaTypeCode == PrimitiveType.BOOLEAN) + if (javaPrimitiveTypeCode == PrimitiveType.BOOLEAN) stsTypeNameCode = StaticTSParser.Boolean; - else if (javaTypeCode == PrimitiveType.BYTE) + else if (javaPrimitiveTypeCode == PrimitiveType.BYTE) stsTypeNameCode = StaticTSParser.Byte; - else if (javaTypeCode == PrimitiveType.CHAR) + else if (javaPrimitiveTypeCode == PrimitiveType.CHAR) stsTypeNameCode = StaticTSParser.Char; - else if (javaTypeCode == PrimitiveType.INT) + else if (javaPrimitiveTypeCode == PrimitiveType.INT) stsTypeNameCode = StaticTSParser.Int; - else if (javaTypeCode == PrimitiveType.DOUBLE) + else if (javaPrimitiveTypeCode == PrimitiveType.DOUBLE) stsTypeNameCode = StaticTSParser.Double; - else if (javaTypeCode == PrimitiveType.FLOAT) + else if (javaPrimitiveTypeCode == PrimitiveType.FLOAT) stsTypeNameCode = StaticTSParser.Float; - else if (javaTypeCode == PrimitiveType.LONG) + else if (javaPrimitiveTypeCode == PrimitiveType.LONG) stsTypeNameCode = StaticTSParser.Long; - else if (javaTypeCode == PrimitiveType.SHORT) + else if (javaPrimitiveTypeCode == PrimitiveType.SHORT) stsTypeNameCode = StaticTSParser.Short; - else if (javaTypeCode == PrimitiveType.VOID) + else if (javaPrimitiveTypeCode == PrimitiveType.VOID) stsTypeNameCode = StaticTSParser.Void; else assert false : "Unknown type"; @@ -96,10 +97,39 @@ public class NodeBuilder { return stsTypeNameCode; } - public static PredefinedTypeContext predefinedType(PrimitiveType javaPrimitive) { + public static PredefinedTypeContext predefinedType(PrimitiveType.Code javaPrimitiveTypeCode) { + // predefinedType -> TerminalNode + PredefinedTypeContext stsPredefinedType = new PredefinedTypeContext(null, 0); + stsPredefinedType.addChild(terminalNode(stsTypeNameCode(javaPrimitiveTypeCode))); + 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(javaPrimitive))); + stsPredefinedType.addChild(terminalNode(stsTypeNameCode(javaTypeName))); return stsPredefinedType; } @@ -147,6 +177,10 @@ public class NodeBuilder { // singleExpression: | literal # LiteralExpression // literal: | CharLiteral public static SingleExpressionContext charLiteral(String value) { + // Add leading and/or terminating quotes if missing + if (!value.startsWith("'")) value = "'" + value; + if (!value.endsWith("'")) value += "'"; + SingleExpressionContext stsExpression = new SingleExpressionContext(null, 0); LiteralContext stsLiteral = new LiteralContext(null, 0); stsLiteral.addChild(new TerminalNodeImpl(new CommonToken(StaticTSParser.CharLiteral, value))); @@ -159,6 +193,11 @@ public class NodeBuilder { // singleExpression: | literal # LiteralExpression // literal: | StringLiteral public static SingleExpressionContext stringLiteral(String value) { + // Add leading and/or terminating quotes if missing + if (!value.startsWith("\"")) value = "\"" + value; + if (!value.endsWith("\"")) value += "\""; + + // TODO: Escape all unescaped characters SingleExpressionContext stsExpression = new SingleExpressionContext(null, 0); LiteralContext stsLiteral = new LiteralContext(null, 0); stsLiteral.addChild(new TerminalNodeImpl(new CommonToken(StaticTSParser.StringLiteral, value))); @@ -180,16 +219,32 @@ public class NodeBuilder { LiteralContext stsLiteral = new LiteralContext(null, 0); CommonToken token; + // parse string representation to create appropriate token - if (value.startsWith("0b")) { + // Ignore d and l suffices that Java allows for numeric literals + // NOTE: The f suffix that Java also allows will be dealt with + // later, as it might conflict with hexadecimal literals. + if (value.endsWith("d") || value.endsWith("D") || + value.endsWith("l") || value.endsWith("L")) { + value = value.substring(0, value.length() - 1); + } + + if (value.startsWith("0b") || value.startsWith("0B")) { token = new CommonToken(StaticTSParser.BinaryIntegerLiteral, value); - } else if (value.startsWith("0x")) { + } + else if (value.startsWith("0x") || value.startsWith("0X")) { token = new CommonToken(StaticTSParser.HexIntegerLiteral, value); - } else if( value.startsWith("0") && !value.contains("89")) { + } + else if (value.startsWith("0") && value.length() > 1 && + !value.contains("89") && !value.contains(".")) { + // STS octal literals start with 0o + value = "0o" + value.substring(1); token = new CommonToken(StaticTSParser.OctalIntegerLiteral, value); - } else { - // Java floats have suffix 'f' - if (value.endsWith("f")) value = value.substring(0,value.length()-1); + } + else { + if (value.endsWith("f") || value.endsWith("F")) { + value = value.substring(0, value.length() - 1); + } token = new CommonToken(StaticTSParser.DecimalLiteral, value); } @@ -219,8 +274,9 @@ public class NodeBuilder { } public static TypeReferenceContext typeReference(PrimitiveType javaPrimitivetype) { + PrimitiveType.Code javaPrimitiveTypeCode = javaPrimitivetype.getPrimitiveTypeCode(); TypeReferenceContext stsTypeReference = new TypeReferenceContext(null, 0); - stsTypeReference.addChild(qualifiedName(stsName(stsTypeNameCode(javaPrimitivetype)))).setParent(stsTypeReference); + stsTypeReference.addChild(qualifiedName(stsName(stsTypeNameCode(javaPrimitiveTypeCode)))).setParent(stsTypeReference); return stsTypeReference; } public static TypeReferenceContext typeReference(String stsQualifierText, Name javaName) { @@ -300,4 +356,118 @@ public class NodeBuilder { stsArrayType.addChild(terminalNode(StaticTSParser.CloseBracket)); } } + + public static ArrayTypeContext arrayType(String elementTypeName, int dimensions) { + ArrayTypeContext stsArrayType = new ArrayTypeContext(null, 0); + stsArrayType.addChild(typeReference(elementTypeName)).setParent(stsArrayType); + for (int i = 0; i < dimensions; ++i) { + stsArrayType.addChild(terminalNode(StaticTSParser.OpenBracket)); + stsArrayType.addChild(terminalNode(StaticTSParser.CloseBracket)); + } + return stsArrayType; + } + + public static TypeAnnotationContext typeAnnotation(TypeReferenceContext stsTypeRef) { + TypeAnnotationContext stsTypeAnno = new TypeAnnotationContext(null, 0); + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsTypeAnno, 0); + stsPrimaryType.addChild(stsTypeRef).setParent(stsPrimaryType); + stsTypeAnno.addChild(stsPrimaryType).setParent(stsTypeAnno); + return stsTypeAnno; + } + + public static TypeAnnotationContext typeAnnotation(String stsTypeName) { + TypeReferenceContext stsTypeRef = typeReference(stsTypeName); + return typeAnnotation(stsTypeRef); + } + + public static TypeAnnotationContext typeAnnotation(PredefinedTypeContext stsPredefType) { + TypeAnnotationContext stsTypeAnno = new TypeAnnotationContext(null, 0); + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsTypeAnno, 0); + stsPrimaryType.addChild(stsPredefType).setParent(stsPrimaryType); + stsTypeAnno.addChild(stsPrimaryType).setParent(stsTypeAnno); + return stsTypeAnno; + } + public static TypeAnnotationContext typeAnnotation(ArrayTypeContext stsArrayType) { + TypeAnnotationContext stsTypeAnno = new TypeAnnotationContext(null, 0); + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsTypeAnno, 0); + stsPrimaryType.addChild(stsArrayType).setParent(stsPrimaryType); + stsTypeAnno.addChild(stsPrimaryType).setParent(stsTypeAnno); + return stsTypeAnno; + } + + public static ParameterContext parameter(String stsParamName, String stsParamType) { + ParameterContext stsParam = new ParameterContext(null, 0); + stsParam.addChild(terminalIdentifier(stsParamName)); + stsParam.addChild(typeAnnotation(stsParamType)).setParent(stsParam); + return stsParam; + } + + public static ParameterContext parameter(String stsParamName, PrimitiveType.Code javaPrimitiveTypeCode) { + ParameterContext stsParam = new ParameterContext(null, 0); + stsParam.addChild(terminalIdentifier(stsParamName)); + stsParam.addChild(typeAnnotation(predefinedType(javaPrimitiveTypeCode))).setParent(stsParam); + return stsParam; + } + + public static ConstructorCallContext ctorCall(boolean isSuperCall, String... stsArgNames) { + ConstructorCallContext stsSuperCtorCall = new ConstructorCallContext(null, 0); + stsSuperCtorCall.addChild(terminalNode(isSuperCall ? StaticTSParser.Super : StaticTSParser.This)); + + ArgumentsContext stsSuperCtorCallArgs = new ArgumentsContext(stsSuperCtorCall, 0); + stsSuperCtorCall.addChild(stsSuperCtorCallArgs).setParent(stsSuperCtorCall); + ExpressionSequenceContext stsExprSeq = new ExpressionSequenceContext(stsSuperCtorCallArgs, 0); + stsSuperCtorCallArgs.addChild(stsExprSeq).setParent(stsSuperCtorCallArgs); + + for (String stsArgName : stsArgNames) { + stsExprSeq.addChild(identifierExpression(stsArgName)).setParent(stsExprSeq); + } + + return stsSuperCtorCall; + } + + public static SingleExpressionContext untranslatedExpression(ASTNode node) { + SingleExpressionContext stsExpression = new SingleExpressionContext(null, 0); + CallExpressionContext stsCallExpression = new CallExpressionContext(stsExpression); + stsExpression.addChild(stsCallExpression).setParent(stsExpression); + + SingleExpressionContext stsIdentifier = identifierExpression("__untranslated_expression"); + stsCallExpression.addChild(stsIdentifier).setParent(stsCallExpression); + + ArgumentsContext stsArguments = new ArgumentsContext(stsCallExpression, 0); + stsCallExpression.addChild(stsArguments).setParent(stsCallExpression); + + stsArguments.addChild(multiLineComment("/*" + node.toString() + "*/")); + + return stsExpression; + } + + public static StatementContext untranslatedStatement(ASTNode node) { + StatementContext stsStatement = new StatementContext(null, 0); + ExpressionStatementContext stsExprStatement = new ExpressionStatementContext(stsStatement, 0); + stsStatement.addChild(stsExprStatement).setParent(stsStatement); + + stsExprStatement.addChild(untranslatedExpression(node)).setParent(stsExprStatement); + + return stsStatement; + } + + public static ShiftOperatorContext shiftOperator(InfixExpression.Operator javaOp) { + ShiftOperatorContext stsShiftOp = new ShiftOperatorContext(null, 0); + + if (javaOp == InfixExpression.Operator.LEFT_SHIFT) { + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.LessThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.LessThan)); + } + else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_SIGNED) { + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + } + else if (javaOp == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED) { + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + stsShiftOp.addChild(NodeBuilder.terminalNode(StaticTSParser.MoreThan)); + } + + return stsShiftOp; + } } diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 index 705a2583cb3b3d35af3b52cb93c77c386bee6012..f0b60c9fa0fc60d812dcf85e25f98c6a43b16a2c 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 @@ -46,9 +46,6 @@ Not: '!'; Multiply: '*'; Divide: '/'; Modulus: '%'; -RightShiftArithmetic: '>>'; -LeftShiftArithmetic: '<<'; -RightShiftLogical: '>>>'; LessThan: '<'; MoreThan: '>'; LessThanEquals: '<='; @@ -86,16 +83,25 @@ BooleanLiteral: 'true' /// Numeric Literals -DecimalLiteral: DecimalIntegerLiteral '.' [0-9]* ExponentPart? - | '.' [0-9]+ ExponentPart? +DecimalLiteral: DecimalIntegerLiteral '.' FractionalPart? ExponentPart? + | '.' FractionalPart ExponentPart? | DecimalIntegerLiteral ExponentPart? ; /// Numeric Literals -HexIntegerLiteral: '0' [xX] HexDigit+; -OctalIntegerLiteral: '0' [oO] [0-7]+ {!this.IsStrictMode()}?; -BinaryIntegerLiteral: '0' [bB] [01]+; +HexIntegerLiteral: '0' [xX] ( + HexDigit + | HexDigit (HexDigit | '_')* HexDigit + ); +OctalIntegerLiteral: '0' [oO] ( + [0-7] + | [0-7] [0-7_]* [0-7] + ); +BinaryIntegerLiteral: '0' [bB] ( + [01] + | [01] [01_]* [01] + ); /// Keywords @@ -240,12 +246,17 @@ fragment HexDigit ; fragment DecimalIntegerLiteral - : '0' - | [1-9] [0-9]* + : [0-9] + | [1-9] [0-9_]* [0-9] + ; + +fragment FractionalPart + : [0-9] + | [0-9] [0-9_]* [0-9] ; fragment ExponentPart - : [eE] [+-]? [0-9]+ + : [eE] [+-]? DecimalIntegerLiteral ; fragment IdentifierPart diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index 30cfd3fdcaa7c9cfb83ad8ea948dea5117716901..de2cf22eef243e5b09d0c49032cf827248f1791c 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -426,7 +426,7 @@ singleExpression | Not singleExpression # NotExpression | singleExpression (Multiply | Divide | Modulus) singleExpression # MultiplicativeExpression | singleExpression (Plus | Minus) singleExpression # AdditiveExpression - | singleExpression (LeftShiftArithmetic | RightShiftArithmetic | RightShiftLogical) singleExpression # BitShiftExpression + | singleExpression shiftOperator singleExpression # BitShiftExpression | singleExpression (LessThan | MoreThan | LessThanEquals | GreaterThanEquals) singleExpression # RelationalExpression | singleExpression Instanceof primaryType # InstanceofExpression | singleExpression (Equals | NotEquals) singleExpression # EqualityExpression @@ -448,6 +448,12 @@ singleExpression | singleExpression As (intersectionType | primaryType) # CastExpression ; +shiftOperator + : first=LessThan second=LessThan {$first.index + 1 == $second.index}? + | first=MoreThan second=MoreThan {$first.index + 1 == $second.index}? + | first=MoreThan second=MoreThan third=MoreThan {$first.index + 1 == $second.index && $second.index + 1 == $third.index}? + ; + lambdaBody : singleExpression | block diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 13b5c09ff97a4b80cf61a7c6e6f23c2f8b988148..dcf7ceed6ea0f6597c71a9776fdf01712c7aa1c1 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -22,6 +22,7 @@ import com.ohos.migrator.staticTS.parser.StaticTSParserBaseVisitor; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import java.io.FileWriter; @@ -126,13 +127,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // typeParameterList: typeParameter (',' typeParameter)*; @Override public Void visitTypeParameterList(TypeParameterListContext stsTypeParameterList) { + int i = 0; for (TypeParameterContext stsTypeParameter : stsTypeParameterList.typeParameter()) { + if (i > 0) sb.append(", "); visitTypeParameter(stsTypeParameter); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", "; - return null; } @@ -187,13 +188,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // typeArgumentList: typeArgument (',' typeArgument)* @Override public Void visitTypeArgumentList(TypeArgumentListContext stsTypeArgumentList) { + int i = 0; for (TypeArgumentContext stsTypeArgument : stsTypeArgumentList.typeArgument()) { + if (i > 0) sb.append(", "); visitTypeArgument(stsTypeArgument); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", ". - return null; } @@ -292,12 +293,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // qualifiedName: Identifier (Dot Identifier)* @Override public Void visitQualifiedName(QualifiedNameContext stsQualName) { + int i = 0; for (TerminalNode identifier : stsQualName.Identifier()) { - sb.append(identifier.getText()).append('.'); + sb.append(identifier.getText()); + if (i > 0) sb.append('.'); + ++i; } - sb.setLength(sb.length() - 1); // Cut off the ending extra '.' - return null; } @@ -556,13 +558,13 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // classOrInterfaceTypeList: typeReference (',' typeReference)* @Override public Void visitInterfaceTypeList(InterfaceTypeListContext stsClassOrInterfaceTypeList) { + int i = 0; for (TypeReferenceContext stsTypeReference : stsClassOrInterfaceTypeList.typeReference()) { + if (i > 0) sb.append(", "); visitTypeReference(stsTypeReference); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", " - return null; } @@ -782,26 +784,25 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // variableDeclarationList: variableDeclaration (',' variableDeclaration)* @Override public Void visitVariableDeclarationList(VariableDeclarationListContext stsVariableDeclarationList) { + int i = 0; for (VariableDeclarationContext stsVariableDeclaration : stsVariableDeclarationList.variableDeclaration()) { + if (i > 0) sb.append(", "); visitVariableDeclaration(stsVariableDeclaration); - sb.append(", "); + ++i; } - - sb.setLength(sb.length() - 2); // Cut off the ending extra ", " - return null; } // constantDeclarationList: constantDeclaration (',' constantDeclaration)* @Override public Void visitConstantDeclarationList(ConstantDeclarationListContext stsConstantDeclarationList) { + int i = 0; for (ConstantDeclarationContext stsConstantDeclaration : stsConstantDeclarationList.constantDeclaration()) { + if (i > 0) sb.append(", "); visitConstantDeclaration(stsConstantDeclaration); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off the ending extra ", " - return null; } @@ -880,7 +881,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { @Override public Void visitDoStatement(DoStatementContext stsDoStatement) { doNeededIndent(); - sb.append(stsDoStatement.Do().getText()); + sb.append(stsDoStatement.Do().getText() + "\n"); StatementContext stsStmt = stsDoStatement.statement(); assert(stsStmt != null); @@ -961,14 +962,14 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // expressionSequence: singleExpression (',' singleExpression)* @Override public Void visitExpressionSequence(ExpressionSequenceContext stsExpressionSequence) { + int i = 0; for (SingleExpressionContext stsExpression : stsExpressionSequence.singleExpression()) { + if (i > 0) sb.append(", "); stsExpression.accept(this); - sb.append(", "); + ++i; } - sb.setLength(sb.length() - 2); // Cut off trailing ", " - - return null; + return null; } // | For '(' Let Identifier typeAnnotation? Of singleExpression ')' (statement | block) # ForInOfStatement @@ -1000,9 +1001,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // continueStatement: Continue Identifier? SemiColon @Override public Void visitContinueStatement(ContinueStatementContext stsContinueStatement) { - if (!doNeededIndent()) { - sb.append(' '); - } + doNeededIndent(); sb.append(stsContinueStatement.Continue().getText()); TerminalNode termIdentifier = stsContinueStatement.Identifier(); @@ -1018,10 +1017,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // breakStatement: Break Identifier? SemiColon @Override public Void visitBreakStatement(BreakStatementContext stsBreakStatement) { - if (!doNeededIndent()) { - sb.append(' '); - } - + doNeededIndent(); sb.append(stsBreakStatement.Break().getText()); TerminalNode termIdentifier = stsBreakStatement.Identifier(); @@ -1089,11 +1085,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { public Void visitSwitchStatement(SwitchStatementContext stsSwitchStatement) { doNeededIndent(); - sb.append(stsSwitchStatement.Switch().getText()).append('('); + sb.append(stsSwitchStatement.Switch().getText()).append(" ("); stsSwitchStatement.singleExpression().accept(this); - sb.append(")\n"); + sb.append(')'); visitCaseBlock(stsSwitchStatement.caseBlock()); + sb.append('\n'); return null; } @@ -1122,7 +1119,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { } indentDecrement(); - sb.append(indentCurrent).append("}\n\n"); + sb.append(indentCurrent).append("}\n"); return null; } @@ -1131,7 +1128,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { @Override public Void visitCaseClauses(CaseClausesContext stsCaseClauses) { List stsCaseClauseList = stsCaseClauses.caseClause(); - for (CaseClauseContext stsCaseClause : stsCaseClauseList) { visitCaseClause(stsCaseClause); } @@ -1154,7 +1150,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitStatement(stsStatement); indentDecrement(); - sb.append('\n'); return null; } @@ -1171,7 +1166,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitStatement(stsStatement); indentDecrement(); - sb.append('\n'); return null; } @@ -1312,7 +1306,11 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitChildren(stsClassBody); indentDecrement(); - sb.append(indentCurrent).append("}\n\n"); + sb.append(indentCurrent).append("}"); + + // Don't start new line if this class body is a part of a object creation expression + if (!(stsClassBody.getParent() instanceof NewClassExpressionContext)) + sb.append("\n\n"); return null; } @@ -1418,12 +1416,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { List stsParameters = stsParameterList.parameter(); if (stsParameters != null) { + int i = 0; for (ParameterContext stsParameter : stsParameters) { + if (i > 0) sb.append(", "); visitParameter(stsParameter); - sb.append(", "); + ++i; } - - sb.setLength(sb.length() - 2); // Cut off trailing ", " } VariadicParameterContext stsVariadicParameter = stsParameterList.variadicParameter(); @@ -1513,13 +1511,27 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { sb.append('('); ExpressionSequenceContext stsArgumentList = stsArguments.expressionSequence(); - if (stsArgumentList != null) visitExpressionSequence(stsArgumentList); + if (stsArgumentList != null) + visitExpressionSequence(stsArgumentList); + else if (stsArguments.getChildCount() > 0) + visitChildren(stsArguments); sb.append(')'); return null; } + @Override + public Void visitTerminal(TerminalNode stsTerminal) { + int stsTerminalCode = stsTerminal.getSymbol().getType(); + if (stsTerminalCode == StaticTSLexer.MultiLineComment || + stsTerminalCode == StaticTSLexer.SingleLineComment) { + sb.append(stsTerminal.getText()); + } + + return null; + } + // | singleExpression Instanceof singleExpression # InstanceofExpression @Override public Void visitInstanceofExpression(InstanceofExpressionContext stsInstanceofExpression) { @@ -1691,10 +1703,10 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } - // | singleExpression ('<<' | '>>' | '>>>') singleExpression # BitShiftExpression + // | singleExpression ('<' '<' | '>' '>' | '>' '>' '>') singleExpression # BitShiftExpression @Override public Void visitBitShiftExpression(BitShiftExpressionContext stsBitShiftExpression) { - String op = stsBitShiftExpression.getChild(1).getText(); + String op = stsBitShiftExpression.shiftOperator().getText(); binaryOperatorWrite(op, stsBitShiftExpression.singleExpression()); return null; } @@ -1795,7 +1807,10 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { @Override public Void visitLambdaExpression(LambdaExpressionContext stsLambdaExpression) { sb.append('('); - visitParameterList(stsLambdaExpression.parameterList()); + ParameterListContext stsParameterList = stsLambdaExpression.parameterList(); + if (stsParameterList != null) { + visitParameterList(stsParameterList); + } sb.append(')'); visitTypeAnnotation(stsLambdaExpression.typeAnnotation()); diff --git a/migrator/test/java/array_creation.java.sts b/migrator/test/java/array_creation.java.sts index 7a386f7a000b7b747853ca4a125f1eb9837aeb7d..6267de61834d43927a3ead28edaa43d6c54b93c7 100644 --- a/migrator/test/java/array_creation.java.sts +++ b/migrator/test/java/array_creation.java.sts @@ -18,7 +18,7 @@ package com.ohos.migrator.test.java; export open class array_creation { private const b1 : byte[] = new byte[8]; private const c1 : char[] = ['a', 'b', 'c']; - private foo(c2 : char): void { + private foo(c2 : char[]): void { } public open bar(): void { foo(['g', 'k', 'h']); diff --git a/migrator/test/java/class_instance_creation.java b/migrator/test/java/class_instance_creation.java index 223ddcc5a66f15b1e473f16f41610bcedb0ad044..53d1eb020f644c0029497a93c44da23f9a1dcd60 100644 --- a/migrator/test/java/class_instance_creation.java +++ b/migrator/test/java/class_instance_creation.java @@ -20,7 +20,13 @@ class class_instance_creation { class_instance_creation() {} class_instance_creation(String s, double d) {} + public void foo() { } + static class_instance_creation inst1 = new class_instance_creation(); static class_instance_creation inst2 = new class_instance_creation(3); static class_instance_creation inst3 = new class_instance_creation("ss", 7.8); + static class_instance_creation inst4 = new class_instance_creation(3) { + private int f; + public void foo() { f = 2; } + }; } diff --git a/migrator/test/java/class_instance_creation.java.sts b/migrator/test/java/class_instance_creation.java.sts index 2dec21a27adcb447d2094a7f8de291a8ccfe0b66..73b5678318ce06598c48c50fc23aaeaac287b0c7 100644 --- a/migrator/test/java/class_instance_creation.java.sts +++ b/migrator/test/java/class_instance_creation.java.sts @@ -24,8 +24,17 @@ open class class_instance_creation { constructor(s : String, d : double) { } + public open foo(): void { + } + static inst1 : class_instance_creation = new class_instance_creation(); static inst2 : class_instance_creation = new class_instance_creation(3); static inst3 : class_instance_creation = new class_instance_creation("ss", 7.8); + static inst4 : class_instance_creation = new class_instance_creation(3) { + private f : int ; + public override foo(): void { + f = 2; + } + }; } diff --git a/migrator/test/java/class_instance_initializer.java b/migrator/test/java/class_instance_initializer.java index 1279d786ef0b3e5a0a560a70696f2288ff76eb8b..959ad31af8dcea2387d85e6501d86ded0de2e54f 100644 --- a/migrator/test/java/class_instance_initializer.java +++ b/migrator/test/java/class_instance_initializer.java @@ -76,4 +76,11 @@ class B extends A { c = 500; d = 600; } -} \ No newline at end of file +} + +// instance initializer without ctors +class C { + String foo; + + { foo = "bar"; } +} diff --git a/migrator/test/java/class_instance_initializer.java.sts b/migrator/test/java/class_instance_initializer.java.sts index 298d22cea75c321afeae0f3b464cb2e393a44e63..c77a40cc6db0538bf23e3e8911a7cff1f4ab7b23 100644 --- a/migrator/test/java/class_instance_initializer.java.sts +++ b/migrator/test/java/class_instance_initializer.java.sts @@ -65,3 +65,10 @@ open class B extends A { } +open class C { + foo : String ; + + public constructor() { + foo = "bar"; + } +} diff --git a/migrator/test/java/conditional_expression.java b/migrator/test/java/conditional_expression.java index 40b5fb2dcd5d5cb021a7342f730f831f18836727..2032053fc0283c446630eb570dd6b33641bfa73a 100644 --- a/migrator/test/java/conditional_expression.java +++ b/migrator/test/java/conditional_expression.java @@ -23,4 +23,4 @@ class ConditionalExpression { boolean someCondition = true; result = someCondition ? value1 : value2; } -} \ No newline at end of file +} diff --git a/migrator/test/java/do_statement.java b/migrator/test/java/do_statement.java new file mode 100644 index 0000000000000000000000000000000000000000..831fe0021aa6b6d69f50aff9e89e1e538015d24c --- /dev/null +++ b/migrator/test/java/do_statement.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +class do_statement { + public static void Test() { + final boolean Flag = true; + int i = 0; + int j = 0; + + do break; while (Flag); + + do { + break; + } while( Flag ); + + do { + i++; + if (i == 2) continue; + if (i == 5) break; + } while ( i < 10 ); + + outerLoop: + do { + + innerLoop: + do { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + while ( j < 5 ); + } while ( i < 5 ); + } +} diff --git a/migrator/test/java/do_statement.java.sts b/migrator/test/java/do_statement.java.sts new file mode 100644 index 0000000000000000000000000000000000000000..180672704284a3a897572cc1f1eea097baa29f2c --- /dev/null +++ b/migrator/test/java/do_statement.java.sts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ohos.migrator.test.java; + +open class do_statement { + public static Test(): void { + const Flag : boolean = true; + let i : int = 0; + let j : int = 0; + do + break; + while(Flag); + do + { + break; + } + while(Flag); + do + { + i++; + if (i == 2) continue; + if (i == 5) break; + } + while(i < 10); + outerLoop: do + { + innerLoop: do + { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + while(j < 5); + } + while(i < 5); + } +} + diff --git a/migrator/test/java/empty_statement.java.sts b/migrator/test/java/empty_statement.java.sts index efe573a472663eeea307d5929fe083bf7cada565..4423bbee92bc76fdb9977bc3f34bf504f1845a4e 100644 --- a/migrator/test/java/empty_statement.java.sts +++ b/migrator/test/java/empty_statement.java.sts @@ -19,6 +19,13 @@ open class empty_statement { public open Test(): void { a = 10; let i : int = 0; + while(i < 2) + { + } + do + { + } + while(i > 3); for (; i < 10; ++i) { } for (let s : int = 1; s < 2; ++s) { @@ -36,3 +43,4 @@ open class empty_statement { public open Run(): void { } } + diff --git a/migrator/test/java/enum_with_class_behavior.java b/migrator/test/java/enum_with_class_behavior.java index a2524adc97ba583db831492f3c1ec2e076cab012..2331696add1f420761a96ce822c62bcfb44a78df 100644 --- a/migrator/test/java/enum_with_class_behavior.java +++ b/migrator/test/java/enum_with_class_behavior.java @@ -36,7 +36,13 @@ enum ArithmeticOperation implements IOperation { DIVIDE { @Override public int apply(int a, int b) { return a / b; } - } + }; + + // tests enum instance initializer translation + // super(name, ordinal) call should be inserted + // into resulting ctor! + private String foo; + { foo = "bar"; } } // Enum declaration with type members (ctor, methods, etc). @@ -46,17 +52,30 @@ enum Planet { VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6), - JUPITER (1.9e+27, 7.1492e7), - SATURN (5.688e+26, 6.0268e7), - URANUS (8.686e+25, 2.5559e7), - NEPTUNE (1.024e+26, 2.4746e7); + JUPITER (1.9e+27, 7.1492e7, PlanetType.GAS), + SATURN (5.688e+26, 6.0268e7, PlanetType.GAS), + URANUS (8.686e+25, 2.5559e7, PlanetType.ICE), + NEPTUNE (1.024e+26, 2.4746e7, PlanetType.ICE); + + enum PlanetType { + ROCK, + GAS, + ICE + } private final double mass; // in kilograms private final double radius; // in meters + private final PlanetType type; - Planet(double mass, double radius) { + Planet(double mass, double radius, PlanetType type) { this.mass = mass; this.radius = radius; + this.type = type; + } + + Planet(double mass, double radius) { + // No super(name, ordinal) call in translation here! + this(mass, radius, PlanetType.ROCK); } // universal gravitational constant (m3 kg-1 s-2) @@ -69,4 +88,4 @@ enum Planet { double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } -} \ No newline at end of file +} diff --git a/migrator/test/java/enum_with_class_behavior.java.sts b/migrator/test/java/enum_with_class_behavior.java.sts index 63344485c714c8ed039906e73418c5bf310740d2..cc2c3c81420c1f27825d281736b601343edcd83d 100644 --- a/migrator/test/java/enum_with_class_behavior.java.sts +++ b/migrator/test/java/enum_with_class_behavior.java.sts @@ -18,19 +18,106 @@ interface IOperation { apply(a : int, b : int): int ; } -enum ArithmeticOperation { - PLUS, - MINUS, - MULTIPLY, - DIVIDE +open class ArithmeticOperation extends Enum implements IOperation { + public static const PLUS : ArithmeticOperation = new ArithmeticOperation("PLUS", 0) { + public override apply(a : int, b : int): int { + return a + b; + } + }; + public static const MINUS : ArithmeticOperation = new ArithmeticOperation("MINUS", 1) { + public override apply(a : int, b : int): int { + return a - b; + } + }; + public static const MULTIPLY : ArithmeticOperation = new ArithmeticOperation("MULTIPLY", 2) { + public override apply(a : int, b : int): int { + return a * b; + } + }; + public static const DIVIDE : ArithmeticOperation = new ArithmeticOperation("DIVIDE", 3) { + public override apply(a : int, b : int): int { + return a / b; + } + }; + + private foo : String ; + + public static values(): ArithmeticOperation[] { + return [PLUS, MINUS, MULTIPLY, DIVIDE]; + } + public static valueOf(name : String): ArithmeticOperation { + for (let value : ArithmeticOperation of values()){ + if (name == value.toString()) return value; + } + return null; + } + + private constructor(name : String, ordinal : int) { + super(name, ordinal); + foo = "bar"; + } } -enum Planet { - MERCURY, - VENUS, - EARTH, - MARS, - JUPITER, - SATURN, - URANUS, - NEPTUNE +class Planet extends Enum { + public static const MERCURY : Planet = new Planet("MERCURY", 0, 3.303e+23, 2.4397e6); + public static const VENUS : Planet = new Planet("VENUS", 1, 4.869e+24, 6.0518e6); + public static const EARTH : Planet = new Planet("EARTH", 2, 5.976e+24, 6.37814e6); + public static const MARS : Planet = new Planet("MARS", 3, 6.421e+23, 3.3972e6); + public static const JUPITER : Planet = new Planet("JUPITER", 4, 1.9e+27, 7.1492e7, PlanetType.GAS); + public static const SATURN : Planet = new Planet("SATURN", 5, 5.688e+26, 6.0268e7, PlanetType.GAS); + public static const URANUS : Planet = new Planet("URANUS", 6, 8.686e+25, 2.5559e7, PlanetType.ICE); + public static const NEPTUNE : Planet = new Planet("NEPTUNE", 7, 1.024e+26, 2.4746e7, PlanetType.ICE); + + static class PlanetType extends Enum { + public static const ROCK : PlanetType = new PlanetType("ROCK", 0); + public static const GAS : PlanetType = new PlanetType("GAS", 1); + public static const ICE : PlanetType = new PlanetType("ICE", 2); + + public static values(): PlanetType[] { + return [ROCK, GAS, ICE]; + } + public static valueOf(name : String): PlanetType { + for (let value : PlanetType of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + } + + private mass : double ; + private radius : double ; + private type : PlanetType ; + + constructor(name : String, ordinal : int, mass : double, radius : double, type : PlanetType) { + super(name, ordinal); + this.mass = mass; + this.radius = radius; + this.type = type; + } + + constructor(name : String, ordinal : int, mass : double, radius : double) { + this(name, ordinal, mass, radius, PlanetType.ROCK); + } + + public static const G : double = 6.67300E-11; + + open surfaceGravity(): double { + return G * mass / (radius * radius); + } + + open surfaceWeight(otherMass : double): double { + return otherMass * surfaceGravity(); + } + + public static values(): Planet[] { + return [MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE]; + } + public static valueOf(name : String): Planet { + for (let value : Planet of values()){ + if (name == value.toString()) return value; + } + return null; + } } diff --git a/migrator/test/java/for_statement.java.sts b/migrator/test/java/for_statement.java.sts index cbdfd1b456fe8e07858dd5f9fadb1ded7a1d7184..c1c6e6c92d8bfb14914affb58b4ff64d92c41f7d 100644 --- a/migrator/test/java/for_statement.java.sts +++ b/migrator/test/java/for_statement.java.sts @@ -17,19 +17,19 @@ package com.ohos.migrator.test.java; open class ForStatements { public static Test(): void { - for (; ; ) break; + for (; ; ) break; for (; ; ) { break; } for (let i : int = 0; ; ) { i++; - if (i == 2) continue; - if (i == 5) break; + if (i == 2) continue; + if (i == 5) break; } let a : int = 0; for (; a < 5; ) a++; for (; ; a--) { - if (a == 0) break; + if (a == 0) break; } for (let i : int = 0, j : int = 0; i < 5; i++, j++) { let k : int = i * j; @@ -40,9 +40,10 @@ open class ForStatements { } outerLoop: for (let i : int = 0; i < 5; i++) { innerLoop: for (let j : int = 0; j < 5; j++) { - if (j == 2) continue innerLoop; - if (i * j == 20) break outerLoop; + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; } } } } + diff --git a/migrator/test/java/generic_class_1.java b/migrator/test/java/generic_class_1.java new file mode 100644 index 0000000000000000000000000000000000000000..1b15fde1eb9d9093283c2da8055ab1e6ed3d5d71 --- /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 0000000000000000000000000000000000000000..192ed6b394cc627b6416df56cf5d0930f78d0f44 --- /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 0000000000000000000000000000000000000000..6959f15b3f7de86b55f9279958e6fa35d8874f61 --- /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 0000000000000000000000000000000000000000..1bd7124f446c87af7f0500a18e8e3dbb27c2a382 --- /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 0000000000000000000000000000000000000000..0ceb85c2860aba21b129482f263c539e844ec356 --- /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 0000000000000000000000000000000000000000..57906a9f8ffa727c5b9ce3dc447bd9b0819099d4 --- /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 0000000000000000000000000000000000000000..6b48d1b69feabd459123b71c0278e8f5f4bb4339 --- /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 0000000000000000000000000000000000000000..ebec1d974c33dcb10d6a87de57331266f195533c --- /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 0000000000000000000000000000000000000000..3f8d042da91ce806640ba288a25ebdf7da57fe85 --- /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 0000000000000000000000000000000000000000..867ca6aa4c6461a44099d9fd93719ccb41a0c0ac --- /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 0000000000000000000000000000000000000000..9c82acd990134c48f3214b4f64b4bdee42587b24 --- /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 0000000000000000000000000000000000000000..a26be036301201e9ee377d0f0f50c3ef8b26355c --- /dev/null +++ b/migrator/test/java/generic_interface_2.java.sts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +interface G1 { + m(): Object ; +} + +interface G2 { + m(): String ; +} + +interface G { +} + diff --git a/migrator/test/java/generic_interface_3.java b/migrator/test/java/generic_interface_3.java new file mode 100644 index 0000000000000000000000000000000000000000..b1ccedea7bb6555341555718e981389047eaca2f --- /dev/null +++ b/migrator/test/java/generic_interface_3.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +import java.util.List; + +interface ListFactory { + List make(); +} + +ListFactory lf = ArrayList::new; +List ls = lf.make(); +List ln = lf.make(); \ No newline at end of file diff --git a/migrator/test/java/generic_interface_3.java.skip b/migrator/test/java/generic_interface_3.java.skip new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/migrator/test/java/inferred_types.java b/migrator/test/java/inferred_types.java new file mode 100644 index 0000000000000000000000000000000000000000..89e76bdea492aa01a59e0a55f44045476561f645 --- /dev/null +++ b/migrator/test/java/inferred_types.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.tests.java; + +import java.util.List; + +class Main { + // Java language allows to omit return/parameter types for lambda expression. + // These types are then inferred by the compiler. + // This test covers all kinds of types that can be inferred by compiler + + class C {} + enum E {} + interface IPrimitiveTypes { void M(int i, boolean b, char c); } // Void, primitive types + interface IClassTypes { IPrimitiveTypes M(C c, String s, E e); } // Class, Interface, Enum + interface IArrays { int[] M(String[] sArray, IPrimitiveTypes[][] iArray, E[] eArray[]); } // Arrays + interface IParametrizedTypes { List M(List list, List listOfArrays, List> listOfLists[]); } // Parametrized type, Raw type + interface IWildcards { List M(List listExtends, List listSuper); } // Wildcards + interface IGeneric { T M(List list); } // Generic interface (parametrized types, type variables, wildcards, etc.) + + static class OuterClass { + class InnerClass { + void M(T t) { + IGeneric l = (list) -> list.get(0); // Generic functional interface parametrized with type variable + } + } + } + interface IInnerOuter { + int M(OuterClass>.InnerClass inner); // Nested type (with parametrized type) + } + + void Test() { + IPrimitiveTypes l1 = (i, b, c) -> { }; // Void, primitive types + IClassTypes l2 = (c, s, e) -> l1; // Class, Interface, Enum + IArrays l3 = (sArray, iArray, eArray) -> new int[5]; // Arrays + IParametrizedTypes l4 = (list, listOfArrays, ListOfLists) -> list; // Parametrized type, Raw type + IWildcards l5 = (listExtends, listSuper) -> listExtends; // Wildcards + + // Generic functional interface + IGeneric l6 = (list) -> list.get(0); // parametrized with explicit type + IGeneric l7 = (list) -> list.get(0); // parametrized with wildcard + IGeneric l8 = (list) -> list.get(0); // parametrized with wildcard with bound + IGeneric l9 = (list) -> list.get(0); // parametrized with wildcard with bound + + IInnerOuter l10 = (inner) -> 0; // Nested type (with parametrized type) + } +} \ No newline at end of file diff --git a/migrator/test/java/inferred_types.java.sts b/migrator/test/java/inferred_types.java.sts new file mode 100644 index 0000000000000000000000000000000000000000..eea79cb1dbbfe7c09f42e395f260997c8dcb9403 --- /dev/null +++ b/migrator/test/java/inferred_types.java.sts @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ohos.migrator.tests.java; + +import java.util.List; +open class Main { + open class C { + } + + static class E extends Enum { + public static values(): E[] { + return []; + } + public static valueOf(name : String): E { + for (let value : E of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + + } + + interface IPrimitiveTypes { + M(i : int, b : boolean, c : char): void ; + } + + interface IClassTypes { + M(c : C, s : String, e : E): IPrimitiveTypes ; + } + + interface IArrays { + M(sArray : String[], iArray : IPrimitiveTypes[][], eArray : E[][]): int[] ; + } + + interface IParametrizedTypes { + M(list : List, listOfArrays : List, listOfLists : List>[]): List ; + } + + interface IWildcards { + M(listExtends : List, listSuper : List): List ; + } + + interface IGeneric { + M(list : List): T ; + } + + static open class OuterClass { + open class InnerClass { + open M(t : T): void { + let l : IGeneric = (list : java.util.List): T =>list.get(0); + } + } + + } + + interface IInnerOuter { + M(inner : OuterClass>.InnerClass): int ; + } + + open Test(): void { + let l1 : IPrimitiveTypes = (i : int, b : boolean, c : char): void => { + } +; + let l2 : IClassTypes = (c : com.ohos.migrator.tests.java.Main.C, s : java.lang.String, e : com.ohos.migrator.tests.java.Main.E): com.ohos.migrator.tests.java.Main.IPrimitiveTypes =>l1; + let l3 : IArrays = (sArray : java.lang.String[], iArray : com.ohos.migrator.tests.java.Main.IPrimitiveTypes[][], eArray : com.ohos.migrator.tests.java.Main.E[][]): int[] =>new int[5]; + let l4 : IParametrizedTypes = (list : java.util.List, listOfArrays : java.util.List, ListOfLists : java.util.List>[]): java.util.List =>list; + let l5 : IWildcards = (listExtends : java.util.List, listSuper : java.util.List): java.util.List =>listExtends; + let l6 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l7 : IGeneric = (list : java.util.List): java.lang.Object =>list.get(0); + let l8 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l9 : IGeneric = (list : java.util.List): java.lang.Number =>list.get(0); + let l10 : IInnerOuter = (inner : com.ohos.migrator.tests.java.Main.OuterClass>.InnerClass): int =>0; + } +} + \ No newline at end of file diff --git a/migrator/test/java/intersection-type.java b/migrator/test/java/intersection-type.java new file mode 100644 index 0000000000000000000000000000000000000000..a1bdbbe67f7ebf83f5ac4d4ac9b68f68d7822211 --- /dev/null +++ b/migrator/test/java/intersection-type.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +class intersection_type { + public void bar(auxilliary arg) { + Runnable r = (Runnable & Something)arg; + r.run(); + + Something s = (Something & Runnable)arg; + s.foo(); + } +} + +class auxilliary implements Runnable, Something { + public void run() { } + public void foo() { } +} + +interface Something { + void foo(); +} diff --git a/migrator/test/java/intersection-type.java.sts b/migrator/test/java/intersection-type.java.sts new file mode 100644 index 0000000000000000000000000000000000000000..b8150eca676ffa4cd5a290de093132fc9c6a3400 --- /dev/null +++ b/migrator/test/java/intersection-type.java.sts @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +open class intersection_type { + public open bar(arg : auxilliary): void { + let r : Runnable = arg as (Runnable & Something); + r.run(); + let s : Something = arg as (Something & Runnable); + s.foo(); + } +} + +open class auxilliary implements Runnable, Something { + public override run(): void { + } + public override foo(): void { + } +} + +interface Something { + foo(): void ; +} diff --git a/migrator/test/java/lambda_expr.java b/migrator/test/java/lambda_expr.java new file mode 100644 index 0000000000000000000000000000000000000000..d24e1a349329b7c5ef396544cb8187b910b2af13 --- /dev/null +++ b/migrator/test/java/lambda_expr.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.tests.java; + +class Main { + + interface I1 { void M(); } + interface I2 { int M(boolean b); } + interface I3 { int M(int i, String s); } + + void Test() { + I1 i1 = () -> { }; + i1.M(); + + I2 i2 = x -> !x ? 1 : 2; + int i = i2.M(true); + + I2 i2_2 = getLambda(); + i2_2.M(false); + + PassLambdaByParam((x1, x2) -> x2.contains("x") ? x1 : 0); + } + + I2 getLambda() { + return (boolean b) -> { + if (b) + return 10; + else + return 20; + }; + } + + int PassLambdaByParam(I3 i3) { + return i3.M(10, "Text"); + } +} \ No newline at end of file diff --git a/migrator/test/java/lambda_expr.java.sts b/migrator/test/java/lambda_expr.java.sts new file mode 100644 index 0000000000000000000000000000000000000000..604fe6764e30be328bca51d48133c204073e8eef --- /dev/null +++ b/migrator/test/java/lambda_expr.java.sts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.ohos.migrator.tests.java; + +open class Main { + interface I1 { + M(): void ; + } + + interface I2 { + M(b : boolean): int ; + } + + interface I3 { + M(i : int, s : String): int ; + } + + open Test(): void { + let i1 : I1 = (): void => { + } +; + i1.M(); + let i2 : I2 = (x : boolean): int =>!x ? 1 : 2; + let i : int = i2.M(true); + let i2_2 : I2 = getLambda(); + i2_2.M(false); + PassLambdaByParam((x1 : int, x2 : java.lang.String): int =>x2.contains("x") ? x1 : 0); + } + open getLambda(): I2 { + return (b : boolean): int => { + if (b) return 10; + else return 20; + } +; + } + open PassLambdaByParam(i3 : I3): int { + return i3.M(10, "Text"); + } +} + \ No newline at end of file diff --git a/migrator/test/java/literals.java b/migrator/test/java/literals.java new file mode 100644 index 0000000000000000000000000000000000000000..5c8c11a6b184217d440a162dc9e9e29918f49c8a --- /dev/null +++ b/migrator/test/java/literals.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +class literals { + void test() { + // integer literals + byte b = 0; + byte b2 = 1_0_2; + short s = 0x1; + short s2 = 0X1_F; + int i = 02; + int i2 = 03_4_56; + long l = 0b11L; + long l2 = 0B1_01_11l; + + // floating-point literals + float f = 4f; + float f2 = 1_2.23_45e+6F; + float f3 = 3.402_823_5e1_7f; + double d = 5.; + double d2 = .123_456; + double d3 = 0.123876; + double pi = 3.1416D; + double G = 6.6_73_00E-11d; + + // char and string literals + char c = '6'; + char c2 = '\t'; + char c3 = '\''; + String str = "7"; + String str2 = "Who needs \"dots\" over \"eyes\"? ;)\r\n"; + + // null and boolean literals + literals nl = null; + boolean tl = true; + boolean fl = false; + + // class literals + Class cl = literals.class; + Class ll = long.class; + Class sal = String[].class; + Class dal = double[].class; + } +} diff --git a/migrator/test/java/literals.java.sts b/migrator/test/java/literals.java.sts new file mode 100755 index 0000000000000000000000000000000000000000..3e3d7934d4048e83801b310a86286732d32a8398 --- /dev/null +++ b/migrator/test/java/literals.java.sts @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +open class literals { + open test(): void { + let b : byte = 0; + let b2 : byte = 1_0_2; + let s : short = 0x1; + let s2 : short = 0X1_F; + let i : int = 0o2; + let i2 : int = 0o3_4_56; + let l : long = 0b11; + let l2 : long = 0B1_01_11; + let f : float = 4; + let f2 : float = 1_2.23_45e+6; + let f3 : float = 3.402_823_5e1_7; + let d : double = 5.; + let d2 : double = .123_456; + let d3 : double = 0.123876; + let pi : double = 3.1416; + let G : double = 6.6_73_00E-11; + let c : char = '6'; + let c2 : char = '\t'; + let c3 : char = '\''; + let str : String = "7"; + let str2 : String = "Who needs \"dots\" over \"eyes\"? ;)\r\n"; + let nl : literals = null; + let tl : boolean = true; + let fl : boolean = false; + let cl : Class = literals.class; + let ll : Class = long.class; + let sal : Class = String[].class; + let dal : Class = double[].class; + } +} + diff --git a/migrator/test/java/method_invocation.java b/migrator/test/java/method_invocation.java index 55d81d8f8052b66d41979d43efd0bcff27a652ef..1c8887cb5902a8a3f613382f502f47f5a6b21f34 100644 --- a/migrator/test/java/method_invocation.java +++ b/migrator/test/java/method_invocation.java @@ -93,4 +93,4 @@ class Test3 { ColoredPoint2 cp = new ColoredPoint2(); //test(cp, cp); // Compile-time error } -} \ No newline at end of file +} diff --git a/migrator/test/java/method_invocation.java.sts b/migrator/test/java/method_invocation.java.sts index d0197e84a18ab2af42d97c07575bfbabcb556058..b7b1808fb2cef72361fb6a925390702eb0c3fea5 100644 --- a/migrator/test/java/method_invocation.java.sts +++ b/migrator/test/java/method_invocation.java.sts @@ -25,12 +25,10 @@ open class SubClass1 extends SuperClass { override foo(): void { } tweak : Runnable = new Runnable() { - public open run(): void { + public override run(): void { SubClass1.super.foo(); } - } - -; + }; } interface SuperInterface { @@ -40,7 +38,7 @@ interface SuperInterface { } open class SubClass2 implements SuperInterface { - public open foo(): void { + public override foo(): void { } open tweak(): void { SuperInterface.super.foo(); @@ -48,14 +46,12 @@ open class SubClass2 implements SuperInterface { } open class SubClass3 implements SuperInterface { - public open foo(): void { + public override foo(): void { } tweak : Runnable = new Runnable() { - public open run(): void { + public override run(): void { } - } - -; + }; } open class Doubler { diff --git a/migrator/test/java/switch_statement.java b/migrator/test/java/switch_statement.java new file mode 100644 index 0000000000000000000000000000000000000000..650307f9e5782df3f7d0ec0de6802488b2c11245 --- /dev/null +++ b/migrator/test/java/switch_statement.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +public class switch_statement { + + public static String ReturnFromSwitch(int id) { + switch (id) { + case 1: + return "First"; + case 2: + return "Second"; + default: + return "Unknown"; + } + } + + public static void CaseClausesVariations() { + int a = 0; + + // empty switch + switch (1) { + } + + // no default clause + switch (2) { + case 1: + a = 21; + break; + case 2: + a = 22; + break; + } + + // only default case + switch (3) { + default: + a = 31; + break; + } + + // case clause followed by default + switch (4) { + case 1: + a = 41; + break; + case 2: + break; + default: + a = 43; + break; + } + + // case clause following default clause + switch (5) { + default: + a = 51; + break; + case 1: + a = 52; + break; + case 2: + a = 53; + break; + } + + // case clauses before and after default clause + switch (6) { + case 1: + a = 61; + break; + default: + a = 62; + break; + case 2: + a = 63; + break; + } + + // Fall-through + switch (7) { + case 1: + case 2: + System.out.println("Falling through case 1 and case 2"); + break; + default: + System.out.println("Default case"); + break; + } + + // Fall-through + switch (8) { + case 1: + default: + System.out.println("Falling through both case and default clauses"); + break; + } + + // Fall-through + switch (9) { + case 1: + System.out.println("In case 1: Falling through to default case"); + default: + System.out.println("In default case"); + break; + case 2: + System.out.println("In case 2"); + break; + } + } + + public static void SwitchWithLocalDeclarations() { + int i = 10; + + // Local variable is referenced across several case clauses. + switch (i) { + case 0: + int q = 5; + int w = q; // This declaration is moved in front of switch. Initialization is turned into assignment. + int e; // This declaration is moved in front of switch. No initialization. + break; + default: + w = 10; + e = 20; + System.out.println(w + e); + break; + } + + // Multiple variables in single variable declaration list. + switch (i) { + case 0: + int q = 5, w, e = 10, r; // 'q' and 'r' are moved in front of switch. + int z = 20, x; // Both 'z' and 'x' declarations are left in this block. + System.out.println(q + e + z); + break; + default: + q = 2; + r = 4; + System.out.println(q + r); + break; + } + + // Block variable and hiding. + switch (i) { + case 1: + { + String localVar = "some value"; // 'String localVar' will hide the 'int localVar' in current block scope. + } + break; + case 2: + int localVar = 5; + break; + default: + localVar = 6; + break; + } + + // Local variable is initialized with expression that can cause side-effects. + // The order of evaluation of variable initializers must be preserved. + switch (i) { + case 0: + int q = i++, w = i++, e = i++; + break; + default: + q = 1; + e = 2; + break; + } + + // Variable 'k' is referenced from nested switch, though, it's still being used + // only within the case clause it was declared in. + switch (i) { + case 1: + int k = 10; + + switch (i) { + case 3: + k = 20; + break; + default: + break; + } + + break; + default: + break; + } + + // Switch with local class declaration + switch (i) { + case 1: + class LocalClass { + void M() { + System.out.println("LocalClass.M()"); + } + } + new LocalClass().M(); + break; + default: + break; + } + } + + enum Color { + Red, + Green, + Blue + } + + private static void SwitchWithEnumValues() { + Color color = Color.Green; + + switch (color) { + case Red: + System.out.println("Color is red"); + break; + case Blue: + System.out.println("Color is blue"); + break; + default: + System.out.println("Color is default"); + break; + } + } +} diff --git a/migrator/test/java/switch_statement.java.sts b/migrator/test/java/switch_statement.java.sts new file mode 100644 index 0000000000000000000000000000000000000000..cebe6f6a9d4cb809474a26409d69145807f3b472 --- /dev/null +++ b/migrator/test/java/switch_statement.java.sts @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +export open class switch_statement { + public static ReturnFromSwitch(id : int): String { + switch (id) { + case 1: + return "First"; + case 2: + return "Second"; + default: + return "Unknown"; + } + + } + public static CaseClausesVariations(): void { + let a : int = 0; + switch (1) { + } + + switch (2) { + case 1: + a = 21; + break; + case 2: + a = 22; + break; + } + + switch (3) { + default: + a = 31; + break; + } + + switch (4) { + case 1: + a = 41; + break; + case 2: + break; + default: + a = 43; + break; + } + + switch (5) { + default: + a = 51; + break; + case 1: + a = 52; + break; + case 2: + a = 53; + break; + } + + switch (6) { + case 1: + a = 61; + break; + default: + a = 62; + break; + case 2: + a = 63; + break; + } + + switch (7) { + case 1: + case 2: + System.out.println("Falling through case 1 and case 2"); + break; + default: + System.out.println("Default case"); + break; + } + + switch (8) { + case 1: + default: + System.out.println("Falling through both case and default clauses"); + break; + } + + switch (9) { + case 1: + System.out.println("In case 1: Falling through to default case"); + default: + System.out.println("In default case"); + break; + case 2: + System.out.println("In case 2"); + break; + } + + } + public static SwitchWithLocalDeclarations(): void { + let i : int = 10; + { + let w : int ; + let e : int ; + switch (i) { + case 0: + { + let q : int = 5; + w = q; + break; + } + default: + w = 10; + e = 20; + System.out.println(w + e); + break; + } + + } + { + let q : int ; + let r : int ; + switch (i) { + case 0: + { + q = 5; + let w : int ; + let e : int = 10; + let z : int = 20; + let x : int ; + System.out.println(q + e + z); + break; + } + default: + q = 2; + r = 4; + System.out.println(q + r); + break; + } + + } + { + let localVar : int ; + switch (i) { + case 1: + { + let localVar : String = "some value"; + } + break; + case 2: + localVar = 5; + break; + default: + localVar = 6; + break; + } + + } + { + let q : int ; + let e : int ; + switch (i) { + case 0: + { + q = i++; + let w : int = i++; + e = i++; + break; + } + default: + q = 1; + e = 2; + break; + } + + } + switch (i) { + case 1: + { + let k : int = 10; + switch (i) { + case 3: + k = 20; + break; + default: + break; + } + + break; + } + default: + break; + } + + switch (i) { + case 1: + { + open class LocalClass { + open M(): void { + System.out.println("LocalClass.M()"); + } + } + + new LocalClass().M(); + break; + } + default: + break; + } + + } + + static class Color extends Enum { + public static const Red : Color = new Color("Red", 0); + public static const Green : Color = new Color("Green", 1); + public static const Blue : Color = new Color("Blue", 2); + public static values(): Color[] { + return [Red, Green, Blue]; + } + public static valueOf(name : String): Color { + for (let value : Color of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + } + + private static SwitchWithEnumValues(): void { + let color : Color = Color.Green; + switch (color) { + case Red: + System.out.println("Color is red"); + break; + case Blue: + System.out.println("Color is blue"); + break; + default: + System.out.println("Color is default"); + break; + } + + } +} diff --git a/migrator/test/java/test_enum.java.sts b/migrator/test/java/test_enum.java.sts index 05aaf180da5195dd7a52c9c994f23e3a0e09278e..d4789956f4713a623a49ddf33fba4609a79807f3 100644 --- a/migrator/test/java/test_enum.java.sts +++ b/migrator/test/java/test_enum.java.sts @@ -14,41 +14,117 @@ */ package com.ohos.migrator.test.java; -export enum test_enum { +export class test_enum extends Enum { + public static values(): test_enum[] { + return []; + } + public static valueOf(name : String): test_enum { + for (let value : test_enum of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } -enum Planet { - MERCURY, - VENUS, - EARTH, - MARS, - JUPITER, - SATURN, - URANUS, - NEPTUNE +class Planet extends Enum { + public static const MERCURY : Planet = new Planet("MERCURY", 0); + public static const VENUS : Planet = new Planet("VENUS", 1); + public static const EARTH : Planet = new Planet("EARTH", 2); + public static const MARS : Planet = new Planet("MARS", 3); + public static const JUPITER : Planet = new Planet("JUPITER", 4); + public static const SATURN : Planet = new Planet("SATURN", 5); + public static const URANUS : Planet = new Planet("URANUS", 6); + public static const NEPTUNE : Planet = new Planet("NEPTUNE", 7); + + public static values(): Planet[] { + return [MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE]; + } + public static valueOf(name : String): Planet { + for (let value : Planet of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } open class NestedEnums { - private enum Colors { - RED, - GREEN, - BLUE - } - protected enum Size { - SMALL, - MEDIUM, - LARGE - } - public enum Direction { - NORTH, - EAST, - SOUTH, - WEST - } - enum Operator { - PLUS, - MINUS, - MULTIPLY, - DIVIDE + private static class Colors extends Enum { + public static const RED : Colors = new Colors("RED", 0); + public static const GREEN : Colors = new Colors("GREEN", 1); + public static const BLUE : Colors = new Colors("BLUE", 2); + + public static values(): Colors[] { + return [RED, GREEN, BLUE]; + } + public static valueOf(name : String): Colors { + for (let value : Colors of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } } -} + protected static class Size extends Enum { + public static const SMALL : Size = new Size("SMALL", 0); + public static const MEDIUM : Size = new Size("MEDIUM", 1); + public static const LARGE : Size = new Size("LARGE", 2); + + public static values(): Size[] { + return [SMALL, MEDIUM, LARGE]; + } + public static valueOf(name : String): Size { + for (let value : Size of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + } + public static class Direction extends Enum { + public static const NORTH : Direction = new Direction("NORTH", 0); + public static const EAST : Direction = new Direction("EAST", 1); + public static const SOUTH : Direction = new Direction("SOUTH", 2); + public static const WEST : Direction = new Direction("WEST", 3); + public static values(): Direction[] { + return [NORTH, EAST, SOUTH, WEST]; + } + public static valueOf(name : String): Direction { + for (let value : Direction of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + } + static class Operator extends Enum { + public static const PLUS : Operator = new Operator("PLUS", 0); + public static const MINUS : Operator = new Operator("MINUS", 1); + public static const MULTIPLY : Operator = new Operator("MULTIPLY", 2); + public static const DIVIDE : Operator = new Operator("DIVIDE", 3); + + public static values(): Operator[] { + return [PLUS, MINUS, MULTIPLY, DIVIDE]; + } + public static valueOf(name : String): Operator { + for (let value : Operator of values()){ + if (name == value.toString()) return value; + } + return null; + } + private constructor(name : String, ordinal : int) { + super(name, ordinal); + } + } +} diff --git a/migrator/test/java/while_statement.java b/migrator/test/java/while_statement.java new file mode 100644 index 0000000000000000000000000000000000000000..3915019cfcdbcaef5d5dd82b0afdaf054e4f4325 --- /dev/null +++ b/migrator/test/java/while_statement.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +class while_statement { + public static void Test() { + final boolean Flag = true; + int i = 0; + int j = 0; + + while (Flag) break; + + while (Flag) { + break; + } + + while ( i< 10 ) { + i++; + if (i == 2) continue; + if (i == 5) break; + } + + outerLoop: + while (i < 5) { + + innerLoop: + while ( j < 5 ) { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + } + } +} diff --git a/migrator/test/java/while_statement.java.sts b/migrator/test/java/while_statement.java.sts new file mode 100644 index 0000000000000000000000000000000000000000..53b82645a526afd206af5ea20d64754821180fc4 --- /dev/null +++ b/migrator/test/java/while_statement.java.sts @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.ohos.migrator.test.java; + +open class while_statement { + public static Test(): void { + const Flag : boolean = true; + let i : int = 0; + let j : int = 0; + while(Flag) + break; + while(Flag) + { + break; + } + while(i < 10) + { + i++; + if (i == 2) continue; + if (i == 5) break; + } + outerLoop: while(i < 5) + { + innerLoop: while(j < 5) + { + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; + } + } + } +} + diff --git a/test/runner.py b/test/runner.py index c6e542bd773cd8bd656e212cb1a130ac47566207..d46ba19c8cdf06b8cc5266ab406e44a1a23167c8 100755 --- a/test/runner.py +++ b/test/runner.py @@ -76,7 +76,7 @@ def get_args(): '--update', action='store_true', dest='update', default=False, help='update skiplist') parser.add_argument( - '--no-run-gc-in-place', action='store_true', dest='no_gip', default=False, + '--run-gc-in-place', action='store_true', dest='run_gc_in_place', default=False, help='enable --run-gc-in-place mode') parser.add_argument( '--filter', '-f', action='store', dest='filter', @@ -101,6 +101,9 @@ def get_args(): parser.add_argument( '--jit', action='store_true', dest='jit', default=False, help='use JIT in interpreter') + parser.add_argument( + '--irtoc', action='store_true', dest='irtoc', default=False, + help='use irtoc in interpreter') parser.add_argument( '--arm64-compiler-skip', action='store_true', dest='arm64_compiler_skip', default=False, help='use skiplist for tests failing on aarch64 in AOT or JIT mode') @@ -133,8 +136,11 @@ class Test: self.skipped = None self.reproduce = "" - def log_cmd(self, cmd): - self.reproduce += "\n" + ' '.join(cmd) + def log_cmd(self, cmd, verbose=False): + cmd_str = ' '.join(cmd) + self.reproduce += "\n" + cmd_str + if verbose: + print(cmd_str, file=sys.stderr) def run(self, runner): cmd = runner.cmd_prefix + [runner.es2panda, "--dump-ast"] @@ -202,11 +208,7 @@ class Test262Test(Test): cmd.append(self.path) - self.log_cmd(cmd) - - if runner.args.verbose: - print('Run es2panda: %s' % ' '.join(cmd), file=sys.stderr) - + self.log_cmd(cmd, runner.args.verbose) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=runner.cmd_env) @@ -235,19 +237,13 @@ class Test262Test(Test): return self if runner.args.aot: - cmd = runner.cmd_prefix + [runner.arkaot] - cmd.extend(runner.aot_args) - cmd.extend(['--paoc-panda-files', test_abc]) - cmd.extend(['--paoc-output', test_an]) + cmd = runner.cmd_prefix + [runner.arkaot] + runner.aot_args + cmd.extend(['--paoc-panda-files', test_abc, '--paoc-output', test_an]) if os.path.isfile(test_an): os.remove(test_an) - self.log_cmd(cmd) - - if runner.args.verbose: - print('Run ark_aot: %s' % ' '.join(cmd), file=sys.stderr) - + self.log_cmd(cmd, runner.args.verbose) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=runner.cmd_env) @@ -266,12 +262,7 @@ class Test262Test(Test): self.error = err.decode("utf-8", errors="ignore") return self - cmd = runner.cmd_prefix + [runner.runtime] - - if runner.args.verbose: - print('Run aot for arm64: %s' % ' '.join(cmd), file=sys.stderr) - - cmd.extend(runner.runtime_args) + cmd = runner.cmd_prefix + [runner.runtime] + runner.runtime_args if runner.args.aot: cmd.extend(['--aot-files', test_an]) @@ -281,13 +272,12 @@ class Test262Test(Test): else: cmd.extend(['--compiler-enable-jit=false']) - cmd.extend([test_abc, "_GLOBAL::func_main_0"]) - - self.log_cmd(cmd) + if runner.args.irtoc: + cmd.extend(['--interpreter-type=irtoc']) - if runner.args.verbose: - print('Run ark: %s' % ' '.join(cmd), file=sys.stderr) + cmd.extend([test_abc, "_GLOBAL::func_main_0"]) + self.log_cmd(cmd, runner.args.verbose) process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=runner.cmd_env) @@ -487,8 +477,12 @@ class Test262Runner(Runner): '--gc-type=%s' % args.gc_type, ] - if not args.no_gip: + if args.run_gc_in_place: self.runtime_args += ['--run-gc-in-place'] + if args.gc_type == "g1-gc": + # Workaround. If don't specify this option G1 may access a deleted class while + # iterating over all objects in a region. + self.runtime_args += ['--g1-track-freed-objects=false'] if args.aot: self.arkaot = path.join(args.build_dir, 'bin', 'ark_aot') @@ -502,7 +496,7 @@ class Test262Runner(Runner): '--gc-type=%s' % args.gc_type, ] - if not args.no_gip: + if args.run_gc_in_place: self.aot_args += ['--run-gc-in-place'] self.aot_args += args.aot_args @@ -518,8 +512,6 @@ class Test262Runner(Runner): if args.bco: self.skiplist_bco_name = "test262skiplist-bco.txt" - if args.arm64_compiler_skip: - self.skiplist_name_list.append("test262skiplist-compiler-arm64.txt") self.tmp_dir = path.join(path.sep, 'tmp', 'panda', 'test262') os.makedirs(self.tmp_dir, exist_ok=True) diff --git a/test/test262skiplist-compiler-arm64.txt b/test/test262skiplist-compiler-arm64.txt deleted file mode 100644 index cf29d31b09671ba1cc4ff3c1630fd4db84b23d0a..0000000000000000000000000000000000000000 --- a/test/test262skiplist-compiler-arm64.txt +++ /dev/null @@ -1,388 +0,0 @@ -annexB/built-ins/Proxy/set/call-parameters-prototype-dunder-proto.js -built-ins/Array/prototype/reduce/15.4.4.21-1-11.js -built-ins/Array/prototype/reduce/15.4.4.21-1-12.js -built-ins/Array/prototype/reduce/15.4.4.21-1-14.js -built-ins/Array/prototype/reduce/15.4.4.21-1-3.js -built-ins/Array/prototype/reduce/15.4.4.21-1-4.js -built-ins/Array/prototype/reduce/15.4.4.21-1-5.js -built-ins/Array/prototype/reduce/15.4.4.21-1-6.js -built-ins/Array/prototype/reduce/15.4.4.21-1-7.js -built-ins/Array/prototype/reduce/15.4.4.21-1-8.js -built-ins/Array/prototype/reduce/15.4.4.21-1-9.js -built-ins/Array/prototype/reduce/15.4.4.21-10-1.js -built-ins/Array/prototype/reduce/15.4.4.21-10-2.js -built-ins/Array/prototype/reduce/15.4.4.21-10-4.js -built-ins/Array/prototype/reduce/15.4.4.21-10-5.js -built-ins/Array/prototype/reduce/15.4.4.21-10-6.js -built-ins/Array/prototype/reduce/15.4.4.21-10-7.js -built-ins/Array/prototype/reduce/15.4.4.21-10-8.js -built-ins/Array/prototype/reduce/15.4.4.21-2-1.js -built-ins/Array/prototype/reduce/15.4.4.21-2-10.js -built-ins/Array/prototype/reduce/15.4.4.21-2-17.js -built-ins/Array/prototype/reduce/15.4.4.21-2-18.js -built-ins/Array/prototype/reduce/15.4.4.21-2-19.js -built-ins/Array/prototype/reduce/15.4.4.21-2-2.js -built-ins/Array/prototype/reduce/15.4.4.21-2-3.js -built-ins/Array/prototype/reduce/15.4.4.21-2-4.js -built-ins/Array/prototype/reduce/15.4.4.21-2-5.js -built-ins/Array/prototype/reduce/15.4.4.21-2-6.js -built-ins/Array/prototype/reduce/15.4.4.21-2-7.js -built-ins/Array/prototype/reduce/15.4.4.21-2-8.js -built-ins/Array/prototype/reduce/15.4.4.21-2-9.js -built-ins/Array/prototype/reduce/15.4.4.21-3-11.js -built-ins/Array/prototype/reduce/15.4.4.21-3-13.js -built-ins/Array/prototype/reduce/15.4.4.21-3-15.js -built-ins/Array/prototype/reduce/15.4.4.21-3-16.js -built-ins/Array/prototype/reduce/15.4.4.21-3-17.js -built-ins/Array/prototype/reduce/15.4.4.21-3-19.js -built-ins/Array/prototype/reduce/15.4.4.21-3-2.js -built-ins/Array/prototype/reduce/15.4.4.21-3-20.js -built-ins/Array/prototype/reduce/15.4.4.21-3-21.js -built-ins/Array/prototype/reduce/15.4.4.21-3-23.js -built-ins/Array/prototype/reduce/15.4.4.21-3-24.js -built-ins/Array/prototype/reduce/15.4.4.21-3-6.js -built-ins/Array/prototype/reduce/15.4.4.21-4-12.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-2.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-3.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-1.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-10.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-11.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-12.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-13.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-14.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-15.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-16.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-17.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-18.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-19.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-2.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-20.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-21.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-22.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-25.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-26.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-27.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-28.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-29.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-3.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-30.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-31.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-4.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-5.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-6.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-7.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-8.js -built-ins/Array/prototype/reduce/15.4.4.21-8-b-iii-1-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-3.js -built-ins/Array/prototype/reduce/15.4.4.21-9-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-6.js -built-ins/Array/prototype/reduce/15.4.4.21-9-7.js -built-ins/Array/prototype/reduce/15.4.4.21-9-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-11.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-12.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-13.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-14.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-15.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-16.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-17.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-18.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-19.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-20.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-21.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-22.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-23.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-24.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-25.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-26.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-27.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-28.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-29.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-3.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-5.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-6.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-7.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-8.js -built-ins/Array/prototype/reduce/15.4.4.21-9-b-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-11.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-12.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-13.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-14.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-15.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-16.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-17.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-18.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-19.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-20.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-21.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-22.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-25.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-26.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-27.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-28.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-29.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-3.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-30.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-31.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-32.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-33.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-5.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-6.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-7.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-8.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-i-9.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-1.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-10.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-11.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-13.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-16.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-17.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-19.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-2.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-20.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-21.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-22.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-23.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-24.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-25.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-26.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-27.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-28.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-29.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-30.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-31.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-32.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-33.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-34.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-35.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-37.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-4-s.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-4.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-5.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-8.js -built-ins/Array/prototype/reduce/15.4.4.21-9-c-ii-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-1-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-10-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-2-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-23.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-24.js -built-ins/Array/prototype/reduceRight/15.4.4.22-3-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-4-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-30.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-31.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-8-b-iii-1-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-23.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-24.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-b-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-12.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-14.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-15.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-3.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-30.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-31.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-32.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-33.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-6.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-7.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-i-9.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-1.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-10.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-11.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-13.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-16.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-17.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-18.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-19.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-2.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-20.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-21.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-22.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-23.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-24.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-25.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-26.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-27.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-28.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-29.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-30.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-31.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-32.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-33.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-34.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-35.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-37.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-4-s.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-4.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-5.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-8.js -built-ins/Array/prototype/reduceRight/15.4.4.22-9-c-ii-9.js -built-ins/Array/prototype/sort/stability-11-elements.js -built-ins/Array/prototype/sort/stability-5-elements.js -built-ins/Proxy/set/boolean-trap-result-is-false-boolean-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-null-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-number-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-string-return-false.js -built-ins/Proxy/set/boolean-trap-result-is-false-undefined-return-false.js -built-ins/Proxy/set/call-parameters-prototype-index.js -built-ins/Proxy/set/call-parameters-prototype.js -built-ins/Proxy/set/call-parameters.js -built-ins/Proxy/set/return-true-target-property-accessor-is-configurable-set-is-undefined.js -built-ins/Proxy/set/return-true-target-property-accessor-is-not-configurable.js -built-ins/Proxy/set/return-true-target-property-is-not-configurable.js -built-ins/Proxy/set/return-true-target-property-is-not-writable.js -built-ins/Proxy/set/target-property-is-accessor-not-configurable-set-is-undefined.js -built-ins/Proxy/set/target-property-is-not-configurable-not-writable-not-equal-to-v.js -built-ins/Proxy/set/trap-is-undefined-target-is-proxy.js -built-ins/TypedArray/prototype/copyWithin/negative-out-of-bounds-end.js -built-ins/TypedArray/prototype/copyWithin/negative-out-of-bounds-target.js -built-ins/TypedArray/prototype/fill/coerced-indexes.js -built-ins/TypedArray/prototype/fill/fill-values-conversion-operations.js -built-ins/TypedArray/prototype/join/custom-separator-result-from-tostring-on-each-value.js -built-ins/TypedArray/prototype/reduce/callbackfn-return-does-not-change-instance.js -built-ins/TypedArray/prototype/reduce/get-length-uses-internal-arraylength.js -built-ins/TypedArray/prototype/reduce/result-is-last-callbackfn-return.js -built-ins/TypedArray/prototype/reduce/result-of-any-type.js -built-ins/TypedArray/prototype/reduceRight/callbackfn-return-does-not-change-instance.js -built-ins/TypedArray/prototype/reduceRight/get-length-uses-internal-arraylength.js -built-ins/TypedArray/prototype/reduceRight/result-is-last-callbackfn-return.js -built-ins/TypedArray/prototype/reduceRight/result-of-any-type.js -built-ins/TypedArray/prototype/set/array-arg-offset-tointeger.js -built-ins/TypedArray/prototype/set/array-arg-set-values.js -built-ins/TypedArray/prototype/set/array-arg-src-tonumber-value-conversions.js -built-ins/TypedArray/prototype/set/typedarray-arg-offset-tointeger.js -built-ins/TypedArray/prototype/set/typedarray-arg-set-values-diff-buffer-other-type.js -built-ins/TypedArray/prototype/slice/results-with-same-length.js -built-ins/TypedArray/prototype/slice/tointeger-end.js -built-ins/TypedArray/prototype/some/returns-false-if-every-cb-returns-false.js -built-ins/TypedArray/prototype/subarray/results-with-different-length.js -built-ins/TypedArray/prototype/subarray/tointeger-begin.js -built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-not-canonical-index.js -built-ins/TypedArrayConstructors/internals/Set/key-is-not-canonical-index.js -language/expressions/bitwise-not/S9.5_A2.2_T2.js -language/types/reference/put-value-prop-base-primitive.js \ No newline at end of file