summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-12-23 10:06:50 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-12-23 10:06:50 -0800
commit841389bc6f879031a8d36a5ffcca5e3c0e1fdcef (patch)
tree898ac7b039c94779f1e52a7d8d0ebaccf2537c01 /src
parenta0b11b32aca74a4c3aee2e8c70356a29cd937727 (diff)
parent467872999e4940e06f2da811d1ae2d8278639126 (diff)
downloadscala-841389bc6f879031a8d36a5ffcca5e3c0e1fdcef.tar.gz
scala-841389bc6f879031a8d36a5ffcca5e3c0e1fdcef.tar.bz2
scala-841389bc6f879031a8d36a5ffcca5e3c0e1fdcef.zip
Merge pull request #4139 from retronym/ticket/7965
SI-7965 Support calls to MethodHandle.{invoke,invokeExact}
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala16
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala5
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
4 files changed, 23 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6671183ff0..5719a9e358 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3281,6 +3281,22 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
handleOverloaded
+ case _ if isPolymorphicSignature(fun.symbol) =>
+ // Mimic's Java's treatment of polymorphic signatures as described in
+ // https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.3
+ //
+ // One can think of these methods as being infinitely overloaded. We create
+ // a ficticious new cloned method symbol for each call site that takes on a signature
+ // governed by a) the argument types and b) the expected type
+ val args1 = typedArgs(args, forArgMode(fun, mode))
+ val pts = args1.map(_.tpe.deconst)
+ val clone = fun.symbol.cloneSymbol
+ val cloneParams = pts map (pt => clone.newValueParameter(currentUnit.freshTermName()).setInfo(pt))
+ val resultType = if (isFullyDefined(pt)) pt else ObjectTpe
+ clone.modifyInfo(mt => copyMethodType(mt, cloneParams, resultType))
+ val fun1 = fun.setSymbol(clone).setType(clone.info)
+ doTypedApply(tree, fun1, args1, mode, resultType).setType(resultType)
+
case mt @ MethodType(params, _) =>
val paramTypes = mt.paramTypes
// repeat vararg as often as needed, remove by-name
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 7e2d124486..4263bbccf3 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -514,6 +514,8 @@ trait Definitions extends api.StandardDefinitions {
lazy val ScalaSignatureAnnotation = requiredClass[scala.reflect.ScalaSignature]
lazy val ScalaLongSignatureAnnotation = requiredClass[scala.reflect.ScalaLongSignature]
+ lazy val MethodHandle = getClassIfDefined("java.lang.invoke.MethodHandle")
+
// Option classes
lazy val OptionClass: ClassSymbol = requiredClass[Option[_]]
lazy val OptionModule: ModuleSymbol = requiredModule[scala.Option.type]
@@ -1508,6 +1510,9 @@ trait Definitions extends api.StandardDefinitions {
lazy val PartialManifestClass = getTypeMember(ReflectPackage, tpnme.ClassManifest)
lazy val ManifestSymbols = Set[Symbol](PartialManifestClass, FullManifestClass, OptManifestClass)
+
+ def isPolymorphicSignature(sym: Symbol) = PolySigMethods(sym)
+ private lazy val PolySigMethods: Set[Symbol] = Set[Symbol](MethodHandle.info.decl(sn.Invoke), MethodHandle.info.decl(sn.InvokeExact)).filter(_.exists)
}
}
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 667ff7c4b4..c94ee996e4 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -1147,6 +1147,7 @@ trait StdNames {
final val GetClassLoader: TermName = newTermName("getClassLoader")
final val GetMethod: TermName = newTermName("getMethod")
final val Invoke: TermName = newTermName("invoke")
+ final val InvokeExact: TermName = newTermName("invokeExact")
val Boxed = immutable.Map[TypeName, TypeName](
tpnme.Boolean -> BoxedBoolean,
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index c87b810bdd..1c0aa7cf6d 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -310,6 +310,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.QuasiquoteClass_api_unapply
definitions.ScalaSignatureAnnotation
definitions.ScalaLongSignatureAnnotation
+ definitions.MethodHandle
definitions.OptionClass
definitions.OptionModule
definitions.SomeClass