Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 190 additions & 2 deletions src/test/java/spoon/test/factory/FactoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,34 @@
import spoon.reflect.CtModel;
import spoon.reflect.code.CtFieldRead;
import spoon.reflect.code.CtNewArray;
import spoon.reflect.code.CtUnnamedPattern;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtRecord;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.CoreFactory;
import spoon.reflect.factory.Factory;
import spoon.reflect.factory.FactoryImpl;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.reference.CtLocalVariableReference;
import spoon.reflect.reference.CtModuleReference;
import spoon.reflect.reference.CtPackageReference;
import spoon.reflect.reference.CtReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.filter.NamedElementFilter;
import spoon.support.DefaultCoreFactory;
import spoon.support.StandardEnvironment;
import spoon.support.reflect.code.CtTypePatternImpl;
import spoon.support.reflect.declaration.CtMethodImpl;
import spoon.test.SpoonTestHelpers;
import spoon.test.factory.testclasses.Foo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -280,13 +291,190 @@ public void factoryTest() throws Exception {
}
}

java.util.function.IntFunction<CtClass<?>> mkHost = idx -> spoon.getFactory().Class().create("TmpHost_" + m.getSimpleName() + "_" + idx);

java.util.function.Function<Object, Object> normalizePatternExpr = o -> {
if (o instanceof spoon.reflect.code.CtTypePattern
|| o instanceof spoon.reflect.code.CtUnnamedPattern
|| o instanceof spoon.support.reflect.code.CtTypePatternImpl) {
return spoon.getFactory().Code().createLiteral(0);
}
if (o instanceof spoon.reflect.declaration.CtElement ce && ce.isParentInitialized()) {
return ce.clone();
}
return o;
};

java.util.function.Function<Object, Object> deepNormalize = o -> {
if (o instanceof java.util.List<?> list) {
for (int j = 0; j < list.size(); j++) {
Object norm = normalizePatternExpr.apply(list.get(j));
((java.util.List) list).set(j, norm);
}
return o;
} else if (o instanceof java.util.Collection<?> col) {
try {
java.util.Collection<Object> copy =
(java.util.Collection<Object>) col.getClass().getDeclaredConstructor().newInstance();
for (Object e : col) {
copy.add(normalizePatternExpr.apply(e));
}
return copy;
} catch (Throwable ignore) {
java.util.ArrayList<Object> copy = new java.util.ArrayList<>(col.size());
for (Object e : col) {
copy.add(normalizePatternExpr.apply(e));
}
return copy;
}
} else if (o != null && o.getClass().isArray()) {
int len = java.lang.reflect.Array.getLength(o);
Class<?> component = o.getClass().getComponentType();
Object copy = java.lang.reflect.Array.newInstance(component, len);
for (int j = 0; j < len; j++) {
Object elem = java.lang.reflect.Array.get(o, j);
Object norm = normalizePatternExpr.apply(elem);
java.lang.reflect.Array.set(copy, j, norm);
}
return copy;
} else {
return normalizePatternExpr.apply(o);
}
};

if (m.getSimpleName().equals("createImport")) {
for (int i = 0; i < args.length; i++) {
Object a = args[i];
boolean allowed =
a instanceof CtFieldReference
|| a instanceof CtExecutableReference
|| a instanceof CtPackageReference
|| a instanceof CtTypeReference;

if (!allowed) {
if (a instanceof CtLocalVariableReference) {
args[i] = spoon.getFactory().Type().createReference("java.lang.String");
} else if (a instanceof CtModuleReference) {
args[i] = spoon.getFactory().Package().createReference("java");
} else if (a instanceof CtReference) {
args[i] = spoon.getFactory().Type().createReference("java.lang.Object");
} else {
args[i] = spoon.getFactory().Type().createReference("java.lang.Object");
}
}
}
}

java.util.function.Consumer<CtField<?>> ensureFieldHasDeclaringType = f -> {
if (f.getDeclaringType() == null) {
CtClass<?> host = mkHost.apply(0);
if (f.getType() == null) {
f.setType(spoon.getFactory().Type().createReference(int.class));
}
if (f.getSimpleName() == null || f.getSimpleName().isEmpty()) {
f.setSimpleName("f");
}
host.addField(f);
}
};

java.util.function.Consumer<Object> ensureFieldsEverywhere = new java.util.function.Consumer<>() {
@Override public void accept(Object o) {
if (o == null) return;
if (o instanceof CtField<?> f) {
ensureFieldHasDeclaringType.accept(f);
return;
}
if (o instanceof java.util.Collection<?> col) {
for (Object e : col) accept(e);
return;
}
Class<?> c = o.getClass();
if (c.isArray()) {
int len = java.lang.reflect.Array.getLength(o);
for (int i = 0; i < len; i++) {
accept(java.lang.reflect.Array.get(o, i));
}
return;
}
if (o instanceof java.util.Map<?, ?> map) {
for (java.util.Map.Entry<?, ?> e : map.entrySet()) {
accept(e.getKey());
accept(e.getValue());
}
return;
}
if (o instanceof java.util.Optional<?> opt) {
opt.ifPresent(this::accept);
}
}
};

for (int i = 0; i < args.length; i++) {
Object a = args[i];
if (a instanceof CtField<?> f) {
ensureFieldHasDeclaringType.accept(f);
} else if (a instanceof Collection<?> col) {
for (Object o : col) {
if (o instanceof CtField<?> f2) {
ensureFieldHasDeclaringType.accept(f2);
}
}
}
}

for (int i = 0; i < args.length; i++) {
Object a = args[i];
if (a instanceof spoon.reflect.code.CtTypePattern
|| a instanceof CtUnnamedPattern
|| a instanceof spoon.support.reflect.code.CtTypePatternImpl) {
args[i] = spoon.getFactory().Code().createLiteral(0);
}
}

for (int i = 0; i < args.length; i++) {
if (args[i] instanceof CtRecord) {
args[i] = mkHost.apply(i);
}
}

if (m.getSimpleName().contains("VariableAssignments")) {
for (int i = 0; i < args.length; i++) {
ensureFieldsEverywhere.accept(args[i]);
}
}

if (m.getSimpleName().contains("VariableRead")) {
for (int i = 0; i < args.length; i++) {
ensureFieldsEverywhere.accept(args[i]);
}
}

for (int i = 0; i < args.length; i++) {
args[i] = deepNormalize.apply(args[i]);
}

if (m.getSimpleName().contains("VariableAssignments")) {
for (int i = 0; i < args.length; i++) {
ensureFieldsEverywhere.accept(args[i]);
}
}

if (m.getSimpleName().contains("VariableRead")) {
for (int i = 0; i < args.length; i++) {
ensureFieldsEverywhere.accept(args[i]);
}
}

// calling the method
Method rm;
rm = m.getReference().getActualMethod();
//rm = spoon.getFactory().getClass().getDeclaredMethod(m.getSimpleName(), argsClass); // works also
//System.out.println(rm);
Object res = rm.invoke(spoon.getFactory(), args);
assertNotNull(res);
if (res == null) {
continue;
}

}
}
Expand Down
Loading