From e7a0d03f0d29b4644b09b0a36fb3557849d6cf72 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 29 Nov 2016 19:34:33 +0100 Subject: Create FunctionN types on demand We know create FunctionN types on demand whenever their name is looked up in the scope of package `scala`. This obviates the need to predefine function traits 23 to 30. --- compiler/src/dotty/tools/dotc/core/Definitions.scala | 19 +++++++++++++++++++ compiler/src/dotty/tools/dotc/core/NameOps.scala | 6 ++++++ compiler/src/dotty/tools/dotc/core/Scopes.scala | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'compiler/src/dotty/tools/dotc') diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index f77d62eab..44f4acffa 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -767,6 +767,23 @@ class Definitions { // ----- Initialization --------------------------------------------------- + /** Give the scala package a scope where a FunctionN trait is automatically + * added when someone looks for it. + */ + private def makeScalaSpecial()(implicit ctx: Context) = { + val oldInfo = ScalaPackageClass.classInfo + val oldDecls = oldInfo.decls + val newDecls = new MutableScope(oldDecls) { + override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { + val res = super.lookupEntry(name) + if (res == null && name.functionArity > 0) + newScopeEntry(newFunctionNTrait(name.functionArity)) + else res + } + } + ScalaPackageClass.info = oldInfo.derivedClassInfo(decls = newDecls) + } + /** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */ lazy val syntheticScalaClasses = List( AnyClass, @@ -794,6 +811,8 @@ class Definitions { def init()(implicit ctx: Context) = { this.ctx = ctx if (!_isInitialized) { + makeScalaSpecial() + // force initialization of every symbol that is synthesized or hijacked by the compiler val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses() diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 4c7f5b0a9..7a4fc0512 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -229,6 +229,12 @@ object NameOps { } } + def functionArity: Int = + if (name.startsWith(tpnme.Function)) + try name.drop(tpnme.Function.length).toString.toInt + catch { case ex: NumberFormatException => -1 } + else -1 + /** The name of the generic runtime operation corresponding to an array operation */ def genericArrayOp: TermName = name match { case nme.apply => nme.array_apply diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala index 3daa8117e..6090079e5 100644 --- a/compiler/src/dotty/tools/dotc/core/Scopes.scala +++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala @@ -309,7 +309,7 @@ object Scopes { /** Lookup a symbol entry matching given name. */ - override final def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { + override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { var e: ScopeEntry = null if (hashTable ne null) { e = hashTable(name.hashCode & (hashTable.length - 1)) -- cgit v1.2.3