diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/reflect/scala/reflect/api/Symbols.scala | 25 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 275 |
2 files changed, 0 insertions, 300 deletions
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index 1d2888961b..c94c796279 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -232,31 +232,6 @@ trait Symbols extends base.Symbols { self: Universe => /** The overloaded alternatives of this symbol */ def alternatives: List[Symbol] - /** Performs method overloading resolution. More precisely, resolves an overloaded TermSymbol - * to a single, non-overloaded TermSymbol that accepts the specified argument types. - * @param pre The prefix type, i.e. the type of the value the method is dispatched on. - * This is required when resolving references to type parameters of the type - * the method is declared in. For example if the method is declared in class `List[A]`, - * providing the prefix as `List[Int]` allows the overloading resolution to use - * `Int` instead of `A`. - * @param targs Type arguments that a candidate alternative must be able to accept. Candidates - * will be considered with these arguments substituted for their corresponding - * type parameters. - * @param posVargs Positional argument types that a candidate alternative must be able to accept. - * @param nameVargs Named argument types that a candidate alternative must be able to accept. - * Each element in the sequence should be a pair of a parameter name and an - * argument type. - * @param expected Return type that a candidate alternative has to be compatible with. - * @return Either a single, non-overloaded Symbol referring to the selected alternative - * or NoSymbol if no single member could be selected given the passed arguments. - */ - def resolveOverloaded( - pre: Type = NoPrefix, - targs: Seq[Type] = List(), - posVargs: Seq[Type] = List(), - nameVargs: Seq[(TermName, Type)] = List(), - expected: Type = NoType - ): Symbol } /** The API of type symbols */ diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index b14306282b..959d4d31ee 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -84,281 +84,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def getAnnotations: List[AnnotationInfo] = { initialize; annotations } def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this } - def resolveOverloaded( - pre: Type, - targs: Seq[Type], - posVargTypes: Seq[Type], - nameVargTypes: Seq[(TermName, Type)], - expected: Type - ): Symbol = { - - // Begin Correlation Helpers - - def isCompatible(tp: Type, pt: Type): Boolean = { - def isCompatibleByName(tp: Type, pt: Type): Boolean = pt match { - case TypeRef(_, ByNameParamClass, List(res)) if !definitions.isByNameParamType(tp) => - isCompatible(tp, res) - case _ => - false - } - (tp weak_<:< pt) || isCompatibleByName(tp, pt) - } - - def signatureAsSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = { - (substituteTypeParams(method1), substituteTypeParams(method2)) match { - case (NullaryMethodType(r1), NullaryMethodType(r2)) => - r1 weak_<:< r2 - case (NullaryMethodType(_), MethodType(_, _)) => - true - case (MethodType(_, _), NullaryMethodType(_)) => - false - case (MethodType(p1, _), MethodType(p2, _)) => - val len = p1.length max p2.length - val sub = extend(p1 map (_.typeSignature), len) - val sup = extend(p2 map (_.typeSignature), len) - (sub corresponds sup)(isCompatible) - } - } - - def scopeMoreSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = { - val o1 = method1.owner.asClassSymbol - val o2 = method2.owner.asClassSymbol - val c1 = if (o1.hasFlag(Flag.MODULE)) o1.companionSymbol else o1 - val c2 = if (o2.hasFlag(Flag.MODULE)) o2.companionSymbol else o2 - c1.typeSignature <:< c2.typeSignature - } - - def moreSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = { - def points(m1: MethodSymbol, m2: MethodSymbol) = { - val p1 = if (signatureAsSpecific(m1, m2)) 1 else 0 - val p2 = if (scopeMoreSpecific(m1, m2)) 1 else 0 - p1 + p2 - } - points(method1, method2) > points(method2, method1) - } - - def combineInto ( - variadic: Boolean - )( - positional: Seq[Type], - named: Seq[(TermName, Type)] - )( - target: Seq[TermName], - defaults: Map[Int, Type] - ): Option[Seq[Type]] = { - - val offset = positional.length - val unfilled = target.zipWithIndex drop offset - val canAcceptAllNameVargs = named forall { case (argName, _) => - unfilled exists (_._1 == argName) - } - - val paramNamesUnique = { - named.length == named.map(_._1).distinct.length - } - - if (canAcceptAllNameVargs && paramNamesUnique) { - - val rest = unfilled map { case (paramName, paramIndex) => - val passedIn = named.collect { - case (argName, argType) if argName == paramName => argType - }.headOption - - passedIn orElse defaults.get(paramIndex).map(_.asInstanceOf[Type]) - } - - val rest1 = { - if (variadic && !rest.isEmpty && !rest.last.isDefined) rest.init - else rest - } - - - if (rest1 forall (_.isDefined)) { - val joined = positional ++ rest1.map(_.get) - val repeatedCollapsed = { - if (variadic) { - val (normal, repeated) = joined.splitAt(target.length - 1) - if (repeated.forall(_ =:= repeated.head)) Some(normal ++ repeated.headOption) - else None - } - else Some(joined) - } - if (repeatedCollapsed.exists(_.length == target.length)) - repeatedCollapsed - else if (variadic && repeatedCollapsed.exists(_.length == target.length - 1)) - repeatedCollapsed - else None - } else None - - } else None - } - - // Begin Reflection Helpers - - // Replaces a repeated parameter type at the end of the parameter list - // with a number of non-repeated parameter types in order to pad the - // list to be nargs in length - def extend(types: Seq[Type], nargs: Int): Seq[Type] = { - if (isVarArgTypes(types)) { - val repeatedType = types.last.normalize.typeArgs.head - types.init ++ Seq.fill(nargs - (types.length - 1))(repeatedType) - } else types - } - - // Replaces by-name parameters with their result type and - // TypeRefs with the thing they reference - def unwrap(paramType: Type): Type = paramType match { - case TypeRef(_, IntClass, _) => typeOf[Int] - case TypeRef(_, LongClass, _) => typeOf[Long] - case TypeRef(_, ShortClass, _) => typeOf[Short] - case TypeRef(_, ByteClass, _) => typeOf[Byte] - case TypeRef(_, CharClass, _) => typeOf[Char] - case TypeRef(_, FloatClass, _) => typeOf[Float] - case TypeRef(_, DoubleClass, _) => typeOf[Double] - case TypeRef(_, BooleanClass, _) => typeOf[Boolean] - case TypeRef(_, UnitClass, _) => typeOf[Unit] - case TypeRef(_, NullClass, _) => typeOf[Null] - case TypeRef(_, AnyClass, _) => typeOf[Any] - case TypeRef(_, NothingClass, _) => typeOf[Nothing] - case TypeRef(_, AnyRefClass, _) => typeOf[AnyRef] - case TypeRef(_, ByNameParamClass, List(resultType)) => unwrap(resultType) - case t: Type => t - } - - // Gives the names of the parameters to a method - def paramNames(signature: Type): Seq[TermName] = signature match { - case PolyType(_, resultType) => paramNames(resultType) - case MethodType(params, _) => params.map(_.name.asInstanceOf[TermName]) - case NullaryMethodType(_) => Seq.empty - } - - def valParams(signature: Type): Seq[TermSymbol] = signature match { - case PolyType(_, resultType) => valParams(resultType) - case MethodType(params, _) => params.map(_.asTermSymbol) - case NullaryMethodType(_) => Seq.empty - } - - // Returns a map from parameter index to default argument type - def defaultTypes(method: MethodSymbol): Map[Int, Type] = { - val typeSig = substituteTypeParams(method) - val owner = method.owner - valParams(typeSig).zipWithIndex.filter(_._1.hasFlag(Flag.DEFAULTPARAM)).map { case(_, index) => - val name = nme.defaultGetterName(method.name.decodedName, index + 1) - val default = owner.asType member name - index -> default.typeSignature.asInstanceOf[NullaryMethodType].resultType - }.toMap - } - - // True if any of method's parameters have default values. False otherwise. - def usesDefault(method: MethodSymbol): Boolean = valParams(method.typeSignature) drop(posVargTypes).length exists { param => - (param hasFlag Flag.DEFAULTPARAM) && nameVargTypes.forall { case (argName, _) => - param.name != argName - } - } - - // The number of type parameters that the method takes - def numTypeParams(x: MethodSymbol): Int = { - x.typeSignature.typeParams.length - } - - def substituteTypeParams(m: MethodSymbol): Type = { - (pre memberType m) match { - case m: MethodType => m - case n: NullaryMethodType => n - case PolyType(tparams, rest) => rest.substituteTypes(tparams, targs.toList) - } - } - - // Begin Selection Helpers - - def select( - alternatives: Seq[MethodSymbol], - filters: Seq[Seq[MethodSymbol] => Seq[MethodSymbol]] - ): Seq[MethodSymbol] = - filters.foldLeft(alternatives)((a, f) => { - if (a.size > 1) f(a) else a - }) - - // Drop arguments that take the wrong number of type - // arguments. - val posTargLength: Seq[MethodSymbol] => Seq[MethodSymbol] = _.filter { alt => - numTypeParams(alt) == targs.length - } - - // Drop methods that are not applicable to the arguments - val applicable: Seq[MethodSymbol] => Seq[MethodSymbol] = _.filter { alt => - // Note: combine returns None if a is not applicable and - // None.exists(_ => true) == false - val paramTypes = - valParams(substituteTypeParams(alt)).map(p => unwrap(p.typeSignature)) - val variadic = isVarArgTypes(paramTypes) - val maybeArgTypes = - combineInto(variadic)(posVargTypes, nameVargTypes)(paramNames(alt.typeSignature), defaultTypes(alt)) - maybeArgTypes exists { argTypes => - if (isVarArgTypes(argTypes) && !isVarArgTypes(paramTypes)) false - else { - val a = argTypes - val p = extend(paramTypes, argTypes.length) - (a corresponds p)(_ weak_<:< _) - } - } - } - - // Always prefer methods that don't need to use default - // arguments over those that do. - // e.g. when resolving foo(1), prefer def foo(x: Int) over - // def foo(x: Int, y: Int = 4) - val noDefaults: Seq[MethodSymbol] => Seq[MethodSymbol] = - _ filterNot usesDefault - - // Try to select the most specific method. If that's not possible, - // return all of the candidates (this will likely cause an error - // higher up in the call stack) - val mostSpecific: Seq[MethodSymbol] => Seq[MethodSymbol] = { alts => - val sorted = alts.sortWith(moreSpecific) - val mostSpecific = sorted.head - val agreeTest: MethodSymbol => Boolean = - moreSpecific(mostSpecific, _) - val disagreeTest: MethodSymbol => Boolean = - moreSpecific(_, mostSpecific) - if (!sorted.tail.forall(agreeTest)) { - mostSpecific +: sorted.tail.filterNot(agreeTest) - } else if (sorted.tail.exists(disagreeTest)) { - mostSpecific +: sorted.tail.filter(disagreeTest) - } else { - Seq(mostSpecific) - } - } - - def finalResult(t: Type): Type = t match { - case PolyType(_, rest) => finalResult(rest) - case MethodType(_, result) => finalResult(result) - case NullaryMethodType(result) => finalResult(result) - case t: Type => t - } - - // If a result type is given, drop alternatives that don't meet it - val resultType: Seq[MethodSymbol] => Seq[MethodSymbol] = - if (expected == NoType) identity - else _.filter { alt => - finalResult(substituteTypeParams(alt)) <:< expected - } - - def defaultFilteringOps = - Seq(posTargLength, resultType, applicable, noDefaults, mostSpecific) - - // Begin Method Proper - - - val alts = alternatives.map(_.asMethodSymbol) - - val selection = select(alts, defaultFilteringOps) - - val knownApplicable = applicable(selection) - - if (knownApplicable.size == 1) knownApplicable.head - else NoSymbol - } } /** The class for all symbols */ |