mirror of
https://github.com/cincheo/jsweet.git
synced 2025-12-15 15:29:22 +00:00
generate human-friendly lopping variable names
This commit is contained in:
parent
82ea42ddf5
commit
11e4b53f6d
@ -87,6 +87,7 @@ import org.jsweet.transpiler.util.JSDoc;
|
|||||||
import org.jsweet.transpiler.util.RollbackException;
|
import org.jsweet.transpiler.util.RollbackException;
|
||||||
import org.jsweet.transpiler.util.Util;
|
import org.jsweet.transpiler.util.Util;
|
||||||
|
|
||||||
|
import com.sun.source.tree.Tree;
|
||||||
import com.sun.source.tree.Tree.Kind;
|
import com.sun.source.tree.Tree.Kind;
|
||||||
import com.sun.tools.javac.code.Attribute;
|
import com.sun.tools.javac.code.Attribute;
|
||||||
import com.sun.tools.javac.code.Attribute.Compound;
|
import com.sun.tools.javac.code.Attribute.Compound;
|
||||||
@ -361,7 +362,9 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
|||||||
private boolean constructor = false;
|
private boolean constructor = false;
|
||||||
|
|
||||||
private boolean decoratorScope = false;
|
private boolean decoratorScope = false;
|
||||||
|
|
||||||
|
public Stack<ForeachLoopScope> foreachLoopContext;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -480,6 +483,16 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ForeachLoopScope {
|
||||||
|
public JCEnhancedForLoop loop;
|
||||||
|
public String variableName;
|
||||||
|
public String arrayName;
|
||||||
|
public ForeachLoopScope(JCEnhancedForLoop loop) {
|
||||||
|
super();
|
||||||
|
this.loop = loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Stack<ClassScope> scope = new Stack<>();
|
private Stack<ClassScope> scope = new Stack<>();
|
||||||
|
|
||||||
private boolean isAnnotationScope = false;
|
private boolean isAnnotationScope = false;
|
||||||
@ -4868,12 +4881,73 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getIndexVariableCount() {
|
||||||
|
return getScope().foreachLoopContext == null ? 0 : getScope().foreachLoopContext.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getGeneratedVariableNames() {
|
||||||
|
Set<String> names = new HashSet<>();
|
||||||
|
if (getScope().foreachLoopContext != null) {
|
||||||
|
getScope().foreachLoopContext.stream().forEach(s -> {
|
||||||
|
names.add(s.variableName);
|
||||||
|
if (s.arrayName != null) {
|
||||||
|
names.add(s.arrayName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getArrayVariableCount() {
|
||||||
|
return getScope().foreachLoopContext == null ? 0
|
||||||
|
: (int) getScope().foreachLoopContext.stream().filter(s -> s.arrayName != null).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFreeVariableName(String variablePrefix, int index) {
|
||||||
|
String name = variablePrefix + (index == 0 ? "" : "" + index);
|
||||||
|
System.out.println("candidate name: " + name);
|
||||||
|
|
||||||
|
Set<String> generatedVariableNames = getGeneratedVariableNames();
|
||||||
|
|
||||||
|
while (generatedVariableNames.contains(name)) {
|
||||||
|
name = variablePrefix + (++index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int position = stack.size() - 2;
|
||||||
|
while(position >= 0 && !(stack.get(position) instanceof JCMethodDecl)) {
|
||||||
|
if (stack.get(position) instanceof JCBlock) {
|
||||||
|
JCBlock block = (JCBlock)stack.get(position);
|
||||||
|
// analyze all the previous declarations in the block
|
||||||
|
for (JCTree t : block.stats) {
|
||||||
|
if (t == stack.get(position + 1)) {
|
||||||
|
// do not analyze post declarations
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// name clash: we try again with another index
|
||||||
|
if (t instanceof JCVariableDecl && name.equals(((JCVariableDecl)t).name.toString())) {
|
||||||
|
return getFreeVariableName(variablePrefix, index + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
position--;
|
||||||
|
}
|
||||||
|
if (position >= 0 && stack.get(position) instanceof JCMethodDecl) {
|
||||||
|
for (JCVariableDecl param : ((JCMethodDecl)stack.get(position)).params) {
|
||||||
|
if (name.equals(param.name.toString())) {
|
||||||
|
// name clash with method parameters
|
||||||
|
return getFreeVariableName(variablePrefix, index + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints a foreach loop tree.
|
* Prints a foreach loop tree.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void visitForeachLoop(JCEnhancedForLoop foreachLoop) {
|
public void visitForeachLoop(JCEnhancedForLoop foreachLoop) {
|
||||||
String indexVarName = "index" + Util.getId();
|
String indexVarName = getFreeVariableName("index", getIndexVariableCount());
|
||||||
boolean[] hasLength = { false };
|
boolean[] hasLength = { false };
|
||||||
TypeSymbol targetType = foreachLoop.expr.type.tsym;
|
TypeSymbol targetType = foreachLoop.expr.type.tsym;
|
||||||
Util.scanMemberDeclarationsInType(targetType, getAdapter().getErasedTypes(), element -> {
|
Util.scanMemberDeclarationsInType(targetType, getAdapter().getErasedTypes(), element -> {
|
||||||
@ -4887,19 +4961,26 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
|||||||
});
|
});
|
||||||
if (!getAdapter().substituteForEachLoop(new ForeachLoopElementSupport(foreachLoop), hasLength[0],
|
if (!getAdapter().substituteForEachLoop(new ForeachLoopElementSupport(foreachLoop), hasLength[0],
|
||||||
indexVarName)) {
|
indexVarName)) {
|
||||||
|
if (getScope().foreachLoopContext == null) {
|
||||||
|
getScope().foreachLoopContext = new Stack<>();
|
||||||
|
}
|
||||||
|
ForeachLoopScope foreachLoopScope = new ForeachLoopScope(foreachLoop);
|
||||||
|
getScope().foreachLoopContext.push(foreachLoopScope);
|
||||||
boolean noVariable = foreachLoop.expr instanceof JCIdent || foreachLoop.expr instanceof JCFieldAccess;
|
boolean noVariable = foreachLoop.expr instanceof JCIdent || foreachLoop.expr instanceof JCFieldAccess;
|
||||||
|
foreachLoopScope.variableName = indexVarName;
|
||||||
if (noVariable) {
|
if (noVariable) {
|
||||||
print("for(" + VAR_DECL_KEYWORD + " " + indexVarName + "=0; " + indexVarName + " < ")
|
print("for(" + VAR_DECL_KEYWORD + " " + indexVarName + " = 0; " + indexVarName + " < ")
|
||||||
.print(foreachLoop.expr).print("." + "length" + "; " + indexVarName + "++) {").println()
|
.print(foreachLoop.expr).print("." + "length" + "; " + indexVarName + "++) {").println()
|
||||||
.startIndent().printIndent();
|
.startIndent().printIndent();
|
||||||
print(VAR_DECL_KEYWORD + " " + avoidJSKeyword(foreachLoop.var.name.toString()) + " = ")
|
print(VAR_DECL_KEYWORD + " " + avoidJSKeyword(foreachLoop.var.name.toString()) + " = ")
|
||||||
.print(foreachLoop.expr).print("[" + indexVarName + "];").println();
|
.print(foreachLoop.expr).print("[" + indexVarName + "];").println();
|
||||||
} else {
|
} else {
|
||||||
String arrayVarName = "array" + Util.getId();
|
String arrayVarName = getFreeVariableName("array", getArrayVariableCount());
|
||||||
|
foreachLoopScope.arrayName = arrayVarName;
|
||||||
print("{").println().startIndent().printIndent();
|
print("{").println().startIndent().printIndent();
|
||||||
print(VAR_DECL_KEYWORD + " " + arrayVarName + " = ").print(foreachLoop.expr).print(";").println()
|
print(VAR_DECL_KEYWORD + " " + arrayVarName + " = ").print(foreachLoop.expr).print(";").println()
|
||||||
.printIndent();
|
.printIndent();
|
||||||
print("for(" + VAR_DECL_KEYWORD + " " + indexVarName + "=0; " + indexVarName + " < " + arrayVarName
|
print("for(" + VAR_DECL_KEYWORD + " " + indexVarName + " = 0; " + indexVarName + " < " + arrayVarName
|
||||||
+ ".length; " + indexVarName + "++) {").println().startIndent().printIndent();
|
+ ".length; " + indexVarName + "++) {").println().startIndent().printIndent();
|
||||||
print(VAR_DECL_KEYWORD + " " + avoidJSKeyword(foreachLoop.var.name.toString()) + " = " + arrayVarName
|
print(VAR_DECL_KEYWORD + " " + avoidJSKeyword(foreachLoop.var.name.toString()) + " = " + arrayVarName
|
||||||
+ "[" + indexVarName + "];").println();
|
+ "[" + indexVarName + "];").println();
|
||||||
@ -4910,6 +4991,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
|||||||
if (!noVariable) {
|
if (!noVariable) {
|
||||||
endIndent().println().printIndent().print("}");
|
endIndent().println().printIndent().print("}");
|
||||||
}
|
}
|
||||||
|
getScope().foreachLoopContext.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -111,15 +111,6 @@ public class Util {
|
|||||||
private Util() {
|
private Util() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long id = 121;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a unique id (incremental).
|
|
||||||
*/
|
|
||||||
public static long getId() {
|
|
||||||
return id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells if the given element is within the Java sources being compiled.
|
* Tells if the given element is within the Java sources being compiled.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -61,8 +61,54 @@ public class Looping {
|
|||||||
System.out.println(">"+i);
|
System.out.println(">"+i);
|
||||||
assert i==-1;
|
assert i==-1;
|
||||||
|
|
||||||
|
int[] array = new int[] { 1, 2, 3 };
|
||||||
|
int pos = 1;
|
||||||
|
for (int integer : array) {
|
||||||
|
assert integer == pos;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 1;
|
||||||
|
for (int integer : array) {
|
||||||
|
assert integer == pos;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nested loops
|
||||||
|
pos = 1;
|
||||||
|
for (int integer : array) {
|
||||||
|
assert integer == pos;
|
||||||
|
pos++;
|
||||||
|
int pos2 = 1;
|
||||||
|
int index1 = 4;
|
||||||
|
for (int integer2 : array) {
|
||||||
|
assert integer2 == pos2;
|
||||||
|
assert index1 == 4;
|
||||||
|
pos2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test clash between iteration variable and local variable
|
||||||
|
int index = 12;
|
||||||
|
pos = 1;
|
||||||
|
for (int integer : array) {
|
||||||
|
assert index == 12;
|
||||||
|
assert integer == pos;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop(array, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void loop(int[] array, int index) {
|
||||||
|
int pos = 1;
|
||||||
|
for (int integer : array) {
|
||||||
|
assert index == 14;
|
||||||
|
assert integer == pos;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
|
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
|
||||||
Collection<String> c = null;
|
Collection<String> c = null;
|
||||||
// TODO: Java accepts this assignment without casting but TypeScript
|
// TODO: Java accepts this assignment without casting but TypeScript
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user