Skip to content

Commit 4106272

Browse files
fluentfuturenick-someone
authored andcommitted
Add ClassInfo.isTopLevel().
Seems like a useful method? I can't remember why I didn't add it in the first place. Perhaps just an oversight. Partially addresses #3349 RELNOTES=`reflect`: Added `ClassInfo.isTopLevel()`. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=338738055
1 parent 33f2b15 commit 4106272

File tree

2 files changed

+54
-22
lines changed

2 files changed

+54
-22
lines changed

android/guava/src/com/google/common/reflect/ClassPath.java

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,6 @@
7878
public final class ClassPath {
7979
private static final Logger logger = Logger.getLogger(ClassPath.class.getName());
8080

81-
private static final Predicate<ClassInfo> IS_TOP_LEVEL =
82-
new Predicate<ClassInfo>() {
83-
@Override
84-
public boolean apply(ClassInfo info) {
85-
return info.className.indexOf('$') == -1;
86-
}
87-
};
88-
8981
/** Separator for the Class-Path manifest attribute value in jar files. */
9082
private static final Splitter CLASS_PATH_ATTRIBUTE_SEPARATOR =
9183
Splitter.on(" ").omitEmptyStrings();
@@ -137,9 +129,21 @@ public ImmutableSet<ClassInfo> getAllClasses() {
137129
return FluentIterable.from(resources).filter(ClassInfo.class).toSet();
138130
}
139131

140-
/** Returns all top level classes loadable from the current class path. */
132+
/**
133+
* Returns all top level classes loadable from the current class path. Note that "top-level-ness"
134+
* is determined heuristically by class name (see {@link ClassInfo#isTopLevel}).
135+
*/
141136
public ImmutableSet<ClassInfo> getTopLevelClasses() {
142-
return FluentIterable.from(resources).filter(ClassInfo.class).filter(IS_TOP_LEVEL).toSet();
137+
return FluentIterable.from(resources)
138+
.filter(ClassInfo.class)
139+
.filter(
140+
new Predicate<ClassInfo>() {
141+
@Override
142+
public boolean apply(ClassInfo info) {
143+
return info.isTopLevel();
144+
}
145+
})
146+
.toSet();
143147
}
144148

145149
/** Returns all top level classes whose package name is {@code packageName}. */
@@ -324,6 +328,18 @@ public String getName() {
324328
return className;
325329
}
326330

331+
/**
332+
* Returns true if the class name "looks to be" top level (not nested), that is, it includes no
333+
* '$' in the name, This method may return false for a top-level class that's intentionally
334+
* named with the '$' character. If ths is a concern, you could use {@link #load} and then check
335+
* on the loaded {@link Class} object instead.
336+
*
337+
* @since NEXT
338+
*/
339+
public boolean isTopLevel() {
340+
return className.indexOf('$') == -1;
341+
}
342+
327343
/**
328344
* Loads (but doesn't link or initialize) the class.
329345
*
@@ -408,7 +424,7 @@ private void scanJar(File file, ClassLoader classloader) throws IOException {
408424
} finally {
409425
try {
410426
jarFile.close();
411-
} catch (IOException ignored) {
427+
} catch (IOException ignored) { // similar to try-with-resources, but don't fail scanning
412428
}
413429
}
414430
}

guava/src/com/google/common/reflect/ClassPath.java

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,6 @@
7878
public final class ClassPath {
7979
private static final Logger logger = Logger.getLogger(ClassPath.class.getName());
8080

81-
private static final Predicate<ClassInfo> IS_TOP_LEVEL =
82-
new Predicate<ClassInfo>() {
83-
@Override
84-
public boolean apply(ClassInfo info) {
85-
return info.className.indexOf('$') == -1;
86-
}
87-
};
88-
8981
/** Separator for the Class-Path manifest attribute value in jar files. */
9082
private static final Splitter CLASS_PATH_ATTRIBUTE_SEPARATOR =
9183
Splitter.on(" ").omitEmptyStrings();
@@ -137,9 +129,21 @@ public ImmutableSet<ClassInfo> getAllClasses() {
137129
return FluentIterable.from(resources).filter(ClassInfo.class).toSet();
138130
}
139131

140-
/** Returns all top level classes loadable from the current class path. */
132+
/**
133+
* Returns all top level classes loadable from the current class path. Note that "top-level-ness"
134+
* is determined heuristically by class name (see {@link ClassInfo#isTopLevel}).
135+
*/
141136
public ImmutableSet<ClassInfo> getTopLevelClasses() {
142-
return FluentIterable.from(resources).filter(ClassInfo.class).filter(IS_TOP_LEVEL).toSet();
137+
return FluentIterable.from(resources)
138+
.filter(ClassInfo.class)
139+
.filter(
140+
new Predicate<ClassInfo>() {
141+
@Override
142+
public boolean apply(ClassInfo info) {
143+
return info.isTopLevel();
144+
}
145+
})
146+
.toSet();
143147
}
144148

145149
/** Returns all top level classes whose package name is {@code packageName}. */
@@ -324,6 +328,18 @@ public String getName() {
324328
return className;
325329
}
326330

331+
/**
332+
* Returns true if the class name "looks to be" top level (not nested), that is, it includes no
333+
* '$' in the name, This method may return false for a top-level class that's intentionally
334+
* named with the '$' character. If ths is a concern, you could use {@link #load} and then check
335+
* on the loaded {@link Class} object instead.
336+
*
337+
* @since NEXT
338+
*/
339+
public boolean isTopLevel() {
340+
return className.indexOf('$') == -1;
341+
}
342+
327343
/**
328344
* Loads (but doesn't link or initialize) the class.
329345
*
@@ -408,7 +424,7 @@ private void scanJar(File file, ClassLoader classloader) throws IOException {
408424
} finally {
409425
try {
410426
jarFile.close();
411-
} catch (IOException ignored) {
427+
} catch (IOException ignored) { // similar to try-with-resources, but don't fail scanning
412428
}
413429
}
414430
}

0 commit comments

Comments
 (0)