Merge "Fix ClassScanner and re-enable CodeInspectionTest tests"

This commit is contained in:
TreeHugger Robot
2017-08-31 23:26:51 +00:00
committed by Android (Google) Code Review
2 changed files with 29 additions and 93 deletions

View File

@@ -16,50 +16,47 @@
package com.android.settings.core.codeinspection;
import java.io.File;
import com.google.common.reflect.ClassPath;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Scans and builds all classes in current classloader.
*/
public class ClassScanner {
private static final String CLASS_SUFFIX = ".class";
public List<Class<?>> getClassesForPackage(String packageName)
throws ClassNotFoundException {
final List<Class<?>> classes = new ArrayList<>();
try {
final Enumeration<URL> resources = Thread.currentThread().getContextClassLoader()
.getResources(packageName.replace('.', '/'));
if (!resources.hasMoreElements()) {
return classes;
}
URL url = resources.nextElement();
while (url != null) {
final URLConnection connection = url.openConnection();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ClassPath classPath = ClassPath.from(classLoader);
if (connection instanceof JarURLConnection) {
loadClassFromJar((JarURLConnection) connection, packageName,
classes);
} else {
loadClassFromDirectory(new File(URLDecoder.decode(url.getPath(), "UTF-8")),
packageName, classes);
}
if (resources.hasMoreElements()) {
url = resources.nextElement();
} else {
break;
// Some anonymous classes don't return true when calling isAnonymousClass(), but they
// always seem to be nested anonymous classes like com.android.settings.Foo$1$2. In
// general we don't want any anonymous classes so we just filter these out by searching
// for $[0-9] in the name.
Pattern anonymousClassPattern = Pattern.compile(".*\\$\\d+.*");
Matcher anonymousClassMatcher = anonymousClassPattern.matcher("");
for (ClassPath.ClassInfo info : classPath.getAllClasses()) {
if (info.getPackageName().startsWith(packageName)) {
try {
Class clazz = classLoader.loadClass(info.getName());
if (clazz.isAnonymousClass() || anonymousClassMatcher.reset(
clazz.getName()).matches()) {
continue;
}
classes.add(clazz);
} catch (NoClassDefFoundError e) {
// do nothing. this class hasn't been found by the
// loader, and we don't care.
}
}
}
} catch (final IOException e) {
@@ -68,63 +65,4 @@ public class ClassScanner {
return classes;
}
private void loadClassFromDirectory(File directory, String packageName, List<Class<?>> classes)
throws ClassNotFoundException {
if (directory.exists() && directory.isDirectory()) {
final String[] files = directory.list();
for (final String file : files) {
if (file.endsWith(CLASS_SUFFIX)) {
try {
classes.add(Class.forName(
packageName + '.' + file.substring(0, file.length() - 6),
false /* init */,
Thread.currentThread().getContextClassLoader()));
} catch (NoClassDefFoundError e) {
// do nothing. this class hasn't been found by the
// loader, and we don't care.
}
} else {
final File tmpDirectory = new File(directory, file);
if (tmpDirectory.isDirectory()) {
loadClassFromDirectory(tmpDirectory, packageName + "." + file, classes);
}
}
}
}
}
private void loadClassFromJar(JarURLConnection connection, String packageName,
List<Class<?>> classes) throws ClassNotFoundException, IOException {
final JarFile jarFile = connection.getJarFile();
final Enumeration<JarEntry> entries = jarFile.entries();
String name;
if (!entries.hasMoreElements()) {
return;
}
JarEntry jarEntry = entries.nextElement();
while (jarEntry != null) {
name = jarEntry.getName();
if (name.contains(CLASS_SUFFIX)) {
name = name.substring(0, name.length() - CLASS_SUFFIX.length()).replace('/', '.');
if (name.startsWith(packageName)) {
try {
classes.add(Class.forName(name,
false /* init */,
Thread.currentThread().getContextClassLoader()));
} catch (NoClassDefFoundError e) {
// do nothing. this class hasn't been found by the
// loader, and we don't care.
}
}
}
if (entries.hasMoreElements()) {
jarEntry = entries.nextElement();
} else {
break;
}
}
}
}

View File

@@ -44,14 +44,12 @@ public class CodeInspectionTest {
@Before
public void setUp() throws Exception {
mClasses = new ClassScanner().getClassesForPackage(CodeInspector.PACKAGE_NAME);
// Disabled temporarily - see b/64840107
//assertThat(mClasses).isNotEmpty();
assertThat(mClasses).isNotEmpty();
}
@Test
public void runCodeInspections() {
// Disabled temporarily - see b/64840107
// new InstrumentableFragmentCodeInspector(mClasses).run();
// new SearchIndexProviderCodeInspector(mClasses).run();
new InstrumentableFragmentCodeInspector(mClasses).run();
new SearchIndexProviderCodeInspector(mClasses).run();
}
}