aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-11-27 19:08:17 +0100
committerMartin Odersky <odersky@gmail.com>2013-11-27 19:08:17 +0100
commitc39c2af036e9e69fc339b805a0869126efadae0f (patch)
tree3406b1e1f671259f5b917c2bc94a187fa19c2acd /src/dotty
parentf8c9dc95929655a198066652cd12109329836198 (diff)
downloaddotty-c39c2af036e9e69fc339b805a0869126efadae0f.tar.gz
dotty-c39c2af036e9e69fc339b805a0869126efadae0f.tar.bz2
dotty-c39c2af036e9e69fc339b805a0869126efadae0f.zip
Optimizing signatures
Interesting signatures are now cached.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala7
-rw-r--r--src/dotty/tools/dotc/core/Signature.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala53
3 files changed, 32 insertions, 30 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index f904f8d78..223079570 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -360,12 +360,7 @@ object Denotations {
override def signature(implicit ctx: Context): Signature = {
if (isType) Signature.NotAMethod
else info match {
- case tp: PolyType =>
- tp.resultType match {
- case mt: MethodType => mt.signature
- case tp => Signature(tp)
- }
- case mt: MethodType => mt.signature
+ case info: SignedType => info.signature
case _ => Signature.NotAMethod
}
}
diff --git a/src/dotty/tools/dotc/core/Signature.scala b/src/dotty/tools/dotc/core/Signature.scala
index 50c42e96d..18e4e5f6c 100644
--- a/src/dotty/tools/dotc/core/Signature.scala
+++ b/src/dotty/tools/dotc/core/Signature.scala
@@ -48,7 +48,7 @@ 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)
+ val NotAMethod = Signature(List(), EmptyTypeName)
/** The signature of a method with no parameters and result type `resultType`. */
def apply(resultType: Type)(implicit ctx: Context): Signature =
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index fb430f336..55d1cf45f 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1362,13 +1362,35 @@ object Types {
// ----- Method types: MethodType/ExprType/PolyType -------------------------------
- // Note: method types are cached whereas poly types are not
+ // Note: method types are cached whereas poly types are not. The reason
// is that most poly types are cyclic via poly params,
// and therefore two different poly types would never be equal.
+ /** A trait that mixes in functionality for signature caching */
+ trait SignedType extends Type {
+
+ private[this] var mySignature: Signature = _
+ private[this] var mySignatureRunId: Int = NoRunId
+
+ protected def computeSignature(implicit ctx: Context): Signature
+
+ protected def resultSignature(implicit ctx: Context) = resultType match {
+ case rtp: SignedType => rtp.signature
+ case tp => Signature(tp)
+ }
+
+ final override def signature(implicit ctx: Context): Signature = {
+ if (ctx.runId != mySignatureRunId) {
+ mySignature = computeSignature
+ mySignatureRunId = ctx.runId
+ }
+ mySignature
+ }
+ }
+
abstract case class MethodType(paramNames: List[TermName], paramTypes: List[Type])
(resultTypeExp: MethodType => Type)
- extends CachedGroundType with BindingType with TermType { thisMethodType =>
+ extends CachedGroundType with BindingType with TermType with SignedType { thisMethodType =>
override val resultType = resultTypeExp(this)
def isJava = false
@@ -1401,23 +1423,8 @@ object Types {
myIsDependent
}
- private[this] var mySignature: Signature = _
- private[this] var mySignatureRunId: Int = NoRunId
-
- override def signature(implicit ctx: Context): Signature = {
- def computeSignature: Signature = {
- val followSig: Signature = resultType match {
- case rtp: MethodType => rtp.signature
- case tp => Signature(tp)
- }
- paramTypes ++: followSig
- }
- if (ctx.runId != mySignatureRunId) {
- mySignature = computeSignature
- mySignatureRunId = ctx.runId
- }
- mySignature
- }
+ protected def computeSignature(implicit ctx: Context): Signature =
+ paramTypes ++: resultSignature
def derivedMethodType(paramNames: List[TermName], paramTypes: List[Type], restpe: Type)(implicit ctx: Context) =
if ((paramNames eq this.paramNames) && (paramTypes eq this.paramTypes) && (restpe eq this.resultType)) this
@@ -1497,9 +1504,9 @@ object Types {
}
abstract case class ExprType(override val resultType: Type)
- extends CachedProxyType with TermType {
+ extends CachedProxyType with TermType with SignedType {
override def underlying(implicit ctx: Context): Type = resultType
- override def signature(implicit ctx: Context): Signature = Signature(resultType) // todo: cache?
+ protected def computeSignature(implicit ctx: Context): Signature = resultSignature
def derivedExprType(resultType: Type)(implicit ctx: Context) =
if (resultType eq this.resultType) this else ExprType(resultType)
override def computeHash = doHash(resultType)
@@ -1513,12 +1520,12 @@ object Types {
}
case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
- extends UncachedGroundType with BindingType with TermType {
+ extends UncachedGroundType with BindingType with TermType with SignedType {
val paramBounds = paramBoundsExp(this)
override val resultType = resultTypeExp(this)
- override def signature(implicit ctx: Context) = resultType.signature
+ protected def computeSignature(implicit ctx: Context) = resultSignature
def instantiate(argTypes: List[Type])(implicit ctx: Context): Type =
resultType.substParams(this, argTypes)