Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ad6638d

Browse files
committedSep 29, 2017
Ignore null in generic lambda tparams
Because of the way lambdas are synthesized by the JVM, at the call-site, it is not possible to know which generic types do lambdas have via the current reflection API. Related but not strictly reasons why this happens can be found in JDK's issue tracker: https://bugs.openjdk.java.net/browse/JDK-8178523?jql=text%20%7E%20%22lambda%20generic%20type%22 As a result, we ignore nulls that are returned by `getGenericParameterTypes`. Fixes #389.
1 parent 8c4b996 commit ad6638d

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed
 

‎internal/zinc-apiinfo/src/main/scala/sbt/internal/inc/ClassToAPI.scala

+16-6
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,14 @@ object ClassToAPI {
244244
accumulate(t).filterNot(_ == null).distinct
245245
}
246246

247-
@deprecated("No longer used", "0.13.0")
248-
def parents(c: Class[_]): Seq[api.Type] = types(allSuperTypes(c))
249-
def types(ts: Seq[Type]): Array[api.Type] = (ts filter (_ ne null) map reference).toArray
247+
def types(ts: Seq[Type]): Array[api.Type] =
248+
ts.filter(_ ne null).map(reference).toArray
250249
def upperBounds(ts: Array[Type]): api.Type =
251250
api.Structure.of(lzy(types(ts)), lzyEmptyDefArray, lzyEmptyDefArray)
252251

252+
@deprecated("No longer used", "0.13.0")
253+
def parents(c: Class[_]): Seq[api.Type] = types(allSuperTypes(c))
254+
253255
@deprecated("Use fieldToDef[4] instead", "0.13.9")
254256
def fieldToDef(enclPkg: Option[String])(f: Field): api.FieldLike = {
255257
val c = f.getDeclaringClass
@@ -496,12 +498,18 @@ object ClassToAPI {
496498
api.Projection.of(api.Singleton.of(pathFromString(p)), cls)
497499
}
498500
}
501+
502+
// sbt/zinc#389: Ignore nulls coming from generic parameter types of lambdas
503+
private[this] def ignoreNulls[T: scala.reflect.ClassTag](genericTypes: Array[T]): Array[T] =
504+
genericTypes.filter(_ != null)
505+
499506
def referenceP(t: ParameterizedType): api.Parameterized = {
500-
val targs = t.getActualTypeArguments
507+
val targs = ignoreNulls(t.getActualTypeArguments)
501508
val args = if (targs.isEmpty) emptyTypeArray else arrayMap(targs)(t => reference(t): api.Type)
502509
val base = reference(t.getRawType)
503510
api.Parameterized.of(base, args)
504511
}
512+
505513
def reference(t: Type): api.Type =
506514
t match {
507515
case _: WildcardType => reference("_")
@@ -553,8 +561,10 @@ object ClassToAPI {
553561
private[this] def exceptionTypes(c: Constructor[_]): Array[Type] = c.getGenericExceptionTypes
554562

555563
private[this] def exceptionTypes(m: Method): Array[Type] = m.getGenericExceptionTypes
556-
private[this] def parameterTypes(m: Method): Array[Type] = m.getGenericParameterTypes
557-
private[this] def parameterTypes(c: Constructor[_]): Array[Type] = c.getGenericParameterTypes
564+
private[this] def parameterTypes(m: Method): Array[Type] =
565+
ignoreNulls(m.getGenericParameterTypes)
566+
private[this] def parameterTypes(c: Constructor[_]): Array[Type] =
567+
ignoreNulls(c.getGenericParameterTypes)
558568

559569
private[this] def typeParameterTypes[T](m: Constructor[T]): Array[TypeVariable[Constructor[T]]] =
560570
m.getTypeParameters
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package typeparameters;
2+
3+
import java.util.function.Supplier;
4+
5+
public class Example {
6+
7+
static <I, O> void call() {
8+
Supplier<BaseBlah<I, O>> blah = () ->
9+
new BaseBlah<I, O>() {
10+
@Override
11+
protected O getResponseInternal(I i) {
12+
return null;
13+
}
14+
};
15+
}
16+
17+
public static void main(String[] args) {
18+
Example.<String, String>call();
19+
}
20+
}
21+
22+
abstract class BaseBlah<I, O> {
23+
protected O getResponseInternal(I i) {
24+
return null;
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
> compile

0 commit comments

Comments
 (0)
Please sign in to comment.