Skip to content

Commit

Permalink
fix: Optimize cast code.
Browse files Browse the repository at this point in the history
  • Loading branch information
teletha committed Mar 13, 2023
1 parent 63aaa91 commit 6321803
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 39 deletions.
4 changes: 2 additions & 2 deletions src/main/java/reincarnation/JavaMethodDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
package reincarnation;

import static org.objectweb.asm.Opcodes.*;
import static reincarnation.Node.Termination;
import static reincarnation.Node.*;
import static reincarnation.OperandCondition.*;
import static reincarnation.OperandUtil.load;
import static reincarnation.OperandUtil.*;

import java.lang.reflect.Executable;
import java.lang.reflect.Method;
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/reincarnation/OperandCast.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class OperandCast extends Operand {
/** The type to cast. */
private final Class type;

private final boolean needCast;

/**
* Create cast code.
*
Expand All @@ -31,19 +33,22 @@ class OperandCast extends Operand {
this.value = value;
this.type = type;
fix(type);
this.needCast = !Inference.instanceOf(value.type.v, type);

encolose();
if (needCast) {
encolose();
}
}

/**
* {@inheritDoc}
*/
@Override
protected void writeCode(Coder coder) {
if (Inference.instanceOf(value.type.v, type)) {
value.writeCode(coder);
} else {
if (needCast) {
coder.writeCast(type, value);
} else {
value.writeCode(coder);
}
}

Expand Down
16 changes: 6 additions & 10 deletions src/main/java/reincarnation/OperandMethodReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
package reincarnation;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;

import reincarnation.coder.Coder;

Expand All @@ -23,14 +21,12 @@ class OperandMethodReference extends Operand {
/** The context. */
private final Operand context;

OperandMethodReference(Class interfaceClass, Method reference, Operand context, Type type) {
this.reference = reference;
this.context = context;

System.out.println(Arrays.toString(reference.getGenericParameterTypes()));
fix(type);
}

/**
* Create the operand for method reference.
*
* @param reference
* @param context
*/
OperandMethodReference(Method reference, Operand context) {
this.reference = reference;
this.context = context;
Expand Down
52 changes: 40 additions & 12 deletions src/main/java/reincarnation/SpecializedType.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,39 @@

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.List;
import java.util.Objects;

import kiss.I;
import reincarnation.coder.Join;

public final class SpecializedType implements Type {
public final class SpecializedType implements ParameterizedType {

/** The reusable type for <?>. */
private static final WildcardType WILD = new WildcardType() {

private static final Type[] O = {Object.class};
private static final Type[] Φ = {};

@Override
public Type[] getUpperBounds() {
return O;
return Φ;
}

@Override
public Type[] getLowerBounds() {
return O;
return Φ;
}

/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "?";
}
};

Expand Down Expand Up @@ -282,22 +292,40 @@ SpecializedType fillBy(Type type) {
}

/**
* Returns an array of Type objects representing the actual type arguments to this type. Note
* that in some cases, the returned array be empty. This can occur if this type represents a
* non-parameterized type nested within a parameterized type.
*
* @return An array of Type objects representing the actual type arguments to this type.
* {@inheritDoc}
*/
@Override
public Type getOwnerType() {
return null;
}

/**
* {@inheritDoc}
*/
@Override
public Type[] getActualTypeArguments() {
return specialized;
}

/**
* Returns the Type object representing the class or interface that declared this type.
*
* @return Type object representing the class or interface that declared this type
* {@inheritDoc}
*/
@Override
public Type getRawType() {
return raw;
}

/**
* {@inheritDoc}
*/
@Override
public String toString() {
return raw.getSimpleName() + Join.of(specialized)
.ignoreEmpty()
.prefix("<")
.separator(", ")
.suffix(">")
.converter(Type::getTypeName)
.write();
}
}
17 changes: 17 additions & 0 deletions src/main/java/reincarnation/coder/Join.java
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,17 @@ public Join<T> remove(Collection<T> values) {
return this;
}

/**
* Write out as {@link String}.
*
* @return
*/
public String write() {
StringBuilder builder = new StringBuilder();
write(builder);
return builder.toString();
}

/**
* {@inheritDoc}
*/
Expand All @@ -207,6 +218,12 @@ public void write(Coder coder) {
write(coder, I.NoOP);
}

/**
* Write out or process if no item.
*
* @param coder
* @param empty
*/
public void write(Coder coder, Runnable empty) {
List<T> values = take == null ? this.values : I.signal(this.values).index(0).take(x -> take.test(x.ⅱ, x.ⅰ)).map(Ⅱ::ⅰ).toList();
int size = values.size();
Expand Down
22 changes: 11 additions & 11 deletions src/main/java/reincarnation/coder/java/JavaCoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ public void writeLocalVariable(Type type, String name) {
if (vars.isDeclared(name)) {
prefix = "";
} else {
boolean needInfer = (type instanceof Class clazz && clazz.getTypeParameters().length != 0) || type instanceof ParameterizedType;
boolean needInfer = (type instanceof Class clazz && clazz.getTypeParameters().length != 0);
prefix = (needInfer ? "var" : name(type)).concat(space);
vars.declare(name);
}
Expand Down Expand Up @@ -976,6 +976,16 @@ private void qualify(Type type, StringBuilder builder) {
.take(x -> x != Object.class)
.ignoreEmpty()
.write(builder);
} else if (type instanceof SpecializedType specialized) {
qualify(specialized.getRawType(), builder);

Join.of(specialized.getActualTypeArguments())
.ignoreEmpty()
.prefix("<")
.separator("," + space)
.suffix(">")
.converter(this::name)
.write(builder);
} else if (type instanceof ParameterizedType parameterized) {
qualify(parameterized.getRawType(), builder);

Expand Down Expand Up @@ -1010,16 +1020,6 @@ private void qualify(Type type, StringBuilder builder) {
});
} else if (type instanceof GenericArrayType array) {
throw new Error("Generic array");
} else if (type instanceof SpecializedType specialized) {
qualify(specialized.getRawType(), builder);

Join.of(specialized.getActualTypeArguments())
.ignoreEmpty()
.prefix("<")
.separator("," + space)
.suffix(">")
.converter(this::name)
.write(builder);
} else {
throw new Error(String.valueOf(type));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
import org.junit.jupiter.api.Test;

import reincarnation.CodeVerifier;
import reincarnation.Debuggable;
import reincarnation.TestCode;

@Debuggable()
class MethodReferenceTest extends CodeVerifier {

@Test
Expand Down

0 comments on commit 6321803

Please sign in to comment.