various fixes

- const analyzer made global to work with default methods
- equals substitution ensures that argument is parenthesized if needed (test added)
This commit is contained in:
Renaud Pawlak 2020-07-04 09:52:31 +02:00
parent 87fb4f41ff
commit b5a4795a34
6 changed files with 54 additions and 13 deletions

View File

@ -19,6 +19,7 @@
package org.jsweet.transpiler;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.ElementKind;
@ -27,6 +28,7 @@ import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCAssignOp;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCUnary;
import com.sun.tools.javac.tree.TreeScanner;
@ -81,4 +83,13 @@ public class ConstAnalyzer extends TreeScanner {
super.visitUnary(unary);
}
/**
* Scans a given compilation unit list.
*/
public void process(List<JCCompilationUnit> cuList) {
for (JCCompilationUnit cu : cuList) {
scan(cu);
}
}
}

View File

@ -116,6 +116,17 @@ public class JSweetContext extends Context {
}
}
/**
* The constant variables (variables assigned only at initialization) scanner
* and accessor.
*
* <p>TODO: This scanner is run globally (for all compilation units) before
* translation. It could be run locally to each compilation unit, except for
* default methods that are injected in the target classes.
*/
public ConstAnalyzer constAnalyzer = null;
private Map<String, TypeMirror> jdkSubclasses = new HashMap<>();
public StaticInitilializerAnalyzer referenceAnalyzer;

View File

@ -991,6 +991,8 @@ public class JSweetTranspiler implements JSweetOptions {
List<JCCompilationUnit> compilationUnits) throws IOException {
// regular file-to-file generation
new OverloadScanner(transpilationHandler, context).process(compilationUnits);
context.constAnalyzer = new ConstAnalyzer();
context.constAnalyzer.scan(compilationUnits);
if (isVerbose()) {
context.dumpOverloads(System.out);
@ -1123,7 +1125,9 @@ public class JSweetTranspiler implements JSweetOptions {
}
new OverloadScanner(transpilationHandler, context).process(orderedCompilationUnits);
context.constAnalyzer = new ConstAnalyzer();
context.constAnalyzer.process(orderedCompilationUnits);
adapter.onTranspilationStarted();
logger.debug("ordered compilation units: " + orderedCompilationUnits.stream().map(cu -> {

View File

@ -483,8 +483,6 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
private boolean isDefinitionScope = false;
private ConstAnalyzer constAnalyzer = null;
protected final boolean isTopLevelScope() {
return getIndent() == 0;
}
@ -739,8 +737,6 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
footer.delete(0, footer.length());
setCompilationUnit(topLevel);
constAnalyzer = new ConstAnalyzer();
constAnalyzer.scan(topLevel);
String packge = topLevel.packge.toString();
@ -2965,9 +2961,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
printInstanceInitialization(getParent(JCClassDecl.class), method.sym);
}
if (!stats.tail.isEmpty()) {
printIndent().print("((").print(") => {").startIndent().println();
printBlockStatements(stats.tail);
endIndent().printIndent().print("})(").print(");").println();
}
} else {
if (!initialized) {
@ -3436,8 +3430,8 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
if (isDefinitionScope) {
print("var ");
} else {
if (!isLazyInitialized(varDecl.sym) && ((!globals && constAnalyzer != null
&& !constAnalyzer.getModifiedVariables().contains(varDecl.sym))
if (!isLazyInitialized(varDecl.sym) && ((!globals && context.constAnalyzer != null
&& !context.constAnalyzer.getModifiedVariables().contains(varDecl.sym))
|| (globals && varDecl.sym.getModifiers().contains(Modifier.FINAL)
&& varDecl.init != null))) {
print("const ");

View File

@ -1289,12 +1289,22 @@ public class Java2TypeScriptAdapter extends PrinterAdapter {
TypeMirror t1 = util().toPrimitiveTypeOrType(invocationElement.getTargetExpression().getType());
TypeMirror t2 = util().toPrimitiveTypeOrType(invocationElement.getArgument(0).getType());
if (types().isSameType(t1, t2) && util().isCoreType(t1)) {
if(isInlinedExpression(invocationElement)) {
if (isInlinedExpression(invocationElement)) {
print("(");
}
print(invocationElement.getTargetExpression()).print(" === ")
.print(invocationElement.getArgument(0));
if(isInlinedExpression(invocationElement)) {
print(invocationElement.getTargetExpression()).print(" === ");
ExtendedElement arg = invocationElement.getArgument(0);
boolean inlinable = arg instanceof VariableAccessElement
|| (arg instanceof MethodInvocationElement
&& !"equals".equals(((MethodInvocationElement) arg).getMethodName()));
if (!inlinable) {
print("(");
}
print(invocationElement.getArgument(0));
if (!inlinable) {
print(")");
}
if (isInlinedExpression(invocationElement)) {
print(")");
}
} else {

View File

@ -8,6 +8,12 @@ public class Equals {
static Array<String> trace = new Array<String>();
static Integer int1 = 0;
static Integer int2 = 0;
static Integer int3 = 0;
static Integer int4 = 0;
static Integer int5 = 0;
public static void main(String[] args) {
trace.push("" + equals("a", "b"));
trace.push("" + equals("a", "a"));
@ -20,6 +26,11 @@ public class Equals {
MyObject2 o = new MyObject2("a");
trace.push("" + equals(o, o));
$export("trace", trace.join(","));
// ensures that this kind of test works fine
if (!int1.equals(int2 == int3
? int4
: int5)) {
}
}
public static boolean equals(Object a, Object b) {