Add classpath abstraction - meant to ease testing
This commit is contained in:
8 files changed
+69
-7
No files matched your search
+3
-3
@@ -27,7 +27,7 @@ public class AsmSymbolResolver implements SymbolResolver {
|
||||
static final int ASM_API_V = Opcodes.ASM9;
|
||||
|
||||
private final TypeSystem ts;
|
||||
private final ClassLoader classLoader;
|
||||
private final Classpath classLoader;
|
||||
private final SignatureParser typeLoader;
|
||||
|
||||
private final ConcurrentHashMap<String, SoftClassReference> knownStubs = new ConcurrentHashMap<>();
|
||||
@@ -38,7 +38,7 @@ public class AsmSymbolResolver implements SymbolResolver {
|
||||
*/
|
||||
private final SoftClassReference failed;
|
||||
|
||||
public AsmSymbolResolver(TypeSystem ts, ClassLoader classLoader) {
|
||||
public AsmSymbolResolver(TypeSystem ts, Classpath classLoader) {
|
||||
this.ts = ts;
|
||||
this.classLoader = classLoader;
|
||||
this.typeLoader = new SignatureParser(this);
|
||||
@@ -104,7 +104,7 @@ public class AsmSymbolResolver implements SymbolResolver {
|
||||
|
||||
@Nullable
|
||||
URL getUrlOfInternalName(String internalName) {
|
||||
return classLoader.getResource(internalName + ".class");
|
||||
return classLoader.getURLForResource(internalName + ".class");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.symbols.internal.asm;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Classpath abstraction.
|
||||
*/
|
||||
public interface Classpath {
|
||||
|
||||
/**
|
||||
* Returns a URL to load the given resource if it exists in this classpath.
|
||||
* Otherwise returns null.
|
||||
*/
|
||||
@Nullable URL getURLForResource(String resourcePath);
|
||||
|
||||
/**
|
||||
* Returns a classpath instance that uses {@link ClassLoader#getResource(String)}
|
||||
* to find resources.
|
||||
*/
|
||||
static Classpath forClassLoader(ClassLoader classLoader) {
|
||||
return classLoader::getResource;
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol;
|
||||
import net.sourceforge.pmd.lang.java.symbols.SymbolResolver;
|
||||
import net.sourceforge.pmd.lang.java.symbols.internal.UnresolvedClassStore;
|
||||
import net.sourceforge.pmd.lang.java.symbols.internal.asm.AsmSymbolResolver;
|
||||
import net.sourceforge.pmd.lang.java.symbols.internal.asm.Classpath;
|
||||
import net.sourceforge.pmd.lang.java.types.BasePrimitiveSymbol.RealPrimitiveSymbol;
|
||||
import net.sourceforge.pmd.lang.java.types.BasePrimitiveSymbol.VoidSymbol;
|
||||
import net.sourceforge.pmd.lang.java.types.JPrimitiveType.PrimitiveTypeKind;
|
||||
@@ -53,7 +54,7 @@ import net.sourceforge.pmd.util.CollectionUtil;
|
||||
* <p>The lifetime of a type system is the analysis: it is shared by
|
||||
* all compilation units.
|
||||
* TODO this is hacked together by comparing the ClassLoader, but this
|
||||
* should be in the language instance
|
||||
* should be in the language instance
|
||||
*
|
||||
* <p>Nodes have a reference to the type system they were created for:
|
||||
* {@link JavaNode#getTypeSystem()}.
|
||||
@@ -179,8 +180,20 @@ public final class TypeSystem {
|
||||
* to populate the fields of the new type
|
||||
* system
|
||||
*/
|
||||
public TypeSystem(ClassLoader bootstrapResourceLoader) {
|
||||
this(ts -> new AsmSymbolResolver(ts, bootstrapResourceLoader));
|
||||
public static TypeSystem usingClassLoaderClasspath(ClassLoader bootstrapResourceLoader) {
|
||||
return usingClasspath(Classpath.forClassLoader(bootstrapResourceLoader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new type system. Its public fields will be initialized
|
||||
* with fresh types, unrelated to other types.
|
||||
*
|
||||
* @param bootstrapResourceLoader Classpath used to resolve class files
|
||||
* to populate the fields of the new type
|
||||
* system
|
||||
*/
|
||||
public static TypeSystem usingClasspath(Classpath bootstrapResourceLoader) {
|
||||
return new TypeSystem(ts -> new AsmSymbolResolver(ts, bootstrapResourceLoader));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -724,6 +737,7 @@ public final class TypeSystem {
|
||||
}
|
||||
|
||||
private static final class NullType implements JTypeMirror {
|
||||
|
||||
private final TypeSystem ts;
|
||||
|
||||
NullType(TypeSystem ts) {
|
||||
|
||||
@@ -37,7 +37,7 @@ public class JavaParsingHelper extends BaseParsingHelper<JavaParsingHelper, ASTC
|
||||
* default options of JavaParsingHelper. This allows constants like
|
||||
* the null type to be compared.
|
||||
*/
|
||||
public static final TypeSystem TEST_TYPE_SYSTEM = new TypeSystem(JavaParsingHelper.class.getClassLoader());
|
||||
public static final TypeSystem TEST_TYPE_SYSTEM = TypeSystem.usingClassLoaderClasspath(JavaParsingHelper.class.getClassLoader());
|
||||
|
||||
/** This just runs the parser and no processing stages. */
|
||||
public static final JavaParsingHelper JUST_PARSE = new JavaParsingHelper(Params.getDefaultNoProcess(), SemanticErrorReporter.noop(), TEST_TYPE_SYSTEM, TypeInferenceLogger.noop());
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
|
||||
package my.pack;
|
||||
|
||||
|
||||
/*
|
||||
For this test we compile this file manually, save the classes in the
|
||||
resource tree, but purposefully exclude SuperItf.class to mimic an
|
||||
incomplete classpath.
|
||||
*/
|
||||
|
||||
|
||||
class SuperKlass<A, B> { }
|
||||
interface SuperItf<A, B> { }
|
||||
|
||||
|
||||
public class BrokenGeneric<C, D> extends SuperKlass<C, C> implements SuperItf<D, D> {
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user