use of spoon.support.SpoonClassNotFoundException in project spoon by INRIA.
the class SuperInheritanceHierarchyFunction method visitSuperInterfaces.
/**
* calls `outputConsumer.accept(interface)` for all superInterfaces of type recursively.
*/
protected void visitSuperInterfaces(CtTypeReference<?> type, CtConsumer<Object> outputConsumer) {
Set<CtTypeReference<?>> superInterfaces;
try {
superInterfaces = type.getSuperInterfaces();
} catch (SpoonClassNotFoundException e) {
if (failOnClassNotFound) {
throw e;
}
Launcher.LOGGER.warn("Cannot load class: " + type.getQualifiedName() + " with class loader " + Thread.currentThread().getContextClassLoader());
return;
}
for (CtTypeReference<?> ifaceRef : superInterfaces) {
ScanningMode mode = enter(ifaceRef, false);
if (mode == SKIP_ALL) {
continue;
}
sendResult(ifaceRef, outputConsumer);
if (mode == NORMAL && query.isTerminated() == false) {
visitSuperInterfaces(ifaceRef, outputConsumer);
}
exit(ifaceRef, false);
if (query.isTerminated()) {
return;
}
}
}
use of spoon.support.SpoonClassNotFoundException in project spoon by INRIA.
the class NoClasspathTest method test.
@Test
public void test() throws Exception {
// do we still have a correct model when the complete classpath is not given as input?
Launcher spoon = new Launcher();
spoon.getEnvironment().setNoClasspath(true);
spoon.getEnvironment().setLevel("OFF");
spoon.addInputResource("./src/test/resources/spoon/test/noclasspath/fields");
spoon.getEnvironment().setSourceOutputDirectory(new File("target/spooned/apitest"));
spoon.run();
Factory factory = spoon.getFactory();
CtClass<Object> clazz = factory.Class().get("Foo");
assertEquals("Foo", clazz.getSimpleName());
CtTypeReference<?> superclass = clazz.getSuperclass();
// "Unknown" is not in the classpath at all
assertEquals("Unknown", superclass.getSimpleName());
try {
superclass.getActualClass();
fail();
} catch (SpoonClassNotFoundException e) {
// expected
}
assertNull(superclass.getDeclaration());
// should be empty as in noClasspath the actual class cannot be retrieved
assertTrue(superclass.getAllFields().isEmpty());
// now we really make sure we don't have the class in the classpath
try {
superclass.getActualClass();
fail();
} catch (SpoonClassNotFoundException e) {
// expected
}
{
CtMethod<?> method = clazz.getMethod("method", new CtTypeReference[0]);
assertNotNull(method);
List<CtInvocation<?>> invocations = method.getElements(new TypeFilter<CtInvocation<?>>(CtInvocation.class));
assertEquals(1, invocations.size());
CtInvocation<?> c = invocations.get(0);
assertEquals("method", c.getExecutable().getSimpleName());
assertEquals("x.method()", method.getBody().getStatement(1).toString());
}
{
CtMethod<?> method = clazz.getMethod("m2", new CtTypeReference[0]);
assertNotNull(method);
List<CtInvocation<?>> invocations = method.getElements(new TypeFilter<CtInvocation<?>>(CtInvocation.class));
assertEquals(3, invocations.size());
CtInvocation<?> c = invocations.get(1);
assertEquals("second", c.getExecutable().getSimpleName());
assertEquals("x.first().second().third()", method.getBody().getStatement(1).toString());
}
{
CtMethod<?> method = clazz.getMethod("m1", new CtTypeReference[0]);
assertNotNull(method);
List<CtInvocation<?>> invocations = method.getElements(new TypeFilter<CtInvocation<?>>(CtInvocation.class));
assertEquals(1, invocations.size());
invocations.get(0);
assertEquals("x.y.z.method()", method.getBody().getStatement(0).toString());
}
{
CtMethod<?> method = clazz.getMethod("m3", new CtTypeReference[0]);
assertNotNull(method);
List<CtInvocation<?>> invocations = method.getElements(new TypeFilter<CtInvocation<?>>(CtInvocation.class));
assertEquals(1, invocations.size());
invocations.get(0);
CtLocalVariable<?> statement = method.getBody().getStatement(0);
CtFieldAccess<?> fa = (CtFieldAccess<?>) statement.getDefaultExpression();
assertTrue(fa.getTarget() instanceof CtInvocation);
assertEquals("field", fa.getVariable().getSimpleName());
assertEquals("int x = first().field", statement.toString());
}
}
use of spoon.support.SpoonClassNotFoundException in project spoon by INRIA.
the class CompilationTest method testExoticClassLoader.
@Test
public void testExoticClassLoader() throws Exception {
// contract: Spoon uses the exotic class loader
final List<String> l = new ArrayList<>();
class MyClassLoader extends ClassLoader {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
l.add(name);
return super.loadClass(name, resolve);
}
}
Launcher launcher = new Launcher();
launcher.getEnvironment().setInputClassLoader(new MyClassLoader());
launcher.getEnvironment().setNoClasspath(true);
launcher.addInputResource("src/test/resources/reference-test/Foo.java");
launcher.buildModel();
launcher.getModel().getRootPackage().accept(new CtScanner() {
@Override
public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
try {
// forcing loading it
reference.getTypeDeclaration();
} catch (SpoonClassNotFoundException ignore) {
}
}
});
assertEquals(3, l.size());
assertTrue(l.contains("KJHKY"));
assertEquals(MyClassLoader.class, launcher.getEnvironment().getInputClassLoader().getClass());
}
use of spoon.support.SpoonClassNotFoundException in project spoon by INRIA.
the class ClassTypingContext method resolveActualTypeArgumentsOf.
/**
* resolve actual type argument values of the provided type reference
* @param typeRef the reference to the type
* whose actual type argument values has to be resolved in scope of `scope` type
* @return actual type arguments of `typeRef` in scope of `scope` element or null if typeRef is not a super type of `scope`
*/
public List<CtTypeReference<?>> resolveActualTypeArgumentsOf(CtTypeReference<?> typeRef) {
final String typeQualifiedName = typeRef.getQualifiedName();
List<CtTypeReference<?>> args = typeToArguments.get(typeQualifiedName);
if (args != null) {
// the actual type arguments of `type` are already resolved
return args;
}
// resolve hierarchy of enclosing class first.
CtTypeReference<?> enclosingTypeRef = getEnclosingType(typeRef);
if (enclosingTypeRef != null) {
if (enclosingClassTypingContext == null) {
return null;
}
// `type` is inner class. Resolve it's enclosing class arguments first
if (enclosingClassTypingContext.resolveActualTypeArgumentsOf(enclosingTypeRef) == null) {
return null;
}
}
/*
* detect where to start/continue with resolving of super classes and super interfaces
* to found actual type arguments of input `type`
*/
if (lastResolvedSuperclass == null) {
/*
* whole super inheritance hierarchy was already resolved for this level.
* It means that `type` is not a super type of `scope` on the level `level`
*/
return null;
}
final HierarchyListener listener = new HierarchyListener(getVisitedSet());
/*
* remove last resolved class from the list of visited,
* because it would avoid visiting it's super hierarchy
*/
getVisitedSet().remove(lastResolvedSuperclass.getQualifiedName());
/*
* visit super inheritance class hierarchy of lastResolve type of level of `type` to found it's actual type arguments.
*/
((CtElement) lastResolvedSuperclass).map(new SuperInheritanceHierarchyFunction().includingSelf(false).returnTypeReferences(true).setListener(listener)).forEach(new CtConsumer<CtTypeReference<?>>() {
@Override
public void accept(CtTypeReference<?> typeRef) {
/*
* typeRef is a reference from sub type to super type.
* It contains actual type arguments in scope of sub type,
* which are going to be substituted as arguments to formal type parameters of super type
*/
String superTypeQualifiedName = typeRef.getQualifiedName();
List<CtTypeReference<?>> actualTypeArguments = typeRef.getActualTypeArguments();
if (actualTypeArguments.isEmpty()) {
// may be they are not set - check whether type declares some generic parameters
List<CtTypeParameter> typeParams;
try {
CtType<?> type = typeRef.getTypeDeclaration();
typeParams = type.getFormalCtTypeParameters();
} catch (final SpoonClassNotFoundException e) {
if (typeRef.getFactory().getEnvironment().getNoClasspath()) {
typeParams = Collections.emptyList();
} else {
throw e;
}
}
if (typeParams.size() > 0) {
// yes, there are generic type parameters. Reference should use actualTypeArguments computed from their bounds
actualTypeArguments = new ArrayList<>(typeParams.size());
for (CtTypeParameter typeParam : typeParams) {
actualTypeArguments.add(typeParam.getTypeErasure());
}
}
}
List<CtTypeReference<?>> superTypeActualTypeArgumentsResolvedFromSubType = resolveTypeParameters(actualTypeArguments);
// Remember actual type arguments of `type`
typeToArguments.put(superTypeQualifiedName, superTypeActualTypeArgumentsResolvedFromSubType);
if (typeQualifiedName.equals(superTypeQualifiedName)) {
/*
* we have found actual type arguments of input `type`
* We can finish. But only after all interfaces of last visited class are processed too
*/
listener.foundArguments = superTypeActualTypeArgumentsResolvedFromSubType;
}
}
});
if (listener.foundArguments == null) {
/*
* superclass was not found. We have scanned whole hierarchy
*/
lastResolvedSuperclass = null;
}
return listener.foundArguments;
}
use of spoon.support.SpoonClassNotFoundException in project spoon by INRIA.
the class CtTypeReferenceImpl method findClass.
/**
* Finds the class requested in {@link #getActualClass()}.
*
* Looks for the class in the standard Java classpath, but also in the sourceClassPath given as option.
*/
@SuppressWarnings("unchecked")
protected Class<T> findClass() {
try {
// creating a classloader on the fly is not the most efficient
// but it decreases the amount of state to maintain
// since getActualClass is only used in rare cases, that's OK.
ClassLoader classLoader = getFactory().getEnvironment().getInputClassLoader();
String qualifiedName = getQualifiedName();
return (Class<T>) classLoader.loadClass(qualifiedName);
} catch (Throwable e) {
throw new SpoonClassNotFoundException("cannot load class: " + getQualifiedName(), e);
}
}
Aggregations