mirror of
https://github.com/cincheo/jsweet.git
synced 2025-12-14 23:09: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.Util;
|
||||
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.tree.Tree.Kind;
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Attribute.Compound;
|
||||
@ -361,7 +362,9 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
private boolean constructor = false;
|
||||
|
||||
private boolean decoratorScope = false;
|
||||
|
||||
|
||||
public Stack<ForeachLoopScope> foreachLoopContext;
|
||||
|
||||
public String getName() {
|
||||
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 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.
|
||||
*/
|
||||
@Override
|
||||
public void visitForeachLoop(JCEnhancedForLoop foreachLoop) {
|
||||
String indexVarName = "index" + Util.getId();
|
||||
String indexVarName = getFreeVariableName("index", getIndexVariableCount());
|
||||
boolean[] hasLength = { false };
|
||||
TypeSymbol targetType = foreachLoop.expr.type.tsym;
|
||||
Util.scanMemberDeclarationsInType(targetType, getAdapter().getErasedTypes(), element -> {
|
||||
@ -4887,19 +4961,26 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
});
|
||||
if (!getAdapter().substituteForEachLoop(new ForeachLoopElementSupport(foreachLoop), hasLength[0],
|
||||
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;
|
||||
foreachLoopScope.variableName = indexVarName;
|
||||
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()
|
||||
.startIndent().printIndent();
|
||||
print(VAR_DECL_KEYWORD + " " + avoidJSKeyword(foreachLoop.var.name.toString()) + " = ")
|
||||
.print(foreachLoop.expr).print("[" + indexVarName + "];").println();
|
||||
} else {
|
||||
String arrayVarName = "array" + Util.getId();
|
||||
String arrayVarName = getFreeVariableName("array", getArrayVariableCount());
|
||||
foreachLoopScope.arrayName = arrayVarName;
|
||||
print("{").println().startIndent().printIndent();
|
||||
print(VAR_DECL_KEYWORD + " " + arrayVarName + " = ").print(foreachLoop.expr).print(";").println()
|
||||
.printIndent();
|
||||
print("for(" + VAR_DECL_KEYWORD + " " + indexVarName + "=0; " + indexVarName + " < " + arrayVarName
|
||||
print("for(" + VAR_DECL_KEYWORD + " " + indexVarName + " = 0; " + indexVarName + " < " + arrayVarName
|
||||
+ ".length; " + indexVarName + "++) {").println().startIndent().printIndent();
|
||||
print(VAR_DECL_KEYWORD + " " + avoidJSKeyword(foreachLoop.var.name.toString()) + " = " + arrayVarName
|
||||
+ "[" + indexVarName + "];").println();
|
||||
@ -4910,6 +4991,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
if (!noVariable) {
|
||||
endIndent().println().printIndent().print("}");
|
||||
}
|
||||
getScope().foreachLoopContext.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -111,15 +111,6 @@ public class 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.
|
||||
*/
|
||||
|
||||
@ -61,8 +61,54 @@ public class Looping {
|
||||
System.out.println(">"+i);
|
||||
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) {
|
||||
Collection<String> c = null;
|
||||
// TODO: Java accepts this assignment without casting but TypeScript
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user