aboutsummaryrefslogblamecommitdiff
path: root/src/dotty/tools/dotc/core/Signature.scala
blob: 50c42e96da8599d33d098b6ee52fa96e99b6ae8a (plain) (tree)























































                                                                                                      
package dotty.tools.dotc
package core

import Names._, Types._, Contexts._
import transform.Erasure.sigName

/** The signature of a denotation.
 *  Overloaded denotations with the same name are distinguished by
 *  their signatures. A signature of a method (of type PolyType,MethodType, or ExprType) is
 *  composed of a list of signature names, one for each parameter type, plus a signature for
 *  the result type. Methods are uncurried before taking their signatures.
 *  The signature name of a type is the fully qualified name of the type symbol of the type's erasure.
 *
 *  For instance a definition
 *
 *      def f(x: Int)(y: List[String]): String
 *
 *  would have signature
 *
 *      Signature(
 *        List("scala.Int".toTypeName, "scala.collection.immutable.List".toTypeName),
 *        "scala.String".toTypeName)
 *
 *  The signatures of non-method types are always `NotAMethod`.
 */
case class Signature private (paramsSig: List[TypeName], resSig: TypeName) {

  /** Does this signature conincide with that signature on their parameter parts? */
  final def sameParams(that: Signature): Boolean = this.paramsSig == that.paramsSig

  /** The meaning of `matches` depends on the phase. If types are not erased,
   *  it means `sameParams`. Once types are erased, it means `==`, comparing parameter as
   *  well as result type parts.
   */
  final def matches(that: Signature)(implicit ctx: Context) =
    if (ctx.erasedTypes) equals(that) else sameParams(that)

  /** Construct a signature by prepending the signature names of the given `params`
   *  to the parameter part of this signature.
   */
  def ++:(params: List[Type])(implicit ctx: Context) =
    Signature((params map sigName) ++ paramsSig, resSig)

}

object Signature {

  /** The signature of everything that's not a method, i.e. that has
   *  a type different from PolyType, MethodType, or ExprType.
   */
  val NotAMethod = Signature(List(EmptyTypeName), EmptyTypeName)

  /** The signature of a method with no parameters and result type `resultType`. */
  def apply(resultType: Type)(implicit ctx: Context): Signature =
    apply(Nil, sigName(resultType))
}