Move static fields from class scope to global scope

This commit is contained in:
Alexey Andreev 2016-04-17 13:26:29 +03:00
parent 2d79da7b1b
commit 894e39c59f
26 changed files with 291 additions and 665 deletions

View File

@ -17,8 +17,8 @@
<inspection_tool class="CloneCallsSuperClone" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="CloneDeclaresCloneNotSupported" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="CodeBlock2Expr" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantConditions" enabled="true" level="WARNING" enabled_by_default="true">
<scope name="classlib" level="WEAK WARNING" enabled="true">
<inspection_tool class="ConstantConditions" enabled="false" level="WARNING" enabled_by_default="false">
<scope name="classlib" level="WEAK WARNING" enabled="false">
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />
</scope>

View File

@ -26,18 +26,14 @@ import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
import org.teavm.model.instructions.ArrayElementType;
/**
*
* @author Alexey Andreev
*/
public class AstIO {
private static NodeModifier[] nodeModifiers = NodeModifier.values();
private static BinaryOperation[] binaryOperations = BinaryOperation.values();
private static UnaryOperation[] unaryOperations = UnaryOperation.values();
private static ArrayElementType[] arrayElementTypes = ArrayElementType.values();
private SymbolTable symbolTable;
private SymbolTable fileTable;
private Map<String, IdentifiedStatement> statementMap = new HashMap<>();
private static final NodeModifier[] nodeModifiers = NodeModifier.values();
private static final BinaryOperation[] binaryOperations = BinaryOperation.values();
private static final UnaryOperation[] unaryOperations = UnaryOperation.values();
private static final ArrayElementType[] arrayElementTypes = ArrayElementType.values();
private final SymbolTable symbolTable;
private final SymbolTable fileTable;
private final Map<String, IdentifiedStatement> statementMap = new HashMap<>();
public AstIO(SymbolTable symbolTable, SymbolTable fileTable) {
this.symbolTable = symbolTable;
@ -51,14 +47,7 @@ public class AstIO {
output.writeShort(var);
}
output.writeShort(method.getParameterDebugNames().size());
for (Set<String> debugNames : method.getParameterDebugNames()) {
output.writeShort(debugNames != null ? debugNames.size() : 0);
if (debugNames != null) {
for (String debugName : debugNames) {
output.writeUTF(debugName);
}
}
}
writeParameters(output, method);
try {
method.getBody().acceptVisitor(new NodeWriter(output));
} catch (IOExceptionWrapper e) {
@ -73,15 +62,7 @@ public class AstIO {
for (int i = 0; i < varCount; ++i) {
node.getVariables().add((int) input.readShort());
}
int paramDebugNameCount = input.readShort();
for (int i = 0; i < paramDebugNameCount; ++i) {
int debugNameCount = input.readShort();
Set<String> debugNames = new HashSet<>();
for (int j = 0; j < debugNameCount; ++j) {
debugNames.add(input.readUTF());
}
node.getParameterDebugNames().add(debugNames);
}
readParameters(input, node);
node.setBody(readStatement(input));
return node;
}
@ -93,14 +74,7 @@ public class AstIO {
output.writeShort(var);
}
output.writeShort(method.getParameterDebugNames().size());
for (Set<String> debugNames : method.getParameterDebugNames()) {
output.writeShort(debugNames != null ? debugNames.size() : 0);
if (debugNames != null) {
for (String debugName : debugNames) {
output.writeUTF(debugName);
}
}
}
writeParameters(output, method);
try {
output.writeShort(method.getBody().size());
for (int i = 0; i < method.getBody().size(); ++i) {
@ -111,6 +85,17 @@ public class AstIO {
}
}
private void writeParameters(DataOutput output, MethodNode method) throws IOException {
for (Set<String> debugNames : method.getParameterDebugNames()) {
output.writeShort(debugNames != null ? debugNames.size() : 0);
if (debugNames != null) {
for (String debugName : debugNames) {
output.writeUTF(debugName);
}
}
}
}
public AsyncMethodNode readAsync(DataInput input, MethodReference method) throws IOException {
AsyncMethodNode node = new AsyncMethodNode(method);
node.getModifiers().addAll(unpackModifiers(input.readInt()));
@ -118,6 +103,17 @@ public class AstIO {
for (int i = 0; i < varCount; ++i) {
node.getVariables().add((int) input.readShort());
}
readParameters(input, node);
int partCount = input.readShort();
for (int i = 0; i < partCount; ++i) {
AsyncMethodPart part = new AsyncMethodPart();
part.setStatement(readStatement(input));
node.getBody().add(part);
}
return node;
}
private void readParameters(DataInput input, MethodNode node) throws IOException {
int paramDebugNameCount = input.readShort();
for (int i = 0; i < paramDebugNameCount; ++i) {
int debugNameCount = input.readShort();
@ -127,13 +123,6 @@ public class AstIO {
}
node.getParameterDebugNames().add(debugNames);
}
int partCount = input.readShort();
for (int i = 0; i < partCount; ++i) {
AsyncMethodPart part = new AsyncMethodPart();
part.setStatement(readStatement(input));
node.getBody().add(part);
}
return node;
}
private int packModifiers(Set<NodeModifier> modifiers) {
@ -154,15 +143,15 @@ public class AstIO {
return modifiers;
}
class NodeWriter implements ExprVisitor, StatementVisitor {
private DataOutput output;
private class NodeWriter implements ExprVisitor, StatementVisitor {
private final DataOutput output;
public NodeWriter(DataOutput output) {
NodeWriter(DataOutput output) {
super();
this.output = output;
}
public void writeExpr(Expr expr) throws IOException {
void writeExpr(Expr expr) throws IOException {
writeLocation(expr.getLocation());
expr.acceptVisitor(this);
}
@ -515,8 +504,10 @@ public class AstIO {
@Override
public void visit(QualificationExpr expr) {
try {
output.writeByte(17);
writeExpr(expr.getQualified());
output.writeByte(expr.getQualified() != null ? 17 : 18);
if (expr.getQualified() != null) {
writeExpr(expr.getQualified());
}
output.writeInt(symbolTable.lookup(expr.getField().getClassName()));
output.writeInt(symbolTable.lookup(expr.getField().getFieldName()));
} catch (IOException e) {
@ -527,7 +518,7 @@ public class AstIO {
@Override
public void visit(NewExpr expr) {
try {
output.writeByte(18);
output.writeByte(19);
output.writeInt(symbolTable.lookup(expr.getConstructedClass()));
} catch (IOException e) {
throw new IOExceptionWrapper(e);
@ -537,7 +528,7 @@ public class AstIO {
@Override
public void visit(NewArrayExpr expr) {
try {
output.writeByte(19);
output.writeByte(20);
writeExpr(expr.getLength());
output.writeInt(symbolTable.lookup(expr.getType().toString()));
} catch (IOException e) {
@ -548,7 +539,7 @@ public class AstIO {
@Override
public void visit(NewMultiArrayExpr expr) {
try {
output.writeByte(20);
output.writeByte(21);
output.writeByte(expr.getDimensions().size());
for (Expr dimension : expr.getDimensions()) {
writeExpr(dimension);
@ -561,19 +552,9 @@ public class AstIO {
@Override
public void visit(InstanceOfExpr expr) {
try {
output.writeByte(21);
writeExpr(expr.getExpr());
output.writeInt(symbolTable.lookup(expr.getType().toString()));
} catch (IOException e) {
throw new IOExceptionWrapper(e);
}
}
@Override
public void visit(StaticClassExpr expr) {
try {
output.writeByte(22);
writeExpr(expr.getExpr());
output.writeInt(symbolTable.lookup(expr.getType().toString()));
} catch (IOException e) {
throw new IOExceptionWrapper(e);
@ -856,24 +837,31 @@ public class AstIO {
return parseInvocationExpr(InvocationType.DYNAMIC, input);
case 17: {
QualificationExpr expr = new QualificationExpr();
expr.setQualified(readExpr(input));
String className = symbolTable.at(input.readInt());
String fieldName = symbolTable.at(input.readInt());
expr.setField(new FieldReference(className, fieldName));
return expr;
}
case 18: {
QualificationExpr expr = new QualificationExpr();
expr.setQualified(readExpr(input));
String className = symbolTable.at(input.readInt());
String fieldName = symbolTable.at(input.readInt());
expr.setField(new FieldReference(className, fieldName));
return expr;
}
case 19: {
NewExpr expr = new NewExpr();
expr.setConstructedClass(symbolTable.at(input.readInt()));
return expr;
}
case 19: {
case 20: {
NewArrayExpr expr = new NewArrayExpr();
expr.setLength(readExpr(input));
expr.setType(ValueType.parse(symbolTable.at(input.readInt())));
return expr;
}
case 20: {
case 21: {
NewMultiArrayExpr expr = new NewMultiArrayExpr();
int dimensionCount = input.readByte();
for (int i = 0; i < dimensionCount; ++i) {
@ -882,17 +870,12 @@ public class AstIO {
expr.setType(ValueType.parse(symbolTable.at(input.readInt())));
return expr;
}
case 21: {
case 22: {
InstanceOfExpr expr = new InstanceOfExpr();
expr.setExpr(readExpr(input));
expr.setType(ValueType.parse(symbolTable.at(input.readInt())));
return expr;
}
case 22: {
StaticClassExpr expr = new StaticClassExpr();
expr.setType(ValueType.parse(symbolTable.at(input.readInt())));
return expr;
}
default:
throw new RuntimeException("Unknown expression type: " + type);
}
@ -911,10 +894,10 @@ public class AstIO {
return expr;
}
static class IOExceptionWrapper extends RuntimeException {
private static class IOExceptionWrapper extends RuntimeException {
private static final long serialVersionUID = -7566355431593608333L;
public IOExceptionWrapper(Throwable cause) {
IOExceptionWrapper(Throwable cause) {
super(cause);
}
}

View File

@ -22,18 +22,14 @@ import org.teavm.javascript.ast.*;
import org.teavm.model.MethodReference;
import org.teavm.parsing.ClassDateProvider;
/**
*
* @author Alexey Andreev
*/
public class DiskRegularMethodNodeCache implements MethodNodeCache {
private File directory;
private AstIO astIO;
private ClassDateProvider classDateProvider;
private Map<MethodReference, Item> cache = new HashMap<>();
private Map<MethodReference, AsyncItem> asyncCache = new HashMap<>();
private Set<MethodReference> newMethods = new HashSet<>();
private Set<MethodReference> newAsyncMethods = new HashSet<>();
private final File directory;
private final AstIO astIO;
private final ClassDateProvider classDateProvider;
private final Map<MethodReference, Item> cache = new HashMap<>();
private final Map<MethodReference, AsyncItem> asyncCache = new HashMap<>();
private final Set<MethodReference> newMethods = new HashSet<>();
private final Set<MethodReference> newAsyncMethods = new HashSet<>();
public DiskRegularMethodNodeCache(File directory, SymbolTable symbolTable, SymbolTable fileTable,
ClassDateProvider classDateProvider) {
@ -52,17 +48,7 @@ public class DiskRegularMethodNodeCache implements MethodNodeCache {
if (file.exists()) {
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
DataInput input = new DataInputStream(stream);
int depCount = input.readShort();
boolean dependenciesChanged = false;
for (int i = 0; i < depCount; ++i) {
String depClass = input.readUTF();
Date depDate = classDateProvider.getModificationDate(depClass);
if (depDate == null || depDate.after(new Date(file.lastModified()))) {
dependenciesChanged = true;
break;
}
}
if (!dependenciesChanged) {
if (!checkIfDependenciesChanged(input, file)) {
item.node = astIO.read(input, methodReference);
}
} catch (IOException e) {
@ -91,17 +77,7 @@ public class DiskRegularMethodNodeCache implements MethodNodeCache {
if (file.exists()) {
try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
DataInput input = new DataInputStream(stream);
int depCount = input.readShort();
boolean dependenciesChanged = false;
for (int i = 0; i < depCount; ++i) {
String depClass = input.readUTF();
Date depDate = classDateProvider.getModificationDate(depClass);
if (depDate == null || depDate.after(new Date(file.lastModified()))) {
dependenciesChanged = true;
break;
}
}
if (!dependenciesChanged) {
if (!checkIfDependenciesChanged(input, file)) {
item.node = astIO.readAsync(input, methodReference);
}
} catch (IOException e) {
@ -112,6 +88,18 @@ public class DiskRegularMethodNodeCache implements MethodNodeCache {
return item.node;
}
private boolean checkIfDependenciesChanged(DataInput input, File file) throws IOException {
int depCount = input.readShort();
for (int i = 0; i < depCount; ++i) {
String depClass = input.readUTF();
Date depDate = classDateProvider.getModificationDate(depClass);
if (depDate == null || depDate.after(new Date(file.lastModified()))) {
return true;
}
}
return false;
}
@Override
public void storeAsync(MethodReference methodReference, AsyncMethodNode node) {
AsyncItem item = new AsyncItem();
@ -159,8 +147,8 @@ public class DiskRegularMethodNodeCache implements MethodNodeCache {
+ (async ? "-async" : ""));
}
static class AstDependencyAnalyzer implements StatementVisitor, ExprVisitor {
Set<String> dependencies = new HashSet<>();
private static class AstDependencyAnalyzer implements StatementVisitor, ExprVisitor {
final Set<String> dependencies = new HashSet<>();
private void visitSequence(List<Statement> statements) {
for (Statement stmt : statements) {
@ -288,7 +276,9 @@ public class DiskRegularMethodNodeCache implements MethodNodeCache {
@Override
public void visit(QualificationExpr expr) {
dependencies.add(expr.getField().getClassName());
expr.getQualified().acceptVisitor(this);
if (expr.getQualified() != null) {
expr.getQualified().acceptVisitor(this);
}
}
@Override
@ -312,10 +302,6 @@ public class DiskRegularMethodNodeCache implements MethodNodeCache {
expr.getExpr().acceptVisitor(this);
}
@Override
public void visit(StaticClassExpr expr) {
}
@Override
public void visit(GotoPartStatement statement) {
}
@ -330,11 +316,11 @@ public class DiskRegularMethodNodeCache implements MethodNodeCache {
}
}
static class Item {
private static class Item {
RegularMethodNode node;
}
static class AsyncItem {
private static class AsyncItem {
AsyncMethodNode node;
}
}

View File

@ -19,18 +19,16 @@ import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public interface AliasProvider {
String getAlias(FieldReference field);
String getFieldAlias(FieldReference field);
String getAlias(MethodReference method);
String getStaticFieldAlias(FieldReference field);
String getAlias(MethodDescriptor method);
String getStaticMethodAlias(MethodReference method);
String getAlias(String className);
String getMethodAlias(MethodDescriptor method);
String getClassAlias(String className);
String getFunctionAlias(String name);
}

View File

@ -15,81 +15,88 @@
*/
package org.teavm.codegen;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class DefaultAliasProvider implements AliasProvider {
private int lastSuffix;
private int lastVirtualSuffix;
private Set<String> usedAliases = new HashSet<>();
private final Map<String, String> classAliases = new HashMap<>();
private final Set<String> knownAliases = new HashSet<>();
private final Set<String> knownVirtualAliases = new HashSet<>();
@Override
public String getAlias(String cls) {
StringBuilder alias = new StringBuilder();
int lastIndex = 0;
while (true) {
int index = cls.indexOf('.', lastIndex);
if (index == -1) {
if (lastIndex > 0) {
alias.append("_");
public String getClassAlias(String cls) {
return classAliases.computeIfAbsent(cls, key -> {
StringBuilder alias = new StringBuilder();
int lastIndex = 0;
while (true) {
int index = cls.indexOf('.', lastIndex);
if (index == -1) {
if (lastIndex > 0) {
alias.append("_");
}
alias.append(cls.substring(lastIndex));
break;
} else {
if (index > lastIndex) {
alias.append(cls.charAt(lastIndex));
}
lastIndex = index + 1;
}
alias.append(cls.substring(lastIndex));
break;
} else {
if (index > lastIndex) {
alias.append(cls.charAt(lastIndex));
}
lastIndex = index + 1;
}
}
alias.append(lastSuffix++);
return alias.toString();
return makeUnique(knownAliases, alias.toString());
});
}
@Override
public String getAlias(MethodDescriptor method) {
public String getMethodAlias(MethodDescriptor method) {
String alias = method.getName();
if (alias.equals("<init>")) {
alias = "$init";
} else if (alias.equals("<clinit>")) {
alias = "$clinit";
}
String result;
do {
result = alias + lastVirtualSuffix++;
} while (!usedAliases.add(result));
return result;
return makeUnique(knownVirtualAliases, alias);
}
@Override
public String getAlias(MethodReference method) {
public String getStaticMethodAlias(MethodReference method) {
String alias = method.getDescriptor().getName();
if (alias.equals("<init>")) {
alias = "$init";
} else if (alias.equals("<clinit>")) {
alias = "$clinit";
}
return alias + lastSuffix++;
return makeUnique(knownAliases, getClassAlias(method.getClassName()) + "_" + alias);
}
@Override
public String getAlias(FieldReference field) {
String result;
do {
result = field.getFieldName() + lastSuffix++;
} while (!usedAliases.add(result));
return result;
public String getFieldAlias(FieldReference field) {
return makeUnique(knownVirtualAliases, field.getFieldName());
}
@Override
public String getStaticFieldAlias(FieldReference field) {
return makeUnique(knownAliases, getClassAlias(field.getClassName()) + "_" + field.getFieldName());
}
@Override
public String getFunctionAlias(String name) {
return name;
}
private String makeUnique(Set<String> knowAliases, String alias) {
String uniqueAlias = alias;
int index = 1;
while (!knowAliases.add(uniqueAlias)) {
uniqueAlias = alias + index++;
}
return uniqueAlias;
}
}

View File

@ -19,41 +19,24 @@ import java.util.HashMap;
import java.util.Map;
import org.teavm.model.*;
/**
*
* @author Alexey Andreev
*/
public class DefaultNamingStrategy implements NamingStrategy {
private AliasProvider aliasProvider;
private ClassReaderSource classSource;
private Map<String, String> aliases = new HashMap<>();
private Map<String, String> privateAliases = new HashMap<>();
private Map<String, String> classAliases = new HashMap<>();
private Map<String, String> fieldAliases = new HashMap<>();
private Map<String, String> functionAliases = new HashMap<>();
private boolean minifying;
private final AliasProvider aliasProvider;
private final ClassReaderSource classSource;
private final Map<String, String> aliases = new HashMap<>();
private final Map<String, String> privateAliases = new HashMap<>();
private final Map<String, String> classAliases = new HashMap<>();
private final Map<String, String> fieldAliases = new HashMap<>();
private final Map<String, String> staticFieldAliases = new HashMap<>();
private final Map<String, String> functionAliases = new HashMap<>();
public DefaultNamingStrategy(AliasProvider aliasProvider, ClassReaderSource classSource) {
this.aliasProvider = aliasProvider;
this.classSource = classSource;
}
public boolean isMinifying() {
return minifying;
}
public void setMinifying(boolean minifying) {
this.minifying = minifying;
}
@Override
public String getNameFor(String cls) {
String name = classAliases.get(cls);
if (name == null) {
name = aliasProvider.getAlias(cls);
classAliases.put(cls, name);
}
return name;
return classAliases.computeIfAbsent(cls, key -> aliasProvider.getClassAlias(cls));
}
@Override
@ -65,7 +48,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
String key = classifier + method.toString();
String alias = aliases.get(key);
if (alias == null) {
alias = aliasProvider.getAlias(method);
alias = aliasProvider.getMethodAlias(method);
aliases.put(key, alias);
}
return alias;
@ -87,16 +70,10 @@ public class DefaultNamingStrategy implements NamingStrategy {
if (method == null) {
throw new NamingException("Can't provide name for method as it was not found: " + originalMethod);
}
if (!minifying) {
return getNameFor(method.getClassName()) + "_" + getNameFor(method.getDescriptor(), classifier);
}
String key = classifier + method.toString();
String alias = privateAliases.get(key);
if (alias == null) {
alias = aliasProvider.getAlias(method);
privateAliases.put(key, alias);
}
return alias;
MethodReference resolvedMethod = method;
return privateAliases.computeIfAbsent(classifier + method.toString(),
key -> aliasProvider.getStaticMethodAlias(resolvedMethod));
}
@Override
@ -107,27 +84,26 @@ public class DefaultNamingStrategy implements NamingStrategy {
fieldAliases.put(field.getClassName() + "#" + field, alias);
return alias;
} else {
String key = realCls + "#" + field;
String alias = fieldAliases.get(key);
if (alias == null) {
alias = aliasProvider.getAlias(field);
fieldAliases.put(key, alias);
}
return fieldAliases.computeIfAbsent(realCls + "#" + field, key -> aliasProvider.getFieldAlias(field));
}
}
@Override
public String getFullNameFor(FieldReference field) throws NamingException {
String realCls = getRealFieldOwner(field.getClassName(), field.getFieldName());
if (!realCls.equals(field.getClassName())) {
String alias = getNameFor(new FieldReference(realCls, field.getFieldName()));
staticFieldAliases.put(field.getClassName() + "#" + field, alias);
return alias;
} else {
return staticFieldAliases.computeIfAbsent(realCls + "#" + field,
key -> aliasProvider.getStaticFieldAlias(field));
}
}
@Override
public String getNameForFunction(String name) throws NamingException {
if (!minifying) {
return name;
}
String alias = functionAliases.get(name);
if (alias == null) {
alias = aliasProvider.getFunctionAlias(name);
functionAliases.put(name, alias);
}
return alias;
return functionAliases.computeIfAbsent(name, key -> aliasProvider.getFunctionAlias(name));
}
private MethodReference getRealMethod(MethodReference methodRef) {

View File

@ -22,22 +22,18 @@ import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public class MinifyingAliasProvider implements AliasProvider {
private static Set<String> keywords = new HashSet<>(Arrays.asList("do", "if", "else", "for", "case",
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 String startLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static String startVirtualLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String startLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final String startVirtualLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private int lastSuffix;
private int lastVirtual;
private Set<String> usedAliases = new HashSet<>();
private final Set<String> usedAliases = new HashSet<>();
@Override
public String getAlias(FieldReference field) {
public String getFieldAlias(FieldReference field) {
String result;
do {
result = getNewAlias(lastVirtual++, startVirtualLetters);
@ -46,12 +42,21 @@ public class MinifyingAliasProvider implements AliasProvider {
}
@Override
public String getAlias(MethodReference method) {
public String getStaticFieldAlias(FieldReference field) {
String result;
do {
result = getNewAlias(lastSuffix++, startLetters);
} while (!usedAliases.add(result) || keywords.contains(result));
return result;
}
@Override
public String getStaticMethodAlias(MethodReference method) {
return getNewAlias(lastSuffix++, startLetters);
}
@Override
public String getAlias(MethodDescriptor method) {
public String getMethodAlias(MethodDescriptor method) {
String result;
do {
result = getNewAlias(lastVirtual++, startVirtualLetters);
@ -60,7 +65,7 @@ public class MinifyingAliasProvider implements AliasProvider {
}
@Override
public String getAlias(String className) {
public String getClassAlias(String className) {
return getNewAlias(lastSuffix++, startLetters);
}

View File

@ -19,10 +19,6 @@ import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
/**
*
* @author Alexey Andreev
*/
public interface NamingStrategy {
String getNameFor(String cls) throws NamingException;
@ -34,5 +30,7 @@ public interface NamingStrategy {
String getNameFor(FieldReference field) throws NamingException;
String getFullNameFor(FieldReference method) throws NamingException;
String getNameForFunction(String name) throws NamingException;
}

View File

@ -21,17 +21,13 @@ import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
/**
*
* @author Alexey Andreev
*/
public class SourceWriter implements Appendable, LocationProvider {
private Appendable innerWriter;
private final Appendable innerWriter;
private int indentSize;
private NamingStrategy naming;
private final NamingStrategy naming;
private boolean lineStart;
private boolean minified;
private int lineWidth;
private final int lineWidth;
private int column;
private int line;
@ -111,6 +107,10 @@ public class SourceWriter implements Appendable, LocationProvider {
return append(naming.getNameFor(field));
}
public SourceWriter appendStaticField(FieldReference field) throws NamingException, IOException {
return append(naming.getFullNameFor(field));
}
public SourceWriter appendMethod(MethodDescriptor method) throws NamingException, IOException {
return append(naming.getNameFor(method));
}

View File

@ -26,8 +26,8 @@ import org.teavm.model.MethodReference;
* @author Alexey Andreev
*/
class AsyncCallsFinder implements StatementVisitor, ExprVisitor {
Set<MethodReference> asyncCalls = new HashSet<>();
Set<MethodReference> allCalls = new HashSet<>();
final Set<MethodReference> asyncCalls = new HashSet<>();
final Set<MethodReference> allCalls = new HashSet<>();
private void visitList(List<Statement> statements) {
for (Statement stmt : statements) {
@ -178,7 +178,9 @@ class AsyncCallsFinder implements StatementVisitor, ExprVisitor {
@Override
public void visit(QualificationExpr expr) {
expr.getQualified().acceptVisitor(this);
if (expr.getQualified() != null) {
expr.getQualified().acceptVisitor(this);
}
}
@Override
@ -201,8 +203,4 @@ class AsyncCallsFinder implements StatementVisitor, ExprVisitor {
public void visit(InstanceOfExpr expr) {
expr.getExpr().acceptVisitor(this);
}
@Override
public void visit(StaticClassExpr expr) {
}
}

View File

@ -21,18 +21,14 @@ import org.teavm.codegen.NameFrequencyConsumer;
import org.teavm.javascript.ast.*;
import org.teavm.model.*;
/**
*
* @author Alexey Andreev
*/
public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, MethodNodeVisitor {
private NameFrequencyConsumer consumer;
private ClassReaderSource classSource;
class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, MethodNodeVisitor {
private final NameFrequencyConsumer consumer;
private final ClassReaderSource classSource;
private boolean async;
private Set<MethodReference> injectedMethods;
private Set<MethodReference> asyncFamilyMethods;
private final Set<MethodReference> injectedMethods;
private final Set<MethodReference> asyncFamilyMethods;
public NameFrequencyEstimator(NameFrequencyConsumer consumer, ClassReaderSource classSource,
NameFrequencyEstimator(NameFrequencyConsumer consumer, ClassReaderSource classSource,
Set<MethodReference> injectedMethods, Set<MethodReference> asyncFamilyMethods) {
this.consumer = consumer;
this.classSource = classSource;
@ -309,7 +305,9 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
@Override
public void visit(QualificationExpr expr) {
expr.getQualified().acceptVisitor(this);
if (expr.getQualified() != null) {
expr.getQualified().acceptVisitor(this);
}
consumer.consume(expr.getField());
}
@ -349,9 +347,4 @@ public class NameFrequencyEstimator implements StatementVisitor, ExprVisitor, Me
consumer.consumeFunction("$rt_isInstance");
}
}
@Override
public void visit(StaticClassExpr expr) {
visitType(expr.getType());
}
}

View File

@ -30,10 +30,6 @@ import org.teavm.model.util.LivenessAnalyzer;
import org.teavm.model.util.ProgramUtils;
import org.teavm.model.util.UsageExtractor;
/**
*
* @author Alexey Andreev
*/
public class Optimizer {
public void optimize(RegularMethodNode method, Program program) {
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());

View File

@ -16,20 +16,17 @@
package org.teavm.javascript;
import java.util.*;
import java.util.stream.Collectors;
import org.teavm.javascript.ast.*;
/**
*
* @author Alexey Andreev
*/
class OptimizingVisitor implements StatementVisitor, ExprVisitor {
public Expr resultExpr;
public Statement resultStmt;
private boolean[] preservedVars;
private int[] readFrequencies;
private Expr resultExpr;
Statement resultStmt;
private final boolean[] preservedVars;
private final int[] readFrequencies;
private List<Statement> resultSequence;
public OptimizingVisitor(boolean[] preservedVars, int[] readFreqencies) {
OptimizingVisitor(boolean[] preservedVars, int[] readFreqencies) {
this.preservedVars = preservedVars;
this.readFrequencies = readFreqencies;
}
@ -261,9 +258,11 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
@Override
public void visit(QualificationExpr expr) {
expr.getQualified().acceptVisitor(this);
Expr qualified = resultExpr;
expr.setQualified(qualified);
if (expr.getQualified() != null) {
expr.getQualified().acceptVisitor(this);
Expr qualified = resultExpr;
expr.setQualified(qualified);
}
resultExpr = expr;
}
@ -297,11 +296,6 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
resultExpr = expr;
}
@Override
public void visit(StaticClassExpr expr) {
resultExpr = expr;
}
@Override
public void visit(AssignmentStatement statement) {
if (statement.getLeftValue() == null) {
@ -331,19 +325,13 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
resultSequence = new ArrayList<>();
processSequenceImpl(statements);
wieldTryCatch(resultSequence);
List<Statement> result = new ArrayList<>();
for (Statement part : resultSequence) {
if (part != null) {
result.add(part);
}
}
List<Statement> result = resultSequence.stream().filter(part -> part != null).collect(Collectors.toList());
resultSequence = backup;
return result;
}
private boolean processSequenceImpl(List<Statement> statements) {
for (int i = 0; i < statements.size(); ++i) {
Statement part = statements.get(i);
for (Statement part : statements) {
if (part instanceof SequentialStatement) {
if (!processSequenceImpl(((SequentialStatement) part).getSequence())) {
return false;
@ -440,7 +428,6 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
List<Statement> remaining = statements.subList(i + 1, statements.size());
cond.getConsequent().addAll(remaining);
remaining.clear();
break check_conditional;
}
}
}

View File

@ -73,7 +73,6 @@ import org.teavm.javascript.ast.ReturnStatement;
import org.teavm.javascript.ast.SequentialStatement;
import org.teavm.javascript.ast.Statement;
import org.teavm.javascript.ast.StatementVisitor;
import org.teavm.javascript.ast.StaticClassExpr;
import org.teavm.javascript.ast.SubscriptExpr;
import org.teavm.javascript.ast.SwitchClause;
import org.teavm.javascript.ast.SwitchStatement;
@ -100,50 +99,46 @@ import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
/**
*
* @author Alexey Andreev
*/
public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext {
private static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
private static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
private NamingStrategy naming;
private SourceWriter writer;
private ListableClassHolderSource classSource;
private ClassLoader classLoader;
private final NamingStrategy naming;
private final SourceWriter writer;
private final ListableClassHolderSource classSource;
private final ClassLoader classLoader;
private boolean minifying;
private Map<MethodReference, InjectorHolder> injectorMap = new HashMap<>();
private Map<String, Integer> stringPoolMap = new HashMap<>();
private List<String> stringPool = new ArrayList<>();
private Properties properties = new Properties();
private ServiceRepository services;
private final Map<MethodReference, InjectorHolder> injectorMap = new HashMap<>();
private final Map<String, Integer> stringPoolMap = new HashMap<>();
private final List<String> stringPool = new ArrayList<>();
private final Properties properties = new Properties();
private final ServiceRepository services;
private DebugInformationEmitter debugEmitter = new DummyDebugInformationEmitter();
private Deque<LocationStackEntry> locationStack = new ArrayDeque<>();
private final Deque<LocationStackEntry> locationStack = new ArrayDeque<>();
private DeferredCallSite lastCallSite;
private DeferredCallSite prevCallSite;
private Set<MethodReference> asyncMethods;
private Set<MethodReference> asyncFamilyMethods;
private Diagnostics diagnostics;
private final Set<MethodReference> asyncMethods;
private final Set<MethodReference> asyncFamilyMethods;
private final Diagnostics diagnostics;
private boolean async;
private Precedence precedence;
private Map<String, String> blockIdMap = new HashMap<>();
private List<Set<String>> debugNames = new ArrayList<>();
private List<String> cachedVariableNames = new ArrayList<>();
private final Map<String, String> blockIdMap = new HashMap<>();
private final List<Set<String>> debugNames = new ArrayList<>();
private final List<String> cachedVariableNames = new ArrayList<>();
private boolean end;
private int currentPart;
private static class InjectorHolder {
public final Injector injector;
public InjectorHolder(Injector injector) {
private InjectorHolder(Injector injector) {
this.injector = injector;
}
}
private static class LocationStackEntry {
NodeLocation location;
final NodeLocation location;
public LocationStackEntry(NodeLocation location) {
LocationStackEntry(NodeLocation location) {
this.location = location;
}
}
@ -403,7 +398,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
value = getDefaultValue(field.getType());
}
FieldReference fieldRef = new FieldReference(cls.getName(), field.getName());
writer.appendClass(cls.getName()).append('.').appendField(fieldRef).ws().append("=").ws()
writer.append("var ").appendStaticField(fieldRef).ws().append("=").ws()
.append(constantToString(value)).append(";").softNewLine();
}
} catch (NamingException e) {
@ -431,9 +426,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
}
if (needsClinit) {
writer.append("function ").appendClass(cls.getName()).append("_$clinit()").ws()
writer.append("function ").appendClass(cls.getName()).append("_$callClinit()").ws()
.append("{").softNewLine().indent();
writer.appendClass(cls.getName()).append("_$clinit").ws().append("=").ws()
writer.appendClass(cls.getName()).append("_$callClinit").ws().append("=").ws()
.append("function(){};").newLine();
for (MethodNode method : clinitMethods) {
renderBody(method, true);
@ -498,7 +493,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
MethodHolder clinit = classSource.get(cls.getName()).getMethod(
new MethodDescriptor("<clinit>", ValueType.VOID));
if (clinit != null) {
writer.appendClass(cls.getName()).append("_$clinit");
writer.appendClass(cls.getName()).append("_$callClinit");
} else {
writer.append('0');
}
@ -624,13 +619,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
}
writer.appendMethodBody(ref).append("(");
writer.append("this");
for (int i = 0; i < args.size(); ++i) {
writer.append(",").ws().append(args.get(i));
for (String arg : args) {
writer.append(",").ws().append(arg);
}
writer.append(");").ws().append("}");
}
public void renderBody(MethodNode method, boolean inner) throws IOException {
private void renderBody(MethodNode method, boolean inner) throws IOException {
debugNames.clear();
cachedVariableNames.clear();
debugNames.addAll(method.getParameterDebugNames());
@ -1211,7 +1206,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
if (statement.getLocation() != null) {
pushLocation(statement.getLocation());
}
writer.appendClass(statement.getClassName()).append("_$clinit();").softNewLine();
writer.appendClass(statement.getClassName()).append("_$callClinit();").softNewLine();
if (statement.getLocation() != null) {
popLocation();
}
@ -1220,7 +1215,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
}
}
public String variableName(int index) {
private String variableName(int index) {
while (index >= cachedVariableNames.size()) {
cachedVariableNames.add(null);
}
@ -1673,7 +1668,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
}
}
public String constantToString(Object cst) {
private String constantToString(Object cst) {
if (cst == null) {
return "null";
}
@ -1948,8 +1943,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
pushLocation(expr.getLocation());
}
precedence = Precedence.MEMBER_ACCESS;
expr.getQualified().acceptVisitor(this);
writer.append('.').appendField(expr.getField());
if (expr.getQualified() != null) {
expr.getQualified().acceptVisitor(this);
writer.append('.').appendField(expr.getField());
} else {
writer.appendStaticField(expr.getField());
}
if (expr.getLocation() != null) {
popLocation();
}
@ -2140,21 +2141,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
}
}
@Override
public void visit(StaticClassExpr expr) {
try {
if (expr.getLocation() != null) {
pushLocation(expr.getLocation());
}
writer.append(typeToClsString(naming, expr.getType()));
if (expr.getLocation() != null) {
popLocation();
}
} catch (IOException e) {
throw new RenderingException("IO error occured", e);
}
}
private void visitStatements(List<Statement> statements) {
if (statements.isEmpty()) {
return;
@ -2313,10 +2299,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
}
private class InjectorContextImpl implements InjectorContext {
private List<Expr> arguments;
private Precedence precedence = Renderer.this.precedence;
private final List<Expr> arguments;
private final Precedence precedence = Renderer.this.precedence;
public InjectorContextImpl(List<Expr> arguments) {
InjectorContextImpl(List<Expr> arguments) {
this.arguments = arguments;
}

View File

@ -23,13 +23,9 @@ import org.teavm.model.*;
import org.teavm.model.instructions.*;
import org.teavm.model.instructions.InvocationType;
/**
*
* @author Alexey Andreev
*/
class StatementGenerator implements InstructionVisitor {
private int lastSwitchId;
List<Statement> statements = new ArrayList<>();
final List<Statement> statements = new ArrayList<>();
GraphIndexer indexer;
BasicBlock nextBlock;
BasicBlock currentBlock;
@ -39,7 +35,7 @@ class StatementGenerator implements InstructionVisitor {
private NodeLocation currentLocation;
boolean async;
public void setCurrentLocation(NodeLocation currentLocation) {
void setCurrentLocation(NodeLocation currentLocation) {
this.currentLocation = currentLocation;
}
@ -478,8 +474,7 @@ class StatementGenerator implements InstructionVisitor {
stmt.setLocation(currentLocation);
statements.add(stmt);
} else {
Expr fieldExpr = Expr.qualify(Expr.staticClass(ValueType.object(insn.getField().getClassName())),
insn.getField());
Expr fieldExpr = Expr.qualify(null, insn.getField());
AssignmentStatement stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), fieldExpr);
stmt.setLocation(currentLocation);
statements.add(stmt);
@ -493,7 +488,7 @@ class StatementGenerator implements InstructionVisitor {
if (insn.getInstance() != null) {
left = Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField());
} else {
left = Expr.qualify(Expr.staticClass(ValueType.object(insn.getField().getClassName())), insn.getField());
left = Expr.qualify(null, insn.getField());
}
AssignmentStatement stmt = Statement.assign(left, right);
stmt.setLocation(currentLocation);

View File

@ -19,16 +19,12 @@ import java.util.Arrays;
import java.util.List;
import org.teavm.javascript.ast.*;
/**
*
* @author Alexey Andreev
*/
class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
int[] variables;
int[] indexes;
private final int[] variables;
private final int[] indexes;
int lastIndex;
public UnusedVariableEliminator(int parameterCount, List<Integer> variables) {
UnusedVariableEliminator(int parameterCount, List<Integer> variables) {
this.variables = new int[variables.size()];
int variableCount = 0;
for (int i = 0; i < variables.size(); ++i) {
@ -176,7 +172,9 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
@Override
public void visit(QualificationExpr expr) {
expr.getQualified().acceptVisitor(this);
if (expr.getQualified() != null) {
expr.getQualified().acceptVisitor(this);
}
}
@Override
@ -200,10 +198,6 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor {
expr.getExpr().acceptVisitor(this);
}
@Override
public void visit(StaticClassExpr expr) {
}
@Override
public void visit(InitClassStatement statement) {
}

View File

@ -20,10 +20,6 @@ import java.util.HashMap;
import java.util.Map;
import org.teavm.model.*;
/**
*
* @author Alexey Andreev
*/
public abstract class Expr implements Cloneable {
private NodeLocation location;
@ -152,12 +148,6 @@ public abstract class Expr implements Cloneable {
return expr;
}
public static Expr staticClass(ValueType type) {
StaticClassExpr expr = new StaticClassExpr();
expr.setType(type);
return expr;
}
public NodeLocation getLocation() {
return location;
}

View File

@ -15,10 +15,6 @@
*/
package org.teavm.javascript.ast;
/**
*
* @author Alexey Andreev
*/
public interface ExprVisitor {
void visit(BinaryExpr expr);
@ -45,6 +41,4 @@ public interface ExprVisitor {
void visit(NewMultiArrayExpr expr);
void visit(InstanceOfExpr expr);
void visit(StaticClassExpr expr);
}

View File

@ -1,206 +0,0 @@
/*
* Copyright 2013 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.javascript.ast;
/**
*
* @author Alexey Andreev
*/
public class RenamingVisitor implements StatementVisitor, ExprVisitor {
private int[] varNames;
public RenamingVisitor(int[] varNames) {
this.varNames = varNames;
}
@Override
public void visit(BinaryExpr expr) {
expr.getFirstOperand().acceptVisitor(this);
expr.getSecondOperand().acceptVisitor(this);
}
@Override
public void visit(UnaryExpr expr) {
expr.getOperand().acceptVisitor(this);
}
@Override
public void visit(ConditionalExpr expr) {
expr.getCondition().acceptVisitor(this);
expr.getConsequent().acceptVisitor(this);
expr.getAlternative().acceptVisitor(this);
}
@Override
public void visit(ConstantExpr expr) {
}
@Override
public void visit(VariableExpr expr) {
expr.setIndex(varNames[expr.getIndex()]);
}
@Override
public void visit(SubscriptExpr expr) {
expr.getArray().acceptVisitor(this);
expr.getIndex().acceptVisitor(this);
}
@Override
public void visit(UnwrapArrayExpr expr) {
expr.getArray().acceptVisitor(this);
}
@Override
public void visit(InvocationExpr expr) {
for (Expr arg : expr.getArguments()) {
arg.acceptVisitor(this);
}
}
@Override
public void visit(QualificationExpr expr) {
expr.getQualified().acceptVisitor(this);
}
@Override
public void visit(NewExpr expr) {
}
@Override
public void visit(NewArrayExpr expr) {
expr.getLength().acceptVisitor(this);
}
@Override
public void visit(NewMultiArrayExpr expr) {
for (Expr dim : expr.getDimensions()) {
dim.acceptVisitor(this);
}
}
@Override
public void visit(InstanceOfExpr expr) {
expr.getExpr().acceptVisitor(this);
}
@Override
public void visit(StaticClassExpr expr) {
}
@Override
public void visit(AssignmentStatement statement) {
if (statement.getLeftValue() != null) {
statement.getLeftValue().acceptVisitor(this);
}
statement.getRightValue().acceptVisitor(this);
}
@Override
public void visit(SequentialStatement statement) {
for (Statement part : statement.getSequence()) {
part.acceptVisitor(this);
}
}
@Override
public void visit(ConditionalStatement statement) {
statement.getCondition().acceptVisitor(this);
for (Statement part : statement.getConsequent()) {
part.acceptVisitor(this);
}
for (Statement part : statement.getAlternative()) {
part.acceptVisitor(this);
}
}
@Override
public void visit(SwitchStatement statement) {
statement.getValue().acceptVisitor(this);
for (SwitchClause clause : statement.getClauses()) {
for (Statement part : clause.getBody()) {
part.acceptVisitor(this);
}
}
for (Statement part : statement.getDefaultClause()) {
part.acceptVisitor(this);
}
}
@Override
public void visit(WhileStatement statement) {
if (statement.getCondition() != null) {
statement.getCondition().acceptVisitor(this);
}
for (Statement part : statement.getBody()) {
part.acceptVisitor(this);
}
}
@Override
public void visit(BlockStatement statement) {
for (Statement part : statement.getBody()) {
part.acceptVisitor(this);
}
}
@Override
public void visit(BreakStatement statement) {
}
@Override
public void visit(ContinueStatement statement) {
}
@Override
public void visit(ReturnStatement statement) {
if (statement.getResult() != null) {
statement.getResult().acceptVisitor(this);
}
}
@Override
public void visit(ThrowStatement statement) {
statement.getException().acceptVisitor(this);
}
@Override
public void visit(InitClassStatement statement) {
}
@Override
public void visit(TryCatchStatement statement) {
for (Statement part : statement.getProtectedBody()) {
part.acceptVisitor(this);
}
for (Statement part : statement.getHandler()) {
part.acceptVisitor(this);
}
statement.setExceptionVariable(varNames[statement.getExceptionVariable()]);
}
@Override
public void visit(GotoPartStatement statement) {
}
@Override
public void visit(MonitorEnterStatement statement) {
}
@Override
public void visit(MonitorExitStatement statement) {
}
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2012 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.javascript.ast;
import java.util.Map;
import org.teavm.model.ValueType;
/**
*
* @author Alexey Andreev
*/
public class StaticClassExpr extends Expr {
private ValueType type;
public ValueType getType() {
return type;
}
public void setType(ValueType type) {
this.type = type;
}
@Override
public void acceptVisitor(ExprVisitor visitor) {
visitor.visit(this);
}
@Override
protected Expr clone(Map<Expr, Expr> cache) {
Expr known = cache.get(this);
if (known != null) {
return known;
}
StaticClassExpr copy = new StaticClassExpr();
cache.put(this, copy);
copy.setType(type);
return copy;
}
}

View File

@ -69,20 +69,20 @@ import org.teavm.vm.spi.TeaVMPlugin;
* @author Alexey Andreev
*/
public class TeaVM implements TeaVMHost, ServiceRepository {
private ClassReaderSource classSource;
private DependencyChecker dependencyChecker;
private AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
private ClassLoader classLoader;
private final ClassReaderSource classSource;
private final DependencyChecker dependencyChecker;
private final AccumulationDiagnostics diagnostics = new AccumulationDiagnostics();
private final ClassLoader classLoader;
private boolean minifying = true;
private boolean bytecodeLogging;
private OutputStream logStream = System.out;
private Map<String, TeaVMEntryPoint> entryPoints = new HashMap<>();
private Map<String, String> exportedClasses = new HashMap<>();
private Map<MethodReference, Generator> methodGenerators = new HashMap<>();
private Map<MethodReference, Injector> methodInjectors = new HashMap<>();
private List<RendererListener> rendererListeners = new ArrayList<>();
private Map<Class<?>, Object> services = new HashMap<>();
private Properties properties = new Properties();
private final OutputStream logStream = System.out;
private final Map<String, TeaVMEntryPoint> entryPoints = new HashMap<>();
private final Map<String, String> exportedClasses = new HashMap<>();
private final Map<MethodReference, Generator> methodGenerators = new HashMap<>();
private final Map<MethodReference, Injector> methodInjectors = new HashMap<>();
private final List<RendererListener> rendererListeners = new ArrayList<>();
private final Map<Class<?>, Object> services = new HashMap<>();
private final Properties properties = new Properties();
private DebugInformationEmitter debugEmitter;
private ProgramCache programCache;
private MethodNodeCache astCache = new EmptyRegularMethodNodeCache();
@ -90,8 +90,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
private TeaVMProgressListener progressListener;
private boolean cancelled;
private ListableClassHolderSource writtenClasses;
private Set<MethodReference> asyncMethods = new HashSet<>();
private Set<MethodReference> asyncFamilyMethods = new HashSet<>();
private final Set<MethodReference> asyncMethods = new HashSet<>();
private final Set<MethodReference> asyncFamilyMethods = new HashSet<>();
TeaVM(ClassReaderSource classSource, ClassLoader classLoader) {
this.classSource = classSource;
@ -288,10 +288,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
exportedClasses.put(name, className);
}
public void linkType(String className) {
dependencyChecker.linkClass(className, null).initClass(null);
}
/**
* Gets a {@link ClassReaderSource} which is used by this TeaVM instance. It is exactly what was
* passed to {@link TeaVMBuilder#setClassSource(ClassHolderSource)}.
@ -420,7 +416,6 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
return;
}
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, dependencyChecker.getClassSource());
naming.setMinifying(minifying);
SourceWriterBuilder builder = new SourceWriterBuilder(naming);
builder.setMinified(minifying);
SourceWriter sourceWriter = builder.build(writer);

View File

@ -7,6 +7,7 @@
<property key="Bundle-Description" value="Implementation of metaprogramming API" />
<property key="Export-Package" value="org.teavm.metaprogramming.*" />
<property key="Bundle-Name" value="TeaVM metaprogramming API implementation" />
<property key="Include-Resource" value="META-INF/services/org.teavm.vm.spi.TeaVMPlugin=$MODULE_DIR$/src/main/resources/META-INF/services/org.teavm.vm.spi.TeaVMPlugin" />
</additionalProperties>
<additionalJARContents />
</configuration>

View File

@ -24,6 +24,8 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.0.1-2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.jetbrains.kotlin:kotlin-runtime:1.0.1-2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.0.1-2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.jetbrains.kotlin:kotlin-runtime:1.0.1-2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.11" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="module" module-name="teavm-classlib" scope="PROVIDED" />

View File

@ -9,7 +9,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="jdk" jdkName="IntelliJ IDEA IU-144.3600.7" jdkType="IDEA JDK" />
<orderEntry type="jdk" jdkName="IntelliJ IDEA" jdkType="IDEA JDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.ow2.asm:asm-debug-all:5.0.4" level="project" />
<orderEntry type="library" name="teavm-all" level="project" />

View File

@ -10,7 +10,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="jdk" jdkName="IntelliJ IDEA IU-144.3600.7" jdkType="IDEA JDK" />
<orderEntry type="jdk" jdkName="IntelliJ IDEA" jdkType="IDEA JDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="teavm-jps-plugin" />
<orderEntry type="library" name="teavm-all" level="project" />

View File

@ -76,7 +76,7 @@ class HtmlUnitRunStrategy implements TestRunStrategy {
private void init() {
webClient.set(new WebClient(BrowserVersion.CHROME));
try {
page.set(webClient.get().getPage("about:blank"));
page.set(webClient.get().<HtmlPage>getPage("about:blank"));
} catch (IOException e) {
throw new RuntimeException(e);
}