Class renaming now works

This commit is contained in:
konsoletyper 2013-11-06 19:46:54 +04:00
parent 9c83d63c86
commit ee10986d05
7 changed files with 78 additions and 58 deletions

View File

@ -9,7 +9,7 @@ import org.teavm.model.MethodReference;
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TClassNativeGenerator implements Generator {
public class ClassNativeGenerator implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
switch (methodRef.getClassName()) {

View File

@ -11,7 +11,7 @@ import org.teavm.model.ValueType;
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TObjectNativeGenerator implements Generator {
public class ObjectNativeGenerator implements Generator {
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
switch (methodRef.getDescriptor().getName()) {
@ -44,7 +44,8 @@ public class TObjectNativeGenerator implements Generator {
writer.append("if (cls === undefined) {").newLine().indent();
MethodReference createMethodRef = new MethodReference(classClass, new MethodDescriptor("createNew",
ValueType.object(classClass)));
writer.append("cls = ").appendClass(classClass).appendMethod(createMethodRef).append("();").newLine();
writer.append("cls = ").appendClass(classClass).append('.').appendMethod(createMethodRef)
.append("();").newLine();
writer.append("cls.$data = ").append(thisArg).append(".$class;").newLine().outdent().append("}").newLine();
writer.append("return cls;").newLine();
}
@ -59,7 +60,7 @@ public class TObjectNativeGenerator implements Generator {
}
private void generateClone(GeneratorContext context, SourceWriter writer) {
writer.append("var copy = new ").append(context.getParameterName(0)).append("obj.$class();").newLine();
writer.append("var copy = new ").append(context.getParameterName(0)).append(".$class();").newLine();
writer.append("for (var field in obj) {").newLine().indent();
writer.append("if (!obj.hasOwnProperty(field)) {").newLine().indent();
writer.append("continue;").newLine().outdent().append("}").newLine();

View File

@ -7,6 +7,10 @@ import org.teavm.javascript.ni.GeneratedBy;
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TClass<T> extends TObject {
@GeneratedBy(TClassNativeGenerator.class)
static TClass<?> createNew() {
return new TClass<>();
}
@GeneratedBy(ClassNativeGenerator.class)
public native boolean isInstance(TObject obj);
}

View File

@ -12,22 +12,22 @@ public class TObject {
init();
}
@GeneratedBy(TObjectNativeGenerator.class)
@GeneratedBy(ObjectNativeGenerator.class)
private native void init();
@GeneratedBy(TObjectNativeGenerator.class)
@GeneratedBy(ObjectNativeGenerator.class)
@Rename("getClass")
public native final TClass<?> getClass0();
@Override
@GeneratedBy(TObjectNativeGenerator.class)
@GeneratedBy(ObjectNativeGenerator.class)
public native int hashCode();
@GeneratedBy(TObjectNativeGenerator.class)
@GeneratedBy(ObjectNativeGenerator.class)
public native boolean equals(TObject other);
@Override
@GeneratedBy(TObjectNativeGenerator.class)
@GeneratedBy(ObjectNativeGenerator.class)
protected native TObject clone();
@Rename("notify")

View File

@ -401,31 +401,31 @@ public class Renderer implements ExprVisitor, StatementVisitor {
visitBinary(expr, "+");
break;
case ADD_LONG:
visitBinaryFunction(expr, "Long.add");
visitBinaryFunction(expr, "Long_add");
break;
case SUBTRACT:
visitBinary(expr, "-");
break;
case SUBTRACT_LONG:
visitBinaryFunction(expr, "Long.sub");
visitBinaryFunction(expr, "Long_sub");
break;
case MULTIPLY:
visitBinary(expr, "*");
break;
case MULTIPLY_LONG:
visitBinaryFunction(expr, "Long.mul");
visitBinaryFunction(expr, "Long_mul");
break;
case DIVIDE:
visitBinary(expr, "/");
break;
case DIVIDE_LONG:
visitBinaryFunction(expr, "Long.div");
visitBinaryFunction(expr, "Long_div");
break;
case MODULO:
visitBinary(expr, "%");
break;
case MODULO_LONG:
visitBinaryFunction(expr, "Long.rem");
visitBinaryFunction(expr, "Long_rem");
break;
case EQUALS:
visitBinary(expr, "==");
@ -452,10 +452,10 @@ public class Renderer implements ExprVisitor, StatementVisitor {
visitBinary(expr, "!==");
break;
case COMPARE:
visitBinaryFunction(expr, "$rt.compare");
visitBinaryFunction(expr, "$rt_compare");
break;
case COMPARE_LONG:
visitBinaryFunction(expr, "Long.compare");
visitBinaryFunction(expr, "Long_compare");
break;
case OR:
visitBinary(expr, "||");
@ -467,37 +467,37 @@ public class Renderer implements ExprVisitor, StatementVisitor {
visitBinary(expr, "|");
break;
case BITWISE_OR_LONG:
visitBinaryFunction(expr, "Long.or");
visitBinaryFunction(expr, "Long_or");
break;
case BITWISE_AND:
visitBinary(expr, "&");
break;
case BITWISE_AND_LONG:
visitBinaryFunction(expr, "Long.and");
visitBinaryFunction(expr, "Long_and");
break;
case BITWISE_XOR:
visitBinary(expr, "^");
break;
case BITWISE_XOR_LONG:
visitBinaryFunction(expr, "Long.xor");
visitBinaryFunction(expr, "Long_xor");
break;
case LEFT_SHIFT:
visitBinary(expr, "<<");
break;
case LEFT_SHIFT_LONG:
visitBinaryFunction(expr, "Long.lsh");
visitBinaryFunction(expr, "Long_lsh");
break;
case RIGHT_SHIFT:
visitBinary(expr, ">>");
break;
case RIGHT_SHIFT_LONG:
visitBinaryFunction(expr, "Long.rsh");
visitBinaryFunction(expr, "Long_rsh");
break;
case UNSIGNED_RIGHT_SHIFT:
visitBinary(expr, ">>>");
break;
case UNSIGNED_RIGHT_SHIFT_LONG:
visitBinaryFunction(expr, "Long.rshu");
visitBinaryFunction(expr, "Long_rshu");
break;
}
}
@ -520,27 +520,27 @@ public class Renderer implements ExprVisitor, StatementVisitor {
writer.append(".length");
break;
case INT_TO_LONG:
writer.append("Long.fromInt(");
writer.append("Long_fromInt(");
expr.getOperand().acceptVisitor(this);
writer.append(')');
break;
case NUM_TO_LONG:
writer.append("Long.fromNumber(");
writer.append("Long_fromNumber(");
expr.getOperand().acceptVisitor(this);
writer.append(')');
break;
case LONG_TO_NUM:
writer.append("Long.toNumber(");
writer.append("Long_toNumber(");
expr.getOperand().acceptVisitor(this);
writer.append(')');
break;
case NEGATE_LONG:
writer.append("Long.neg(");
writer.append("Long_neg(");
expr.getOperand().acceptVisitor(this);
writer.append(')');
break;
case NOT_LONG:
writer.append("Long.not(");
writer.append("Long_not(");
expr.getOperand().acceptVisitor(this);
writer.append(')');
break;
@ -569,15 +569,15 @@ public class Renderer implements ExprVisitor, StatementVisitor {
}
if (cst instanceof ValueType) {
ValueType type = (ValueType)cst;
return "$rt.cls(" + typeToClsString(naming, type) + ")";
return "$rt_cls(" + typeToClsString(naming, type) + ")";
} else if (cst instanceof String) {
return "$rt.str(\"" + escapeString((String)cst) + "\")";
return "$rt_str(\"" + escapeString((String)cst) + "\")";
} else if (cst instanceof Long) {
long value = (Long)cst;
if (value == 0) {
return "Long.ZERO";
return "Long_ZERO";
} else if ((int)value == value) {
return "Long.fromInt(" + value + ")";
return "Long_fromInt(" + value + ")";
} else {
return "new Long(" + (value & 0xFFFFFFFF) + ", " + (value >>> 32) + ")";
}
@ -597,33 +597,33 @@ public class Renderer implements ExprVisitor, StatementVisitor {
ValueType.Object objType = (ValueType.Object)type;
value = naming.getNameFor(objType.getClassName());
} else if (type instanceof ValueType.Void) {
value = "$rt.voidcls()";
value = "$rt_voidcls()";
} else if (type instanceof ValueType.Primitive) {
ValueType.Primitive primitiveType = (ValueType.Primitive)type;
switch (primitiveType.getKind()) {
case BOOLEAN:
value = "$rt.booleancls()";
value = "$rt_booleancls()";
break;
case CHARACTER:
value = "$rt.charcls()";
value = "$rt_charcls()";
break;
case BYTE:
value = "$rt.bytecls()";
value = "$rt_bytecls()";
break;
case SHORT:
value = "$rt.shortcls()";
value = "$rt_shortcls()";
break;
case INTEGER:
value = "$rt.intcls()";
value = "$rt_intcls()";
break;
case LONG:
value = "$rt.longcls()";
value = "$rt_longcls()";
break;
case FLOAT:
value = "$rt.floatcls()";
value = "$rt_floatcls()";
break;
case DOUBLE:
value = "$rt.doublecls()";
value = "$rt_doublecls()";
break;
default:
throw new IllegalArgumentException("The type is not renderable");
@ -633,7 +633,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
}
for (int i = 0; i < arrayCount; ++i) {
value = "$rt.arraycls(" + value + ")";
value = "$rt_arraycls(" + value + ")";
}
return value;
}
@ -755,48 +755,48 @@ public class Renderer implements ExprVisitor, StatementVisitor {
if (type instanceof ValueType.Primitive) {
switch (((ValueType.Primitive)type).getKind()) {
case BOOLEAN:
writer.append("$rt.createBooleanArray($rt.booleancls(), ");
writer.append("$rt_createBooleanArray($rt_booleancls(), ");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
case BYTE:
writer.append("$rt.createNumericArray($rt.bytecls(), ");
writer.append("$rt_createNumericArray($rt_bytecls(), ");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
case SHORT:
writer.append("$rt.createNumericArray($rt.shortcls(), ");
writer.append("$rt_createNumericArray($rt_shortcls(), ");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
case INTEGER:
writer.append("$rt.createNumericArray($rt.intcls(), ");
writer.append("$rt_createNumericArray($rt_intcls(), ");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
case LONG:
writer.append("$rt.createLongArray(");
writer.append("$rt_createLongArray(");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
case FLOAT:
writer.append("$rt.createNumericArray($rt.floatcls(), ");
writer.append("$rt_createNumericArray($rt_floatcls(), ");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
case DOUBLE:
writer.append("$rt.createNumericArray($rt.doublecls(), ");
writer.append("$rt_createNumericArray($rt_doublecls(), ");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
case CHARACTER:
writer.append("$rt.createNumericArray($rt.charcls(), ");
writer.append("$rt_createNumericArray($rt_charcls(), ");
expr.getLength().acceptVisitor(this);
writer.append(")");
break;
}
} else {
writer.append("$rt.createArray(").append(typeToClsString(naming, expr.getType())).append(", ");
writer.append("$rt_createArray(").append(typeToClsString(naming, expr.getType())).append(", ");
expr.getLength().acceptVisitor(this);
writer.append(")");
}
@ -804,7 +804,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
@Override
public void visit(NewMultiArrayExpr expr) {
writer.append("$rt.createMultiArray(").append(typeToClsString(naming, expr.getType()))
writer.append("$rt_createMultiArray(").append(typeToClsString(naming, expr.getType()))
.append(", [");
boolean first = true;
for (Expr dimension : expr.getDimensions()) {
@ -829,7 +829,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
return;
}
}
writer.append("$rt.isInstance(");
writer.append("$rt_isInstance(");
expr.getExpr().acceptVisitor(this);
writer.append(", ").append(typeToClsString(naming, expr.getType())).append(")");
}

View File

@ -21,7 +21,7 @@ class ClassRefsRenamer implements InstructionVisitor {
ClassHolder renamedCls = new ClassHolder(classNameMapper.map(cls.getName()));
renamedCls.getModifiers().addAll(cls.getModifiers());
renamedCls.setLevel(cls.getLevel());
if (cls != null) {
if (cls.getParent() != null) {
renamedCls.setParent(classNameMapper.map(cls.getParent()));
}
for (MethodHolder method : cls.getMethods()) {
@ -79,7 +79,7 @@ class ClassRefsRenamer implements InstructionVisitor {
private AnnotationHolder rename(AnnotationHolder annot) {
AnnotationHolder renamedAnnot = new AnnotationHolder(classNameMapper.map(annot.getType()));
for (Map.Entry<String, AnnotationValue> entry : renamedAnnot.getValues().entrySet()) {
for (Map.Entry<String, AnnotationValue> entry : annot.getValues().entrySet()) {
renamedAnnot.getValues().put(entry.getKey(), entry.getValue());
}
return renamedAnnot;
@ -216,6 +216,11 @@ class ClassRefsRenamer implements InstructionVisitor {
@Override
public void visit(InvokeInstruction insn) {
insn.setClassName(classNameMapper.map(insn.getClassName()));
ValueType[] signature = insn.getMethod().getSignature();
for (int i = 0; i < signature.length; ++i) {
signature[i] = rename(signature[i]);
}
insn.setMethod(new MethodDescriptor(insn.getMethod().getName(), signature));
}
@Override

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
import org.teavm.codegen.ConcurrentCachedMapper;
import org.teavm.codegen.Mapper;
import org.teavm.model.ClassHolder;
@ -16,6 +17,7 @@ public class ClasspathResourceMapper implements Mapper<String, ClassHolder> {
private static String CLASS_PREFIX = "classPrefix.";
private Mapper<String, ClassHolder> innerMapper;
private List<Transformation> transformations = new ArrayList<>();
private ClassRefsRenamer renamer;
private static class Transformation {
String packageName;
@ -41,6 +43,7 @@ public class ClasspathResourceMapper implements Mapper<String, ClassHolder> {
} catch (IOException e) {
throw new RuntimeException("Error reading resources", e);
}
renamer = new ClassRefsRenamer(new ConcurrentCachedMapper<>(classNameMapper));
}
private void loadProperties(Properties properties, Map<String, Transformation> cache) {
@ -78,24 +81,31 @@ public class ClasspathResourceMapper implements Mapper<String, ClassHolder> {
String packageName = name.substring(0, index);
ClassHolder classHolder = innerMapper.map(transformation.packagePrefix + "." + packageName +
"." + transformation.classPrefix + className);
return classHolder;
return renamer.rename(classHolder);
}
}
return innerMapper.map(name);
}
String renameClass(String name) {
private String renameClass(String name) {
for (Transformation transformation : transformations) {
if (name.startsWith(transformation.fullPrefix)) {
int index = name.lastIndexOf('.');
String className = name.substring(index + 1);
String packageName = name.substring(0, index);
if (className.startsWith(transformation.classPrefix)) {
return packageName.substring(transformation.fullPrefix.length()) + "." +
return packageName.substring(transformation.packagePrefix.length()) + "." +
className.substring(transformation.classPrefix.length());
}
}
}
return name;
}
private Mapper<String, String> classNameMapper = new Mapper<String, String>() {
@Override
public String map(String preimage) {
return renameClass(preimage);
}
};
}