From e84a1b0bae64a2952357f5c4f4c093a50ffccd65 Mon Sep 17 00:00:00 2001 From: Renaud Pawlak Date: Thu, 4 Jun 2020 09:07:08 +0200 Subject: [PATCH] add parenthesis for binary/unary operator arguments when necessary --- .../transpiler/Java2TypeScriptTranslator.java | 3 +++ .../extension/Java2TypeScriptAdapter.java | 6 +++++ .../transpiler/extension/PrinterAdapter.java | 12 +++++++++ .../transpiler/util/AbstractTreePrinter.java | 26 +++++++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java b/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java index e682070d..b34ca1a3 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java @@ -4949,10 +4949,12 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { } protected void printBinaryRightOperand(JCBinary binary) { + addInlinedExpression(binary.rhs); print(binary.rhs); } protected void printBinaryLeftOperand(JCBinary binary) { + addInlinedExpression(binary.lhs); print(binary.lhs); } @@ -5272,6 +5274,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { @Override public void visitUnary(JCUnary unary) { if (!getAdapter().substituteUnaryOperator(new UnaryOperatorElementSupport(unary))) { + addInlinedExpression(unary.arg); if (!inRollback) { JCStatement statement = null; VarSymbol[] staticInitializedField = { null }; diff --git a/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java b/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java index d9165b42..81752945 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/extension/Java2TypeScriptAdapter.java @@ -1289,8 +1289,14 @@ public class Java2TypeScriptAdapter extends PrinterAdapter { if (types().isSameType(invocationElement.getTargetExpression().getType(), util().getType(String.class)) || util().isNumber(invocationElement.getTargetExpression().getType())) { + if(isInlinedExpression(invocationElement)) { + print("("); + } print(invocationElement.getTargetExpression()).print(" === ") .print(invocationElement.getArgument(0)); + if(isInlinedExpression(invocationElement)) { + print(")"); + } } else { printMacroName(targetMethodName); print("(((o1: any, o2: any) => { if(o1 && o1.equals) { return o1.equals(o2); } else { return o1 === o2; } })("); diff --git a/transpiler/src/main/java/org/jsweet/transpiler/extension/PrinterAdapter.java b/transpiler/src/main/java/org/jsweet/transpiler/extension/PrinterAdapter.java index 3f299181..e4b1b85b 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/extension/PrinterAdapter.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/extension/PrinterAdapter.java @@ -1177,4 +1177,16 @@ public class PrinterAdapter { public final String getHeader(String key) { return context.getHeader(key); } + + /** + * Tells if this element is an inlined expression. An inlined expression + * typically requires parenthesis (on contrary to top-level statement for instance). + * + * @param element the element to check + * @return true if an inlined expression + */ + public final boolean isInlinedExpression(ExtendedElement element) { + return printer.isInlinedExpression(((ExtendedElementSupport) element).getTree()); + } + } diff --git a/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreePrinter.java b/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreePrinter.java index fbc6403e..3714b63e 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreePrinter.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/util/AbstractTreePrinter.java @@ -18,7 +18,9 @@ */ package org.jsweet.transpiler.util; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.Stack; import java.util.function.Consumer; @@ -51,6 +53,30 @@ public abstract class AbstractTreePrinter extends AbstractTreeScanner { private Stack positionStack = new Stack<>(); + private Set inlinedExpressions = new HashSet(); + + /** + * Tells if the given expression is an inlined expression + * (and would require parenthesis). + */ + public boolean isInlinedExpression(JCTree tree) { + return this.inlinedExpressions.contains(tree); + } + + /** + * Adds an inlined expression. + */ + public void addInlinedExpression(JCTree tree) { + this.inlinedExpressions.add(tree); + } + + /** + * Clears the inlined expressions. + */ + public void clearInlinedExpression() { + this.inlinedExpressions.clear(); + } + /** * A footer to be printed at the end of the output. */