Skip to content

Commit

Permalink
Changes for correct handling of void composites.
Browse files Browse the repository at this point in the history
  • Loading branch information
szegedi committed Jan 26, 2015
1 parent 797ea85 commit 1e0fc79
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,9 @@ private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor ca

// We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be
// valid for us to convert return values proactively. Also, since we don't know what setters will be
// invoked, we'll conservatively presume Object return type.
final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
// invoked, we'll conservatively presume Object return type. The one exception is void return.
final MethodType origType = callSiteDescriptor.getMethodType();
final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class);

// What's below is basically:
// foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ class OverloadedMethod {
varArgMethods = new ArrayList<>(methodHandles.size());
final int argNum = callSiteType.parameterCount();
for(MethodHandle mh: methodHandles) {
mh = mh.asType(mh.type().changeReturnType(commonRetType));
if(mh.isVarargsCollector()) {
final MethodHandle asFixed = mh.asFixedArity();
if(argNum == asFixed.type().parameterCount()) {
Expand Down
22 changes: 11 additions & 11 deletions src/main/java/org/dynalang/dynalink/support/TypeUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,13 @@ private TypeUtilities() {
public static Class<?> getCommonLosslessConversionType(final Class<?> c1, final Class<?> c2) {
if(c1 == c2) {
return c1;
} else if (c1 == void.class || c2 == void.class) {
return Object.class;
} else if(isConvertibleWithoutLoss(c2, c1)) {
return c1;
} else if(isConvertibleWithoutLoss(c1, c2)) {
return c2;
}
if(c1 == void.class) {
return c2;
} else if(c2 == void.class) {
return c1;
}
if(c1.isPrimitive() && c2.isPrimitive()) {
} else if(c1.isPrimitive() && c2.isPrimitive()) {
if((c1 == byte.class && c2 == char.class) || (c1 == char.class && c2 == byte.class)) {
// byte + char = int
return int.class;
Expand Down Expand Up @@ -236,20 +232,24 @@ public static boolean isMethodInvocationConvertible(final Class<?> sourceType, f
}

/**
* Determines whether a type can be converted to another without losing any
* precision.
* Determines whether a type can be converted to another without losing any precision. As a special case,
* void is considered convertible only to Object and void, while anything can be converted to void. This
* is because a target type of void means we don't care about the value, so the conversion is always
* permissible.
*
* @param sourceType the source type
* @param targetType the target type
* @return true if lossless conversion is possible
*/
public static boolean isConvertibleWithoutLoss(final Class<?> sourceType, final Class<?> targetType) {
if(targetType.isAssignableFrom(sourceType)) {
if(targetType.isAssignableFrom(sourceType) || targetType == void.class) {
return true;
}
if(sourceType.isPrimitive()) {
if(sourceType == void.class) {
return false; // Void can't be losslessly represented by any type
// Void should be losslessly representable by Object, either as null or as a custom value that
// can be set with DynamicLinkerFactory.setAutoConversionStrategy.
return targetType == Object.class;
}
if(targetType.isPrimitive()) {
return isProperPrimitiveLosslessSubtype(sourceType, targetType);
Expand Down

0 comments on commit 1e0fc79

Please sign in to comment.