try new-method
This commit is contained in:
parent
78237d9c80
commit
52b4651f1a
3812 changed files with 228702 additions and 223704 deletions
59
src/com/google/common/reflect/AbstractInvocationHandler.java
Normal file
59
src/com/google/common/reflect/AbstractInvocationHandler.java
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public abstract class AbstractInvocationHandler
|
||||
implements InvocationHandler {
|
||||
private static final Object[] NO_ARGS = new Object[0];
|
||||
|
||||
@Override
|
||||
public final Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
|
||||
if (args == null) {
|
||||
args = NO_ARGS;
|
||||
}
|
||||
if (args.length == 0 && method.getName().equals("hashCode")) {
|
||||
return this.hashCode();
|
||||
}
|
||||
if (args.length == 1 && method.getName().equals("equals") && method.getParameterTypes()[0] == Object.class) {
|
||||
Object arg = args[0];
|
||||
if (arg == null) {
|
||||
return false;
|
||||
}
|
||||
if (proxy == arg) {
|
||||
return true;
|
||||
}
|
||||
return AbstractInvocationHandler.isProxyOfSameInterfaces(arg, proxy.getClass()) && this.equals(Proxy.getInvocationHandler(arg));
|
||||
}
|
||||
if (args.length == 0 && method.getName().equals("toString")) {
|
||||
return this.toString();
|
||||
}
|
||||
return this.handleInvocation(proxy, method, args);
|
||||
}
|
||||
|
||||
protected abstract Object handleInvocation(Object var1, Method var2, Object[] var3) throws Throwable;
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
private static boolean isProxyOfSameInterfaces(Object arg, Class<?> proxyClass) {
|
||||
return proxyClass.isInstance(arg) || Proxy.isProxyClass(arg.getClass()) && Arrays.equals(arg.getClass().getInterfaces(), proxyClass.getInterfaces());
|
||||
}
|
||||
}
|
342
src/com/google/common/reflect/ClassPath.java
Normal file
342
src/com/google/common/reflect/ClassPath.java
Normal file
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableCollection;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.reflect.Reflection;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public final class ClassPath {
|
||||
private static final Logger logger = Logger.getLogger(ClassPath.class.getName());
|
||||
private static final Predicate<ClassInfo> IS_TOP_LEVEL = new Predicate<ClassInfo>(){
|
||||
|
||||
@Override
|
||||
public boolean apply(ClassInfo info) {
|
||||
return info.className.indexOf(36) == -1;
|
||||
}
|
||||
};
|
||||
private static final Splitter CLASS_PATH_ATTRIBUTE_SEPARATOR = Splitter.on(" ").omitEmptyStrings();
|
||||
private static final String CLASS_FILE_NAME_EXTENSION = ".class";
|
||||
private final ImmutableSet<ResourceInfo> resources;
|
||||
|
||||
private ClassPath(ImmutableSet<ResourceInfo> resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
public static ClassPath from(ClassLoader classloader) throws IOException {
|
||||
Scanner scanner = new Scanner();
|
||||
for (Map.Entry entry : ClassPath.getClassPathEntries(classloader).entrySet()) {
|
||||
scanner.scan((URI)entry.getKey(), (ClassLoader)entry.getValue());
|
||||
}
|
||||
return new ClassPath(scanner.getResources());
|
||||
}
|
||||
|
||||
public ImmutableSet<ResourceInfo> getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
public ImmutableSet<ClassInfo> getAllClasses() {
|
||||
return FluentIterable.from(this.resources).filter(ClassInfo.class).toSet();
|
||||
}
|
||||
|
||||
public ImmutableSet<ClassInfo> getTopLevelClasses() {
|
||||
return FluentIterable.from(this.resources).filter(ClassInfo.class).filter(IS_TOP_LEVEL).toSet();
|
||||
}
|
||||
|
||||
public ImmutableSet<ClassInfo> getTopLevelClasses(String packageName) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
ImmutableSet.Builder builder = ImmutableSet.builder();
|
||||
for (ClassInfo classInfo : this.getTopLevelClasses()) {
|
||||
if (!classInfo.getPackageName().equals(packageName)) continue;
|
||||
builder.add(classInfo);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public ImmutableSet<ClassInfo> getTopLevelClassesRecursive(String packageName) {
|
||||
Preconditions.checkNotNull(packageName);
|
||||
String string = String.valueOf(String.valueOf(packageName));
|
||||
String packagePrefix = new StringBuilder(1 + string.length()).append(string).append(".").toString();
|
||||
ImmutableSet.Builder builder = ImmutableSet.builder();
|
||||
for (ClassInfo classInfo : this.getTopLevelClasses()) {
|
||||
if (!classInfo.getName().startsWith(packagePrefix)) continue;
|
||||
builder.add(classInfo);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static ImmutableMap<URI, ClassLoader> getClassPathEntries(ClassLoader classloader) {
|
||||
LinkedHashMap<URI, ClassLoader> entries = Maps.newLinkedHashMap();
|
||||
ClassLoader parent = classloader.getParent();
|
||||
if (parent != null) {
|
||||
entries.putAll(ClassPath.getClassPathEntries(parent));
|
||||
}
|
||||
if (classloader instanceof URLClassLoader) {
|
||||
URLClassLoader urlClassLoader = (URLClassLoader)classloader;
|
||||
for (URL entry : urlClassLoader.getURLs()) {
|
||||
URI uri;
|
||||
try {
|
||||
uri = entry.toURI();
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
if (entries.containsKey(uri)) continue;
|
||||
entries.put(uri, classloader);
|
||||
}
|
||||
}
|
||||
return ImmutableMap.copyOf(entries);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static String getClassName(String filename) {
|
||||
int classNameEnd = filename.length() - CLASS_FILE_NAME_EXTENSION.length();
|
||||
return filename.substring(0, classNameEnd).replace('/', '.');
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static final class Scanner {
|
||||
private final ImmutableSortedSet.Builder<ResourceInfo> resources = new ImmutableSortedSet.Builder<Object>(Ordering.usingToString());
|
||||
private final Set<URI> scannedUris = Sets.newHashSet();
|
||||
|
||||
Scanner() {
|
||||
}
|
||||
|
||||
ImmutableSortedSet<ResourceInfo> getResources() {
|
||||
return this.resources.build();
|
||||
}
|
||||
|
||||
void scan(URI uri, ClassLoader classloader) throws IOException {
|
||||
if (uri.getScheme().equals("file") && this.scannedUris.add(uri)) {
|
||||
this.scanFrom(new File(uri), classloader);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void scanFrom(File file, ClassLoader classloader) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
this.scanDirectory(file, classloader);
|
||||
} else {
|
||||
this.scanJar(file, classloader);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanDirectory(File directory, ClassLoader classloader) throws IOException {
|
||||
this.scanDirectory(directory, classloader, "", ImmutableSet.<File>of());
|
||||
}
|
||||
|
||||
private void scanDirectory(File directory, ClassLoader classloader, String packagePrefix, ImmutableSet<File> ancestors) throws IOException {
|
||||
File canonical = directory.getCanonicalFile();
|
||||
if (ancestors.contains(canonical)) {
|
||||
return;
|
||||
}
|
||||
File[] files = directory.listFiles();
|
||||
if (files == null) {
|
||||
String string = String.valueOf(String.valueOf(directory));
|
||||
logger.warning(new StringBuilder(22 + string.length()).append("Cannot read directory ").append(string).toString());
|
||||
return;
|
||||
}
|
||||
ImmutableCollection newAncestors = ((ImmutableSet.Builder)((ImmutableSet.Builder)ImmutableSet.builder().addAll(ancestors)).add(canonical)).build();
|
||||
for (File f : files) {
|
||||
String resourceName;
|
||||
String name = f.getName();
|
||||
if (f.isDirectory()) {
|
||||
String string = String.valueOf(String.valueOf(packagePrefix));
|
||||
String string2 = String.valueOf(String.valueOf(name));
|
||||
this.scanDirectory(f, classloader, new StringBuilder(1 + string.length() + string2.length()).append(string).append(string2).append("/").toString(), (ImmutableSet<File>)newAncestors);
|
||||
continue;
|
||||
}
|
||||
String string = String.valueOf(packagePrefix);
|
||||
String string3 = String.valueOf(name);
|
||||
String string4 = resourceName = string3.length() != 0 ? string.concat(string3) : new String(string);
|
||||
if (resourceName.equals("META-INF/MANIFEST.MF")) continue;
|
||||
this.resources.add((Object)ResourceInfo.of(resourceName, classloader));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING - Removed try catching itself - possible behaviour change.
|
||||
*/
|
||||
private void scanJar(File file, ClassLoader classloader) throws IOException {
|
||||
JarFile jarFile;
|
||||
try {
|
||||
jarFile = new JarFile(file);
|
||||
}
|
||||
catch (IOException e) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
for (URI uri : Scanner.getClassPathFromManifest(file, jarFile.getManifest())) {
|
||||
this.scan(uri, classloader);
|
||||
}
|
||||
Enumeration<JarEntry> entries = jarFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
if (entry.isDirectory() || entry.getName().equals("META-INF/MANIFEST.MF")) continue;
|
||||
this.resources.add((Object)ResourceInfo.of(entry.getName(), classloader));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
jarFile.close();
|
||||
}
|
||||
catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static ImmutableSet<URI> getClassPathFromManifest(File jarFile, @Nullable Manifest manifest) {
|
||||
if (manifest == null) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
ImmutableSet.Builder builder = ImmutableSet.builder();
|
||||
String classpathAttribute = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH.toString());
|
||||
if (classpathAttribute != null) {
|
||||
for (String path : CLASS_PATH_ATTRIBUTE_SEPARATOR.split(classpathAttribute)) {
|
||||
URI uri;
|
||||
try {
|
||||
uri = Scanner.getClassPathEntry(jarFile, path);
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
String string = String.valueOf(path);
|
||||
logger.warning(string.length() != 0 ? "Invalid Class-Path entry: ".concat(string) : new String("Invalid Class-Path entry: "));
|
||||
continue;
|
||||
}
|
||||
builder.add(uri);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static URI getClassPathEntry(File jarFile, String path) throws URISyntaxException {
|
||||
URI uri = new URI(path);
|
||||
if (uri.isAbsolute()) {
|
||||
return uri;
|
||||
}
|
||||
return new File(jarFile.getParentFile(), path.replace('/', File.separatorChar)).toURI();
|
||||
}
|
||||
}
|
||||
|
||||
@Beta
|
||||
public static final class ClassInfo
|
||||
extends ResourceInfo {
|
||||
private final String className;
|
||||
|
||||
ClassInfo(String resourceName, ClassLoader loader) {
|
||||
super(resourceName, loader);
|
||||
this.className = ClassPath.getClassName(resourceName);
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return Reflection.getPackageName(this.className);
|
||||
}
|
||||
|
||||
public String getSimpleName() {
|
||||
int lastDollarSign = this.className.lastIndexOf(36);
|
||||
if (lastDollarSign != -1) {
|
||||
String innerClassName = this.className.substring(lastDollarSign + 1);
|
||||
return CharMatcher.DIGIT.trimLeadingFrom(innerClassName);
|
||||
}
|
||||
String packageName = this.getPackageName();
|
||||
if (packageName.isEmpty()) {
|
||||
return this.className;
|
||||
}
|
||||
return this.className.substring(packageName.length() + 1);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.className;
|
||||
}
|
||||
|
||||
public Class<?> load() {
|
||||
try {
|
||||
return this.loader.loadClass(this.className);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.className;
|
||||
}
|
||||
}
|
||||
|
||||
@Beta
|
||||
public static class ResourceInfo {
|
||||
private final String resourceName;
|
||||
final ClassLoader loader;
|
||||
|
||||
static ResourceInfo of(String resourceName, ClassLoader loader) {
|
||||
if (resourceName.endsWith(ClassPath.CLASS_FILE_NAME_EXTENSION)) {
|
||||
return new ClassInfo(resourceName, loader);
|
||||
}
|
||||
return new ResourceInfo(resourceName, loader);
|
||||
}
|
||||
|
||||
ResourceInfo(String resourceName, ClassLoader loader) {
|
||||
this.resourceName = Preconditions.checkNotNull(resourceName);
|
||||
this.loader = Preconditions.checkNotNull(loader);
|
||||
}
|
||||
|
||||
public final URL url() {
|
||||
return Preconditions.checkNotNull(this.loader.getResource(this.resourceName), "Failed to load resource: %s", this.resourceName);
|
||||
}
|
||||
|
||||
public final String getResourceName() {
|
||||
return this.resourceName;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.resourceName.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ResourceInfo) {
|
||||
ResourceInfo that = (ResourceInfo)obj;
|
||||
return this.resourceName.equals(that.resourceName) && this.loader == that.loader;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.resourceName;
|
||||
}
|
||||
}
|
||||
}
|
138
src/com/google/common/reflect/Element.java
Normal file
138
src/com/google/common/reflect/Element.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Modifier;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
class Element
|
||||
extends AccessibleObject
|
||||
implements Member {
|
||||
private final AccessibleObject accessibleObject;
|
||||
private final Member member;
|
||||
|
||||
<M extends AccessibleObject> Element(M member) {
|
||||
Preconditions.checkNotNull(member);
|
||||
this.accessibleObject = member;
|
||||
this.member = (Member)((Object)member);
|
||||
}
|
||||
|
||||
public TypeToken<?> getOwnerType() {
|
||||
return TypeToken.of(this.getDeclaringClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
|
||||
return this.accessibleObject.isAnnotationPresent(annotationClass);
|
||||
}
|
||||
|
||||
public final <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
|
||||
return this.accessibleObject.getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Annotation[] getAnnotations() {
|
||||
return this.accessibleObject.getAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Annotation[] getDeclaredAnnotations() {
|
||||
return this.accessibleObject.getDeclaredAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setAccessible(boolean flag) throws SecurityException {
|
||||
this.accessibleObject.setAccessible(flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isAccessible() {
|
||||
return this.accessibleObject.isAccessible();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getDeclaringClass() {
|
||||
return this.member.getDeclaringClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getName() {
|
||||
return this.member.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getModifiers() {
|
||||
return this.member.getModifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isSynthetic() {
|
||||
return this.member.isSynthetic();
|
||||
}
|
||||
|
||||
public final boolean isPublic() {
|
||||
return Modifier.isPublic(this.getModifiers());
|
||||
}
|
||||
|
||||
public final boolean isProtected() {
|
||||
return Modifier.isProtected(this.getModifiers());
|
||||
}
|
||||
|
||||
public final boolean isPackagePrivate() {
|
||||
return !this.isPrivate() && !this.isPublic() && !this.isProtected();
|
||||
}
|
||||
|
||||
public final boolean isPrivate() {
|
||||
return Modifier.isPrivate(this.getModifiers());
|
||||
}
|
||||
|
||||
public final boolean isStatic() {
|
||||
return Modifier.isStatic(this.getModifiers());
|
||||
}
|
||||
|
||||
public final boolean isFinal() {
|
||||
return Modifier.isFinal(this.getModifiers());
|
||||
}
|
||||
|
||||
public final boolean isAbstract() {
|
||||
return Modifier.isAbstract(this.getModifiers());
|
||||
}
|
||||
|
||||
public final boolean isNative() {
|
||||
return Modifier.isNative(this.getModifiers());
|
||||
}
|
||||
|
||||
public final boolean isSynchronized() {
|
||||
return Modifier.isSynchronized(this.getModifiers());
|
||||
}
|
||||
|
||||
final boolean isVolatile() {
|
||||
return Modifier.isVolatile(this.getModifiers());
|
||||
}
|
||||
|
||||
final boolean isTransient() {
|
||||
return Modifier.isTransient(this.getModifiers());
|
||||
}
|
||||
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof Element) {
|
||||
Element that = (Element)obj;
|
||||
return this.getOwnerType().equals(that.getOwnerType()) && this.member.equals(that.member);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.member.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.member.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.collect.ForwardingMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeToInstanceMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import java.util.Map;
|
||||
|
||||
@Beta
|
||||
public final class ImmutableTypeToInstanceMap<B>
|
||||
extends ForwardingMap<TypeToken<? extends B>, B>
|
||||
implements TypeToInstanceMap<B> {
|
||||
private final ImmutableMap<TypeToken<? extends B>, B> delegate;
|
||||
|
||||
public static <B> ImmutableTypeToInstanceMap<B> of() {
|
||||
return new ImmutableTypeToInstanceMap(ImmutableMap.of());
|
||||
}
|
||||
|
||||
public static <B> Builder<B> builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
private ImmutableTypeToInstanceMap(ImmutableMap<TypeToken<? extends B>, B> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends B> T getInstance(TypeToken<T> type) {
|
||||
return this.trustedGet(type.rejectTypeVariables());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends B> T putInstance(TypeToken<T> type, T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends B> T getInstance(Class<T> type) {
|
||||
return this.trustedGet(TypeToken.of(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends B> T putInstance(Class<T> type, T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<TypeToken<? extends B>, B> delegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
private <T extends B> T trustedGet(TypeToken<T> type) {
|
||||
return (T)this.delegate.get(type);
|
||||
}
|
||||
|
||||
@Beta
|
||||
public static final class Builder<B> {
|
||||
private final ImmutableMap.Builder<TypeToken<? extends B>, B> mapBuilder = ImmutableMap.builder();
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public <T extends B> Builder<B> put(Class<T> key, T value) {
|
||||
this.mapBuilder.put(TypeToken.of(key), value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T extends B> Builder<B> put(TypeToken<T> key, T value) {
|
||||
this.mapBuilder.put(key.rejectTypeVariables(), value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ImmutableTypeToInstanceMap<B> build() {
|
||||
return new ImmutableTypeToInstanceMap(this.mapBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
236
src/com/google/common/reflect/Invokable.java
Normal file
236
src/com/google/common/reflect/Invokable.java
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.reflect.Element;
|
||||
import com.google.common.reflect.Parameter;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.common.reflect.Types;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.GenericDeclaration;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.Arrays;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public abstract class Invokable<T, R>
|
||||
extends Element
|
||||
implements GenericDeclaration {
|
||||
<M extends AccessibleObject> Invokable(M member) {
|
||||
super(member);
|
||||
}
|
||||
|
||||
public static Invokable<?, Object> from(Method method) {
|
||||
return new MethodInvokable(method);
|
||||
}
|
||||
|
||||
public static <T> Invokable<T, T> from(Constructor<T> constructor) {
|
||||
return new ConstructorInvokable(constructor);
|
||||
}
|
||||
|
||||
public abstract boolean isOverridable();
|
||||
|
||||
public abstract boolean isVarArgs();
|
||||
|
||||
public final R invoke(@Nullable T receiver, Object ... args) throws InvocationTargetException, IllegalAccessException {
|
||||
return (R)this.invokeInternal(receiver, Preconditions.checkNotNull(args));
|
||||
}
|
||||
|
||||
public final TypeToken<? extends R> getReturnType() {
|
||||
return TypeToken.of(this.getGenericReturnType());
|
||||
}
|
||||
|
||||
public final ImmutableList<Parameter> getParameters() {
|
||||
Type[] parameterTypes = this.getGenericParameterTypes();
|
||||
Annotation[][] annotations = this.getParameterAnnotations();
|
||||
ImmutableList.Builder builder = ImmutableList.builder();
|
||||
for (int i = 0; i < parameterTypes.length; ++i) {
|
||||
builder.add(new Parameter(this, i, TypeToken.of(parameterTypes[i]), annotations[i]));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public final ImmutableList<TypeToken<? extends Throwable>> getExceptionTypes() {
|
||||
ImmutableList.Builder builder = ImmutableList.builder();
|
||||
for (Type type : this.getGenericExceptionTypes()) {
|
||||
TypeToken<?> exceptionType = TypeToken.of(type);
|
||||
builder.add(exceptionType);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public final <R1 extends R> Invokable<T, R1> returning(Class<R1> returnType) {
|
||||
return this.returning(TypeToken.of(returnType));
|
||||
}
|
||||
|
||||
public final <R1 extends R> Invokable<T, R1> returning(TypeToken<R1> returnType) {
|
||||
if (!returnType.isAssignableFrom(this.getReturnType())) {
|
||||
String string = String.valueOf(String.valueOf(this.getReturnType()));
|
||||
String string2 = String.valueOf(String.valueOf(returnType));
|
||||
throw new IllegalArgumentException(new StringBuilder(35 + string.length() + string2.length()).append("Invokable is known to return ").append(string).append(", not ").append(string2).toString());
|
||||
}
|
||||
Invokable specialized = this;
|
||||
return specialized;
|
||||
}
|
||||
|
||||
public final Class<? super T> getDeclaringClass() {
|
||||
return super.getDeclaringClass();
|
||||
}
|
||||
|
||||
public TypeToken<T> getOwnerType() {
|
||||
return TypeToken.of(this.getDeclaringClass());
|
||||
}
|
||||
|
||||
abstract Object invokeInternal(@Nullable Object var1, Object[] var2) throws InvocationTargetException, IllegalAccessException;
|
||||
|
||||
abstract Type[] getGenericParameterTypes();
|
||||
|
||||
abstract Type[] getGenericExceptionTypes();
|
||||
|
||||
abstract Annotation[][] getParameterAnnotations();
|
||||
|
||||
abstract Type getGenericReturnType();
|
||||
|
||||
static class ConstructorInvokable<T>
|
||||
extends Invokable<T, T> {
|
||||
final Constructor<?> constructor;
|
||||
|
||||
ConstructorInvokable(Constructor<?> constructor) {
|
||||
super(constructor);
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Object invokeInternal(@Nullable Object receiver, Object[] args) throws InvocationTargetException, IllegalAccessException {
|
||||
try {
|
||||
return this.constructor.newInstance(args);
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
String string = String.valueOf(String.valueOf(this.constructor));
|
||||
throw new RuntimeException(new StringBuilder(8 + string.length()).append(string).append(" failed.").toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Type getGenericReturnType() {
|
||||
Class declaringClass = this.getDeclaringClass();
|
||||
Type[] typeParams = declaringClass.getTypeParameters();
|
||||
if (typeParams.length > 0) {
|
||||
return Types.newParameterizedType(declaringClass, typeParams);
|
||||
}
|
||||
return declaringClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericParameterTypes() {
|
||||
Class<?>[] rawParamTypes;
|
||||
Type[] types = this.constructor.getGenericParameterTypes();
|
||||
if (types.length > 0 && this.mayNeedHiddenThis() && types.length == (rawParamTypes = this.constructor.getParameterTypes()).length && rawParamTypes[0] == this.getDeclaringClass().getEnclosingClass()) {
|
||||
return Arrays.copyOfRange(types, 1, types.length);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericExceptionTypes() {
|
||||
return this.constructor.getGenericExceptionTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
final Annotation[][] getParameterAnnotations() {
|
||||
return this.constructor.getParameterAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TypeVariable<?>[] getTypeParameters() {
|
||||
TypeVariable<Class<T>>[] declaredByClass = this.getDeclaringClass().getTypeParameters();
|
||||
TypeVariable<Constructor<?>>[] declaredByConstructor = this.constructor.getTypeParameters();
|
||||
TypeVariable[] result = new TypeVariable[declaredByClass.length + declaredByConstructor.length];
|
||||
System.arraycopy(declaredByClass, 0, result, 0, declaredByClass.length);
|
||||
System.arraycopy(declaredByConstructor, 0, result, declaredByClass.length, declaredByConstructor.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isOverridable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isVarArgs() {
|
||||
return this.constructor.isVarArgs();
|
||||
}
|
||||
|
||||
private boolean mayNeedHiddenThis() {
|
||||
Class<?> declaringClass = this.constructor.getDeclaringClass();
|
||||
if (declaringClass.getEnclosingConstructor() != null) {
|
||||
return true;
|
||||
}
|
||||
Method enclosingMethod = declaringClass.getEnclosingMethod();
|
||||
if (enclosingMethod != null) {
|
||||
return !Modifier.isStatic(enclosingMethod.getModifiers());
|
||||
}
|
||||
return declaringClass.getEnclosingClass() != null && !Modifier.isStatic(declaringClass.getModifiers());
|
||||
}
|
||||
}
|
||||
|
||||
static class MethodInvokable<T>
|
||||
extends Invokable<T, Object> {
|
||||
final Method method;
|
||||
|
||||
MethodInvokable(Method method) {
|
||||
super(method);
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
final Object invokeInternal(@Nullable Object receiver, Object[] args) throws InvocationTargetException, IllegalAccessException {
|
||||
return this.method.invoke(receiver, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
Type getGenericReturnType() {
|
||||
return this.method.getGenericReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericParameterTypes() {
|
||||
return this.method.getGenericParameterTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericExceptionTypes() {
|
||||
return this.method.getGenericExceptionTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
final Annotation[][] getParameterAnnotations() {
|
||||
return this.method.getParameterAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TypeVariable<?>[] getTypeParameters() {
|
||||
return this.method.getTypeParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isOverridable() {
|
||||
return !this.isFinal() && !this.isPrivate() && !this.isStatic() && !Modifier.isFinal(this.getDeclaringClass().getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isVarArgs() {
|
||||
return this.method.isVarArgs();
|
||||
}
|
||||
}
|
||||
}
|
134
src/com/google/common/reflect/MutableTypeToInstanceMap.java
Normal file
134
src/com/google/common/reflect/MutableTypeToInstanceMap.java
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ForwardingMap;
|
||||
import com.google.common.collect.ForwardingMapEntry;
|
||||
import com.google.common.collect.ForwardingSet;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.reflect.TypeToInstanceMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public final class MutableTypeToInstanceMap<B>
|
||||
extends ForwardingMap<TypeToken<? extends B>, B>
|
||||
implements TypeToInstanceMap<B> {
|
||||
private final Map<TypeToken<? extends B>, B> backingMap = Maps.newHashMap();
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends B> T getInstance(Class<T> type) {
|
||||
return this.trustedGet(TypeToken.of(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends B> T putInstance(Class<T> type, @Nullable T value) {
|
||||
return this.trustedPut(TypeToken.of(type), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends B> T getInstance(TypeToken<T> type) {
|
||||
return this.trustedGet(type.rejectTypeVariables());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends B> T putInstance(TypeToken<T> type, @Nullable T value) {
|
||||
return this.trustedPut(type.rejectTypeVariables(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public B put(TypeToken<? extends B> key, B value) {
|
||||
throw new UnsupportedOperationException("Please use putInstance() instead.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends TypeToken<? extends B>, ? extends B> map) {
|
||||
throw new UnsupportedOperationException("Please use putInstance() instead.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Map.Entry<TypeToken<? extends B>, B>> entrySet() {
|
||||
return UnmodifiableEntry.transformEntries(super.entrySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<TypeToken<? extends B>, B> delegate() {
|
||||
return this.backingMap;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <T extends B> T trustedPut(TypeToken<T> type, @Nullable T value) {
|
||||
return (T)this.backingMap.put(type, value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <T extends B> T trustedGet(TypeToken<T> type) {
|
||||
return (T)this.backingMap.get(type);
|
||||
}
|
||||
|
||||
private static final class UnmodifiableEntry<K, V>
|
||||
extends ForwardingMapEntry<K, V> {
|
||||
private final Map.Entry<K, V> delegate;
|
||||
|
||||
static <K, V> Set<Map.Entry<K, V>> transformEntries(final Set<Map.Entry<K, V>> entries) {
|
||||
return new ForwardingSet<Map.Entry<K, V>>(){
|
||||
|
||||
@Override
|
||||
protected Set<Map.Entry<K, V>> delegate() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Map.Entry<K, V>> iterator() {
|
||||
return UnmodifiableEntry.transformEntries(super.iterator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return this.standardToArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] array) {
|
||||
return this.standardToArray(array);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <K, V> Iterator<Map.Entry<K, V>> transformEntries(Iterator<Map.Entry<K, V>> entries) {
|
||||
return Iterators.transform(entries, new Function<Map.Entry<K, V>, Map.Entry<K, V>>(){
|
||||
|
||||
@Override
|
||||
public Map.Entry<K, V> apply(Map.Entry<K, V> entry) {
|
||||
return new UnmodifiableEntry(entry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private UnmodifiableEntry(Map.Entry<K, V> delegate) {
|
||||
this.delegate = Preconditions.checkNotNull(delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map.Entry<K, V> delegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
95
src/com/google/common/reflect/Parameter.java
Normal file
95
src/com/google/common/reflect/Parameter.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public final class Parameter
|
||||
implements AnnotatedElement {
|
||||
private final Invokable<?, ?> declaration;
|
||||
private final int position;
|
||||
private final TypeToken<?> type;
|
||||
private final ImmutableList<Annotation> annotations;
|
||||
|
||||
Parameter(Invokable<?, ?> declaration, int position, TypeToken<?> type, Annotation[] annotations) {
|
||||
this.declaration = declaration;
|
||||
this.position = position;
|
||||
this.type = type;
|
||||
this.annotations = ImmutableList.copyOf(annotations);
|
||||
}
|
||||
|
||||
public TypeToken<?> getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Invokable<?, ?> getDeclaringInvokable() {
|
||||
return this.declaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
|
||||
return this.getAnnotation((Class)annotationType) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
|
||||
Preconditions.checkNotNull(annotationType);
|
||||
for (Annotation annotation : this.annotations) {
|
||||
if (!annotationType.isInstance(annotation)) continue;
|
||||
return (A)((Annotation)annotationType.cast(annotation));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Annotation[] getAnnotations() {
|
||||
return this.getDeclaredAnnotations();
|
||||
}
|
||||
|
||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
|
||||
return this.getDeclaredAnnotationsByType(annotationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Annotation[] getDeclaredAnnotations() {
|
||||
return this.annotations.toArray(new Annotation[this.annotations.size()]);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationType) {
|
||||
Preconditions.checkNotNull(annotationType);
|
||||
return (A)((Annotation)FluentIterable.from(this.annotations).filter(annotationType).first().orNull());
|
||||
}
|
||||
|
||||
public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationType) {
|
||||
return (Annotation[])FluentIterable.from(this.annotations).filter(annotationType).toArray(annotationType);
|
||||
}
|
||||
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof Parameter) {
|
||||
Parameter that = (Parameter)obj;
|
||||
return this.position == that.position && this.declaration.equals(that.declaration);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String string = String.valueOf(String.valueOf(this.type));
|
||||
int n = this.position;
|
||||
return new StringBuilder(15 + string.length()).append(string).append(" arg").append(n).toString();
|
||||
}
|
||||
}
|
42
src/com/google/common/reflect/Reflection.java
Normal file
42
src/com/google/common/reflect/Reflection.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
@Beta
|
||||
public final class Reflection {
|
||||
public static String getPackageName(Class<?> clazz) {
|
||||
return Reflection.getPackageName(clazz.getName());
|
||||
}
|
||||
|
||||
public static String getPackageName(String classFullName) {
|
||||
int lastDot = classFullName.lastIndexOf(46);
|
||||
return lastDot < 0 ? "" : classFullName.substring(0, lastDot);
|
||||
}
|
||||
|
||||
public static void initialize(Class<?> ... classes) {
|
||||
for (Class<?> clazz : classes) {
|
||||
try {
|
||||
Class.forName(clazz.getName(), true, clazz.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new AssertionError((Object)e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T newProxy(Class<T> interfaceType, InvocationHandler handler) {
|
||||
Preconditions.checkNotNull(handler);
|
||||
Preconditions.checkArgument(interfaceType.isInterface(), "%s is not an interface", interfaceType);
|
||||
Object object = Proxy.newProxyInstance(interfaceType.getClassLoader(), new Class[]{interfaceType}, handler);
|
||||
return interfaceType.cast(object);
|
||||
}
|
||||
|
||||
private Reflection() {
|
||||
}
|
||||
}
|
19
src/com/google/common/reflect/TypeCapture.java
Normal file
19
src/com/google/common/reflect/TypeCapture.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
abstract class TypeCapture<T> {
|
||||
TypeCapture() {
|
||||
}
|
||||
|
||||
final Type capture() {
|
||||
Type superclass = this.getClass().getGenericSuperclass();
|
||||
Preconditions.checkArgument(superclass instanceof ParameterizedType, "%s isn't parameterized", superclass);
|
||||
return ((ParameterizedType)superclass).getActualTypeArguments()[0];
|
||||
}
|
||||
}
|
39
src/com/google/common/reflect/TypeParameter.java
Normal file
39
src/com/google/common/reflect/TypeParameter.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.reflect.TypeCapture;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public abstract class TypeParameter<T>
|
||||
extends TypeCapture<T> {
|
||||
final TypeVariable<?> typeVariable;
|
||||
|
||||
protected TypeParameter() {
|
||||
Type type = this.capture();
|
||||
Preconditions.checkArgument(type instanceof TypeVariable, "%s should be a type variable.", type);
|
||||
this.typeVariable = (TypeVariable)type;
|
||||
}
|
||||
|
||||
public final int hashCode() {
|
||||
return this.typeVariable.hashCode();
|
||||
}
|
||||
|
||||
public final boolean equals(@Nullable Object o) {
|
||||
if (o instanceof TypeParameter) {
|
||||
TypeParameter that = (TypeParameter)o;
|
||||
return this.typeVariable.equals(that.typeVariable);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.typeVariable.toString();
|
||||
}
|
||||
}
|
374
src/com/google/common/reflect/TypeResolver.java
Normal file
374
src/com/google/common/reflect/TypeResolver.java
Normal file
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.reflect.TypeVisitor;
|
||||
import com.google.common.reflect.Types;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public final class TypeResolver {
|
||||
private final TypeTable typeTable;
|
||||
|
||||
public TypeResolver() {
|
||||
this.typeTable = new TypeTable();
|
||||
}
|
||||
|
||||
private TypeResolver(TypeTable typeTable) {
|
||||
this.typeTable = typeTable;
|
||||
}
|
||||
|
||||
static TypeResolver accordingTo(Type type) {
|
||||
return new TypeResolver().where(TypeMappingIntrospector.getTypeMappings(type));
|
||||
}
|
||||
|
||||
public TypeResolver where(Type formal, Type actual) {
|
||||
HashMap<TypeVariableKey, Type> mappings = Maps.newHashMap();
|
||||
TypeResolver.populateTypeMappings(mappings, Preconditions.checkNotNull(formal), Preconditions.checkNotNull(actual));
|
||||
return this.where(mappings);
|
||||
}
|
||||
|
||||
TypeResolver where(Map<TypeVariableKey, ? extends Type> mappings) {
|
||||
return new TypeResolver(this.typeTable.where(mappings));
|
||||
}
|
||||
|
||||
private static void populateTypeMappings(final Map<TypeVariableKey, Type> mappings, Type from, final Type to) {
|
||||
if (from.equals(to)) {
|
||||
return;
|
||||
}
|
||||
new TypeVisitor(){
|
||||
|
||||
@Override
|
||||
void visitTypeVariable(TypeVariable<?> typeVariable) {
|
||||
mappings.put(new TypeVariableKey(typeVariable), to);
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitWildcardType(WildcardType fromWildcardType) {
|
||||
int i;
|
||||
WildcardType toWildcardType = (WildcardType)TypeResolver.expectArgument(WildcardType.class, to);
|
||||
Type[] fromUpperBounds = fromWildcardType.getUpperBounds();
|
||||
Type[] toUpperBounds = toWildcardType.getUpperBounds();
|
||||
Type[] fromLowerBounds = fromWildcardType.getLowerBounds();
|
||||
Type[] toLowerBounds = toWildcardType.getLowerBounds();
|
||||
Preconditions.checkArgument(fromUpperBounds.length == toUpperBounds.length && fromLowerBounds.length == toLowerBounds.length, "Incompatible type: %s vs. %s", fromWildcardType, to);
|
||||
for (i = 0; i < fromUpperBounds.length; ++i) {
|
||||
TypeResolver.populateTypeMappings(mappings, fromUpperBounds[i], toUpperBounds[i]);
|
||||
}
|
||||
for (i = 0; i < fromLowerBounds.length; ++i) {
|
||||
TypeResolver.populateTypeMappings(mappings, fromLowerBounds[i], toLowerBounds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitParameterizedType(ParameterizedType fromParameterizedType) {
|
||||
ParameterizedType toParameterizedType = (ParameterizedType)TypeResolver.expectArgument(ParameterizedType.class, to);
|
||||
Preconditions.checkArgument(fromParameterizedType.getRawType().equals(toParameterizedType.getRawType()), "Inconsistent raw type: %s vs. %s", fromParameterizedType, to);
|
||||
Type[] fromArgs = fromParameterizedType.getActualTypeArguments();
|
||||
Type[] toArgs = toParameterizedType.getActualTypeArguments();
|
||||
Preconditions.checkArgument(fromArgs.length == toArgs.length, "%s not compatible with %s", fromParameterizedType, toParameterizedType);
|
||||
for (int i = 0; i < fromArgs.length; ++i) {
|
||||
TypeResolver.populateTypeMappings(mappings, fromArgs[i], toArgs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitGenericArrayType(GenericArrayType fromArrayType) {
|
||||
Type componentType = Types.getComponentType(to);
|
||||
Preconditions.checkArgument(componentType != null, "%s is not an array type.", to);
|
||||
TypeResolver.populateTypeMappings(mappings, fromArrayType.getGenericComponentType(), componentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitClass(Class<?> fromClass) {
|
||||
String string = String.valueOf(String.valueOf(fromClass));
|
||||
throw new IllegalArgumentException(new StringBuilder(21 + string.length()).append("No type mapping from ").append(string).toString());
|
||||
}
|
||||
}.visit(from);
|
||||
}
|
||||
|
||||
public Type resolveType(Type type) {
|
||||
Preconditions.checkNotNull(type);
|
||||
if (type instanceof TypeVariable) {
|
||||
return this.typeTable.resolve((TypeVariable)type);
|
||||
}
|
||||
if (type instanceof ParameterizedType) {
|
||||
return this.resolveParameterizedType((ParameterizedType)type);
|
||||
}
|
||||
if (type instanceof GenericArrayType) {
|
||||
return this.resolveGenericArrayType((GenericArrayType)type);
|
||||
}
|
||||
if (type instanceof WildcardType) {
|
||||
return this.resolveWildcardType((WildcardType)type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private Type[] resolveTypes(Type[] types) {
|
||||
Type[] result = new Type[types.length];
|
||||
for (int i = 0; i < types.length; ++i) {
|
||||
result[i] = this.resolveType(types[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private WildcardType resolveWildcardType(WildcardType type) {
|
||||
Type[] lowerBounds = type.getLowerBounds();
|
||||
Type[] upperBounds = type.getUpperBounds();
|
||||
return new Types.WildcardTypeImpl(this.resolveTypes(lowerBounds), this.resolveTypes(upperBounds));
|
||||
}
|
||||
|
||||
private Type resolveGenericArrayType(GenericArrayType type) {
|
||||
Type componentType = type.getGenericComponentType();
|
||||
Type resolvedComponentType = this.resolveType(componentType);
|
||||
return Types.newArrayType(resolvedComponentType);
|
||||
}
|
||||
|
||||
private ParameterizedType resolveParameterizedType(ParameterizedType type) {
|
||||
Type owner = type.getOwnerType();
|
||||
Type resolvedOwner = owner == null ? null : this.resolveType(owner);
|
||||
Type resolvedRawType = this.resolveType(type.getRawType());
|
||||
Type[] args = type.getActualTypeArguments();
|
||||
Type[] resolvedArgs = this.resolveTypes(args);
|
||||
return Types.newParameterizedTypeWithOwner(resolvedOwner, (Class)resolvedRawType, resolvedArgs);
|
||||
}
|
||||
|
||||
private static <T> T expectArgument(Class<T> type, Object arg) {
|
||||
try {
|
||||
return type.cast(arg);
|
||||
}
|
||||
catch (ClassCastException e) {
|
||||
String string = String.valueOf(String.valueOf(arg));
|
||||
String string2 = String.valueOf(String.valueOf(type.getSimpleName()));
|
||||
throw new IllegalArgumentException(new StringBuilder(10 + string.length() + string2.length()).append(string).append(" is not a ").append(string2).toString());
|
||||
}
|
||||
}
|
||||
|
||||
static final class TypeVariableKey {
|
||||
private final TypeVariable<?> var;
|
||||
|
||||
TypeVariableKey(TypeVariable<?> var) {
|
||||
this.var = Preconditions.checkNotNull(var);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.var.getGenericDeclaration(), this.var.getName());
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof TypeVariableKey) {
|
||||
TypeVariableKey that = (TypeVariableKey)obj;
|
||||
return this.equalsTypeVariable(that.var);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.var.toString();
|
||||
}
|
||||
|
||||
static Object forLookup(Type t) {
|
||||
if (t instanceof TypeVariable) {
|
||||
return new TypeVariableKey((TypeVariable)t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean equalsType(Type type) {
|
||||
if (type instanceof TypeVariable) {
|
||||
return this.equalsTypeVariable((TypeVariable)type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean equalsTypeVariable(TypeVariable<?> that) {
|
||||
return this.var.getGenericDeclaration().equals(that.getGenericDeclaration()) && this.var.getName().equals(that.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class WildcardCapturer {
|
||||
private final AtomicInteger id = new AtomicInteger();
|
||||
|
||||
private WildcardCapturer() {
|
||||
}
|
||||
|
||||
Type capture(Type type) {
|
||||
Preconditions.checkNotNull(type);
|
||||
if (type instanceof Class) {
|
||||
return type;
|
||||
}
|
||||
if (type instanceof TypeVariable) {
|
||||
return type;
|
||||
}
|
||||
if (type instanceof GenericArrayType) {
|
||||
GenericArrayType arrayType = (GenericArrayType)type;
|
||||
return Types.newArrayType(this.capture(arrayType.getGenericComponentType()));
|
||||
}
|
||||
if (type instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType)type;
|
||||
return Types.newParameterizedTypeWithOwner(this.captureNullable(parameterizedType.getOwnerType()), (Class)parameterizedType.getRawType(), this.capture(parameterizedType.getActualTypeArguments()));
|
||||
}
|
||||
if (type instanceof WildcardType) {
|
||||
WildcardType wildcardType = (WildcardType)type;
|
||||
Type[] lowerBounds = wildcardType.getLowerBounds();
|
||||
if (lowerBounds.length == 0) {
|
||||
Object[] upperBounds = wildcardType.getUpperBounds();
|
||||
int n = this.id.incrementAndGet();
|
||||
String string = String.valueOf(String.valueOf(Joiner.on('&').join(upperBounds)));
|
||||
String name = new StringBuilder(33 + string.length()).append("capture#").append(n).append("-of ? extends ").append(string).toString();
|
||||
return Types.newArtificialTypeVariable(WildcardCapturer.class, name, wildcardType.getUpperBounds());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
throw new AssertionError((Object)"must have been one of the known types");
|
||||
}
|
||||
|
||||
private Type captureNullable(@Nullable Type type) {
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
return this.capture(type);
|
||||
}
|
||||
|
||||
private Type[] capture(Type[] types) {
|
||||
Type[] result = new Type[types.length];
|
||||
for (int i = 0; i < types.length; ++i) {
|
||||
result[i] = this.capture(types[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TypeMappingIntrospector
|
||||
extends TypeVisitor {
|
||||
private static final WildcardCapturer wildcardCapturer = new WildcardCapturer();
|
||||
private final Map<TypeVariableKey, Type> mappings = Maps.newHashMap();
|
||||
|
||||
private TypeMappingIntrospector() {
|
||||
}
|
||||
|
||||
static ImmutableMap<TypeVariableKey, Type> getTypeMappings(Type contextType) {
|
||||
TypeMappingIntrospector introspector = new TypeMappingIntrospector();
|
||||
introspector.visit(wildcardCapturer.capture(contextType));
|
||||
return ImmutableMap.copyOf(introspector.mappings);
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitClass(Class<?> clazz) {
|
||||
this.visit(clazz.getGenericSuperclass());
|
||||
this.visit(clazz.getGenericInterfaces());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitParameterizedType(ParameterizedType parameterizedType) {
|
||||
Type[] typeArgs;
|
||||
Class rawClass = (Class)parameterizedType.getRawType();
|
||||
TypeVariable<Class<T>>[] vars = rawClass.getTypeParameters();
|
||||
Preconditions.checkState(vars.length == (typeArgs = parameterizedType.getActualTypeArguments()).length);
|
||||
for (int i = 0; i < vars.length; ++i) {
|
||||
this.map(new TypeVariableKey(vars[i]), typeArgs[i]);
|
||||
}
|
||||
this.visit(rawClass);
|
||||
this.visit(parameterizedType.getOwnerType());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitTypeVariable(TypeVariable<?> t) {
|
||||
this.visit(t.getBounds());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitWildcardType(WildcardType t) {
|
||||
this.visit(t.getUpperBounds());
|
||||
}
|
||||
|
||||
private void map(TypeVariableKey var, Type arg) {
|
||||
if (this.mappings.containsKey(var)) {
|
||||
return;
|
||||
}
|
||||
Type t = arg;
|
||||
while (t != null) {
|
||||
if (var.equalsType(t)) {
|
||||
Type x = arg;
|
||||
while (x != null) {
|
||||
x = this.mappings.remove(TypeVariableKey.forLookup(x));
|
||||
}
|
||||
return;
|
||||
}
|
||||
t = this.mappings.get(TypeVariableKey.forLookup(t));
|
||||
}
|
||||
this.mappings.put(var, arg);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TypeTable {
|
||||
private final ImmutableMap<TypeVariableKey, Type> map;
|
||||
|
||||
TypeTable() {
|
||||
this.map = ImmutableMap.of();
|
||||
}
|
||||
|
||||
private TypeTable(ImmutableMap<TypeVariableKey, Type> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
final TypeTable where(Map<TypeVariableKey, ? extends Type> mappings) {
|
||||
ImmutableMap.Builder<TypeVariableKey, Type> builder = ImmutableMap.builder();
|
||||
builder.putAll(this.map);
|
||||
for (Map.Entry<TypeVariableKey, ? extends Type> mapping : mappings.entrySet()) {
|
||||
Type type;
|
||||
TypeVariableKey variable = mapping.getKey();
|
||||
Preconditions.checkArgument(!variable.equalsType(type = mapping.getValue()), "Type variable %s bound to itself", variable);
|
||||
builder.put(variable, type);
|
||||
}
|
||||
return new TypeTable(builder.build());
|
||||
}
|
||||
|
||||
final Type resolve(final TypeVariable<?> var) {
|
||||
final TypeTable unguarded = this;
|
||||
TypeTable guarded = new TypeTable(){
|
||||
|
||||
@Override
|
||||
public Type resolveInternal(TypeVariable<?> intermediateVar, TypeTable forDependent) {
|
||||
if (intermediateVar.getGenericDeclaration().equals(var.getGenericDeclaration())) {
|
||||
return intermediateVar;
|
||||
}
|
||||
return unguarded.resolveInternal(intermediateVar, forDependent);
|
||||
}
|
||||
};
|
||||
return this.resolveInternal(var, guarded);
|
||||
}
|
||||
|
||||
Type resolveInternal(TypeVariable<?> var, TypeTable forDependants) {
|
||||
Type type = this.map.get(new TypeVariableKey(var));
|
||||
if (type == null) {
|
||||
Object[] bounds = var.getBounds();
|
||||
if (bounds.length == 0) {
|
||||
return var;
|
||||
}
|
||||
Object[] resolvedBounds = new TypeResolver(forDependants).resolveTypes((Type[])bounds);
|
||||
if (Types.NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY && Arrays.equals(bounds, resolvedBounds)) {
|
||||
return var;
|
||||
}
|
||||
return Types.newArtificialTypeVariable(var.getGenericDeclaration(), var.getName(), (Type[])resolvedBounds);
|
||||
}
|
||||
return new TypeResolver(forDependants).resolveType(type);
|
||||
}
|
||||
}
|
||||
}
|
25
src/com/google/common/reflect/TypeToInstanceMap.java
Normal file
25
src/com/google/common/reflect/TypeToInstanceMap.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public interface TypeToInstanceMap<B>
|
||||
extends Map<TypeToken<? extends B>, B> {
|
||||
@Nullable
|
||||
public <T extends B> T getInstance(Class<T> var1);
|
||||
|
||||
@Nullable
|
||||
public <T extends B> T putInstance(Class<T> var1, @Nullable T var2);
|
||||
|
||||
@Nullable
|
||||
public <T extends B> T getInstance(TypeToken<T> var1);
|
||||
|
||||
@Nullable
|
||||
public <T extends B> T putInstance(TypeToken<T> var1, @Nullable T var2);
|
||||
}
|
898
src/com/google/common/reflect/TypeToken.java
Normal file
898
src/com/google/common/reflect/TypeToken.java
Normal file
|
@ -0,0 +1,898 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ForwardingSet;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.primitives.Primitives;
|
||||
import com.google.common.reflect.Invokable;
|
||||
import com.google.common.reflect.TypeCapture;
|
||||
import com.google.common.reflect.TypeParameter;
|
||||
import com.google.common.reflect.TypeResolver;
|
||||
import com.google.common.reflect.TypeVisitor;
|
||||
import com.google.common.reflect.Types;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Beta
|
||||
public abstract class TypeToken<T>
|
||||
extends TypeCapture<T>
|
||||
implements Serializable {
|
||||
private final Type runtimeType;
|
||||
private transient TypeResolver typeResolver;
|
||||
|
||||
protected TypeToken() {
|
||||
this.runtimeType = this.capture();
|
||||
Preconditions.checkState(!(this.runtimeType instanceof TypeVariable), "Cannot construct a TypeToken for a type variable.\nYou probably meant to call new TypeToken<%s>(getClass()) that can resolve the type variable for you.\nIf you do need to create a TypeToken of a type variable, please use TypeToken.of() instead.", this.runtimeType);
|
||||
}
|
||||
|
||||
protected TypeToken(Class<?> declaringClass) {
|
||||
Type captured = super.capture();
|
||||
this.runtimeType = captured instanceof Class ? captured : TypeToken.of(declaringClass).resolveType((Type)captured).runtimeType;
|
||||
}
|
||||
|
||||
private TypeToken(Type type) {
|
||||
this.runtimeType = Preconditions.checkNotNull(type);
|
||||
}
|
||||
|
||||
public static <T> TypeToken<T> of(Class<T> type) {
|
||||
return new SimpleTypeToken((Type)type);
|
||||
}
|
||||
|
||||
public static TypeToken<?> of(Type type) {
|
||||
return new SimpleTypeToken(type);
|
||||
}
|
||||
|
||||
public final Class<? super T> getRawType() {
|
||||
Class<?> rawType;
|
||||
Class<?> result = rawType = TypeToken.getRawType(this.runtimeType);
|
||||
return result;
|
||||
}
|
||||
|
||||
private ImmutableSet<Class<? super T>> getImmediateRawTypes() {
|
||||
ImmutableSet<Class<? super T>> result = TypeToken.getRawTypes(this.runtimeType);
|
||||
return result;
|
||||
}
|
||||
|
||||
public final Type getType() {
|
||||
return this.runtimeType;
|
||||
}
|
||||
|
||||
public final <X> TypeToken<T> where(TypeParameter<X> typeParam, TypeToken<X> typeArg) {
|
||||
TypeResolver resolver = new TypeResolver().where(ImmutableMap.of(new TypeResolver.TypeVariableKey(typeParam.typeVariable), typeArg.runtimeType));
|
||||
return new SimpleTypeToken(resolver.resolveType(this.runtimeType));
|
||||
}
|
||||
|
||||
public final <X> TypeToken<T> where(TypeParameter<X> typeParam, Class<X> typeArg) {
|
||||
return this.where(typeParam, TypeToken.of(typeArg));
|
||||
}
|
||||
|
||||
public final TypeToken<?> resolveType(Type type) {
|
||||
Preconditions.checkNotNull(type);
|
||||
TypeResolver resolver = this.typeResolver;
|
||||
if (resolver == null) {
|
||||
resolver = this.typeResolver = TypeResolver.accordingTo(this.runtimeType);
|
||||
}
|
||||
return TypeToken.of(resolver.resolveType(type));
|
||||
}
|
||||
|
||||
private Type[] resolveInPlace(Type[] types) {
|
||||
for (int i = 0; i < types.length; ++i) {
|
||||
types[i] = this.resolveType(types[i]).getType();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
private TypeToken<?> resolveSupertype(Type type) {
|
||||
TypeToken<?> supertype = this.resolveType(type);
|
||||
supertype.typeResolver = this.typeResolver;
|
||||
return supertype;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
final TypeToken<? super T> getGenericSuperclass() {
|
||||
if (this.runtimeType instanceof TypeVariable) {
|
||||
return this.boundAsSuperclass(((TypeVariable)this.runtimeType).getBounds()[0]);
|
||||
}
|
||||
if (this.runtimeType instanceof WildcardType) {
|
||||
return this.boundAsSuperclass(((WildcardType)this.runtimeType).getUpperBounds()[0]);
|
||||
}
|
||||
Type superclass = this.getRawType().getGenericSuperclass();
|
||||
if (superclass == null) {
|
||||
return null;
|
||||
}
|
||||
TypeToken<?> superToken = this.resolveSupertype(superclass);
|
||||
return superToken;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeToken<? super T> boundAsSuperclass(Type bound) {
|
||||
TypeToken<?> token = TypeToken.of(bound);
|
||||
if (token.getRawType().isInterface()) {
|
||||
return null;
|
||||
}
|
||||
TypeToken<?> superclass = token;
|
||||
return superclass;
|
||||
}
|
||||
|
||||
final ImmutableList<TypeToken<? super T>> getGenericInterfaces() {
|
||||
if (this.runtimeType instanceof TypeVariable) {
|
||||
return this.boundsAsInterfaces(((TypeVariable)this.runtimeType).getBounds());
|
||||
}
|
||||
if (this.runtimeType instanceof WildcardType) {
|
||||
return this.boundsAsInterfaces(((WildcardType)this.runtimeType).getUpperBounds());
|
||||
}
|
||||
ImmutableList.Builder builder = ImmutableList.builder();
|
||||
for (Type interfaceType : this.getRawType().getGenericInterfaces()) {
|
||||
TypeToken<?> resolvedInterface = this.resolveSupertype(interfaceType);
|
||||
builder.add(resolvedInterface);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private ImmutableList<TypeToken<? super T>> boundsAsInterfaces(Type[] bounds) {
|
||||
ImmutableList.Builder builder = ImmutableList.builder();
|
||||
for (Type bound : bounds) {
|
||||
TypeToken<?> boundType = TypeToken.of(bound);
|
||||
if (!boundType.getRawType().isInterface()) continue;
|
||||
builder.add(boundType);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public final TypeSet getTypes() {
|
||||
return new TypeSet();
|
||||
}
|
||||
|
||||
public final TypeToken<? super T> getSupertype(Class<? super T> superclass) {
|
||||
Preconditions.checkArgument(superclass.isAssignableFrom(this.getRawType()), "%s is not a super class of %s", superclass, this);
|
||||
if (this.runtimeType instanceof TypeVariable) {
|
||||
return this.getSupertypeFromUpperBounds(superclass, ((TypeVariable)this.runtimeType).getBounds());
|
||||
}
|
||||
if (this.runtimeType instanceof WildcardType) {
|
||||
return this.getSupertypeFromUpperBounds(superclass, ((WildcardType)this.runtimeType).getUpperBounds());
|
||||
}
|
||||
if (superclass.isArray()) {
|
||||
return this.getArraySupertype(superclass);
|
||||
}
|
||||
TypeToken<?> supertype = this.resolveSupertype(TypeToken.toGenericType(superclass).runtimeType);
|
||||
return supertype;
|
||||
}
|
||||
|
||||
public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
|
||||
Preconditions.checkArgument(!(this.runtimeType instanceof TypeVariable), "Cannot get subtype of type variable <%s>", this);
|
||||
if (this.runtimeType instanceof WildcardType) {
|
||||
return this.getSubtypeFromLowerBounds(subclass, ((WildcardType)this.runtimeType).getLowerBounds());
|
||||
}
|
||||
Preconditions.checkArgument(this.getRawType().isAssignableFrom(subclass), "%s isn't a subclass of %s", subclass, this);
|
||||
if (this.isArray()) {
|
||||
return this.getArraySubtype(subclass);
|
||||
}
|
||||
TypeToken<?> subtype = TypeToken.of(this.resolveTypeArgsForSubclass(subclass));
|
||||
return subtype;
|
||||
}
|
||||
|
||||
public final boolean isAssignableFrom(TypeToken<?> type) {
|
||||
return this.isAssignableFrom(type.runtimeType);
|
||||
}
|
||||
|
||||
public final boolean isAssignableFrom(Type type) {
|
||||
return TypeToken.isAssignable(Preconditions.checkNotNull(type), this.runtimeType);
|
||||
}
|
||||
|
||||
public final boolean isArray() {
|
||||
return this.getComponentType() != null;
|
||||
}
|
||||
|
||||
public final boolean isPrimitive() {
|
||||
return this.runtimeType instanceof Class && ((Class)this.runtimeType).isPrimitive();
|
||||
}
|
||||
|
||||
public final TypeToken<T> wrap() {
|
||||
if (this.isPrimitive()) {
|
||||
Class type = (Class)this.runtimeType;
|
||||
return TypeToken.of(Primitives.wrap(type));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean isWrapper() {
|
||||
return Primitives.allWrapperTypes().contains(this.runtimeType);
|
||||
}
|
||||
|
||||
public final TypeToken<T> unwrap() {
|
||||
if (this.isWrapper()) {
|
||||
Class type = (Class)this.runtimeType;
|
||||
return TypeToken.of(Primitives.unwrap(type));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final TypeToken<?> getComponentType() {
|
||||
Type componentType = Types.getComponentType(this.runtimeType);
|
||||
if (componentType == null) {
|
||||
return null;
|
||||
}
|
||||
return TypeToken.of(componentType);
|
||||
}
|
||||
|
||||
public final Invokable<T, Object> method(Method method) {
|
||||
Preconditions.checkArgument(TypeToken.of(method.getDeclaringClass()).isAssignableFrom(this), "%s not declared by %s", method, this);
|
||||
return new Invokable.MethodInvokable<T>(method){
|
||||
|
||||
@Override
|
||||
Type getGenericReturnType() {
|
||||
return TypeToken.this.resolveType(super.getGenericReturnType()).getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericParameterTypes() {
|
||||
return TypeToken.this.resolveInPlace(super.getGenericParameterTypes());
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericExceptionTypes() {
|
||||
return TypeToken.this.resolveInPlace(super.getGenericExceptionTypes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeToken<T> getOwnerType() {
|
||||
return TypeToken.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String string = String.valueOf(String.valueOf(this.getOwnerType()));
|
||||
String string2 = String.valueOf(String.valueOf(super.toString()));
|
||||
return new StringBuilder(1 + string.length() + string2.length()).append(string).append(".").append(string2).toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public final Invokable<T, T> constructor(Constructor<?> constructor) {
|
||||
Preconditions.checkArgument(constructor.getDeclaringClass() == this.getRawType(), "%s not declared by %s", constructor, this.getRawType());
|
||||
return new Invokable.ConstructorInvokable<T>(constructor){
|
||||
|
||||
@Override
|
||||
Type getGenericReturnType() {
|
||||
return TypeToken.this.resolveType(super.getGenericReturnType()).getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericParameterTypes() {
|
||||
return TypeToken.this.resolveInPlace(super.getGenericParameterTypes());
|
||||
}
|
||||
|
||||
@Override
|
||||
Type[] getGenericExceptionTypes() {
|
||||
return TypeToken.this.resolveInPlace(super.getGenericExceptionTypes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeToken<T> getOwnerType() {
|
||||
return TypeToken.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String string = String.valueOf(String.valueOf(this.getOwnerType()));
|
||||
String string2 = String.valueOf(String.valueOf(Joiner.on(", ").join(this.getGenericParameterTypes())));
|
||||
return new StringBuilder(2 + string.length() + string2.length()).append(string).append("(").append(string2).append(")").toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof TypeToken) {
|
||||
TypeToken that = (TypeToken)o;
|
||||
return this.runtimeType.equals(that.runtimeType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.runtimeType.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Types.toString(this.runtimeType);
|
||||
}
|
||||
|
||||
protected Object writeReplace() {
|
||||
return TypeToken.of(new TypeResolver().resolveType(this.runtimeType));
|
||||
}
|
||||
|
||||
final TypeToken<T> rejectTypeVariables() {
|
||||
new TypeVisitor(){
|
||||
|
||||
@Override
|
||||
void visitTypeVariable(TypeVariable<?> type) {
|
||||
String string = String.valueOf(String.valueOf(TypeToken.this.runtimeType));
|
||||
throw new IllegalArgumentException(new StringBuilder(58 + string.length()).append(string).append("contains a type variable and is not safe for the operation").toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitWildcardType(WildcardType type) {
|
||||
this.visit(type.getLowerBounds());
|
||||
this.visit(type.getUpperBounds());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitParameterizedType(ParameterizedType type) {
|
||||
this.visit(type.getActualTypeArguments());
|
||||
this.visit(type.getOwnerType());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitGenericArrayType(GenericArrayType type) {
|
||||
this.visit(type.getGenericComponentType());
|
||||
}
|
||||
}.visit(this.runtimeType);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static boolean isAssignable(Type from, Type to) {
|
||||
if (to.equals(from)) {
|
||||
return true;
|
||||
}
|
||||
if (to instanceof WildcardType) {
|
||||
return TypeToken.isAssignableToWildcardType(from, (WildcardType)to);
|
||||
}
|
||||
if (from instanceof TypeVariable) {
|
||||
return TypeToken.isAssignableFromAny(((TypeVariable)from).getBounds(), to);
|
||||
}
|
||||
if (from instanceof WildcardType) {
|
||||
return TypeToken.isAssignableFromAny(((WildcardType)from).getUpperBounds(), to);
|
||||
}
|
||||
if (from instanceof GenericArrayType) {
|
||||
return TypeToken.isAssignableFromGenericArrayType((GenericArrayType)from, to);
|
||||
}
|
||||
if (to instanceof Class) {
|
||||
return TypeToken.isAssignableToClass(from, (Class)to);
|
||||
}
|
||||
if (to instanceof ParameterizedType) {
|
||||
return TypeToken.isAssignableToParameterizedType(from, (ParameterizedType)to);
|
||||
}
|
||||
if (to instanceof GenericArrayType) {
|
||||
return TypeToken.isAssignableToGenericArrayType(from, (GenericArrayType)to);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isAssignableFromAny(Type[] fromTypes, Type to) {
|
||||
for (Type from : fromTypes) {
|
||||
if (!TypeToken.isAssignable(from, to)) continue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isAssignableToClass(Type from, Class<?> to) {
|
||||
return to.isAssignableFrom(TypeToken.getRawType(from));
|
||||
}
|
||||
|
||||
private static boolean isAssignableToWildcardType(Type from, WildcardType to) {
|
||||
return TypeToken.isAssignable(from, TypeToken.supertypeBound(to)) && TypeToken.isAssignableBySubtypeBound(from, to);
|
||||
}
|
||||
|
||||
private static boolean isAssignableBySubtypeBound(Type from, WildcardType to) {
|
||||
Type toSubtypeBound = TypeToken.subtypeBound(to);
|
||||
if (toSubtypeBound == null) {
|
||||
return true;
|
||||
}
|
||||
Type fromSubtypeBound = TypeToken.subtypeBound(from);
|
||||
if (fromSubtypeBound == null) {
|
||||
return false;
|
||||
}
|
||||
return TypeToken.isAssignable(toSubtypeBound, fromSubtypeBound);
|
||||
}
|
||||
|
||||
private static boolean isAssignableToParameterizedType(Type from, ParameterizedType to) {
|
||||
Class<?> matchedClass = TypeToken.getRawType(to);
|
||||
if (!matchedClass.isAssignableFrom(TypeToken.getRawType(from))) {
|
||||
return false;
|
||||
}
|
||||
TypeVariable<Class<?>>[] typeParams = matchedClass.getTypeParameters();
|
||||
Type[] toTypeArgs = to.getActualTypeArguments();
|
||||
TypeToken<?> fromTypeToken = TypeToken.of(from);
|
||||
for (int i = 0; i < typeParams.length; ++i) {
|
||||
Type fromTypeArg = fromTypeToken.resolveType(typeParams[i]).runtimeType;
|
||||
if (TypeToken.matchTypeArgument(fromTypeArg, toTypeArgs[i])) continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isAssignableToGenericArrayType(Type from, GenericArrayType to) {
|
||||
if (from instanceof Class) {
|
||||
Class fromClass = (Class)from;
|
||||
if (!fromClass.isArray()) {
|
||||
return false;
|
||||
}
|
||||
return TypeToken.isAssignable(fromClass.getComponentType(), to.getGenericComponentType());
|
||||
}
|
||||
if (from instanceof GenericArrayType) {
|
||||
GenericArrayType fromArrayType = (GenericArrayType)from;
|
||||
return TypeToken.isAssignable(fromArrayType.getGenericComponentType(), to.getGenericComponentType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isAssignableFromGenericArrayType(GenericArrayType from, Type to) {
|
||||
if (to instanceof Class) {
|
||||
Class toClass = (Class)to;
|
||||
if (!toClass.isArray()) {
|
||||
return toClass == Object.class;
|
||||
}
|
||||
return TypeToken.isAssignable(from.getGenericComponentType(), toClass.getComponentType());
|
||||
}
|
||||
if (to instanceof GenericArrayType) {
|
||||
GenericArrayType toArrayType = (GenericArrayType)to;
|
||||
return TypeToken.isAssignable(from.getGenericComponentType(), toArrayType.getGenericComponentType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean matchTypeArgument(Type from, Type to) {
|
||||
if (from.equals(to)) {
|
||||
return true;
|
||||
}
|
||||
if (to instanceof WildcardType) {
|
||||
return TypeToken.isAssignableToWildcardType(from, (WildcardType)to);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Type supertypeBound(Type type) {
|
||||
if (type instanceof WildcardType) {
|
||||
return TypeToken.supertypeBound((WildcardType)type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static Type supertypeBound(WildcardType type) {
|
||||
Type[] upperBounds = type.getUpperBounds();
|
||||
if (upperBounds.length == 1) {
|
||||
return TypeToken.supertypeBound(upperBounds[0]);
|
||||
}
|
||||
if (upperBounds.length == 0) {
|
||||
return Object.class;
|
||||
}
|
||||
String string = String.valueOf(String.valueOf(type));
|
||||
throw new AssertionError((Object)new StringBuilder(59 + string.length()).append("There should be at most one upper bound for wildcard type: ").append(string).toString());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Type subtypeBound(Type type) {
|
||||
if (type instanceof WildcardType) {
|
||||
return TypeToken.subtypeBound((WildcardType)type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Type subtypeBound(WildcardType type) {
|
||||
Type[] lowerBounds = type.getLowerBounds();
|
||||
if (lowerBounds.length == 1) {
|
||||
return TypeToken.subtypeBound(lowerBounds[0]);
|
||||
}
|
||||
if (lowerBounds.length == 0) {
|
||||
return null;
|
||||
}
|
||||
String string = String.valueOf(String.valueOf(type));
|
||||
throw new AssertionError((Object)new StringBuilder(46 + string.length()).append("Wildcard should have at most one lower bound: ").append(string).toString());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static Class<?> getRawType(Type type) {
|
||||
return (Class)TypeToken.getRawTypes(type).iterator().next();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static ImmutableSet<Class<?>> getRawTypes(Type type) {
|
||||
Preconditions.checkNotNull(type);
|
||||
final ImmutableSet.Builder builder = ImmutableSet.builder();
|
||||
new TypeVisitor(){
|
||||
|
||||
@Override
|
||||
void visitTypeVariable(TypeVariable<?> t) {
|
||||
this.visit(t.getBounds());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitWildcardType(WildcardType t) {
|
||||
this.visit(t.getUpperBounds());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitParameterizedType(ParameterizedType t) {
|
||||
builder.add((Class)t.getRawType());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitClass(Class<?> t) {
|
||||
builder.add(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitGenericArrayType(GenericArrayType t) {
|
||||
builder.add(Types.getArrayClass(TypeToken.getRawType(t.getGenericComponentType())));
|
||||
}
|
||||
}.visit(type);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
|
||||
if (cls.isArray()) {
|
||||
Type arrayOfGenericType = Types.newArrayType(TypeToken.toGenericType(cls.getComponentType()).runtimeType);
|
||||
TypeToken<?> result = TypeToken.of(arrayOfGenericType);
|
||||
return result;
|
||||
}
|
||||
Type[] typeParams = cls.getTypeParameters();
|
||||
if (typeParams.length > 0) {
|
||||
TypeToken<?> type = TypeToken.of(Types.newParameterizedType(cls, typeParams));
|
||||
return type;
|
||||
}
|
||||
return TypeToken.of(cls);
|
||||
}
|
||||
|
||||
private TypeToken<? super T> getSupertypeFromUpperBounds(Class<? super T> supertype, Type[] upperBounds) {
|
||||
for (Type upperBound : upperBounds) {
|
||||
TypeToken<?> bound = TypeToken.of(upperBound);
|
||||
if (!TypeToken.of(supertype).isAssignableFrom(bound)) continue;
|
||||
TypeToken<? super T> result = bound.getSupertype(supertype);
|
||||
return result;
|
||||
}
|
||||
String string = String.valueOf(String.valueOf(supertype));
|
||||
String string2 = String.valueOf(String.valueOf(this));
|
||||
throw new IllegalArgumentException(new StringBuilder(23 + string.length() + string2.length()).append(string).append(" isn't a super type of ").append(string2).toString());
|
||||
}
|
||||
|
||||
private TypeToken<? extends T> getSubtypeFromLowerBounds(Class<?> subclass, Type[] lowerBounds) {
|
||||
int i$ = 0;
|
||||
Type[] arr$ = lowerBounds;
|
||||
int len$ = arr$.length;
|
||||
if (i$ < len$) {
|
||||
Type lowerBound = arr$[i$];
|
||||
TypeToken<?> bound = TypeToken.of(lowerBound);
|
||||
return bound.getSubtype(subclass);
|
||||
}
|
||||
String string = String.valueOf(String.valueOf(subclass));
|
||||
String string2 = String.valueOf(String.valueOf(this));
|
||||
throw new IllegalArgumentException(new StringBuilder(21 + string.length() + string2.length()).append(string).append(" isn't a subclass of ").append(string2).toString());
|
||||
}
|
||||
|
||||
private TypeToken<? super T> getArraySupertype(Class<? super T> supertype) {
|
||||
TypeToken<?> componentType = Preconditions.checkNotNull(this.getComponentType(), "%s isn't a super type of %s", supertype, this);
|
||||
TypeToken<?> componentSupertype = componentType.getSupertype(supertype.getComponentType());
|
||||
TypeToken<?> result = TypeToken.of(TypeToken.newArrayClassOrGenericArrayType(componentSupertype.runtimeType));
|
||||
return result;
|
||||
}
|
||||
|
||||
private TypeToken<? extends T> getArraySubtype(Class<?> subclass) {
|
||||
TypeToken<?> componentSubtype = this.getComponentType().getSubtype(subclass.getComponentType());
|
||||
TypeToken<?> result = TypeToken.of(TypeToken.newArrayClassOrGenericArrayType(componentSubtype.runtimeType));
|
||||
return result;
|
||||
}
|
||||
|
||||
private Type resolveTypeArgsForSubclass(Class<?> subclass) {
|
||||
if (this.runtimeType instanceof Class) {
|
||||
return subclass;
|
||||
}
|
||||
TypeToken<?> genericSubtype = TypeToken.toGenericType(subclass);
|
||||
Type supertypeWithArgsFromSubtype = genericSubtype.getSupertype(this.getRawType()).runtimeType;
|
||||
return new TypeResolver().where(supertypeWithArgsFromSubtype, this.runtimeType).resolveType(genericSubtype.runtimeType);
|
||||
}
|
||||
|
||||
private static Type newArrayClassOrGenericArrayType(Type componentType) {
|
||||
return Types.JavaVersion.JAVA7.newArrayType(componentType);
|
||||
}
|
||||
|
||||
private static abstract class TypeCollector<K> {
|
||||
static final TypeCollector<TypeToken<?>> FOR_GENERIC_TYPE = new TypeCollector<TypeToken<?>>(){
|
||||
|
||||
@Override
|
||||
Class<?> getRawType(TypeToken<?> type) {
|
||||
return type.getRawType();
|
||||
}
|
||||
|
||||
@Override
|
||||
Iterable<? extends TypeToken<?>> getInterfaces(TypeToken<?> type) {
|
||||
return type.getGenericInterfaces();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
TypeToken<?> getSuperclass(TypeToken<?> type) {
|
||||
return type.getGenericSuperclass();
|
||||
}
|
||||
};
|
||||
static final TypeCollector<Class<?>> FOR_RAW_TYPE = new TypeCollector<Class<?>>(){
|
||||
|
||||
@Override
|
||||
Class<?> getRawType(Class<?> type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
Iterable<? extends Class<?>> getInterfaces(Class<?> type) {
|
||||
return Arrays.asList(type.getInterfaces());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
Class<?> getSuperclass(Class<?> type) {
|
||||
return type.getSuperclass();
|
||||
}
|
||||
};
|
||||
|
||||
private TypeCollector() {
|
||||
}
|
||||
|
||||
final TypeCollector<K> classesOnly() {
|
||||
return new ForwardingTypeCollector<K>(this){
|
||||
|
||||
@Override
|
||||
Iterable<? extends K> getInterfaces(K type) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
ImmutableList<K> collectTypes(Iterable<? extends K> types) {
|
||||
ImmutableList.Builder builder = ImmutableList.builder();
|
||||
for (Object type : types) {
|
||||
if (this.getRawType(type).isInterface()) continue;
|
||||
builder.add(type);
|
||||
}
|
||||
return super.collectTypes(builder.build());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
final ImmutableList<K> collectTypes(K type) {
|
||||
return this.collectTypes((Iterable<? extends K>)ImmutableList.of(type));
|
||||
}
|
||||
|
||||
ImmutableList<K> collectTypes(Iterable<? extends K> types) {
|
||||
HashMap map = Maps.newHashMap();
|
||||
for (K type : types) {
|
||||
this.collectTypes(type, map);
|
||||
}
|
||||
return TypeCollector.sortKeysByValue(map, Ordering.natural().reverse());
|
||||
}
|
||||
|
||||
private int collectTypes(K type, Map<? super K, Integer> map) {
|
||||
Integer existing = map.get(this);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
int aboveMe = this.getRawType(type).isInterface() ? 1 : 0;
|
||||
for (K interfaceType : this.getInterfaces(type)) {
|
||||
aboveMe = Math.max(aboveMe, this.collectTypes(interfaceType, map));
|
||||
}
|
||||
K superclass = this.getSuperclass(type);
|
||||
if (superclass != null) {
|
||||
aboveMe = Math.max(aboveMe, this.collectTypes(superclass, map));
|
||||
}
|
||||
map.put(type, aboveMe + 1);
|
||||
return aboveMe + 1;
|
||||
}
|
||||
|
||||
private static <K, V> ImmutableList<K> sortKeysByValue(final Map<K, V> map, final Comparator<? super V> valueComparator) {
|
||||
Ordering keyOrdering = new Ordering<K>(){
|
||||
|
||||
@Override
|
||||
public int compare(K left, K right) {
|
||||
return valueComparator.compare(map.get(left), map.get(right));
|
||||
}
|
||||
};
|
||||
return keyOrdering.immutableSortedCopy(map.keySet());
|
||||
}
|
||||
|
||||
abstract Class<?> getRawType(K var1);
|
||||
|
||||
abstract Iterable<? extends K> getInterfaces(K var1);
|
||||
|
||||
@Nullable
|
||||
abstract K getSuperclass(K var1);
|
||||
|
||||
private static class ForwardingTypeCollector<K>
|
||||
extends TypeCollector<K> {
|
||||
private final TypeCollector<K> delegate;
|
||||
|
||||
ForwardingTypeCollector(TypeCollector<K> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<?> getRawType(K type) {
|
||||
return this.delegate.getRawType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
Iterable<? extends K> getInterfaces(K type) {
|
||||
return this.delegate.getInterfaces(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
K getSuperclass(K type) {
|
||||
return this.delegate.getSuperclass(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SimpleTypeToken<T>
|
||||
extends TypeToken<T> {
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
SimpleTypeToken(Type type) {
|
||||
super(type);
|
||||
}
|
||||
}
|
||||
|
||||
private static enum TypeFilter implements Predicate<TypeToken<?>>
|
||||
{
|
||||
IGNORE_TYPE_VARIABLE_OR_WILDCARD{
|
||||
|
||||
@Override
|
||||
public boolean apply(TypeToken<?> type) {
|
||||
return !(((TypeToken)type).runtimeType instanceof TypeVariable) && !(((TypeToken)type).runtimeType instanceof WildcardType);
|
||||
}
|
||||
}
|
||||
,
|
||||
INTERFACE_ONLY{
|
||||
|
||||
@Override
|
||||
public boolean apply(TypeToken<?> type) {
|
||||
return type.getRawType().isInterface();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private final class ClassSet
|
||||
extends TypeSet {
|
||||
private transient ImmutableSet<TypeToken<? super T>> classes;
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
private ClassSet() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<TypeToken<? super T>> delegate() {
|
||||
ImmutableSet result = this.classes;
|
||||
if (result == null) {
|
||||
ImmutableList<TypeToken> collectedTypes = TypeCollector.FOR_GENERIC_TYPE.classesOnly().collectTypes(TypeToken.this);
|
||||
this.classes = FluentIterable.from(collectedTypes).filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD).toSet();
|
||||
return this.classes;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeSet classes() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<? super T>> rawTypes() {
|
||||
ImmutableList<Class<?>> collectedTypes = TypeCollector.FOR_RAW_TYPE.classesOnly().collectTypes(TypeToken.this.getImmediateRawTypes());
|
||||
return ImmutableSet.copyOf(collectedTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeSet interfaces() {
|
||||
throw new UnsupportedOperationException("classes().interfaces() not supported.");
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return TypeToken.this.getTypes().classes();
|
||||
}
|
||||
}
|
||||
|
||||
private final class InterfaceSet
|
||||
extends TypeSet {
|
||||
private final transient TypeSet allTypes;
|
||||
private transient ImmutableSet<TypeToken<? super T>> interfaces;
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
InterfaceSet(TypeSet allTypes) {
|
||||
this.allTypes = allTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<TypeToken<? super T>> delegate() {
|
||||
ImmutableSet result = this.interfaces;
|
||||
if (result == null) {
|
||||
this.interfaces = FluentIterable.from(this.allTypes).filter(TypeFilter.INTERFACE_ONLY).toSet();
|
||||
return this.interfaces;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeSet interfaces() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Class<? super T>> rawTypes() {
|
||||
ImmutableList<Class<?>> collectedTypes = TypeCollector.FOR_RAW_TYPE.collectTypes(TypeToken.this.getImmediateRawTypes());
|
||||
return FluentIterable.from(collectedTypes).filter(new Predicate<Class<?>>(){
|
||||
|
||||
@Override
|
||||
public boolean apply(Class<?> type) {
|
||||
return type.isInterface();
|
||||
}
|
||||
}).toSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeSet classes() {
|
||||
throw new UnsupportedOperationException("interfaces().classes() not supported.");
|
||||
}
|
||||
|
||||
private Object readResolve() {
|
||||
return TypeToken.this.getTypes().interfaces();
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeSet
|
||||
extends ForwardingSet<TypeToken<? super T>>
|
||||
implements Serializable {
|
||||
private transient ImmutableSet<TypeToken<? super T>> types;
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
TypeSet() {
|
||||
}
|
||||
|
||||
public TypeSet interfaces() {
|
||||
return new InterfaceSet(this);
|
||||
}
|
||||
|
||||
public TypeSet classes() {
|
||||
return new ClassSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<TypeToken<? super T>> delegate() {
|
||||
ImmutableSet filteredTypes = this.types;
|
||||
if (filteredTypes == null) {
|
||||
ImmutableList<TypeToken> collectedTypes = TypeCollector.FOR_GENERIC_TYPE.collectTypes(TypeToken.this);
|
||||
this.types = FluentIterable.from(collectedTypes).filter(TypeFilter.IGNORE_TYPE_VARIABLE_OR_WILDCARD).toSet();
|
||||
return this.types;
|
||||
}
|
||||
return filteredTypes;
|
||||
}
|
||||
|
||||
public Set<Class<? super T>> rawTypes() {
|
||||
ImmutableList<Class<?>> collectedTypes = TypeCollector.FOR_RAW_TYPE.collectTypes(TypeToken.this.getImmediateRawTypes());
|
||||
return ImmutableSet.copyOf(collectedTypes);
|
||||
}
|
||||
}
|
||||
}
|
68
src/com/google/common/reflect/TypeVisitor.java
Normal file
68
src/com/google/common/reflect/TypeVisitor.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.Set;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
@NotThreadSafe
|
||||
abstract class TypeVisitor {
|
||||
private final Set<Type> visited = Sets.newHashSet();
|
||||
|
||||
TypeVisitor() {
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING - Removed try catching itself - possible behaviour change.
|
||||
*/
|
||||
public final void visit(Type ... types) {
|
||||
for (Type type : types) {
|
||||
if (type == null || !this.visited.add(type)) continue;
|
||||
boolean succeeded = false;
|
||||
try {
|
||||
if (type instanceof TypeVariable) {
|
||||
this.visitTypeVariable((TypeVariable)type);
|
||||
} else if (type instanceof WildcardType) {
|
||||
this.visitWildcardType((WildcardType)type);
|
||||
} else if (type instanceof ParameterizedType) {
|
||||
this.visitParameterizedType((ParameterizedType)type);
|
||||
} else if (type instanceof Class) {
|
||||
this.visitClass((Class)type);
|
||||
} else if (type instanceof GenericArrayType) {
|
||||
this.visitGenericArrayType((GenericArrayType)type);
|
||||
} else {
|
||||
String string = String.valueOf(String.valueOf(type));
|
||||
throw new AssertionError((Object)new StringBuilder(14 + string.length()).append("Unknown type: ").append(string).toString());
|
||||
}
|
||||
succeeded = true;
|
||||
}
|
||||
finally {
|
||||
if (!succeeded) {
|
||||
this.visited.remove(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visitClass(Class<?> t) {
|
||||
}
|
||||
|
||||
void visitGenericArrayType(GenericArrayType t) {
|
||||
}
|
||||
|
||||
void visitParameterizedType(ParameterizedType t) {
|
||||
}
|
||||
|
||||
void visitTypeVariable(TypeVariable<?> t) {
|
||||
}
|
||||
|
||||
void visitWildcardType(WildcardType t) {
|
||||
}
|
||||
}
|
491
src/com/google/common/reflect/Types.java
Normal file
491
src/com/google/common/reflect/Types.java
Normal file
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package com.google.common.reflect;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.reflect.TypeCapture;
|
||||
import com.google.common.reflect.TypeVisitor;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.GenericDeclaration;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class Types {
|
||||
private static final Function<Type, String> TYPE_NAME = new Function<Type, String>(){
|
||||
|
||||
@Override
|
||||
public String apply(Type from) {
|
||||
return JavaVersion.CURRENT.typeName(from);
|
||||
}
|
||||
};
|
||||
private static final Joiner COMMA_JOINER = Joiner.on(", ").useForNull("null");
|
||||
|
||||
static Type newArrayType(Type componentType) {
|
||||
if (componentType instanceof WildcardType) {
|
||||
WildcardType wildcard = (WildcardType)componentType;
|
||||
Type[] lowerBounds = wildcard.getLowerBounds();
|
||||
Preconditions.checkArgument(lowerBounds.length <= 1, "Wildcard cannot have more than one lower bounds.");
|
||||
if (lowerBounds.length == 1) {
|
||||
return Types.supertypeOf(Types.newArrayType(lowerBounds[0]));
|
||||
}
|
||||
Type[] upperBounds = wildcard.getUpperBounds();
|
||||
Preconditions.checkArgument(upperBounds.length == 1, "Wildcard should have only one upper bound.");
|
||||
return Types.subtypeOf(Types.newArrayType(upperBounds[0]));
|
||||
}
|
||||
return JavaVersion.CURRENT.newArrayType(componentType);
|
||||
}
|
||||
|
||||
static ParameterizedType newParameterizedTypeWithOwner(@Nullable Type ownerType, Class<?> rawType, Type ... arguments) {
|
||||
if (ownerType == null) {
|
||||
return Types.newParameterizedType(rawType, arguments);
|
||||
}
|
||||
Preconditions.checkNotNull(arguments);
|
||||
Preconditions.checkArgument(rawType.getEnclosingClass() != null, "Owner type for unenclosed %s", rawType);
|
||||
return new ParameterizedTypeImpl(ownerType, rawType, arguments);
|
||||
}
|
||||
|
||||
static ParameterizedType newParameterizedType(Class<?> rawType, Type ... arguments) {
|
||||
return new ParameterizedTypeImpl(ClassOwnership.JVM_BEHAVIOR.getOwnerType(rawType), rawType, arguments);
|
||||
}
|
||||
|
||||
static <D extends GenericDeclaration> TypeVariable<D> newArtificialTypeVariable(D declaration, String name, Type ... bounds) {
|
||||
Type[] typeArray;
|
||||
if (bounds.length == 0) {
|
||||
Type[] typeArray2 = new Type[1];
|
||||
typeArray = typeArray2;
|
||||
typeArray2[0] = Object.class;
|
||||
} else {
|
||||
typeArray = bounds;
|
||||
}
|
||||
return new TypeVariableImpl<D>(declaration, name, typeArray);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static WildcardType subtypeOf(Type upperBound) {
|
||||
return new WildcardTypeImpl(new Type[0], new Type[]{upperBound});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static WildcardType supertypeOf(Type lowerBound) {
|
||||
return new WildcardTypeImpl(new Type[]{lowerBound}, new Type[]{Object.class});
|
||||
}
|
||||
|
||||
static String toString(Type type) {
|
||||
return type instanceof Class ? ((Class)type).getName() : type.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Type getComponentType(Type type) {
|
||||
Preconditions.checkNotNull(type);
|
||||
final AtomicReference result = new AtomicReference();
|
||||
new TypeVisitor(){
|
||||
|
||||
@Override
|
||||
void visitTypeVariable(TypeVariable<?> t) {
|
||||
result.set(Types.subtypeOfComponentType(t.getBounds()));
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitWildcardType(WildcardType t) {
|
||||
result.set(Types.subtypeOfComponentType(t.getUpperBounds()));
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitGenericArrayType(GenericArrayType t) {
|
||||
result.set(t.getGenericComponentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
void visitClass(Class<?> t) {
|
||||
result.set(t.getComponentType());
|
||||
}
|
||||
}.visit(type);
|
||||
return (Type)result.get();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Type subtypeOfComponentType(Type[] bounds) {
|
||||
for (Type bound : bounds) {
|
||||
Class componentClass;
|
||||
Type componentType = Types.getComponentType(bound);
|
||||
if (componentType == null) continue;
|
||||
if (componentType instanceof Class && (componentClass = (Class)componentType).isPrimitive()) {
|
||||
return componentClass;
|
||||
}
|
||||
return Types.subtypeOf(componentType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Type[] toArray(Collection<Type> types) {
|
||||
return types.toArray(new Type[types.size()]);
|
||||
}
|
||||
|
||||
private static Iterable<Type> filterUpperBounds(Iterable<Type> bounds) {
|
||||
return Iterables.filter(bounds, Predicates.not(Predicates.equalTo(Object.class)));
|
||||
}
|
||||
|
||||
private static void disallowPrimitiveType(Type[] types, String usedAs) {
|
||||
for (Type type : types) {
|
||||
if (!(type instanceof Class)) continue;
|
||||
Class cls = (Class)type;
|
||||
Preconditions.checkArgument(!cls.isPrimitive(), "Primitive type '%s' used as %s", cls, usedAs);
|
||||
}
|
||||
}
|
||||
|
||||
static Class<?> getArrayClass(Class<?> componentType) {
|
||||
return Array.newInstance(componentType, 0).getClass();
|
||||
}
|
||||
|
||||
private Types() {
|
||||
}
|
||||
|
||||
static final class NativeTypeVariableEquals<X> {
|
||||
static final boolean NATIVE_TYPE_VARIABLE_ONLY = !NativeTypeVariableEquals.class.getTypeParameters()[0].equals(Types.newArtificialTypeVariable(NativeTypeVariableEquals.class, "X", new Type[0]));
|
||||
|
||||
NativeTypeVariableEquals() {
|
||||
}
|
||||
}
|
||||
|
||||
static enum JavaVersion {
|
||||
JAVA6{
|
||||
|
||||
@Override
|
||||
GenericArrayType newArrayType(Type componentType) {
|
||||
return new GenericArrayTypeImpl(componentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
Type usedInGenericType(Type type) {
|
||||
Class cls;
|
||||
Preconditions.checkNotNull(type);
|
||||
if (type instanceof Class && (cls = (Class)type).isArray()) {
|
||||
return new GenericArrayTypeImpl(cls.getComponentType());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
,
|
||||
JAVA7{
|
||||
|
||||
@Override
|
||||
Type newArrayType(Type componentType) {
|
||||
if (componentType instanceof Class) {
|
||||
return Types.getArrayClass((Class)componentType);
|
||||
}
|
||||
return new GenericArrayTypeImpl(componentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
Type usedInGenericType(Type type) {
|
||||
return Preconditions.checkNotNull(type);
|
||||
}
|
||||
}
|
||||
,
|
||||
JAVA8{
|
||||
|
||||
@Override
|
||||
Type newArrayType(Type componentType) {
|
||||
return JAVA7.newArrayType(componentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
Type usedInGenericType(Type type) {
|
||||
return JAVA7.usedInGenericType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
String typeName(Type type) {
|
||||
try {
|
||||
Method getTypeName = Type.class.getMethod("getTypeName", new Class[0]);
|
||||
return (String)getTypeName.invoke(type, new Object[0]);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new AssertionError((Object)"Type.getTypeName should be available in Java 8");
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static final JavaVersion CURRENT;
|
||||
|
||||
abstract Type newArrayType(Type var1);
|
||||
|
||||
abstract Type usedInGenericType(Type var1);
|
||||
|
||||
String typeName(Type type) {
|
||||
return Types.toString(type);
|
||||
}
|
||||
|
||||
final ImmutableList<Type> usedInGenericType(Type[] types) {
|
||||
ImmutableList.Builder builder = ImmutableList.builder();
|
||||
for (Type type : types) {
|
||||
builder.add(this.usedInGenericType(type));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static {
|
||||
CURRENT = AnnotatedElement.class.isAssignableFrom(TypeVariable.class) ? JAVA8 : (new TypeCapture<int[]>(){}.capture() instanceof Class ? JAVA7 : JAVA6);
|
||||
}
|
||||
}
|
||||
|
||||
static final class WildcardTypeImpl
|
||||
implements WildcardType,
|
||||
Serializable {
|
||||
private final ImmutableList<Type> lowerBounds;
|
||||
private final ImmutableList<Type> upperBounds;
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
WildcardTypeImpl(Type[] lowerBounds, Type[] upperBounds) {
|
||||
Types.disallowPrimitiveType(lowerBounds, "lower bound for wildcard");
|
||||
Types.disallowPrimitiveType(upperBounds, "upper bound for wildcard");
|
||||
this.lowerBounds = JavaVersion.CURRENT.usedInGenericType(lowerBounds);
|
||||
this.upperBounds = JavaVersion.CURRENT.usedInGenericType(upperBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getLowerBounds() {
|
||||
return Types.toArray(this.lowerBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getUpperBounds() {
|
||||
return Types.toArray(this.upperBounds);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof WildcardType) {
|
||||
WildcardType that = (WildcardType)obj;
|
||||
return this.lowerBounds.equals(Arrays.asList(that.getLowerBounds())) && this.upperBounds.equals(Arrays.asList(that.getUpperBounds()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.lowerBounds.hashCode() ^ this.upperBounds.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder("?");
|
||||
for (Type lowerBound : this.lowerBounds) {
|
||||
builder.append(" super ").append(JavaVersion.CURRENT.typeName(lowerBound));
|
||||
}
|
||||
for (Type upperBound : Types.filterUpperBounds(this.upperBounds)) {
|
||||
builder.append(" extends ").append(JavaVersion.CURRENT.typeName(upperBound));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TypeVariableImpl<D extends GenericDeclaration>
|
||||
implements TypeVariable<D> {
|
||||
private final D genericDeclaration;
|
||||
private final String name;
|
||||
private final ImmutableList<Type> bounds;
|
||||
|
||||
TypeVariableImpl(D genericDeclaration, String name, Type[] bounds) {
|
||||
Types.disallowPrimitiveType(bounds, "bound for type variable");
|
||||
this.genericDeclaration = (GenericDeclaration)Preconditions.checkNotNull(genericDeclaration);
|
||||
this.name = Preconditions.checkNotNull(name);
|
||||
this.bounds = ImmutableList.copyOf(bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getBounds() {
|
||||
return Types.toArray(this.bounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public D getGenericDeclaration() {
|
||||
return this.genericDeclaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.genericDeclaration.hashCode() ^ this.name.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (NativeTypeVariableEquals.NATIVE_TYPE_VARIABLE_ONLY) {
|
||||
if (obj instanceof TypeVariableImpl) {
|
||||
TypeVariableImpl that = (TypeVariableImpl)obj;
|
||||
return this.name.equals(that.getName()) && this.genericDeclaration.equals(that.getGenericDeclaration()) && this.bounds.equals(that.bounds);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof TypeVariable) {
|
||||
TypeVariable that = (TypeVariable)obj;
|
||||
return this.name.equals(that.getName()) && this.genericDeclaration.equals(that.getGenericDeclaration());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ParameterizedTypeImpl
|
||||
implements ParameterizedType,
|
||||
Serializable {
|
||||
private final Type ownerType;
|
||||
private final ImmutableList<Type> argumentsList;
|
||||
private final Class<?> rawType;
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
ParameterizedTypeImpl(@Nullable Type ownerType, Class<?> rawType, Type[] typeArguments) {
|
||||
Preconditions.checkNotNull(rawType);
|
||||
Preconditions.checkArgument(typeArguments.length == rawType.getTypeParameters().length);
|
||||
Types.disallowPrimitiveType(typeArguments, "type parameter");
|
||||
this.ownerType = ownerType;
|
||||
this.rawType = rawType;
|
||||
this.argumentsList = JavaVersion.CURRENT.usedInGenericType(typeArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getActualTypeArguments() {
|
||||
return Types.toArray(this.argumentsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getRawType() {
|
||||
return this.rawType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getOwnerType() {
|
||||
return this.ownerType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (this.ownerType != null) {
|
||||
builder.append(JavaVersion.CURRENT.typeName(this.ownerType)).append('.');
|
||||
}
|
||||
builder.append(this.rawType.getName()).append('<').append(COMMA_JOINER.join(Iterables.transform(this.argumentsList, TYPE_NAME))).append('>');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (this.ownerType == null ? 0 : this.ownerType.hashCode()) ^ this.argumentsList.hashCode() ^ this.rawType.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ParameterizedType)) {
|
||||
return false;
|
||||
}
|
||||
ParameterizedType that = (ParameterizedType)other;
|
||||
return this.getRawType().equals(that.getRawType()) && Objects.equal(this.getOwnerType(), that.getOwnerType()) && Arrays.equals(this.getActualTypeArguments(), that.getActualTypeArguments());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class GenericArrayTypeImpl
|
||||
implements GenericArrayType,
|
||||
Serializable {
|
||||
private final Type componentType;
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
GenericArrayTypeImpl(Type componentType) {
|
||||
this.componentType = JavaVersion.CURRENT.usedInGenericType(componentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getGenericComponentType() {
|
||||
return this.componentType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.valueOf(Types.toString(this.componentType)).concat("[]");
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.componentType.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof GenericArrayType) {
|
||||
GenericArrayType that = (GenericArrayType)obj;
|
||||
return Objects.equal(this.getGenericComponentType(), that.getGenericComponentType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static enum ClassOwnership {
|
||||
OWNED_BY_ENCLOSING_CLASS{
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
Class<?> getOwnerType(Class<?> rawType) {
|
||||
return rawType.getEnclosingClass();
|
||||
}
|
||||
}
|
||||
,
|
||||
LOCAL_CLASS_HAS_NO_OWNER{
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
Class<?> getOwnerType(Class<?> rawType) {
|
||||
if (rawType.isLocalClass()) {
|
||||
return null;
|
||||
}
|
||||
return rawType.getEnclosingClass();
|
||||
}
|
||||
};
|
||||
|
||||
static final ClassOwnership JVM_BEHAVIOR;
|
||||
|
||||
@Nullable
|
||||
abstract Class<?> getOwnerType(Class<?> var1);
|
||||
|
||||
private static ClassOwnership detectJvmBehavior() {
|
||||
class LocalClass<T> {
|
||||
LocalClass() {
|
||||
}
|
||||
}
|
||||
Class<?> subclass = new LocalClass<String>(){
|
||||
{
|
||||
}
|
||||
}.getClass();
|
||||
ParameterizedType parameterizedType = (ParameterizedType)subclass.getGenericSuperclass();
|
||||
for (ClassOwnership behavior : ClassOwnership.values()) {
|
||||
if (behavior.getOwnerType(LocalClass.class) != parameterizedType.getOwnerType()) continue;
|
||||
return behavior;
|
||||
}
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
static {
|
||||
JVM_BEHAVIOR = ClassOwnership.detectJvmBehavior();
|
||||
}
|
||||
}
|
||||
}
|
8
src/com/google/common/reflect/package-info.java
Normal file
8
src/com/google/common/reflect/package-info.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
package com.google.common.reflect;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue