From a34ac772bccb0829abbc462eb0e49f9dac112525 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Tue, 30 Aug 2022 15:05:04 +0300 Subject: [PATCH 1/3] Implemented translation of synchronized blocks. Defer statement is implemented in STS as part of the above. Added a test to validate translation of synchronized blocks. Change-Id: I22e6df938e3782de58518c02776d5a8ce90bcb25 Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 49 ++++++++++++++++--- .../migrator/staticTS/parser/StaticTSLexer.g4 | 1 + .../staticTS/parser/StaticTSParser.g4 | 5 ++ .../staticTS/writer/StaticTSWriter.java | 10 ++++ migrator/test/java/synchronized_blocks.java | 27 ++++++++++ .../test/java/synchronized_blocks.java.sts | 34 +++++++++++++ 6 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 migrator/test/java/synchronized_blocks.java create mode 100644 migrator/test/java/synchronized_blocks.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index ff53eaf63..92d76baf8 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -27,7 +27,6 @@ import org.eclipse.jdt.core.dom.*; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Stack; @@ -3354,16 +3353,55 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // Java: + // synchronized(X) { statements } + // + // STS: + // { Monitor.lock(X); defer Monitor.unlock(X); statements } @Override public boolean visit(SynchronizedStatement javaSynchrStmt) { - // TODO: To be implemented - // Emit __untranslated_statement call with commented-out original syntax as argument for now. - // This is done to avoid building invalid STS AST which causes exceptions in StaticTSWriter. - stsCurrent.addChild(NodeBuilder.untranslatedStatement(javaSynchrStmt)).setParent(stsCurrent); + pushStatement(new BlockContext(stsCurrent, 0)); + + // Add Monitor.lock call + Expression javaExpr = javaSynchrStmt.getExpression(); + createIntrinsicCall("MonitorEnter", javaExpr); + + // Add deferred Monitor.unlock call + pushStatement(new DeferStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Defer)); + createIntrinsicCall("MonitorExit", javaExpr); + popStatement(); // DeferStatementContext + // Translate block statements + List javaStmts = javaSynchrStmt.getBody().statements(); + for (Statement javaStmt : javaStmts) + javaStmt.accept(this); + + popStatement(); // BlockContext + + ++countStmtTransformed; return false; } + private void createIntrinsicCall(String name, Expression... args) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new CallExpressionContext(pushSingleExpression())); + + stsCurrent.addChild(NodeBuilder.identifierExpression(name)).setParent(stsCurrent); + + pushCurrent(new ArgumentsContext(stsCurrent, 0)); + pushCurrent(new ExpressionSequenceContext(stsCurrent, 0)); + + for (Expression arg : args) + arg.accept(this); + + popCurrent(); // ExpressionSequenceContext + popCurrent(); // ArgumentsContext + + popSingleExpression(); // CallExpressionContext + popStatement(); // ExpressionStatementContext + } + // The list of not yet translated Java Expressions: // CreationReference, //?? ExpressionMethodReference, @@ -3371,6 +3409,5 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // SuperMethodReference, // TypeMethodReference // TryStatement - // SynchronizedStatement // ThrowStatement } \ No newline at end of file diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 index f0b60c9fa..d915ba7ca 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSLexer.g4 @@ -126,6 +126,7 @@ If: 'if'; Throw: 'throw'; Of: 'of'; Try: 'try'; +Defer: 'defer'; From: 'from'; As: 'as'; diff --git a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 index de2cf22ee..ca2f06803 100644 --- a/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 +++ b/migrator/src/com/ohos/migrator/staticTS/parser/StaticTSParser.g4 @@ -326,6 +326,7 @@ statement | switchStatement | throwStatement | tryStatement + | deferStatement | expressionStatement ; @@ -404,6 +405,10 @@ finallyClause : Finally block ; +deferStatement + : Defer statement + ; + expressionStatement : {this.notOpenBraceAndNotFunction()}? singleExpression SemiColon? ; diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index dcf7ceed6..4e652d54f 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1856,4 +1856,14 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { return null; } + + @Override + public Void visitDeferStatement(DeferStatementContext stsDeferStmt) { + doNeededIndent(); + + sb.append(stsDeferStmt.Defer().getText()).append(' '); + stsDeferStmt.statement().accept(this); + + return null; + } } diff --git a/migrator/test/java/synchronized_blocks.java b/migrator/test/java/synchronized_blocks.java new file mode 100644 index 000000000..67ea454cc --- /dev/null +++ b/migrator/test/java/synchronized_blocks.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +class synchronized_blocks { + public static void main(String[] args) { + synchronized_blocks t = new synchronized_blocks(); + synchronized(t) { + synchronized(System.out) { + System.out.println("made it!"); + } + } + } +} diff --git a/migrator/test/java/synchronized_blocks.java.sts b/migrator/test/java/synchronized_blocks.java.sts new file mode 100644 index 000000000..9116b4b75 --- /dev/null +++ b/migrator/test/java/synchronized_blocks.java.sts @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +open class synchronized_blocks { + public static main(args : String[]): void { + let t : synchronized_blocks = new synchronized_blocks(); + + { + MonitorEnter(t); + defer MonitorExit(t); + + { + MonitorEnter(System.out); + defer MonitorExit(System.out); + + System.out.println("made it!"); + } + } + } +} -- Gitee From 749465f839a0b75c6af2d8bb26eb9bff5f9adcc1 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Wed, 31 Aug 2022 13:26:51 +0300 Subject: [PATCH 2/3] Implemented translation of synchronized methods. Added a test to validate the functionality above. Change-Id: I4912bc76b7c1b9685dd2b60b0a81536eba13f04e Signed-off-by: Mikhail Velikanov --- .../ohos/migrator/java/JavaTransformer.java | 63 ++++++++++++++++--- .../ohos/migrator/staticTS/NodeBuilder.java | 46 +++++++++++++- migrator/test/java/synchronized_methods.java | 35 +++++++++++ .../test/java/synchronized_methods.java.sts | 43 +++++++++++++ 4 files changed, 178 insertions(+), 9 deletions(-) create mode 100644 migrator/test/java/synchronized_methods.java create mode 100644 migrator/test/java/synchronized_methods.java.sts diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index 92d76baf8..d709a6d32 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -1350,8 +1350,17 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(MethodDeclaration javaMethodDeclaration) { boolean isInClassContext = stsCurrent instanceof ClassBodyContext; assert(isInClassContext || (stsCurrent instanceof InterfaceBodyContext)); - - pushCurrent(createMemberContextWithAccessModifier(javaMethodDeclaration.getModifiers())); + + // Get current enclosing context - we'll need it later if + // current method is synchronized (see below). Also store + // modifiers of the current method for the same reason. + // NOTE: This has to happen BEFORE any further pushCurrent + // or a similar call that changes the value of stsCurrent! + ParserRuleContext enclosingContext = stsCurrent.getParent(); + int javaMods = javaMethodDeclaration.getModifiers(); + + pushCurrent(createMemberContextWithAccessModifier(javaMods)); + Block javaBlock = javaMethodDeclaration.getBody(); if (javaMethodDeclaration.isConstructor()) { @@ -1391,6 +1400,42 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new BlockContext(stsCurrent, 0)); } + // For synchronized methods, inject MonitorEnter and deferred MonitorExit calls + // in front of all other statements in the method body. The argument of both calls + // is 'this' for non-static methods and class literal of the enclosing class otherwise. + if ((javaMods & Modifier.SYNCHRONIZED) != 0) { + // Figure out enclosing class or interface name. In case we're in anonymous class + // instance creation context, leave it null - we won't need it as this context + // doesn't allow static methods for which we need the class or interface name. + String enclosingTypeName = null; + if (enclosingContext.getRuleIndex() == StaticTSParser.RULE_classDeclaration) + enclosingTypeName = ((ClassDeclarationContext)enclosingContext).Identifier().getText(); + else if (enclosingContext.getRuleIndex() == StaticTSParser.RULE_interfaceDeclaration) + enclosingTypeName = ((InterfaceDeclarationContext)enclosingContext).Identifier().getText(); + + // Add MonitorEnter call + // NOTE: The argument has to be added manually as we don't have it in Java AST. + CallExpressionContext stsMonitorEnterCall = createIntrinsicCall("MonitorEnter"); + SingleExpressionContext stsMonitorEnterCallArg = (javaMods & Modifier.STATIC) == 0 + ? NodeBuilder.thisExpression(null) + : NodeBuilder.classLiteral(enclosingTypeName); + NodeBuilder.addArgument(stsMonitorEnterCall, stsMonitorEnterCallArg); + + // Add deferred MonitorExit call + // NOTE: The argument has to be created again to keep STS AST structure valid + // and added manually as above. + pushStatement(new DeferStatementContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Defer)); + + CallExpressionContext stsMonitorExitCall = createIntrinsicCall("MonitorExit"); + SingleExpressionContext stsMonitorExitCallArg = (javaMods & Modifier.STATIC) == 0 + ? NodeBuilder.thisExpression(null) + : NodeBuilder.classLiteral(enclosingTypeName); + NodeBuilder.addArgument(stsMonitorExitCall, stsMonitorExitCallArg); + + popStatement(); // DeferStatementContext + } + List javaBlockStmts = javaBlock.statements(); for (Statement javaStmt : javaBlockStmts) { javaStmt.accept(this); @@ -3357,16 +3402,16 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // synchronized(X) { statements } // // STS: - // { Monitor.lock(X); defer Monitor.unlock(X); statements } + // { MonitorEnter(X); defer MonitorExit(X); statements } @Override public boolean visit(SynchronizedStatement javaSynchrStmt) { pushStatement(new BlockContext(stsCurrent, 0)); - // Add Monitor.lock call + // Add MonitorEnter call Expression javaExpr = javaSynchrStmt.getExpression(); createIntrinsicCall("MonitorEnter", javaExpr); - // Add deferred Monitor.unlock call + // Add deferred MonitorExit call pushStatement(new DeferStatementContext(stsCurrent, 0)); stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Defer)); createIntrinsicCall("MonitorExit", javaExpr); @@ -3383,9 +3428,11 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } - private void createIntrinsicCall(String name, Expression... args) { + private CallExpressionContext createIntrinsicCall(String name, Expression... args) { pushStatement(new ExpressionStatementContext(stsCurrent, 0)); - pushCurrent(new CallExpressionContext(pushSingleExpression())); + + CallExpressionContext stsCallExpr = new CallExpressionContext(pushSingleExpression()); + pushCurrent(stsCallExpr); stsCurrent.addChild(NodeBuilder.identifierExpression(name)).setParent(stsCurrent); @@ -3400,6 +3447,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popSingleExpression(); // CallExpressionContext popStatement(); // ExpressionStatementContext + + return stsCallExpr; } // The list of not yet translated Java Expressions: diff --git a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java index ec7daf0ac..cdea22909 100644 --- a/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java +++ b/migrator/src/com/ohos/migrator/staticTS/NodeBuilder.java @@ -17,7 +17,6 @@ package com.ohos.migrator.staticTS; import com.ohos.migrator.staticTS.parser.StaticTSParser; import com.ohos.migrator.staticTS.parser.StaticTSParser.*; -import kotlin.jvm.internal.TypeReference; import org.antlr.v4.runtime.CommonToken; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Vocabulary; @@ -230,7 +229,7 @@ public class NodeBuilder { // SimpleType: { Annotation } TypeName // STS: // typeReference: typeReferencePart ('.' typeReferencePart)* - // typeReference: qualifiedName typeArguments? + // typeReferencePart: qualifiedName typeArguments? public static TypeReferenceContext typeReference(String typeName) { TypeReferenceContext stsTypeReference = new TypeReferenceContext(null, 0); TypeReferencePartContext stsTypeRefPart = typeReferencePart(typeName); @@ -441,4 +440,47 @@ public class NodeBuilder { return stsShiftOp; } + + public static void addArgument(CallExpressionContext stsCallExpr, SingleExpressionContext stsArg) { + ArgumentsContext stsArgs = stsCallExpr.arguments(); + if (stsArgs != null) { + ExpressionSequenceContext stsExprSeq = stsArgs.expressionSequence(); + if (stsExprSeq != null) { + stsExprSeq.addChild(stsArg).setParent(stsExprSeq); + } + } + } + + public static SingleExpressionContext thisExpression(TypeReferenceContext stsTypeRef) { + SingleExpressionContext stsSingleExpr = new SingleExpressionContext(null, 0); + ThisExpressionContext stsThisExpression = new ThisExpressionContext(stsSingleExpr); + stsSingleExpr.addChild(stsThisExpression).setParent(stsSingleExpr); + + if (stsTypeRef != null) { + stsThisExpression.addChild(stsTypeRef).setParent(stsThisExpression); + } + stsThisExpression.addChild(terminalNode(StaticTSParser.This)); + + return stsSingleExpr; + } + + public static SingleExpressionContext classLiteral(String className) { + // Sanity check + if (className == null) return null; + + SingleExpressionContext stsSingleExpr = new SingleExpressionContext(null, 0); + ClassLiteralExpressionContext stsClassLiteral = new ClassLiteralExpressionContext(stsSingleExpr); + stsSingleExpr.addChild(stsClassLiteral).setParent(stsSingleExpr); + + // NOTE: Class literal requires PrimaryTypeContext! + // | primaryType Dot Class # ClassLiteralExpression + PrimaryTypeContext stsPrimaryType = new PrimaryTypeContext(stsClassLiteral, 0); + stsPrimaryType.addChild(typeReference(className)).setParent(stsPrimaryType); + stsClassLiteral.addChild(stsPrimaryType).setParent(stsClassLiteral); + + stsClassLiteral.addChild(terminalNode(StaticTSParser.Dot)); + stsClassLiteral.addChild(terminalNode(StaticTSParser.Class)); + + return stsSingleExpr; + } } diff --git a/migrator/test/java/synchronized_methods.java b/migrator/test/java/synchronized_methods.java new file mode 100644 index 000000000..5ade2cd3c --- /dev/null +++ b/migrator/test/java/synchronized_methods.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +class synchronized_methods { + int count; + synchronized void bump() { + count++; + } + + static int classCount; + static synchronized void classBump() { + classCount++; + } + + public static void main(String[] args) { + synchronized_methods t = new synchronized_methods() { + private int anonCount; + public synchronized void bump() { anonCount++; } + }; + } +} diff --git a/migrator/test/java/synchronized_methods.java.sts b/migrator/test/java/synchronized_methods.java.sts new file mode 100644 index 000000000..b0de0936a --- /dev/null +++ b/migrator/test/java/synchronized_methods.java.sts @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +open class synchronized_methods { + count : int ; + open bump(): void { + MonitorEnter(this); + defer MonitorExit(this); + count++; + } + + static classCount : int ; + static classBump(): void { + MonitorEnter(synchronized_methods.class); + defer MonitorExit(synchronized_methods.class); + classCount++; + } + + public static main(args : String[]): void { + let t : synchronized_methods = new synchronized_methods() { + private anonCount : int ; + public override bump(): void { + MonitorEnter(this); + defer MonitorExit(this); + anonCount++; + } + }; + } +} -- Gitee From 821456656c8f1768b252c86a5c07966b2dc259e5 Mon Sep 17 00:00:00 2001 From: Mikhail Velikanov Date: Thu, 1 Sep 2022 12:27:45 +0300 Subject: [PATCH 3/3] Fixed possible NPEs in lambda translation. Added command-line option -noxrefs to avoid processing all input sources as source references (i.e. block resolution of crossreferences in input sources). The latter is needed to speedup processing of some benchmarks. Change-Id: I8b29d83f778960f522f1a87659e0436ae04b293c Signed-off-by: Mikhail Velikanov --- migrator/src/com/ohos/migrator/Main.java | 5 +- .../com/ohos/migrator/java/JavaParser.java | 7 +- .../ohos/migrator/java/JavaTransformer.java | 67 +++++++++++++++++-- .../ohos/migrator/java/JavaTranspiler.java | 13 ++-- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/migrator/src/com/ohos/migrator/Main.java b/migrator/src/com/ohos/migrator/Main.java index 5141f4c3d..cacf67668 100644 --- a/migrator/src/com/ohos/migrator/Main.java +++ b/migrator/src/com/ohos/migrator/Main.java @@ -84,7 +84,7 @@ public class Main { options.addOption(new Option("l","libs",true, "List of libraries separate with commas")); options.addOption(new Option("T","check-sts-syntax",false,"Check syntactical correctness of StaticTS sources")); options.addOption(new Option("R", "conversion-rate", false, "Report conversion rate")); - + options.addOption(new Option("noxrefs", "noxrefs", false, "Don't resolve cross-references in the input source files")); options.addOption(new Option("verbose","verbose",false,"Prints extended diagnostic messages")); options.addOption(new Option("v","version",false,"Version information")); @@ -185,11 +185,12 @@ public class Main { double convRate = 0.; int numLanguages = 0; + boolean noxrefs = cmd.hasOption("noxrefs"); if (!javaSources.isEmpty()) { System.out.println("Transpiling " + javaSources.size() + " Java files."); - JavaTranspiler javaTranspiler = new JavaTranspiler(javaSources, jarLibs, outDir); + JavaTranspiler javaTranspiler = new JavaTranspiler(javaSources, jarLibs, outDir, noxrefs); resultCode = javaTranspiler.transpile(); outFiles.addAll(javaTranspiler.getOutFiles()); errorList.addAll(javaTranspiler.getErrorList()); diff --git a/migrator/src/com/ohos/migrator/java/JavaParser.java b/migrator/src/com/ohos/migrator/java/JavaParser.java index f2cc113e4..214f4c7cb 100644 --- a/migrator/src/com/ohos/migrator/java/JavaParser.java +++ b/migrator/src/com/ohos/migrator/java/JavaParser.java @@ -59,11 +59,12 @@ public class JavaParser { * parser's 'sourcepaths' setting. * @param classpaths List of paths to jar files or directories with '.class' files. */ - public JavaParser(File sourceFile, List sourceFiles, List classpaths) throws IOException { + public JavaParser(File sourceFile, List sourceFiles, List classpaths, boolean noxrefs) throws IOException { this(sourceFile); - // Compute reference source paths once - if (sourcepathEntries == null) + // Compute reference source paths once, unless + // explicitly prohibited by command-line option + if (!noxrefs && sourcepathEntries == null) setSourcepathEntries(sourceFiles); setClasspathEntries(classpaths); diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index d709a6d32..057415c05 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -15,6 +15,8 @@ package com.ohos.migrator.java; +import com.ohos.migrator.Main; +import com.ohos.migrator.ResultCode; import com.ohos.migrator.Transformer; import com.ohos.migrator.staticTS.NodeBuilder; import com.ohos.migrator.staticTS.parser.StaticTSParser; @@ -26,6 +28,7 @@ import org.antlr.v4.runtime.tree.TerminalNode; import org.eclipse.jdt.core.dom.*; import org.jetbrains.annotations.NotNull; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Stack; @@ -37,6 +40,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final CompilationUnit javaCU; private CompilationUnitContext stsCU; + private final File srcFile; private ParserRuleContext stsCurrent; private final Stack stsSaved = new Stack<>(); @@ -149,8 +153,9 @@ public class JavaTransformer extends ASTVisitor implements Transformer { popStatement(); // IterationStatement, StatementContext } - public JavaTransformer(CompilationUnit javaCU) { + public JavaTransformer(CompilationUnit javaCU, File srcFile) { this.javaCU = javaCU; + this.srcFile = srcFile; } public CompilationUnitContext transform() { @@ -172,6 +177,32 @@ public class JavaTransformer extends ASTVisitor implements Transformer { else if (node instanceof Type) ++countTypeTotal; } + + // TODO: Remove as translation of remaining Java AST nodes is implemented! + @Override + public boolean visit(TryStatement node) { + return false; + } + @Override + public boolean visit(ThrowStatement node) { + return false; + } + @Override + public boolean visit(ExpressionMethodReference node) { + return false; + } + @Override + public boolean visit(SuperMethodReference node) { + return false; + } + @Override + public boolean visit(TypeMethodReference node) { + return false; + } + @Override + public boolean visit(CreationReference node) { + return false; + } }); // Visit Java AST and construct StaticTS AST. @@ -1540,7 +1571,20 @@ public class JavaTransformer extends ASTVisitor implements Transformer { pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); IVariableBinding variableBinding = javaVariableDeclarationFragment.resolveBinding(); - translateType(variableBinding.getType()); + + if (variableBinding != null) { + translateType(variableBinding.getType()); + } + else { + // Warn and emit __UnknownType__ as variable type + String loc = srcFile.getPath() + ":" + javaCU.getLineNumber(javaVariableDeclarationFragment.getStartPosition()); + Main.addError(ResultCode.TranspileError, "Failed to resolve lambda parameter at " + loc); + + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference("__UnknownType__")).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + } + popCurrent(); // TypeAnnotationContext // Note: no need to process the "{ Dimension }" part, as the extra dimensions @@ -3221,7 +3265,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { public boolean visit(SimpleName javaName) { IBinding binding = javaName.resolveBinding(); - if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { + if (binding != null && binding.isEqualTo(javaVarBinding) && javaSwitchCase != currentSwitchCase) { javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); done = true; } @@ -3292,9 +3336,21 @@ public class JavaTransformer extends ASTVisitor implements Transformer { createStsParameterList(javaLambdaExpr.parameters()); IMethodBinding lambdaMethod = javaLambdaExpr.resolveMethodBinding(); - pushCurrent(new TypeAnnotationContext(stsCurrent, 0)); - translateType(lambdaMethod.getReturnType()); + + if (lambdaMethod != null) { + translateType(lambdaMethod.getReturnType()); + } + else { + // Warn and emit __UnknownType__ as return type + String loc = srcFile.getPath() + ":" + javaCU.getLineNumber(javaLambdaExpr.getStartPosition()); + Main.addError(ResultCode.TranspileError, "Failed to resolve lambda expression at " + loc); + + pushCurrent(new PrimaryTypeContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.typeReference("__UnknownType__")).setParent(stsCurrent); + popCurrent(); // PrimaryTypeContext + } + popCurrent(); // TypeAnnotationContext stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Arrow)); @@ -3454,7 +3510,6 @@ public class JavaTransformer extends ASTVisitor implements Transformer { // The list of not yet translated Java Expressions: // CreationReference, //?? ExpressionMethodReference, - // LambdaExpression, // SuperMethodReference, // TypeMethodReference // TryStatement diff --git a/migrator/src/com/ohos/migrator/java/JavaTranspiler.java b/migrator/src/com/ohos/migrator/java/JavaTranspiler.java index 3d00af70e..0579956ee 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTranspiler.java +++ b/migrator/src/com/ohos/migrator/java/JavaTranspiler.java @@ -37,8 +37,11 @@ import java.util.List; */ public class JavaTranspiler extends AbstractTranspiler { - public JavaTranspiler(List src, List libs, String outDir) { + + private boolean noxrefs = false; + public JavaTranspiler(List src, List libs, String outDir, boolean noxrefs) { super(src, libs, outDir); + this.noxrefs = noxrefs; } @Override @@ -46,7 +49,7 @@ public class JavaTranspiler extends AbstractTranspiler { try { CompilationUnit javaCU = parse(srcFile); - CompilationUnitContext stsCU = transform(javaCU); + CompilationUnitContext stsCU = transform(javaCU, srcFile); write(stsCU, srcFile); } catch (IOException e) { @@ -57,12 +60,12 @@ public class JavaTranspiler extends AbstractTranspiler { } private CompilationUnit parse(File srcFile) throws IOException, JavaParserException { - JavaParser parser = new JavaParser(srcFile, sourceFiles, libFiles); + JavaParser parser = new JavaParser(srcFile, sourceFiles, libFiles, noxrefs); return parser.parse(); } - private CompilationUnitContext transform(CompilationUnit javaCU) { - JavaTransformer transformer = new JavaTransformer(javaCU); + private CompilationUnitContext transform(CompilationUnit javaCU, File srcFile) { + JavaTransformer transformer = new JavaTransformer(javaCU, srcFile); return transformer.transform(); } -- Gitee