summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-06 11:58:05 -0700
committerPaul Phillips <paulp@improving.org>2012-04-06 11:58:05 -0700
commit8e179506e7c230a9ff01cda9584ce2a73953e446 (patch)
tree0bbcf7f956784646fb996b8c6a944a3d8155e80c /src
parent22c229e4ed2100d662fe05f9a610186ce1ebbb5a (diff)
parent115f5467e3f3ff07abbba2b23c40c2ff0d7ddd1b (diff)
downloadscala-8e179506e7c230a9ff01cda9584ce2a73953e446.tar.gz
scala-8e179506e7c230a9ff01cda9584ce2a73953e446.tar.bz2
scala-8e179506e7c230a9ff01cda9584ce2a73953e446.zip
Merge commit 'pull/358/head' into develop
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala8
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala67
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala9
3 files changed, 80 insertions, 4 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index e1740b621e..0fa2762c0f 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -386,10 +386,10 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isCastSymbol(sym: Symbol) = sym == Any_asInstanceOf || sym == Object_asInstanceOf
def isJavaVarArgsMethod(m: Symbol) = m.isMethod && isJavaVarArgs(m.info.params)
- def isJavaVarArgs(params: List[Symbol]) = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe)
- def isScalaVarArgs(params: List[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
- def isVarArgsList(params: List[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe)
- def isVarArgTypes(formals: List[Type]) = formals.nonEmpty && isRepeatedParamType(formals.last)
+ def isJavaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe)
+ def isScalaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
+ def isVarArgsList(params: Seq[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe)
+ def isVarArgTypes(formals: Seq[Type]) = formals.nonEmpty && isRepeatedParamType(formals.last)
def hasRepeatedParam(tp: Type): Boolean = tp match {
case MethodType(formals, restpe) => isScalaVarArgs(formals) || hasRepeatedParam(restpe)
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index cfab069588..dc72ac2338 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -76,6 +76,73 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def setInternalFlags(flag: Long): this.type = { setFlag(flag); this }
def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
+
+ private def lastElemType(ts: Seq[Type]): Type = ts.last.normalize.typeArgs.head
+
+ private def formalTypes(formals: List[Type], nargs: Int): List[Type] = {
+ val formals1 = formals mapConserve {
+ case TypeRef(_, ByNameParamClass, List(arg)) => arg
+ case formal => formal
+ }
+ if (isVarArgTypes(formals1)) {
+ val ft = lastElemType(formals)
+ formals1.init ::: List.fill(nargs - (formals1.length - 1))(ft)
+ } else formals1
+ }
+
+ def resolveOverloaded(pre: Type, targs: Seq[Type], actuals: Seq[Type]): Symbol = {
+ def firstParams(tpe: Type): (List[Symbol], List[Type]) = tpe match {
+ case PolyType(tparams, restpe) =>
+ val (Nil, formals) = firstParams(restpe)
+ (tparams, formals)
+ case MethodType(params, _) =>
+ (Nil, params map (_.tpe))
+ case _ =>
+ (Nil, Nil)
+ }
+ def isApplicable(alt: Symbol, targs: List[Type], actuals: Seq[Type]) = {
+ def isApplicableType(tparams: List[Symbol], tpe: Type): Boolean = {
+ val (tparams, formals) = firstParams(pre memberType alt)
+ val formals1 = formalTypes(formals, actuals.length)
+ val actuals1 =
+ if (isVarArgTypes(actuals)) {
+ if (!isVarArgTypes(formals)) return false
+ actuals.init :+ lastElemType(actuals)
+ } else actuals
+ if (formals1.length != actuals1.length) return false
+
+ if (tparams.isEmpty) return (actuals1 corresponds formals1)(_ <:< _)
+
+ if (targs.length == tparams.length)
+ isApplicableType(List(), tpe.instantiateTypeParams(tparams, targs))
+ else if (targs.nonEmpty)
+ false
+ else {
+ val tvars = tparams map (TypeVar(_))
+ (actuals1 corresponds formals1) { (actual, formal) =>
+ val tp1 = actual.deconst.instantiateTypeParams(tparams, tvars)
+ val pt1 = actual.instantiateTypeParams(tparams, tvars)
+ tp1 <:< pt1
+ } &&
+ solve(tvars, tparams, List.fill(tparams.length)(COVARIANT), upper = false)
+ }
+ }
+ isApplicableType(List(), pre.memberType(alt))
+ }
+ def isAsGood(alt1: Symbol, alt2: Symbol): Boolean = {
+ alt1 == alt2 ||
+ alt2 == NoSymbol || {
+ val (tparams, formals) = firstParams(pre memberType alt1)
+ isApplicable(alt2, tparams map (_.tpe), formals)
+ }
+ }
+ assert(isOverloaded)
+ val applicables = alternatives filter (isApplicable(_, targs.toList, actuals))
+ def winner(alts: List[Symbol]) =
+ ((NoSymbol: Symbol) /: alts)((best, alt) => if (isAsGood(alt, best)) alt else best)
+ val best = winner(applicables)
+ if (best == winner(applicables.reverse)) best else NoSymbol
+ }
}
/** The class for all symbols */
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index 383312b8f5..ab59a4a39a 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -134,6 +134,10 @@ trait Symbols { self: Universe =>
*/
def isAbstractType : Boolean
+ /** Is this symbol an overloaded method?
+ */
+ def isOverloaded: Boolean
+
/** The type signature of this symbol.
* Note if the symbol is a member of a class, one almost always is interested
* in `typeSignatureIn` with a site type instead.
@@ -180,6 +184,11 @@ trait Symbols { self: Universe =>
*/
def selfType: Type
+ /** The overloaded alternatives of this symbol */
+ def alternatives: List[Symbol]
+
+ def resolveOverloaded(pre: Type = NoPrefix, targs: Seq[Type] = List(), actuals: Seq[Type]): Symbol
+
/** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
* the current symbol as its owner.
*/