aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Definitions.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-11-07 19:09:07 +0100
committerMartin Odersky <odersky@gmail.com>2015-11-09 15:45:39 +0100
commit5398c5a723b0f8b0d35e6c3ad230c5046169e837 (patch)
tree832f93128ce25194d9418b682f4e248adba51dd4 /src/dotty/tools/dotc/core/Definitions.scala
parent5db52d25256568cf7d8c2335ee733a38b059b5ad (diff)
downloaddotty-5398c5a723b0f8b0d35e6c3ad230c5046169e837.tar.gz
dotty-5398c5a723b0f8b0d35e6c3ad230c5046169e837.tar.bz2
dotty-5398c5a723b0f8b0d35e6c3ad230c5046169e837.zip
Avoid overhead of generating symbol sets on each access
1) Have symbol sets cached per run 2) Use methods Denotation#isPrimitiveValueClass, Denotation#isNumericValueClass instead of calling contains directly on symbol sets.
Diffstat (limited to 'src/dotty/tools/dotc/core/Definitions.scala')
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala44
1 files changed, 29 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index d57897eb1..66e5f062d 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -3,7 +3,7 @@ package dotc
package core
import Types._, Contexts._, Symbols._, Denotations._, SymDenotations._, StdNames._, Names._
-import Flags._, Scopes._, Decorators._, NameOps._, util.Positions._
+import Flags._, Scopes._, Decorators._, NameOps._, util.Positions._, Periods._
import unpickleScala2.Scala2Unpickler.ensureConstructor
import scala.annotation.{ switch, meta }
import scala.collection.{ mutable, immutable }
@@ -558,15 +558,17 @@ class Definitions {
private lazy val TupleTypeRefs: Set[TypeRef] = TupleTypeRef.toSet
private lazy val ProductTypeRefs: Set[TypeRef] = ProductNTypeRef.toSet
- /** If type refers to a class in the scala package, its name, otherwise EmptyTypeName */
- def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = {
- val cls = ref.classSymbol
+ /** If `cls` is a class in the scala package, its name, otherwise EmptyTypeName */
+ def scalaClassName(cls: Symbol)(implicit ctx: Context): TypeName =
if (cls.isClass && cls.owner == ScalaPackageClass) cls.asClass.name else EmptyTypeName
- }
- def isVarArityClass(cls: Symbol, prefix: Name) =
- cls.owner == ScalaPackageClass && cls.name.startsWith(prefix) &&
- cls.name.drop(prefix.length).forall(_.isDigit)
+ /** If type `ref` refers to a class in the scala package, its name, otherwise EmptyTypeName */
+ def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = scalaClassName(ref.classSymbol)
+
+ private def isVarArityClass(cls: Symbol, prefix: Name) = {
+ val name = scalaClassName(cls)
+ name.startsWith(prefix) && name.drop(prefix.length).forall(_.isDigit)
+ }
def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
@@ -676,6 +678,18 @@ class Definitions {
// ----- primitive value class machinery ------------------------------------------
+ class SymbolsPerRun(generate: Context => collection.Set[Symbol]) {
+ private var current: RunId = NoRunId
+ private var syms: collection.Set[Symbol] = _
+ def apply()(implicit ctx: Context) = {
+ if (current != ctx.runId) {
+ syms = generate(ctx)
+ current = ctx.runId
+ }
+ syms
+ }
+ }
+
lazy val ScalaNumericValueTypeList = List(
ByteTypeRef,
ShortTypeRef,
@@ -686,12 +700,12 @@ class Definitions {
DoubleTypeRef)
private lazy val ScalaNumericValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypeList.toSet
- def ScalaNumericValueClasses = ScalaNumericValueTypes.map(_.symbol)
private lazy val ScalaValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypes + UnitTypeRef + BooleanTypeRef
- def ScalaValueClasses = ScalaValueTypes.map(_.symbol)
+ private lazy val ScalaBoxedTypeRefs = ScalaValueTypes map (t => boxedTypeRef(t.name))
- lazy val ScalaBoxedTypeRefs = ScalaValueTypes map (t => boxedTypeRef(t.name))
- def ScalaBoxedClasses = ScalaBoxedTypeRefs.map(_.symbol)
+ val ScalaNumericValueClasses = new SymbolsPerRun(implicit ctx => ScalaNumericValueTypes.map(_.symbol))
+ val ScalaValueClasses = new SymbolsPerRun(implicit ctx => ScalaValueTypes.map(_.symbol))
+ val ScalaBoxedClasses = new SymbolsPerRun(implicit ctx => ScalaBoxedTypeRefs.map(_.symbol))
private val boxedTypeRef = mutable.Map[TypeName, TypeRef]()
private val valueTypeEnc = mutable.Map[TypeName, PrimitiveClassEnc]()
@@ -735,7 +749,7 @@ class Definitions {
def isValueSubType(tref1: TypeRef, tref2: TypeRef)(implicit ctx: Context) =
valueTypeEnc(tref2.name) % valueTypeEnc(tref1.name) == 0
def isValueSubClass(sym1: Symbol, sym2: Symbol) =
- isValueSubType(sym1.typeRef, sym2.typeRef)
+ valueTypeEnc(sym2.asClass.name) % valueTypeEnc(sym1.asClass.name) == 0
// ----- Initialization ---------------------------------------------------
@@ -757,13 +771,13 @@ class Definitions {
lazy val syntheticCoreMethods = AnyMethods ++ ObjectMethods ++ List(String_+)
private[this] var _isInitialized = false
- def isInitialized = _isInitialized
+ private def isInitialized = _isInitialized
def init(implicit ctx: Context) = {
this.ctx = ctx
if (!_isInitialized) {
// force initialization of every symbol that is synthesized or hijacked by the compiler
- val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses
+ val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
_isInitialized = true
}
}