Lines 26-41
Link Here
|
26 |
import com.google.common.base.Objects; |
26 |
import com.google.common.base.Objects; |
27 |
import com.google.common.base.Predicates; |
27 |
import com.google.common.base.Predicates; |
28 |
import com.google.common.collect.ImmutableList; |
28 |
import com.google.common.collect.ImmutableList; |
|
|
29 |
import com.google.common.collect.ImmutableMap; |
29 |
import com.google.common.collect.Iterables; |
30 |
import com.google.common.collect.Iterables; |
30 |
|
31 |
|
31 |
import java.io.Serializable; |
32 |
import java.io.Serializable; |
32 |
import java.lang.reflect.Array; |
33 |
import java.lang.reflect.Array; |
33 |
import java.lang.reflect.GenericArrayType; |
34 |
import java.lang.reflect.GenericArrayType; |
34 |
import java.lang.reflect.GenericDeclaration; |
35 |
import java.lang.reflect.GenericDeclaration; |
|
|
36 |
import java.lang.reflect.InvocationHandler; |
37 |
import java.lang.reflect.InvocationTargetException; |
38 |
import java.lang.reflect.Method; |
35 |
import java.lang.reflect.ParameterizedType; |
39 |
import java.lang.reflect.ParameterizedType; |
|
|
40 |
import java.lang.reflect.Proxy; |
36 |
import java.lang.reflect.Type; |
41 |
import java.lang.reflect.Type; |
37 |
import java.lang.reflect.TypeVariable; |
42 |
import java.lang.reflect.TypeVariable; |
38 |
import java.lang.reflect.WildcardType; |
43 |
import java.lang.reflect.WildcardType; |
|
|
44 |
import java.security.AccessControlException; |
39 |
import java.util.Arrays; |
45 |
import java.util.Arrays; |
40 |
import java.util.Collection; |
46 |
import java.util.Collection; |
41 |
import java.util.concurrent.atomic.AtomicReference; |
47 |
import java.util.concurrent.atomic.AtomicReference; |
Lines 146-152
private static ClassOwnership detectJvmBehavior() {
Link Here
|
146 |
*/ |
152 |
*/ |
147 |
static <D extends GenericDeclaration> TypeVariable<D> newArtificialTypeVariable( |
153 |
static <D extends GenericDeclaration> TypeVariable<D> newArtificialTypeVariable( |
148 |
D declaration, String name, Type... bounds) { |
154 |
D declaration, String name, Type... bounds) { |
149 |
return new TypeVariableImpl<D>( |
155 |
return newTypeVariableImpl( |
150 |
declaration, |
156 |
declaration, |
151 |
name, |
157 |
name, |
152 |
(bounds.length == 0) |
158 |
(bounds.length == 0) |
Lines 314-321
static String toString(Type type) {
Link Here
|
314 |
private static final long serialVersionUID = 0; |
320 |
private static final long serialVersionUID = 0; |
315 |
} |
321 |
} |
316 |
|
322 |
|
317 |
private static final class TypeVariableImpl<D extends GenericDeclaration> |
323 |
private static <D extends GenericDeclaration> TypeVariable<D> newTypeVariableImpl( |
318 |
implements TypeVariable<D> { |
324 |
D genericDeclaration, String name, Type[] bounds) { |
|
|
325 |
TypeVariableImpl<D> typeVariableImpl = |
326 |
new TypeVariableImpl<D>(genericDeclaration, name, bounds); |
327 |
@SuppressWarnings("unchecked") |
328 |
TypeVariable<D> typeVariable = Reflection.newProxy( |
329 |
TypeVariable.class, new TypeVariableInvocationHandler(typeVariableImpl)); |
330 |
return typeVariable; |
331 |
} |
332 |
|
333 |
/** |
334 |
* Invocation handler to work around a compatibility problem between Java 7 and Java 8. |
335 |
* |
336 |
* <p>Java 8 introduced a new method {@code getAnnotatedBounds()} in the {@link TypeVariable} |
337 |
* interface, whose return type {@code AnnotatedType[]} is also new in Java 8. That means that we |
338 |
* cannot implement that interface in source code in a way that will compile on both Java 7 and |
339 |
* Java 8. If we include the {@code getAnnotatedBounds()} method then its return type means |
340 |
* it won't compile on Java 7, while if we don't include the method then the compiler will |
341 |
* complain that an abstract method is unimplemented. So instead we use a dynamic proxy to |
342 |
* get an implementation. If the method being called on the {@code TypeVariable} instance has |
343 |
* the same name as one of the public methods of {@link TypeVariableImpl}, the proxy calls |
344 |
* the same method on its instance of {@code TypeVariableImpl}. Otherwise it throws {@link |
345 |
* UnsupportedOperationException}; this should only apply to {@code getAnnotatedBounds()}. This |
346 |
* does mean that users on Java 8 who obtain an instance of {@code TypeVariable} from {@link |
347 |
* TypeResolver#resolveType} will not be able to call {@code getAnnotatedBounds()} on it, but that |
348 |
* should hopefully be rare. |
349 |
* |
350 |
* <p>This workaround should be removed at a distant future time when we no longer support Java |
351 |
* versions earlier than 8. |
352 |
*/ |
353 |
private static final class TypeVariableInvocationHandler implements InvocationHandler { |
354 |
private static final ImmutableMap<String, Method> typeVariableMethods; |
355 |
static { |
356 |
ImmutableMap.Builder<String, Method> builder = ImmutableMap.builder(); |
357 |
for (Method method : TypeVariableImpl.class.getMethods()) { |
358 |
if (method.getDeclaringClass().equals(TypeVariableImpl.class)) { |
359 |
try { |
360 |
method.setAccessible(true); |
361 |
} catch (AccessControlException e) { |
362 |
// OK: the method is accessible to us anyway. The setAccessible call is only for |
363 |
// unusual execution environments where that might not be true. |
364 |
} |
365 |
builder.put(method.getName(), method); |
366 |
} |
367 |
} |
368 |
typeVariableMethods = builder.build(); |
369 |
} |
370 |
|
371 |
private final TypeVariableImpl<?> typeVariableImpl; |
372 |
|
373 |
TypeVariableInvocationHandler(TypeVariableImpl<?> typeVariableImpl) { |
374 |
this.typeVariableImpl = typeVariableImpl; |
375 |
} |
376 |
|
377 |
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { |
378 |
String methodName = method.getName(); |
379 |
Method typeVariableMethod = typeVariableMethods.get(methodName); |
380 |
if (typeVariableMethod == null) { |
381 |
throw new UnsupportedOperationException(methodName); |
382 |
} else { |
383 |
try { |
384 |
return typeVariableMethod.invoke(typeVariableImpl, args); |
385 |
} catch (InvocationTargetException e) { |
386 |
throw e.getCause(); |
387 |
} |
388 |
} |
389 |
} |
390 |
} |
391 |
|
392 |
private static final class TypeVariableImpl<D extends GenericDeclaration> { |
319 |
|
393 |
|
320 |
private final D genericDeclaration; |
394 |
private final D genericDeclaration; |
321 |
private final String name; |
395 |
private final String name; |
Lines 328-342
static String toString(Type type) {
Link Here
|
328 |
this.bounds = ImmutableList.copyOf(bounds); |
402 |
this.bounds = ImmutableList.copyOf(bounds); |
329 |
} |
403 |
} |
330 |
|
404 |
|
331 |
@Override public Type[] getBounds() { |
405 |
public Type[] getBounds() { |
332 |
return toArray(bounds); |
406 |
return toArray(bounds); |
333 |
} |
407 |
} |
334 |
|
408 |
|
335 |
@Override public D getGenericDeclaration() { |
409 |
public D getGenericDeclaration() { |
336 |
return genericDeclaration; |
410 |
return genericDeclaration; |
337 |
} |
411 |
} |
338 |
|
412 |
|
339 |
@Override public String getName() { |
413 |
public String getName() { |
|
|
414 |
return name; |
415 |
} |
416 |
|
417 |
public String getTypeName() { |
340 |
return name; |
418 |
return name; |
341 |
} |
419 |
} |
342 |
|
420 |
|
Lines 351-358
static String toString(Type type) {
Link Here
|
351 |
} |
429 |
} |
352 |
|
430 |
|
353 |
@Override public boolean equals(Object obj) { |
431 |
@Override public boolean equals(Object obj) { |
354 |
if (obj instanceof TypeVariable) { |
432 |
if (obj != null |
355 |
TypeVariable<?> that = (TypeVariable<?>) obj; |
433 |
&& Proxy.isProxyClass(obj.getClass()) |
|
|
434 |
&& Proxy.getInvocationHandler(obj) instanceof TypeVariableInvocationHandler) { |
435 |
TypeVariableInvocationHandler typeVariableInvocationHandler = |
436 |
(TypeVariableInvocationHandler) Proxy.getInvocationHandler(obj); |
437 |
TypeVariableImpl<?> that = typeVariableInvocationHandler.typeVariableImpl; |
356 |
return name.equals(that.getName()) |
438 |
return name.equals(that.getName()) |
357 |
&& genericDeclaration.equals(that.getGenericDeclaration()); |
439 |
&& genericDeclaration.equals(that.getGenericDeclaration()); |
358 |
} |
440 |
} |
359 |
proactively prevent name shadowing with Java 8. ------------- Created by MOE: |
441 |
proactively prevent name shadowing with Java 8. ------------- Created by MOE: |
360 |
http://code.google.com/p/moe-java MOE_MIGRATED_REVID=57671698 |
442 |
http://code.google.com/p/moe-java MOE_MIGRATED_REVID=57671698 |
361 |
-- |
|
|
362 |
.../google/common/base/super/com/google/common/base/Splitter.java | 8 ++++---- |
443 |
.../google/common/base/super/com/google/common/base/Splitter.java | 8 ++++---- |
363 |
guava/src/com/google/common/base/Splitter.java | 8 ++++---- |
444 |
guava/src/com/google/common/base/Splitter.java | 8 ++++---- |
364 |
2 files changed, 8 insertions(+), 8 deletions(-) |
445 |
2 files changed, 8 insertions(+), 8 deletions(-) |