Don't produce keywords for label names

This commit is contained in:
Alexey Andreev 2017-03-17 16:41:35 +03:00
parent 6c97f8afe3
commit b28f5a6b71
3 changed files with 51 additions and 38 deletions

View File

@ -15,18 +15,15 @@
*/
package org.teavm.backend.javascript.codegen;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.teavm.backend.javascript.rendering.RenderingUtil;
import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
public class MinifyingAliasProvider implements AliasProvider {
private static final Set<String> keywords = new HashSet<>(Arrays.asList("do", "if", "else", "for", "case",
"goto", "in", "let", "new", "this", "try", "var", "void", "with"));
private static final String startLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final String startVirtualLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private int lastSuffix;
private int lastVirtual;
@ -36,8 +33,8 @@ public class MinifyingAliasProvider implements AliasProvider {
public String getFieldAlias(FieldReference field) {
String result;
do {
result = getNewAlias(lastVirtual++, startVirtualLetters);
} while (!usedAliases.add(result) || keywords.contains(result));
result = RenderingUtil.indexToId(lastVirtual++, startVirtualLetters);
} while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result;
}
@ -45,43 +42,32 @@ public class MinifyingAliasProvider implements AliasProvider {
public String getStaticFieldAlias(FieldReference field) {
String result;
do {
result = getNewAlias(lastSuffix++, startLetters);
} while (!usedAliases.add(result) || keywords.contains(result));
result = RenderingUtil.indexToId(lastSuffix++, startLetters);
} while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result;
}
@Override
public String getStaticMethodAlias(MethodReference method) {
return getNewAlias(lastSuffix++, startLetters);
return RenderingUtil.indexToId(lastSuffix++, startLetters);
}
@Override
public String getMethodAlias(MethodDescriptor method) {
String result;
do {
result = getNewAlias(lastVirtual++, startVirtualLetters);
} while (!usedAliases.add(result) || keywords.contains(result));
result = RenderingUtil.indexToId(lastVirtual++, startVirtualLetters);
} while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result;
}
@Override
public String getClassAlias(String className) {
return getNewAlias(lastSuffix++, startLetters);
return RenderingUtil.indexToId(lastSuffix++, startLetters);
}
@Override
public String getFunctionAlias(String className) {
return getNewAlias(lastSuffix++, startLetters);
}
private String getNewAlias(int index, String startLetters) {
StringBuilder sb = new StringBuilder();
sb.append(startLetters.charAt(index % startLetters.length()));
index /= startLetters.length();
while (index > 0) {
sb.append(letters.charAt(index % letters.length()));
index /= letters.length();
}
return sb.toString();
return RenderingUtil.indexToId(lastSuffix++, startLetters);
}
}

View File

@ -15,9 +15,18 @@
*/
package org.teavm.backend.javascript.rendering;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public final class RenderingUtil {
private static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
private static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
public static final Set<String> KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("break", "case",
"catch", "class", "const", "continue", "debugger", "default", "delete", "do", "else", "export",
"extends", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "return",
"super", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "yield")));
public static final String VARIABLE_START_CHARS = "abcdefghijklmnopqrstuvwxyz";
public static final String VARIABLE_PART_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
private RenderingUtil() {
}
@ -73,14 +82,18 @@ public final class RenderingUtil {
return sb.toString();
}
public static String indexToId(int index) {
public static String indexToId(int index, String startChars) {
StringBuilder sb = new StringBuilder();
sb.append(variableNames.charAt(index % variableNames.length()));
index /= variableNames.length();
sb.append(startChars.charAt(index % startChars.length()));
index /= startChars.length();
while (index > 0) {
sb.append(variablePartNames.charAt(index % variablePartNames.length()));
index /= variablePartNames.length();
sb.append(VARIABLE_PART_CHARS.charAt(index % VARIABLE_PART_CHARS.length()));
index /= VARIABLE_PART_CHARS.length();
}
return sb.toString();
}
public static String indexToId(int index) {
return indexToId(index, VARIABLE_START_CHARS);
}
}

View File

@ -15,9 +15,10 @@
*/
package org.teavm.backend.javascript.rendering;
import com.carrotsearch.hppc.IntArrayList;
import com.carrotsearch.hppc.IntIndexedContainer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -83,10 +84,6 @@ import org.teavm.model.ValueType;
import org.teavm.vm.RenderingException;
public class StatementRenderer implements ExprVisitor, StatementVisitor {
private static final Set<String> keywords = new HashSet<>(Arrays.asList("break", "case", "catch",
"class", "const", "continue", "debugger", "default", "delete", "do", "else", "export",
"extends", "finally", "for", "function", "if", "import", "in", "instanceof", "new", "return",
"super", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "yield"));
private RenderingContext context;
private SourceWriter writer;
private ClassReaderSource classSource;
@ -103,6 +100,8 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
private final Set<String> usedVariableNames = new HashSet<>();
private MethodNode currentMethod;
private int currentPart;
private List<String> blockIds = new ArrayList<>();
private IntIndexedContainer blockIndexMap = new IntArrayList();
public StatementRenderer(RenderingContext context, SourceWriter writer) {
this.context = context;
@ -307,12 +306,27 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
String name = blockIdMap.get(id);
if (name == null) {
int index = blockIdMap.size();
name = RenderingUtil.indexToId(index);
name = generateBlockId(index);
blockIdMap.put(id, name);
}
return name;
}
private String generateBlockId(int index) {
int mappedIndex;
while (blockIds.size() <= index) {
mappedIndex = blockIndexMap.isEmpty() ? -1 : blockIndexMap.get(blockIds.size());
mappedIndex++;
while (RenderingUtil.KEYWORDS.contains(RenderingUtil.indexToId(mappedIndex))) {
mappedIndex++;
}
blockIndexMap.add(mappedIndex);
blockIds.add(RenderingUtil.indexToId(mappedIndex));
}
mappedIndex = blockIndexMap.get(index);
return blockIds.get(mappedIndex);
}
@Override
public void visit(BlockStatement statement) {
try {
@ -459,7 +473,7 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
: null;
if (variable != null && variable.getName() != null) {
String result = "$" + RenderingUtil.escapeName(variable.getName());
if (keywords.contains(result) || !usedVariableNames.add(result)) {
if (RenderingUtil.KEYWORDS.contains(result) || !usedVariableNames.add(result)) {
String base = result;
int suffix = 0;
do {