mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-12-15 02:10:30 +08:00
Further work on decreasing generated code size
This commit is contained in:
parent
b71a2b6c65
commit
c1891a1908
@ -25,7 +25,7 @@ import org.teavm.model.util.ProgramUtils;
|
||||
public class ObfuscationHacks implements ClassHolderTransformer {
|
||||
@Override
|
||||
public void transformClass(ClassHolder cls, ClassHolderTransformerContext context) {
|
||||
if (cls.getName().equals("java.lang.Object")) {
|
||||
if (cls.getName().equals("java.lang.Object") || cls.getName().equals("java.lang.Class")) {
|
||||
if (context.isObfuscated() && !context.isStrict()) {
|
||||
processObjectClass(cls);
|
||||
}
|
||||
|
@ -82,8 +82,11 @@ public class TClass<T> extends TObject implements TAnnotatedElement, TType {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
|
||||
+ getName();
|
||||
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class ")) + getName();
|
||||
}
|
||||
|
||||
private String obfuscatedToString() {
|
||||
return "javaClass@" + identity();
|
||||
}
|
||||
|
||||
public PlatformClass getPlatformClass() {
|
||||
|
@ -65,7 +65,7 @@ public abstract class TEnum<E extends TEnum<E>> extends TObject implements TComp
|
||||
public final int compareTo(E o) {
|
||||
if (o.getDeclaringClass() != getDeclaringClass()) {
|
||||
throw new TIllegalArgumentException("Can't compare "
|
||||
+ getDeclaringClass().getName() + " to " + o.getDeclaringClass().getName());
|
||||
+ getDeclaringClass() + " to " + o.getDeclaringClass());
|
||||
}
|
||||
return TInteger.compare(ordinal, o.ordinal());
|
||||
}
|
||||
@ -81,6 +81,6 @@ public abstract class TEnum<E extends TEnum<E>> extends TObject implements TComp
|
||||
return constant;
|
||||
}
|
||||
}
|
||||
throw new TIllegalArgumentException("Enum does not have the " + name + "constant");
|
||||
throw new TIllegalArgumentException("Enum " + enumType + " does not have the " + name + "constant");
|
||||
}
|
||||
}
|
||||
|
@ -326,10 +326,10 @@ class DependencyGraphBuilder {
|
||||
@Override
|
||||
protected void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||
List<? extends VariableReader> arguments) {
|
||||
if (method.getDescriptor().equals(GET_CLASS)) {
|
||||
invokeGetClass(receiver, instance);
|
||||
if (handleSpecialMethod(receiver, instance, method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallLocation callLocation = getCallLocation();
|
||||
if (instance == null) {
|
||||
dependencyAnalyzer.linkClass(method.getClassName()).initClass(callLocation);
|
||||
@ -366,8 +366,7 @@ class DependencyGraphBuilder {
|
||||
@Override
|
||||
protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||
List<? extends VariableReader> arguments) {
|
||||
if (method.getDescriptor().equals(GET_CLASS)) {
|
||||
invokeGetClass(receiver, instance);
|
||||
if (handleSpecialMethod(receiver, instance, method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -387,6 +386,26 @@ class DependencyGraphBuilder {
|
||||
});
|
||||
}
|
||||
|
||||
private boolean handleSpecialMethod(VariableReader receiver, VariableReader instance, MethodReference method) {
|
||||
if (method.getDescriptor().equals(GET_CLASS)) {
|
||||
invokeGetClass(receiver, instance);
|
||||
return true;
|
||||
} else if (method.getClassName().equals("java.lang.Class")) {
|
||||
switch (method.getName()) {
|
||||
case "getComponentType":
|
||||
invokeGetComponentType(receiver, instance, method);
|
||||
return true;
|
||||
case "getSuperclass":
|
||||
invokeGetSuperclass(receiver, instance, method);
|
||||
return true;
|
||||
case "getInterfaces":
|
||||
invokeGetInterfaces(receiver, instance, method);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void invokeGetClass(VariableReader receiver, VariableReader instance) {
|
||||
MethodDependency getClassDep = dependencyAnalyzer.linkMethod("java.lang.Object", GET_CLASS);
|
||||
getClassDep.addLocation(getCallLocation());
|
||||
@ -402,6 +421,75 @@ class DependencyGraphBuilder {
|
||||
getClassDep.use();
|
||||
}
|
||||
|
||||
private void invokeGetComponentType(VariableReader receiver, VariableReader instance,
|
||||
MethodReference methodReference) {
|
||||
MethodDependency methodDep = dependencyAnalyzer.linkMethod(methodReference);
|
||||
methodDep.use();
|
||||
|
||||
DependencyNode instanceNode = getNode(instance);
|
||||
DependencyNode receiverNode = getNode(receiver);
|
||||
receiverNode.propagate(dependencyAnalyzer.classType);
|
||||
instanceNode.getClassValueNode().addConsumer(t -> {
|
||||
if (!t.getName().startsWith("[")) {
|
||||
return;
|
||||
}
|
||||
String typeName = t.getName().substring(1);
|
||||
if (typeName.charAt(0) == 'L') {
|
||||
typeName = ((ValueType.Object) ValueType.parse(typeName)).getClassName();
|
||||
}
|
||||
receiverNode.getClassValueNode().propagate(dependencyAnalyzer.getType(typeName));
|
||||
|
||||
methodDep.getVariable(0).propagate(t);
|
||||
});
|
||||
}
|
||||
|
||||
private void invokeGetSuperclass(VariableReader receiver, VariableReader instance,
|
||||
MethodReference methodReference) {
|
||||
MethodDependency methodDep = dependencyAnalyzer.linkMethod(methodReference);
|
||||
methodDep.use();
|
||||
|
||||
DependencyNode instanceNode = getNode(instance);
|
||||
DependencyNode receiverNode = getNode(receiver);
|
||||
receiverNode.propagate(dependencyAnalyzer.classType);
|
||||
instanceNode.getClassValueNode().addConsumer(type -> {
|
||||
String className = type.getName();
|
||||
if (className.startsWith("[")) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClassReader cls = dependencyAnalyzer.getClassSource().get(className);
|
||||
if (cls != null && cls.getParent() != null) {
|
||||
receiverNode.getClassValueNode().propagate(dependencyAnalyzer.getType(cls.getParent()));
|
||||
}
|
||||
methodDep.getVariable(0).propagate(type);
|
||||
});
|
||||
}
|
||||
|
||||
private void invokeGetInterfaces(VariableReader receiver, VariableReader instance,
|
||||
MethodReference methodReference) {
|
||||
MethodDependency methodDep = dependencyAnalyzer.linkMethod(methodReference);
|
||||
methodDep.use();
|
||||
|
||||
DependencyNode instanceNode = getNode(instance);
|
||||
DependencyNode receiverNode = getNode(receiver);
|
||||
receiverNode.propagate(dependencyAnalyzer.classType);
|
||||
instanceNode.getClassValueNode().addConsumer(type -> {
|
||||
String className = type.getName();
|
||||
if (className.startsWith("[")) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClassReader cls = dependencyAnalyzer.getClassSource().get(className);
|
||||
if (cls != null) {
|
||||
for (String iface : cls.getInterfaces()) {
|
||||
receiverNode.getClassValueNode().propagate(dependencyAnalyzer.getType(iface));
|
||||
}
|
||||
}
|
||||
|
||||
methodDep.getVariable(0).propagate(type);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nullCheck(VariableReader receiver, VariableReader value) {
|
||||
super.nullCheck(receiver, value);
|
||||
|
@ -21,7 +21,6 @@ import net.java.html.json.tests.KnockoutTest;
|
||||
import net.java.html.json.tests.MinesTest;
|
||||
import net.java.html.json.tests.OperationsTest;
|
||||
import net.java.html.json.tests.WebSocketTest;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.teavm.junit.SkipJVM;
|
||||
@ -323,7 +322,6 @@ public class KnockoutTCKTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void deserializeWrongEnum() throws Exception {
|
||||
jsonTest.deserializeWrongEnum();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user