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; package org.teavm.backend.javascript.codegen;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.teavm.backend.javascript.rendering.RenderingUtil;
import org.teavm.model.FieldReference; import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
public class MinifyingAliasProvider implements AliasProvider { 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 startLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final String startVirtualLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final String startVirtualLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private int lastSuffix; private int lastSuffix;
private int lastVirtual; private int lastVirtual;
@ -36,8 +33,8 @@ public class MinifyingAliasProvider implements AliasProvider {
public String getFieldAlias(FieldReference field) { public String getFieldAlias(FieldReference field) {
String result; String result;
do { do {
result = getNewAlias(lastVirtual++, startVirtualLetters); result = RenderingUtil.indexToId(lastVirtual++, startVirtualLetters);
} while (!usedAliases.add(result) || keywords.contains(result)); } while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result; return result;
} }
@ -45,43 +42,32 @@ public class MinifyingAliasProvider implements AliasProvider {
public String getStaticFieldAlias(FieldReference field) { public String getStaticFieldAlias(FieldReference field) {
String result; String result;
do { do {
result = getNewAlias(lastSuffix++, startLetters); result = RenderingUtil.indexToId(lastSuffix++, startLetters);
} while (!usedAliases.add(result) || keywords.contains(result)); } while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result; return result;
} }
@Override @Override
public String getStaticMethodAlias(MethodReference method) { public String getStaticMethodAlias(MethodReference method) {
return getNewAlias(lastSuffix++, startLetters); return RenderingUtil.indexToId(lastSuffix++, startLetters);
} }
@Override @Override
public String getMethodAlias(MethodDescriptor method) { public String getMethodAlias(MethodDescriptor method) {
String result; String result;
do { do {
result = getNewAlias(lastVirtual++, startVirtualLetters); result = RenderingUtil.indexToId(lastVirtual++, startVirtualLetters);
} while (!usedAliases.add(result) || keywords.contains(result)); } while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result; return result;
} }
@Override @Override
public String getClassAlias(String className) { public String getClassAlias(String className) {
return getNewAlias(lastSuffix++, startLetters); return RenderingUtil.indexToId(lastSuffix++, startLetters);
} }
@Override @Override
public String getFunctionAlias(String className) { public String getFunctionAlias(String className) {
return getNewAlias(lastSuffix++, startLetters); return RenderingUtil.indexToId(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();
} }
} }

View File

@ -15,9 +15,18 @@
*/ */
package org.teavm.backend.javascript.rendering; 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 { public final class RenderingUtil {
private static final String variableNames = "abcdefghijkmnopqrstuvwxyz"; public static final Set<String> KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("break", "case",
private static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; "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() { private RenderingUtil() {
} }
@ -73,14 +82,18 @@ public final class RenderingUtil {
return sb.toString(); return sb.toString();
} }
public static String indexToId(int index) { public static String indexToId(int index, String startChars) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(variableNames.charAt(index % variableNames.length())); sb.append(startChars.charAt(index % startChars.length()));
index /= variableNames.length(); index /= startChars.length();
while (index > 0) { while (index > 0) {
sb.append(variablePartNames.charAt(index % variablePartNames.length())); sb.append(VARIABLE_PART_CHARS.charAt(index % VARIABLE_PART_CHARS.length()));
index /= variablePartNames.length(); index /= VARIABLE_PART_CHARS.length();
} }
return sb.toString(); 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; package org.teavm.backend.javascript.rendering;
import com.carrotsearch.hppc.IntArrayList;
import com.carrotsearch.hppc.IntIndexedContainer;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -83,10 +84,6 @@ import org.teavm.model.ValueType;
import org.teavm.vm.RenderingException; import org.teavm.vm.RenderingException;
public class StatementRenderer implements ExprVisitor, StatementVisitor { 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 RenderingContext context;
private SourceWriter writer; private SourceWriter writer;
private ClassReaderSource classSource; private ClassReaderSource classSource;
@ -103,6 +100,8 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
private final Set<String> usedVariableNames = new HashSet<>(); private final Set<String> usedVariableNames = new HashSet<>();
private MethodNode currentMethod; private MethodNode currentMethod;
private int currentPart; private int currentPart;
private List<String> blockIds = new ArrayList<>();
private IntIndexedContainer blockIndexMap = new IntArrayList();
public StatementRenderer(RenderingContext context, SourceWriter writer) { public StatementRenderer(RenderingContext context, SourceWriter writer) {
this.context = context; this.context = context;
@ -307,12 +306,27 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
String name = blockIdMap.get(id); String name = blockIdMap.get(id);
if (name == null) { if (name == null) {
int index = blockIdMap.size(); int index = blockIdMap.size();
name = RenderingUtil.indexToId(index); name = generateBlockId(index);
blockIdMap.put(id, name); blockIdMap.put(id, name);
} }
return 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 @Override
public void visit(BlockStatement statement) { public void visit(BlockStatement statement) {
try { try {
@ -459,7 +473,7 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
: null; : null;
if (variable != null && variable.getName() != null) { if (variable != null && variable.getName() != null) {
String result = "$" + RenderingUtil.escapeName(variable.getName()); String result = "$" + RenderingUtil.escapeName(variable.getName());
if (keywords.contains(result) || !usedVariableNames.add(result)) { if (RenderingUtil.KEYWORDS.contains(result) || !usedVariableNames.add(result)) {
String base = result; String base = result;
int suffix = 0; int suffix = 0;
do { do {