summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Constants.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala345
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala8
-rw-r--r--src/compiler/scala/reflect/internal/Kinds.scala10
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala37
-rw-r--r--src/compiler/scala/reflect/internal/Names.scala204
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala506
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala111
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala21
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala345
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala20
-rw-r--r--src/compiler/scala/reflect/internal/util/Collections.scala20
-rw-r--r--src/compiler/scala/reflect/internal/util/Origins.scala (renamed from src/compiler/scala/tools/nsc/util/Origins.scala)16
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala40
-rw-r--r--src/compiler/scala/reflect/runtime/ScalaToJava.scala14
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala6
-rw-r--r--src/compiler/scala/reflect/runtime/TreeBuildUtil.scala10
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala3
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala4
-rw-r--r--src/compiler/scala/tools/nsc/Driver.scala8
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ScalaDoc.scala8
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala6
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala16
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala41
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/JavaPlatform.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala156
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala12
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala19
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ICodes.scala17
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala61
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Printers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala27
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala43
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala11
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala32
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala11
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala65
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala23
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala17
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala18
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala39
-rw-r--r--src/compiler/scala/tools/nsc/dependencies/Changes.scala4
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Picklers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/REPL.scala4
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Dossiers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala31
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala19
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala79
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Imports.scala17
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala76
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Naming.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala2
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala14
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala10
-rw-r--r--src/compiler/scala/tools/nsc/reporters/Reporter.scala23
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala43
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala19
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala200
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala35
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala23
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala37
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala15
-rw-r--r--src/compiler/scala/tools/nsc/transform/TailCalls.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala22
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala33
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala15
-rw-r--r--src/compiler/scala/tools/nsc/util/ProxyReport.scala14
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala45
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala2
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala20
-rw-r--r--src/library/scala/Option.scala7
-rw-r--r--src/library/scala/Symbol.scala4
-rw-r--r--src/library/scala/collection/parallel/mutable/ParHashMap.scala5
-rw-r--r--src/library/scala/io/Codec.scala10
-rw-r--r--src/library/scala/reflect/ClassManifest.scala4
-rw-r--r--src/library/scala/reflect/Manifest.scala66
-rw-r--r--src/library/scala/reflect/api/Trees.scala6
-rw-r--r--src/library/scala/runtime/AbstractPartialFunction.scala4
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java18
-rw-r--r--src/library/scala/xml/Elem.scala4
-rw-r--r--src/library/scala/xml/MetaData.scala4
-rw-r--r--src/library/scala/xml/PrefixedAttribute.scala15
-rw-r--r--src/library/scala/xml/UnprefixedAttribute.scala2
-rw-r--r--src/library/scala/xml/Utility.scala2
-rw-r--r--src/scalap/scala/tools/scalap/JavaWriter.scala20
-rw-r--r--src/scalap/scala/tools/scalap/Main.scala3
-rw-r--r--src/scalap/scala/tools/scalap/Names.scala96
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala3
114 files changed, 2083 insertions, 1547 deletions
diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala
index 2edb0d1fe6..9c4b2b2245 100644
--- a/src/compiler/scala/reflect/internal/Constants.scala
+++ b/src/compiler/scala/reflect/internal/Constants.scala
@@ -217,7 +217,7 @@ trait Constants extends api.Constants {
}
def escapedStringValue: String = {
- def escape(text: String): String = (text map escapedChar) mkString ""
+ def escape(text: String): String = text flatMap escapedChar
tag match {
case NullTag => "null"
case StringTag => "\"" + escape(stringValue) + "\""
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 54c1153f81..d3af8e2623 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -6,6 +6,7 @@
package scala.reflect
package internal
+import annotation.{ switch }
import scala.collection.{ mutable, immutable }
import Flags._
import PartialFunction._
@@ -60,8 +61,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val numericWeight = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight)
lazy val boxedModule = classesMap(x => getModule(boxedName(x)))
lazy val boxedClass = classesMap(x => getClass(boxedName(x)))
- lazy val refClass = classesMap(x => getClass("scala.runtime." + x + "Ref"))
- lazy val volatileRefClass = classesMap(x => getClass("scala.runtime.Volatile" + x + "Ref"))
+ lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref"))
+ lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref"))
lazy val boxMethod = classesMap(x => valueModuleMethod(x, nme.box))
lazy val unboxMethod = classesMap(x => valueModuleMethod(x, nme.unbox))
@@ -85,12 +86,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isGetClass(sym: Symbol) =
(sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty)
- private[Definitions] def fullNameStrings: List[String] = nme.ScalaValueNames map ("scala." + _)
- private[Definitions] lazy val fullValueName: Set[Name] = {
- val values = nme.ScalaValueNames flatMap (x => List(newTypeName("scala." + x), newTermName("scala." + x)))
- values.toSet + newTypeName("scala.AnyVal")
- }
-
lazy val AnyValClass = valueCache(tpnme.AnyVal)
lazy val UnitClass = valueCache(tpnme.Unit)
lazy val ByteClass = valueCache(tpnme.Byte)
@@ -101,9 +96,9 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val FloatClass = valueCache(tpnme.Float)
lazy val DoubleClass = valueCache(tpnme.Double)
lazy val BooleanClass = valueCache(tpnme.Boolean)
- def Boolean_and = getMember(BooleanClass, nme.ZAND)
- def Boolean_or = getMember(BooleanClass, nme.ZOR)
- def Boolean_not = getMember(BooleanClass, nme.UNARY_!)
+ lazy val Boolean_and = getMember(BooleanClass, nme.ZAND)
+ lazy val Boolean_or = getMember(BooleanClass, nme.ZOR)
+ lazy val Boolean_not = getMember(BooleanClass, nme.UNARY_!)
def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass)
def ScalaValueClasses: List[Symbol] = List(
@@ -151,8 +146,10 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val ScalaPackage = getModule(nme.scala_)
lazy val ScalaPackageClass = ScalaPackage.moduleClass
- lazy val RuntimePackage = getModule("scala.runtime")
+ lazy val RuntimePackage = getRequiredModule("scala.runtime")
lazy val RuntimePackageClass = RuntimePackage.moduleClass
+
+ lazy val JavaLangEnumClass = getRequiredClass("java.lang.Enum")
// convenient one-argument parameter lists
lazy val anyparam = List(AnyClass.typeConstructor)
@@ -163,17 +160,45 @@ trait Definitions extends reflect.api.StandardDefinitions {
private def booltype = BooleanClass.typeConstructor
private def inttype = IntClass.typeConstructor
private def stringtype = StringClass.typeConstructor
+
+ // Java types
+ def javaTypeName(jclazz: Class[_]): TypeName = newTypeName(jclazz.getName)
+
+ def javaTypeToValueClass(jtype: Class[_]): Symbol = jtype match {
+ case java.lang.Void.TYPE => UnitClass
+ case java.lang.Byte.TYPE => ByteClass
+ case java.lang.Character.TYPE => CharClass
+ case java.lang.Short.TYPE => ShortClass
+ case java.lang.Integer.TYPE => IntClass
+ case java.lang.Long.TYPE => LongClass
+ case java.lang.Float.TYPE => FloatClass
+ case java.lang.Double.TYPE => DoubleClass
+ case java.lang.Boolean.TYPE => BooleanClass
+ case _ => NoSymbol
+ }
+ def valueClassToJavaType(sym: Symbol): Class[_] = sym match {
+ case UnitClass => java.lang.Void.TYPE
+ case ByteClass => java.lang.Byte.TYPE
+ case CharClass => java.lang.Character.TYPE
+ case ShortClass => java.lang.Short.TYPE
+ case IntClass => java.lang.Integer.TYPE
+ case LongClass => java.lang.Long.TYPE
+ case FloatClass => java.lang.Float.TYPE
+ case DoubleClass => java.lang.Double.TYPE
+ case BooleanClass => java.lang.Boolean.TYPE
+ case _ => null
+ }
// top types
lazy val AnyClass = newClass(ScalaPackageClass, tpnme.Any, Nil) setFlag (ABSTRACT)
lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor)
lazy val ObjectClass = getClass(sn.Object)
- lazy val AnyCompanionClass = getClass("scala.AnyCompanion") setFlag (SEALED | ABSTRACT | TRAIT)
- lazy val AnyValCompanionClass = getClass("scala.AnyValCompanion") setFlag (SEALED | ABSTRACT | TRAIT)
+ lazy val AnyCompanionClass = getRequiredClass("scala.AnyCompanion") setFlag (SEALED | ABSTRACT | TRAIT)
+ lazy val AnyValCompanionClass = getRequiredClass("scala.AnyValCompanion") setFlag (SEALED | ABSTRACT | TRAIT)
// bottom types
- lazy val RuntimeNothingClass = getClass(ClassfileConstants.SCALA_NOTHING)
- lazy val RuntimeNullClass = getClass(ClassfileConstants.SCALA_NULL)
+ lazy val RuntimeNothingClass = getClass(fulltpnme.RuntimeNothing)
+ lazy val RuntimeNullClass = getClass(fulltpnme.RuntimeNull)
sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) {
locally {
@@ -194,25 +219,25 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
// exceptions and other throwables
- lazy val ClassCastExceptionClass = getClass("java.lang.ClassCastException")
+ lazy val ClassCastExceptionClass = getRequiredClass("java.lang.ClassCastException")
lazy val IndexOutOfBoundsExceptionClass = getClass(sn.IOOBException)
lazy val InvocationTargetExceptionClass = getClass(sn.InvTargetException)
- lazy val MatchErrorClass = getClass("scala.MatchError")
- lazy val NonLocalReturnControlClass = getClass("scala.runtime.NonLocalReturnControl")
+ lazy val MatchErrorClass = getRequiredClass("scala.MatchError")
+ lazy val NonLocalReturnControlClass = getRequiredClass("scala.runtime.NonLocalReturnControl")
lazy val NullPointerExceptionClass = getClass(sn.NPException)
lazy val ThrowableClass = getClass(sn.Throwable)
- lazy val UninitializedErrorClass = getClass("scala.UninitializedFieldError")
+ lazy val UninitializedErrorClass = getRequiredClass("scala.UninitializedFieldError")
// fundamental reference classes
lazy val ScalaObjectClass = getMember(ScalaPackageClass, tpnme.ScalaObject)
- lazy val PartialFunctionClass = getClass("scala.PartialFunction")
- lazy val AbstractPartialFunctionClass = getClass("scala.runtime.AbstractPartialFunction")
- lazy val SymbolClass = getClass("scala.Symbol")
+ lazy val PartialFunctionClass = getRequiredClass("scala.PartialFunction")
+ lazy val AbstractPartialFunctionClass = getRequiredClass("scala.runtime.AbstractPartialFunction")
+ lazy val SymbolClass = getRequiredClass("scala.Symbol")
lazy val StringClass = getClass(sn.String)
lazy val StringModule = StringClass.linkedClassOfClass
lazy val ClassClass = getClass(sn.Class)
def Class_getMethod = getMember(ClassClass, nme.getMethod_)
- lazy val DynamicClass = getClass("scala.Dynamic")
+ lazy val DynamicClass = getRequiredClass("scala.Dynamic")
// fundamental modules
lazy val SysPackage = getPackageObject("scala.sys")
@@ -223,7 +248,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Those modules and their module classes
lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass)
- lazy val PredefModule: Symbol = getModule("scala.Predef")
+ lazy val PredefModule: Symbol = getRequiredModule("scala.Predef")
lazy val PredefModuleClass = PredefModule.moduleClass
// Note: this is not the type alias AnyRef, it's a val defined in Predef
// used by the @specialize annotation.
@@ -242,26 +267,27 @@ trait Definitions extends reflect.api.StandardDefinitions {
(sym.name == name) && (sym.owner == PredefModule.moduleClass)
)
- lazy val ConsoleModule: Symbol = getModule("scala.Console")
- lazy val ScalaRunTimeModule: Symbol = getModule("scala.runtime.ScalaRunTime")
- lazy val SymbolModule: Symbol = getModule("scala.Symbol")
- lazy val Symbol_apply = getMember(SymbolModule, nme.apply)
+ lazy val ConsoleModule: Symbol = getRequiredModule("scala.Console")
+ lazy val ScalaRunTimeModule: Symbol = getRequiredModule("scala.runtime.ScalaRunTime")
+ lazy val SymbolModule: Symbol = getRequiredModule("scala.Symbol")
+ lazy val Symbol_apply = SymbolModule.info decl nme.apply
+
def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq)
- def arrayApplyMethod = getMember(ScalaRunTimeModule, "array_apply")
- def arrayUpdateMethod = getMember(ScalaRunTimeModule, "array_update")
- def arrayLengthMethod = getMember(ScalaRunTimeModule, "array_length")
- def arrayCloneMethod = getMember(ScalaRunTimeModule, "array_clone")
- def ensureAccessibleMethod = getMember(ScalaRunTimeModule, "ensureAccessible")
+ def arrayApplyMethod = getMember(ScalaRunTimeModule, nme.array_apply)
+ def arrayUpdateMethod = getMember(ScalaRunTimeModule, nme.array_update)
+ def arrayLengthMethod = getMember(ScalaRunTimeModule, nme.array_length)
+ def arrayCloneMethod = getMember(ScalaRunTimeModule, nme.array_clone)
+ def ensureAccessibleMethod = getMember(ScalaRunTimeModule, nme.ensureAccessible)
def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements)
// classes with special meanings
- lazy val StringAddClass = getClass("scala.runtime.StringAdd")
- lazy val ArrowAssocClass = getClass("scala.Predef.ArrowAssoc")
+ lazy val StringAddClass = getRequiredClass("scala.runtime.StringAdd")
+ lazy val ArrowAssocClass = getRequiredClass("scala.Predef.ArrowAssoc")
lazy val StringAdd_+ = getMember(StringAddClass, nme.PLUS)
- lazy val NotNullClass = getClass("scala.NotNull")
- lazy val ScalaNumberClass = getClass("scala.math.ScalaNumber")
- lazy val TraitSetterAnnotationClass = getClass("scala.runtime.TraitSetter")
- lazy val DelayedInitClass = getClass("scala.DelayedInit")
+ lazy val NotNullClass = getRequiredClass("scala.NotNull")
+ lazy val ScalaNumberClass = getRequiredClass("scala.math.ScalaNumber")
+ lazy val TraitSetterAnnotationClass = getRequiredClass("scala.runtime.TraitSetter")
+ lazy val DelayedInitClass = getRequiredClass("scala.DelayedInit")
def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit)
// a dummy value that communicates that a delayedInit call is compiler-generated
// from phase UnCurry to phase Constructors
@@ -269,14 +295,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
// def delayedInitArgVal = EmptyPackageClass.newValue(NoPosition, nme.delayedInitArg)
// .setInfo(UnitClass.tpe)
- lazy val TypeConstraintClass = getClass("scala.annotation.TypeConstraint")
+ lazy val TypeConstraintClass = getRequiredClass("scala.annotation.TypeConstraint")
lazy val SingletonClass = newClass(ScalaPackageClass, tpnme.Singleton, anyparam) setFlag (ABSTRACT | TRAIT | FINAL)
- lazy val SerializableClass = getClass("scala.Serializable")
+ lazy val SerializableClass = getRequiredClass("scala.Serializable")
lazy val JavaSerializableClass = getClass(sn.JavaSerializable)
- lazy val ComparableClass = getClass("java.lang.Comparable")
- lazy val JavaCloneableClass = getClass("java.lang.Cloneable")
- lazy val RemoteInterfaceClass = getClass("java.rmi.Remote")
- lazy val RemoteExceptionClass = getClass("java.rmi.RemoteException")
+ lazy val ComparableClass = getRequiredClass("java.lang.Comparable")
+ lazy val JavaCloneableClass = getRequiredClass("java.lang.Cloneable")
+ lazy val RemoteInterfaceClass = getRequiredClass("java.rmi.Remote")
+ lazy val RemoteExceptionClass = getRequiredClass("java.rmi.RemoteException")
lazy val RepeatedParamClass = newCovariantPolyClass(
ScalaPackageClass,
@@ -326,66 +352,68 @@ trait Definitions extends reflect.api.StandardDefinitions {
val clazz = newClass(ScalaPackageClass, tpnme.EQUALS_PATTERN_NAME, Nil)
clazz setInfo polyType(List(newTypeParam(clazz, 0)), ClassInfoType(anyparam, new Scope, clazz))
}
+ lazy val MatchingStrategyClass = getRequiredClass("scala.MatchingStrategy")
// collections classes
- lazy val ConsClass = getClass("scala.collection.immutable.$colon$colon")
- lazy val IterableClass = getClass("scala.collection.Iterable")
- lazy val IteratorClass = getClass("scala.collection.Iterator")
- lazy val ListClass = getClass("scala.collection.immutable.List")
- lazy val SeqClass = getClass("scala.collection.Seq")
- lazy val StringBuilderClass = getClass("scala.collection.mutable.StringBuilder")
- lazy val TraversableClass = getClass("scala.collection.Traversable")
-
- lazy val ListModule = getModule("scala.collection.immutable.List")
+ lazy val ConsClass = getRequiredClass("scala.collection.immutable.$colon$colon")
+ lazy val IterableClass = getRequiredClass("scala.collection.Iterable")
+ lazy val IteratorClass = getRequiredClass("scala.collection.Iterator")
+ lazy val ListClass = getRequiredClass("scala.collection.immutable.List")
+ lazy val SeqClass = getRequiredClass("scala.collection.Seq")
+ lazy val StringBuilderClass = getRequiredClass("scala.collection.mutable.StringBuilder")
+ lazy val TraversableClass = getRequiredClass("scala.collection.Traversable")
+
+ lazy val ListModule = getRequiredModule("scala.collection.immutable.List")
lazy val List_apply = getMember(ListModule, nme.apply)
- lazy val NilModule = getModule("scala.collection.immutable.Nil")
- lazy val SeqModule = getModule("scala.collection.Seq")
+ lazy val NilModule = getRequiredModule("scala.collection.immutable.Nil")
+ lazy val SeqModule = getRequiredModule("scala.collection.Seq")
+ lazy val IteratorModule = getRequiredModule("scala.collection.Iterator")
+ lazy val Iterator_apply = getMember(IteratorModule, nme.apply)
// arrays and their members
- lazy val ArrayModule = getModule("scala.Array")
- def ArrayModule_overloadedApply = getMember(ArrayModule, nme.apply)
- lazy val ArrayClass = getClass("scala.Array")
- def Array_apply = getMember(ArrayClass, nme.apply)
- def Array_update = getMember(ArrayClass, nme.update)
- def Array_length = getMember(ArrayClass, nme.length)
- lazy val Array_clone = getMember(ArrayClass, nme.clone_)
+ lazy val ArrayModule = getRequiredModule("scala.Array")
+ lazy val ArrayModule_overloadedApply = getMember(ArrayModule, nme.apply)
+ lazy val ArrayClass = getRequiredClass("scala.Array")
+ lazy val Array_apply = getMember(ArrayClass, nme.apply)
+ lazy val Array_update = getMember(ArrayClass, nme.update)
+ lazy val Array_length = getMember(ArrayClass, nme.length)
+ lazy val Array_clone = getMember(ArrayClass, nme.clone_)
// reflection / structural types
- lazy val SoftReferenceClass = getClass("java.lang.ref.SoftReference")
- lazy val WeakReferenceClass = getClass("java.lang.ref.WeakReference")
+ lazy val SoftReferenceClass = getRequiredClass("java.lang.ref.SoftReference")
+ lazy val WeakReferenceClass = getRequiredClass("java.lang.ref.WeakReference")
lazy val MethodClass = getClass(sn.MethodAsObject)
def methodClass_setAccessible = getMember(MethodClass, nme.setAccessible)
- lazy val EmptyMethodCacheClass = getClass("scala.runtime.EmptyMethodCache")
- lazy val MethodCacheClass = getClass("scala.runtime.MethodCache")
+ lazy val EmptyMethodCacheClass = getRequiredClass("scala.runtime.EmptyMethodCache")
+ lazy val MethodCacheClass = getRequiredClass("scala.runtime.MethodCache")
def methodCache_find = getMember(MethodCacheClass, nme.find_)
def methodCache_add = getMember(MethodCacheClass, nme.add_)
// scala.reflect
- lazy val ReflectApiUniverse = getClass("scala.reflect.api.Universe")
- lazy val ReflectRuntimeMirror = getModule("scala.reflect.runtime.Mirror")
- def freeValueMethod = getMember(ReflectRuntimeMirror, "freeValue")
+ lazy val ReflectApiUniverse = getRequiredClass("scala.reflect.api.Universe")
+ lazy val ReflectRuntimeMirror = getRequiredModule("scala.reflect.runtime.Mirror")
+ def freeValueMethod = getMember(ReflectRuntimeMirror, nme.freeValue)
lazy val ReflectPackage = getPackageObject("scala.reflect")
- def Reflect_mirror = getMember(ReflectPackage, "mirror")
-
-
- lazy val PartialManifestClass = getClass("scala.reflect.ClassManifest")
- lazy val PartialManifestModule = getModule("scala.reflect.ClassManifest")
- lazy val FullManifestClass = getClass("scala.reflect.Manifest")
- lazy val FullManifestModule = getModule("scala.reflect.Manifest")
- lazy val OptManifestClass = getClass("scala.reflect.OptManifest")
- lazy val NoManifest = getModule("scala.reflect.NoManifest")
+ def Reflect_mirror = getMember(ReflectPackage, nme.mirror)
+
+ lazy val PartialManifestClass = getRequiredClass("scala.reflect.ClassManifest")
+ lazy val PartialManifestModule = getRequiredModule("scala.reflect.ClassManifest")
+ lazy val FullManifestClass = getRequiredClass("scala.reflect.Manifest")
+ lazy val FullManifestModule = getRequiredModule("scala.reflect.Manifest")
+ lazy val OptManifestClass = getRequiredClass("scala.reflect.OptManifest")
+ lazy val NoManifest = getRequiredModule("scala.reflect.NoManifest")
lazy val CodeClass = getClass(sn.Code)
lazy val CodeModule = getModule(sn.Code)
- def Code_lift = getMember(CodeModule, nme.lift_)
+ lazy val Code_lift = getMember(CodeModule, nme.lift_)
- lazy val ScalaSignatureAnnotation = getClass("scala.reflect.ScalaSignature")
- lazy val ScalaLongSignatureAnnotation = getClass("scala.reflect.ScalaLongSignature")
+ lazy val ScalaSignatureAnnotation = getRequiredClass("scala.reflect.ScalaSignature")
+ lazy val ScalaLongSignatureAnnotation = getRequiredClass("scala.reflect.ScalaLongSignature")
// Option classes
- lazy val OptionClass: Symbol = getClass("scala.Option")
- lazy val SomeClass: Symbol = getClass("scala.Some")
- lazy val NoneModule: Symbol = getModule("scala.None")
- lazy val SomeModule: Symbol = getModule("scala.Some")
+ lazy val OptionClass: Symbol = getRequiredClass("scala.Option")
+ lazy val SomeClass: Symbol = getRequiredClass("scala.Some")
+ lazy val NoneModule: Symbol = getRequiredModule("scala.None")
+ lazy val SomeModule: Symbol = getRequiredModule("scala.Some")
/** Note: don't use this manifest/type function for anything important,
* as it is incomplete. Would love to have things like existential types
@@ -441,7 +469,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Product, Tuple, Function
private def mkArityArray(name: String, arity: Int, countFrom: Int = 1): Array[Symbol] = {
- val list = countFrom to arity map (i => getClass("scala." + name + i))
+ val list = countFrom to arity map (i => getRequiredClass("scala." + name + i))
if (countFrom == 0) list.toArray
else (NoSymbol +: list).toArray
}
@@ -457,10 +485,24 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0)
lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0)
lazy val isProductNClass = ProductClass.toSet
+ def wrapArrayMethodName(elemtp: Type): TermName = elemtp.typeSymbol match {
+ case ByteClass => nme.wrapByteArray
+ case ShortClass => nme.wrapShortArray
+ case CharClass => nme.wrapCharArray
+ case IntClass => nme.wrapIntArray
+ case LongClass => nme.wrapLongArray
+ case FloatClass => nme.wrapFloatArray
+ case DoubleClass => nme.wrapDoubleArray
+ case BooleanClass => nme.wrapBooleanArray
+ case UnitClass => nme.wrapUnitArray
+ case _ =>
+ if ((elemtp <:< AnyRefClass.tpe) && !isPhantomClass(elemtp.typeSymbol)) nme.wrapRefArray
+ else nme.genericWrapArray
+ }
- def tupleField(n: Int, j: Int) = getMember(TupleClass(n), "_" + j)
- def isTupleType(tp: Type): Boolean = isTupleType(tp, false)
- def isTupleTypeOrSubtype(tp: Type): Boolean = isTupleType(tp, true)
+ def tupleField(n: Int, j: Int) = getMember(TupleClass(n), nme.productAccessorName(j))
+ def isTupleType(tp: Type): Boolean = isTupleType(tp, false)
+ def isTupleTypeOrSubtype(tp: Type): Boolean = isTupleType(tp, true)
private def isTupleType(tp: Type, subtypeOK: Boolean) = tp.normalize match {
case TypeRef(_, sym, args) if args.nonEmpty =>
val len = args.length
@@ -479,7 +521,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
} else NoType
}
- lazy val ProductRootClass: Symbol = getClass("scala.Product")
+ lazy val ProductRootClass: Symbol = getRequiredClass("scala.Product")
def Product_productArity = getMember(ProductRootClass, nme.productArity)
def Product_productElement = getMember(ProductRootClass, nme.productElement)
// def Product_productElementName = getMember(ProductRootClass, nme.productElementName)
@@ -548,9 +590,10 @@ trait Definitions extends reflect.api.StandardDefinitions {
case _ => NoType
}
- def seqType(arg: Type) = appliedType(SeqClass.typeConstructor, List(arg))
- def arrayType(arg: Type) = appliedType(ArrayClass.typeConstructor, List(arg))
- def byNameType(arg: Type) = appliedType(ByNameParamClass.typeConstructor, List(arg))
+ def seqType(arg: Type) = appliedType(SeqClass.typeConstructor, List(arg))
+ def arrayType(arg: Type) = appliedType(ArrayClass.typeConstructor, List(arg))
+ def byNameType(arg: Type) = appliedType(ByNameParamClass.typeConstructor, List(arg))
+ def iteratorOfType(tp: Type) = appliedType(IteratorClass.typeConstructor, List(tp))
def ClassType(arg: Type) =
if (phase.erasedTypes || forMSIL) ClassClass.tpe
@@ -560,7 +603,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// .NET backend
//
- lazy val ComparatorClass = getClass("scala.runtime.Comparator")
+ lazy val ComparatorClass = getRequiredClass("scala.runtime.Comparator")
// System.ValueType
lazy val ValueTypeClass: Symbol = getClass(sn.ValueType)
// System.MulticastDelegate
@@ -605,10 +648,10 @@ trait Definitions extends reflect.api.StandardDefinitions {
var Object_## : Symbol = _
var Object_synchronized: Symbol = _
lazy val Object_isInstanceOf = newPolyMethod(
- ObjectClass, "$isInstanceOf",
+ ObjectClass, newTermName("$isInstanceOf"),
tparam => MethodType(List(), booltype)) setFlag (FINAL | SYNTHETIC)
lazy val Object_asInstanceOf = newPolyMethod(
- ObjectClass, "$asInstanceOf",
+ ObjectClass, newTermName("$asInstanceOf"),
tparam => MethodType(List(), tparam.typeConstructor)) setFlag (FINAL | SYNTHETIC)
def Object_getClass = getMember(ObjectClass, nme.getClass_)
@@ -623,57 +666,57 @@ trait Definitions extends reflect.api.StandardDefinitions {
var String_+ : Symbol = _
// boxed classes
- lazy val ObjectRefClass = getClass("scala.runtime.ObjectRef")
- lazy val VolatileObjectRefClass = getClass("scala.runtime.VolatileObjectRef")
- lazy val BoxesRunTimeClass = getModule("scala.runtime.BoxesRunTime")
+ lazy val ObjectRefClass = getRequiredClass("scala.runtime.ObjectRef")
+ lazy val VolatileObjectRefClass = getRequiredClass("scala.runtime.VolatileObjectRef")
+ lazy val BoxesRunTimeClass = getRequiredModule("scala.runtime.BoxesRunTime")
lazy val BoxedNumberClass = getClass(sn.BoxedNumber)
lazy val BoxedCharacterClass = getClass(sn.BoxedCharacter)
lazy val BoxedBooleanClass = getClass(sn.BoxedBoolean)
- lazy val BoxedByteClass = getClass("java.lang.Byte")
- lazy val BoxedShortClass = getClass("java.lang.Short")
- lazy val BoxedIntClass = getClass("java.lang.Integer")
- lazy val BoxedLongClass = getClass("java.lang.Long")
- lazy val BoxedFloatClass = getClass("java.lang.Float")
- lazy val BoxedDoubleClass = getClass("java.lang.Double")
-
- lazy val BoxedUnitClass = getClass("scala.runtime.BoxedUnit")
- lazy val BoxedUnitModule = getModule("scala.runtime.BoxedUnit")
- def BoxedUnit_UNIT = getMember(BoxedUnitModule, "UNIT")
- def BoxedUnit_TYPE = getMember(BoxedUnitModule, "TYPE")
+ lazy val BoxedByteClass = getRequiredClass("java.lang.Byte")
+ lazy val BoxedShortClass = getRequiredClass("java.lang.Short")
+ lazy val BoxedIntClass = getRequiredClass("java.lang.Integer")
+ lazy val BoxedLongClass = getRequiredClass("java.lang.Long")
+ lazy val BoxedFloatClass = getRequiredClass("java.lang.Float")
+ lazy val BoxedDoubleClass = getRequiredClass("java.lang.Double")
+
+ lazy val BoxedUnitClass = getRequiredClass("scala.runtime.BoxedUnit")
+ lazy val BoxedUnitModule = getRequiredModule("scala.runtime.BoxedUnit")
+ def BoxedUnit_UNIT = getMember(BoxedUnitModule, nme.UNIT)
+ def BoxedUnit_TYPE = getMember(BoxedUnitModule, nme.TYPE_)
// Annotation base classes
- lazy val AnnotationClass = getClass("scala.annotation.Annotation")
- lazy val ClassfileAnnotationClass = getClass("scala.annotation.ClassfileAnnotation")
- lazy val StaticAnnotationClass = getClass("scala.annotation.StaticAnnotation")
+ lazy val AnnotationClass = getRequiredClass("scala.annotation.Annotation")
+ lazy val ClassfileAnnotationClass = getRequiredClass("scala.annotation.ClassfileAnnotation")
+ lazy val StaticAnnotationClass = getRequiredClass("scala.annotation.StaticAnnotation")
// Annotations
- lazy val BridgeClass = getClass("scala.annotation.bridge")
- lazy val ElidableMethodClass = getClass("scala.annotation.elidable")
- lazy val ImplicitNotFoundClass = getClass("scala.annotation.implicitNotFound")
- lazy val MigrationAnnotationClass = getClass("scala.annotation.migration")
- lazy val ScalaStrictFPAttr = getClass("scala.annotation.strictfp")
- lazy val SerializableAttr = getClass("scala.annotation.serializable") // @serializable is deprecated
- lazy val SwitchClass = getClass("scala.annotation.switch")
- lazy val TailrecClass = getClass("scala.annotation.tailrec")
- lazy val VarargsClass = getClass("scala.annotation.varargs")
- lazy val uncheckedStableClass = getClass("scala.annotation.unchecked.uncheckedStable")
- lazy val uncheckedVarianceClass = getClass("scala.annotation.unchecked.uncheckedVariance")
-
- lazy val BeanPropertyAttr = getClass("scala.beans.BeanProperty")
- lazy val BooleanBeanPropertyAttr = getClass("scala.beans.BooleanBeanProperty")
- lazy val CloneableAttr = getClass("scala.cloneable")
- lazy val DeprecatedAttr = getClass("scala.deprecated")
- lazy val DeprecatedNameAttr = getClass("scala.deprecatedName")
- lazy val NativeAttr = getClass("scala.native")
- lazy val RemoteAttr = getClass("scala.remote")
- lazy val ScalaInlineClass = getClass("scala.inline")
- lazy val ScalaNoInlineClass = getClass("scala.noinline")
- lazy val SerialVersionUIDAttr = getClass("scala.SerialVersionUID")
- lazy val SpecializedClass = getClass("scala.specialized")
- lazy val ThrowsClass = getClass("scala.throws")
- lazy val TransientAttr = getClass("scala.transient")
- lazy val UncheckedClass = getClass("scala.unchecked")
- lazy val VolatileAttr = getClass("scala.volatile")
+ lazy val BridgeClass = getRequiredClass("scala.annotation.bridge")
+ lazy val ElidableMethodClass = getRequiredClass("scala.annotation.elidable")
+ lazy val ImplicitNotFoundClass = getRequiredClass("scala.annotation.implicitNotFound")
+ lazy val MigrationAnnotationClass = getRequiredClass("scala.annotation.migration")
+ lazy val ScalaStrictFPAttr = getRequiredClass("scala.annotation.strictfp")
+ lazy val SerializableAttr = getRequiredClass("scala.annotation.serializable") // @serializable is deprecated
+ lazy val SwitchClass = getRequiredClass("scala.annotation.switch")
+ lazy val TailrecClass = getRequiredClass("scala.annotation.tailrec")
+ lazy val VarargsClass = getRequiredClass("scala.annotation.varargs")
+ lazy val uncheckedStableClass = getRequiredClass("scala.annotation.unchecked.uncheckedStable")
+ lazy val uncheckedVarianceClass = getRequiredClass("scala.annotation.unchecked.uncheckedVariance")
+
+ lazy val BeanPropertyAttr = getRequiredClass("scala.beans.BeanProperty")
+ lazy val BooleanBeanPropertyAttr = getRequiredClass("scala.beans.BooleanBeanProperty")
+ lazy val CloneableAttr = getRequiredClass("scala.cloneable")
+ lazy val DeprecatedAttr = getRequiredClass("scala.deprecated")
+ lazy val DeprecatedNameAttr = getRequiredClass("scala.deprecatedName")
+ lazy val NativeAttr = getRequiredClass("scala.native")
+ lazy val RemoteAttr = getRequiredClass("scala.remote")
+ lazy val ScalaInlineClass = getRequiredClass("scala.inline")
+ lazy val ScalaNoInlineClass = getRequiredClass("scala.noinline")
+ lazy val SerialVersionUIDAttr = getRequiredClass("scala.SerialVersionUID")
+ lazy val SpecializedClass = getRequiredClass("scala.specialized")
+ lazy val ThrowsClass = getRequiredClass("scala.throws")
+ lazy val TransientAttr = getRequiredClass("scala.transient")
+ lazy val UncheckedClass = getRequiredClass("scala.unchecked")
+ lazy val VolatileAttr = getRequiredClass("scala.volatile")
// Meta-annotations
lazy val BeanGetterTargetClass = getMetaAnnotation("beanGetter")
@@ -684,7 +727,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val SetterTargetClass = getMetaAnnotation("setter")
// TODO: module, moduleClass? package, packageObject?
- private def getMetaAnnotation(name: String) = getClass("scala.annotation.meta." + name)
+ private def getMetaAnnotation(name: String) = getRequiredClass("scala.annotation.meta." + name)
def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || (
// Trying to allow for deprecated locations
sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol)
@@ -702,11 +745,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
attr
}
- def getPackageObjectClass(fullname: Name): Symbol =
+ def getPackageObjectClass(fullname: String): Symbol =
getPackageObject(fullname).companionClass
- def getPackageObject(fullname: Name): Symbol =
- getModule(fullname).info member nme.PACKAGE
+ def getPackageObject(fullname: String): Symbol =
+ getModule(newTermName(fullname)).info member nme.PACKAGE
def getModule(fullname: Name): Symbol =
getModuleOrClass(fullname.toTermName)
@@ -716,6 +759,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
while (result.isAliasType) result = result.info.typeSymbol
result
}
+
+ def getRequiredModule(fullname: String): Symbol =
+ getModule(newTermNameCached(fullname))
+ def getRequiredClass(fullname: String): Symbol =
+ getClass(newTypeNameCached(fullname))
def getClassIfDefined(fullname: String): Symbol =
getClassIfDefined(newTypeName(fullname))
@@ -953,8 +1001,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
ObjectClass, nme.synchronized_,
tparam => msym => MethodType(msym.newSyntheticValueParams(List(tparam.typeConstructor)), tparam.typeConstructor)) setFlag FINAL
- String_+ = newMethod(
- StringClass, "+", anyparam, stringtype) setFlag FINAL
+ String_+ = newMethod(StringClass, nme.raw.PLUS, anyparam, stringtype) setFlag FINAL
val forced = List( // force initialization of every symbol that is entered as a side effect
AnnotationDefaultAttr, // #2264
@@ -987,7 +1034,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
assert(forMSIL, "scalaCallers can only be created if target is .NET")
// object: reference to object on which to call (scala-)method
val paramTypes: List[Type] = List(ObjectClass.tpe)
- val name: String = "$scalaCaller$$" + nbScalaCallers
+ val name = newTermName("$scalaCaller$$" + nbScalaCallers)
// tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the
// type parameter =-> a MethodType in this case
// TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index a4af4bf8f3..38f808cef9 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -20,8 +20,8 @@ trait Importers { self: SymbolTable =>
def importSymbol(sym: from.Symbol): Symbol = {
def doImport(sym: from.Symbol): Symbol = {
val myowner = importSymbol(sym.owner)
- val mypos = importPosition(sym.pos)
- val myname = importName(sym.name)
+ val mypos = importPosition(sym.pos)
+ val myname = importName(sym.name).toTermName
def linkReferenced(mysym: TermSymbol, x: from.TermSymbol, op: from.Symbol => Symbol): Symbol = {
symMap(x) = mysym
mysym.referenced = op(x.referenced)
@@ -33,7 +33,7 @@ trait Importers { self: SymbolTable =>
case x: from.ModuleSymbol =>
linkReferenced(new ModuleSymbol(myowner, mypos, myname), x, doImport)
case x: from.FreeVar =>
- new FreeVar(importName(x.name), importType(x.tpe), x.value)
+ new FreeVar(importName(x.name).toTermName, importType(x.tpe), x.value)
case x: from.TermSymbol =>
linkReferenced(new TermSymbol(myowner, mypos, myname), x, importSymbol)
case x: from.TypeSkolem =>
@@ -167,7 +167,7 @@ trait Importers { self: SymbolTable =>
case from.AntiPolyType(pre, targs) =>
AntiPolyType(importType(pre), targs map importType)
case x: from.TypeVar =>
- new TypeVar(importType(x.origin), importTypeConstraint(x.constr0), x.typeArgs map importType, x.params map importSymbol)
+ TypeVar(importType(x.origin), importTypeConstraint(x.constr0), x.typeArgs map importType, x.params map importSymbol)
case from.NotNullType(tpe) =>
NotNullType(importType(tpe))
case from.AnnotatedType(annots, tpe, selfsym) =>
diff --git a/src/compiler/scala/reflect/internal/Kinds.scala b/src/compiler/scala/reflect/internal/Kinds.scala
index 15fcb5f94d..e675be43dc 100644
--- a/src/compiler/scala/reflect/internal/Kinds.scala
+++ b/src/compiler/scala/reflect/internal/Kinds.scala
@@ -110,10 +110,7 @@ trait Kinds {
): List[(Type, Symbol, KindErrors)] = {
// instantiate type params that come from outside the abstract type we're currently checking
- def transform(tp: Type, clazz: Symbol): Type =
- tp.asSeenFrom(pre, clazz)
- def transformedBounds(p: Symbol, o: Symbol) =
- transform(p.info.instantiateTypeParams(tparams, targs).bounds, o)
+ def transform(tp: Type, clazz: Symbol): Type = tp.asSeenFrom(pre, clazz)
// check that the type parameters hkargs to a higher-kinded type conform to the
// expected params hkparams
@@ -131,6 +128,7 @@ trait Kinds {
// @M sometimes hkargs != arg.typeParams, the symbol and the type may
// have very different type parameters
val hkparams = param.typeParams
+
def kindCheck(cond: Boolean, f: KindErrors => KindErrors) {
if (!cond)
kindErrors = f(kindErrors)
@@ -160,8 +158,8 @@ trait Kinds {
// conceptually the same. Could also replace the types by
// polytypes, but can't just strip the symbols, as ordering
// is lost then.
- val declaredBounds = transformedBounds(hkparam, paramowner)
- val declaredBoundsInst = bindHKParams(declaredBounds)
+ val declaredBounds = transform(hkparam.info.instantiateTypeParams(tparams, targs).bounds, paramowner)
+ val declaredBoundsInst = transform(bindHKParams(declaredBounds), owner)
val argumentBounds = transform(hkarg.info.bounds, owner)
kindCheck(declaredBoundsInst <:< argumentBounds, _ strictnessError (hkarg -> hkparam))
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index d4aa6339ff..ef092f16bb 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -23,8 +23,8 @@ trait NameManglers {
val MODULE_SUFFIX_STRING = NameTransformer.MODULE_SUFFIX_STRING
val NAME_JOIN_STRING = NameTransformer.NAME_JOIN_STRING
- val MODULE_SUFFIX_NAME: TermName = MODULE_SUFFIX_STRING
- val NAME_JOIN_NAME: TermName = NAME_JOIN_STRING
+ val MODULE_SUFFIX_NAME: TermName = newTermName(MODULE_SUFFIX_STRING)
+ val NAME_JOIN_NAME: TermName = newTermName(NAME_JOIN_STRING)
def flattenedName(segments: Name*): NameType = compactedString(segments mkString NAME_JOIN_STRING)
@@ -75,12 +75,12 @@ trait NameManglers {
val LOCALDUMMY_PREFIX = "<local " // owner of local blocks
val PROTECTED_PREFIX = "protected$"
val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set"
- val SETTER_SUFFIX = encode("_=")
val SINGLETON_SUFFIX = ".type"
val SPECIALIZED_SUFFIX_STRING = "$sp"
val SUPER_PREFIX_STRING = "super$"
val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
+ val SETTER_SUFFIX: TermName = encode("_=")
val SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX_STRING
def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
@@ -124,6 +124,11 @@ trait NameManglers {
name.subName(0, name.lastIndexOf('m') - 1)
else name
)
+
+ def macroMethodName(name: Name) = {
+ val base = if (name.isTypeName) nme.TYPEkw else nme.DEFkw
+ base append nme.MACRO append name
+ }
/** Return the original name and the types on which this name
* is specialized. For example,
@@ -136,7 +141,7 @@ trait NameManglers {
*/
def splitSpecializedName(name: Name): (Name, String, String) =
if (name endsWith SPECIALIZED_SUFFIX_NAME) {
- val name1 = name stripEnd SPECIALIZED_SUFFIX_NAME
+ val name1 = name dropRight SPECIALIZED_SUFFIX_NAME.length
val idxC = name1 lastIndexOf 'c'
val idxM = name1 lastIndexOf 'm'
@@ -147,18 +152,18 @@ trait NameManglers {
(name, "", "")
def getterName(name: TermName): TermName = if (isLocalName(name)) localToGetter(name) else name
- def getterToLocal(name: TermName): TermName = name.toTermName append LOCAL_SUFFIX_STRING
- def getterToSetter(name: TermName): TermName = name.toTermName append SETTER_SUFFIX
- def localToGetter(name: TermName): TermName = name stripEnd LOCAL_SUFFIX_STRING toTermName
+ def getterToLocal(name: TermName): TermName = name append LOCAL_SUFFIX_STRING
+ def getterToSetter(name: TermName): TermName = name append SETTER_SUFFIX
+ def localToGetter(name: TermName): TermName = name dropRight LOCAL_SUFFIX_STRING.length
def dropLocalSuffix(name: Name): Name = if (name endsWith ' ') name dropRight 1 else name
def setterToGetter(name: TermName): TermName = {
val p = name.pos(TRAIT_SETTER_SEPARATOR_STRING)
if (p < name.length)
- setterToGetter(name.subName(p + TRAIT_SETTER_SEPARATOR_STRING.length, name.length))
+ setterToGetter(name drop (p + TRAIT_SETTER_SEPARATOR_STRING.length))
else
- name stripEnd SETTER_SUFFIX toTermName
+ name.subName(0, name.length - SETTER_SUFFIX.length)
}
def defaultGetterName(name: Name, pos: Int): TermName = {
@@ -167,8 +172,8 @@ trait NameManglers {
}
def defaultGetterToMethod(name: Name): TermName = {
val p = name.pos(DEFAULT_GETTER_STRING)
- if (p < name.length) name.subName(0, p)
- else name
+ if (p < name.length) name.toTermName.subName(0, p)
+ else name.toTermName
}
/** !!! I'm putting this logic in place because I can witness
@@ -192,18 +197,14 @@ trait NameManglers {
}
def stripModuleSuffix(name: Name): Name = (
- if (isModuleName(name)) name stripEnd MODULE_SUFFIX_STRING else name
+ if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name
)
- /** Note that for performance reasons, stripEnd does not verify that the
- * suffix is actually the suffix specified.
- */
- def dropSingletonName(name: Name): TypeName = name stripEnd SINGLETON_SUFFIX toTypeName
+ def dropSingletonName(name: Name): TypeName = name dropRight SINGLETON_SUFFIX.length toTypeName
def singletonName(name: Name): TypeName = name append SINGLETON_SUFFIX toTypeName
def implClassName(name: Name): TypeName = name append IMPL_CLASS_SUFFIX toTypeName
- def interfaceName(implname: Name): TypeName = implname stripEnd IMPL_CLASS_SUFFIX toTypeName
+ def interfaceName(implname: Name): TypeName = implname dropRight IMPL_CLASS_SUFFIX.length toTypeName
def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">")
- def productAccessorName(i: Int): TermName = newTermName("_" + i)
def superName(name: Name): TermName = newTermName(SUPER_PREFIX_STRING + name)
/** The name of an accessor for protected symbols. */
diff --git a/src/compiler/scala/reflect/internal/Names.scala b/src/compiler/scala/reflect/internal/Names.scala
index 8453b1e758..b960695f51 100644
--- a/src/compiler/scala/reflect/internal/Names.scala
+++ b/src/compiler/scala/reflect/internal/Names.scala
@@ -71,25 +71,38 @@ trait Names extends api.Names {
}
/** Create a term name from the characters in cs[offset..offset+len-1]. */
- def newTermName(cs: Array[Char], offset: Int, len: Int): TermName = {
+ def newTermName(cs: Array[Char], offset: Int, len: Int): TermName =
+ newTermName(cs, offset, len, cachedString = null)
+
+ def newTermName(cs: Array[Char]): TermName = newTermName(cs, 0, cs.length)
+ def newTypeName(cs: Array[Char]): TypeName = newTypeName(cs, 0, cs.length)
+
+ /** Create a term name from the characters in cs[offset..offset+len-1]. */
+ protected def newTermName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TermName = {
val h = hashValue(cs, offset, len) & HASH_MASK
var n = termHashtable(h)
while ((n ne null) && (n.length != len || !equals(n.start, cs, offset, len)))
n = n.next
- if (n eq null) {
+
+ if (n ne null) n
+ else {
// The logic order here is future-proofing against the possibility
// that name.toString will become an eager val, in which case the call
// to enterChars cannot follow the construction of the TermName.
val ncStart = nc
enterChars(cs, offset, len)
- n = new TermName(ncStart, len, h)
+ if (cachedString ne null) new TermName_S(ncStart, len, h, cachedString)
+ else new TermName_R(ncStart, len, h)
}
- n
}
+ protected def newTypeName(cs: Array[Char], offset: Int, len: Int, cachedString: String): TypeName =
+ newTermName(cs, offset, len, cachedString).toTypeName
/** Create a term name from string. */
- def newTermName(s: String): TermName =
- newTermName(s.toCharArray(), 0, s.length())
+ def newTermName(s: String): TermName = newTermName(s.toCharArray(), 0, s.length(), null)
+
+ /** Create a type name from string. */
+ def newTypeName(s: String): TypeName = newTermName(s).toTypeName
/** Create a term name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */
def newTermName(bs: Array[Byte], offset: Int, len: Int): TermName = {
@@ -97,13 +110,15 @@ trait Names extends api.Names {
newTermName(chars, 0, chars.length)
}
+ def newTermNameCached(s: String): TermName =
+ newTermName(s.toCharArray(), 0, s.length(), cachedString = s)
+
+ def newTypeNameCached(s: String): TypeName =
+ newTypeName(s.toCharArray(), 0, s.length(), cachedString = s)
+
/** Create a type name from the characters in cs[offset..offset+len-1]. */
def newTypeName(cs: Array[Char], offset: Int, len: Int): TypeName =
- newTermName(cs, offset, len).toTypeName
-
- /** Create a type name from string. */
- def newTypeName(s: String): TypeName =
- newTermName(s).toTypeName
+ newTermName(cs, offset, len, cachedString = null).toTypeName
/** Create a type name from the UTF8 encoded bytes in bs[offset..offset+len-1]. */
def newTypeName(bs: Array[Byte], offset: Int, len: Int): TypeName =
@@ -114,19 +129,27 @@ trait Names extends api.Names {
// Classes ----------------------------------------------------------------------
- /** The name class. */
+ /** The name class.
+ * TODO - resolve schizophrenia regarding whether to treat Names as Strings
+ * or Strings as Names. Give names the key functions the absence of which
+ * make people want Strings all the time.
+ */
sealed abstract class Name(protected val index: Int, protected val len: Int) extends AbsName with Function1[Int, Char] {
+ type ThisNameType <: Name
+ protected[this] def thisName: ThisNameType
+
/** Index into name table */
def start: Int = index
/** The next name in the same hash bucket. */
- def next: Name
+ def next: ThisNameType
/** The length of this name. */
final def length: Int = len
final def isEmpty = length == 0
final def nonEmpty = !isEmpty
+ def nameKind: String
def isTermName: Boolean
def isTypeName: Boolean
def toTermName: TermName
@@ -134,6 +157,15 @@ trait Names extends api.Names {
def companionName: Name
def bothNames: List[Name] = List(toTermName, toTypeName)
+ /** Return the subname with characters from from to to-1. */
+ def subName(from: Int, to: Int): ThisNameType
+
+ /** Return a new name of the same variety. */
+ def newName(str: String): ThisNameType
+
+ /** Return a new name based on string transformation. */
+ def mapName(f: String => String): ThisNameType = newName(f(toString))
+
/** Copy bytes of this name to buffer cs, starting at position `offset`. */
final def copyChars(cs: Array[Char], offset: Int) =
compat.Platform.arraycopy(chrs, index, cs, offset, len)
@@ -145,21 +177,13 @@ trait Names extends api.Names {
cs
}
- /** @return the string representation of this name */
- final override def toString(): String = new String(chrs, index, len)
- // Should we opt to make toString into a val to avoid the creation
- // of 750,000 copies of x$1, here's the line.
- // final override val toString = new String(chrs, index, len)
-
- def debugString() = NameTransformer.decode(toString) + (if (isTypeName) "!" else "")
-
/** Write to UTF8 representation of this name to given character array.
* Start copying to index `to`. Return index of next free byte in array.
* Array must have enough remaining space for all bytes
* (i.e. maximally 3*length bytes).
*/
final def copyUTF8(bs: Array[Byte], offset: Int): Int = {
- val bytes = Codec toUTF8 chrs.slice(index, index + len)
+ val bytes = Codec.toUTF8(chrs, index, len)
compat.Platform.arraycopy(bytes, 0, bs, offset, bytes.length)
offset + bytes.length
}
@@ -326,17 +350,20 @@ trait Names extends api.Names {
final def startsWith(name: String): Boolean = startsWith(newTermName(name))
final def endsWith(char: Char): Boolean = len > 0 && endChar == char
final def endsWith(name: String): Boolean = endsWith(newTermName(name))
- final def stripStart(prefix: Name): Name = subName(prefix.length, len)
- final def stripStart(prefix: String): Name = subName(prefix.length, len)
- final def stripEnd(suffix: Name): Name = subName(0, len - suffix.length)
- final def stripEnd(suffix: String): Name = subName(0, len - suffix.length)
-
- def dropRight(n: Int) = subName(0, len - n)
-
- def lastIndexOf(ch: Char) = toChars lastIndexOf ch
- /** Return the subname with characters from from to to-1. */
- def subName(from: Int, to: Int): Name
+ def dropRight(n: Int) = subName(0, len - n)
+ def drop(n: Int) = subName(n, len)
+
+ def indexOf(ch: Char) = {
+ val idx = pos(ch)
+ if (idx == length) -1 else idx
+ }
+ def indexOf(ch: Char, fromIndex: Int) = {
+ val idx = pos(ch, fromIndex)
+ if (idx == length) -1 else idx
+ }
+ def lastIndexOf(ch: Char) = lastPos(ch)
+ def lastIndexOf(ch: Char, fromIndex: Int) = lastPos(ch, fromIndex)
/** Replace all occurrences of `from` by `to` in
* name; result is always a term name.
@@ -351,31 +378,79 @@ trait Names extends api.Names {
}
newTermName(cs, 0, len)
}
+
+ /** TODO - reconcile/fix that encode returns a Name but
+ * decode returns a String.
+ */
/** Replace operator symbols by corresponding $op_name. */
- def encode: Name = {
+ def encode: ThisNameType = {
val str = toString
val res = NameTransformer.encode(str)
- if (res == str) this
- else if (isTypeName) newTypeName(res)
- else newTermName(res)
+ if (res == str) thisName else newName(res)
}
- def append(ch: Char): Name
- def append(suffix: String): Name
- def append(suffix: Name): Name
-
/** Replace $op_name by corresponding operator symbol. */
- def decode: String = (
- NameTransformer.decode(toString) +
- (if (nameDebug && isTypeName) "!" else ""))//debug
+ def decode: String = {
+ if (this containsChar '$') {
+ val str = toString
+ val res = NameTransformer.decode(str)
+ if (res == str) str
+ else res
+ }
+ else toString
+ }
+ /** TODO - find some efficiency. */
+ def append(ch: Char) = newName("" + this + ch)
+ def append(suffix: String) = newName("" + this + suffix)
+ def append(suffix: Name) = newName("" + this + suffix)
+ def prepend(ch: Char) = newName("" + ch + this)
+ def prepend(prefix: String) = newName("" + prefix + this)
+ def prepend(prefix: Name) = newName("" + prefix + this)
+
+ def decodedName: ThisNameType = newName(decode)
def isOperatorName: Boolean = decode != toString
- def nameKind: String = if (isTypeName) "type" else "term"
- def longString: String = nameKind + " " + NameTransformer.decode(toString)
+ def longString: String = nameKind + " " + decode
+ def debugString = { val s = decode ; if (isTypeName) s + "!" else s }
+ }
+
+ /** A name that contains no operator chars nor dollar signs.
+ * TODO - see if it's any faster to do something along these lines.
+ */
+ trait AlphaNumName extends Name {
+ final override def encode = thisName
+ final override def decodedName = thisName
+ final override def decode = toString
+ final override def isOperatorName = false
+ }
+
+ /** TermName_S and TypeName_S have fields containing the string version of the name.
+ * TermName_R and TypeName_R recreate it each time toString is called.
+ */
+ private class TermName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TermName(index0, len0, hash) {
+ protected def createCompanionName(h: Int): TypeName = new TypeName_S(index, len, h, toString)
+ override def newName(str: String): TermName = newTermNameCached(str)
+ }
+ private class TypeName_S(index0: Int, len0: Int, hash: Int, override val toString: String) extends TypeName(index0, len0, hash) {
+ protected def createCompanionName(h: Int): TermName = new TermName_S(index, len, h, toString)
+ override def newName(str: String): TypeName = newTypeNameCached(str)
+ }
+
+ private class TermName_R(index0: Int, len0: Int, hash: Int) extends TermName(index0, len0, hash) {
+ protected def createCompanionName(h: Int): TypeName = new TypeName_R(index, len, h)
+ override def toString = new String(chrs, index, len)
}
- final class TermName(_index: Int, _len: Int, hash: Int) extends Name(_index, _len) {
+ private class TypeName_R(index0: Int, len0: Int, hash: Int) extends TypeName(index0, len0, hash) {
+ protected def createCompanionName(h: Int): TermName = new TermName_R(index, len, h)
+ override def toString = new String(chrs, index, len)
+ }
+
+ sealed abstract class TermName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) {
+ type ThisNameType = TermName
+ protected[this] def thisName: TermName = this
+
var next: TermName = termHashtable(hash)
termHashtable(hash) = this
def isTermName: Boolean = true
@@ -385,20 +460,24 @@ trait Names extends api.Names {
val h = hashValue(chrs, index, len) & HASH_MASK
var n = typeHashtable(h)
while ((n ne null) && n.start != index)
- n = n.next;
- if (n eq null)
- n = new TypeName(index, len, h);
- n
+ n = n.next
+
+ if (n ne null) n
+ else createCompanionName(h)
}
- def append(ch: Char): TermName = append("" + ch)
- def append(suffix: String): TermName = newTermName(this + suffix)
- def append(suffix: Name): TermName = append(suffix.toString)
+ def newName(str: String): TermName = newTermName(str)
def companionName: TypeName = toTypeName
def subName(from: Int, to: Int): TermName =
newTermName(chrs, start + from, to - from)
+
+ def nameKind = "term"
+ protected def createCompanionName(h: Int): TypeName
}
- final class TypeName(_index: Int, _len: Int, hash: Int) extends Name(_index, _len) {
+ sealed abstract class TypeName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) {
+ type ThisNameType = TypeName
+ protected[this] def thisName: TypeName = this
+
var next: TypeName = typeHashtable(hash)
typeHashtable(hash) = this
def isTermName: Boolean = false
@@ -407,18 +486,19 @@ trait Names extends api.Names {
val h = hashValue(chrs, index, len) & HASH_MASK
var n = termHashtable(h)
while ((n ne null) && n.start != index)
- n = n.next;
- if (n eq null)
- n = new TermName(index, len, h);
- n
+ n = n.next
+
+ if (n ne null) n
+ else createCompanionName(h)
}
def toTypeName: TypeName = this
-
- def append(ch: Char): TypeName = append("" + ch)
- def append(suffix: String): TypeName = newTypeName(this + suffix)
- def append(suffix: Name): TypeName = append(suffix.toString)
+ def newName(str: String): TypeName = newTypeName(str)
def companionName: TermName = toTermName
def subName(from: Int, to: Int): TypeName =
newTypeName(chrs, start + from, to - from)
+
+ def nameKind = "type"
+ override def decode = if (nameDebug) super.decode + "!" else super.decode
+ protected def createCompanionName(h: Int): TermName
}
}
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 8afe276514..ea5565c581 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -8,18 +8,21 @@ package internal
import scala.collection.immutable
import NameTransformer.MODULE_SUFFIX_STRING
+import annotation.switch
-trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: SymbolTable =>
+trait StdNames extends NameManglers { self: SymbolTable =>
- def encode(str: String): TermName = newTermName(NameTransformer.encode(str))
+ def encode(str: String): TermName = newTermNameCached(NameTransformer.encode(str))
+
+ implicit def lowerTermNames(n: TermName): String = "" + n
- implicit def stringToTermName(s: String): TermName = newTermName(s)
+ // implicit def stringToTermName(s: String): TermName = newTermName(s)
/** This should be the first trait in the linearization. */
trait Keywords {
private var kws: Set[TermName] = Set()
private def kw(s: String): TermName = {
- val result = newTermName(s)
+ val result = newTermNameCached(s)
kws = kws + result
result
}
@@ -87,7 +90,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
trait CommonNames /*extends LibraryCommonNames*/ {
type NameType <: Name
- implicit def createNameType(name: String): NameType
+ protected implicit def createNameType(name: String): NameType
val EMPTY: NameType = ""
val ANON_FUN_NAME: NameType = "$anonfun"
@@ -146,6 +149,10 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
final val String: NameType = "String"
final val Throwable: NameType = "Throwable"
+ final val Annotation: NameType = "Annotation"
+ final val ClassfileAnnotation: NameType = "ClassfileAnnotation"
+ final val Enum: NameType = "Enum"
+
// Annotation simple names, used in Namer
final val BeanPropertyAnnot: NameType = "BeanProperty"
final val BooleanBeanPropertyAnnot: NameType = "BooleanBeanProperty"
@@ -172,123 +179,191 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
final val SyntheticATTR: NameType = "Synthetic"
}
-
trait TermNames extends Keywords with CommonNames {
// Compiler internal names
+ val EXPAND_SEPARATOR_STRING = "$$"
+
val ANYNAME: NameType = "<anyname>"
val CONSTRUCTOR: NameType = "<init>"
val FAKE_LOCAL_THIS: NameType = "this$"
val INITIALIZER: NameType = CONSTRUCTOR // Is this buying us something?
+ val LAZY_LOCAL: NameType = "$lzy"
+ val LOCAL_SUFFIX_STRING = " "
+ val MACRO: NameType = "macro$"
+ val MIRROR_PREFIX: NameType = "$mr."
+ val MIRROR_SHORT: NameType = "$mr"
val MIXIN_CONSTRUCTOR: NameType = "$init$"
val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
val OUTER: NameType = "$outer"
- val OUTER_LOCAL: NameType = "$outer " // note the space
+ val OUTER_LOCAL: NameType = OUTER + LOCAL_SUFFIX_STRING // "$outer ", note the space
val OUTER_SYNTH: NameType = "<outer>" // emitted by virtual pattern matcher, replaced by outer accessor in explicitouter
+ val SELECTOR_DUMMY: NameType = "<unapply-selector>"
val SELF: NameType = "$this"
val SPECIALIZED_INSTANCE: NameType = "specInstance$"
val STAR: NameType = "*"
val THIS: NameType = "_$this"
- val SELECTOR_DUMMY: NameType = "<unapply-selector>"
final val Nil: NameType = "Nil"
final val Predef: NameType = "Predef"
final val ScalaRunTime: NameType = "ScalaRunTime"
final val Some: NameType = "Some"
+
+ val _1 : NameType = "_1"
+ val _2 : NameType = "_2"
+ val _3 : NameType = "_3"
+ val _4 : NameType = "_4"
+ val _5 : NameType = "_5"
+ val _6 : NameType = "_6"
+ val _7 : NameType = "_7"
+ val _8 : NameType = "_8"
+ val _9 : NameType = "_9"
+ val _10 : NameType = "_10"
+ val _11 : NameType = "_11"
+ val _12 : NameType = "_12"
+ val _13 : NameType = "_13"
+ val _14 : NameType = "_14"
+ val _15 : NameType = "_15"
+ val _16 : NameType = "_16"
+ val _17 : NameType = "_17"
+ val _18 : NameType = "_18"
+ val _19 : NameType = "_19"
+ val _20 : NameType = "_20"
+ val _21 : NameType = "_21"
+ val _22 : NameType = "_22"
+
+ val wrapRefArray: NameType = "wrapRefArray"
+ val wrapByteArray: NameType = "wrapByteArray"
+ val wrapShortArray: NameType = "wrapShortArray"
+ val wrapCharArray: NameType = "wrapCharArray"
+ val wrapIntArray: NameType = "wrapIntArray"
+ val wrapLongArray: NameType = "wrapLongArray"
+ val wrapFloatArray: NameType = "wrapFloatArray"
+ val wrapDoubleArray: NameType = "wrapDoubleArray"
+ val wrapBooleanArray: NameType = "wrapBooleanArray"
+ val wrapUnitArray: NameType = "wrapUnitArray"
+ val genericWrapArray: NameType = "genericWrapArray"
// Compiler utilized names
// val productElementName: NameType = "productElementName"
- val TYPE_ : NameType = "TYPE"
- val add_ : NameType = "add"
- val anyValClass: NameType = "anyValClass"
- val append: NameType = "append"
- val apply: NameType = "apply"
- val arrayValue: NameType = "arrayValue"
- val arraycopy: NameType = "arraycopy"
- val asInstanceOf_ : NameType = "asInstanceOf"
- val assert_ : NameType = "assert"
- val assume_ : NameType = "assume"
- val box: NameType = "box"
- val bytes: NameType = "bytes"
- val canEqual_ : NameType = "canEqual"
- val checkInitialized: NameType = "checkInitialized"
- val classOf: NameType = "classOf"
- val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure
- val conforms: NameType = "conforms"
- val copy: NameType = "copy"
- val delayedInit: NameType = "delayedInit"
- val delayedInitArg: NameType = "delayedInit$body"
- val drop: NameType = "drop"
- val elem: NameType = "elem"
- val eq: NameType = "eq"
- val equals_ : NameType = if (forMSIL) "Equals" else "equals"
- val error: NameType = "error"
- val ex: NameType = "ex"
- val false_ : NameType = "false"
- val filter: NameType = "filter"
- val finalize_ : NameType = if (forMSIL) "Finalize" else "finalize"
- val find_ : NameType = "find"
- val flatMap: NameType = "flatMap"
- val foreach: NameType = "foreach"
- val formatted: NameType = "formatted"
- val genericArrayOps: NameType = "genericArrayOps"
- val get: NameType = "get"
- val hasNext: NameType = "hasNext"
- val hashCode_ : NameType = if (forMSIL) "GetHashCode" else "hashCode"
- val hash_ : NameType = "hash"
- val head: NameType = "head"
- val identity: NameType = "identity"
- val inlinedEquals: NameType = "inlinedEquals"
- val applyDynamic: NameType = "applyDynamic"
- val isArray: NameType = "isArray"
- val isDefinedAt: NameType = "isDefinedAt"
- val _isDefinedAt: NameType = "_isDefinedAt"
- val isEmpty: NameType = "isEmpty"
- val isInstanceOf_ : NameType = "isInstanceOf"
- val java: NameType = "java"
- val lang: NameType = "lang"
- val length: NameType = "length"
- val lengthCompare: NameType = "lengthCompare"
- val lift_ : NameType = "lift"
- val macro_ : NameType = "macro"
- val main: NameType = "main"
- val map: NameType = "map"
- val missingCase: NameType = "missingCase"
- val ne: NameType = "ne"
- val newArray: NameType = "newArray"
- val next: NameType = "next"
- val notifyAll_ : NameType = "notifyAll"
- val notify_ : NameType = "notify"
- val null_ : NameType = "null"
- val ofDim: NameType = "ofDim"
- val productArity: NameType = "productArity"
- val productElement: NameType = "productElement"
- val productIterator: NameType = "productIterator"
- val productPrefix: NameType = "productPrefix"
- val readResolve: NameType = "readResolve"
- val runOrElse: NameType = "runOrElse"
- val sameElements: NameType = "sameElements"
- val scala_ : NameType = "scala"
- val self: NameType = "self"
- val setAccessible: NameType = "setAccessible"
- val synchronized_ : NameType = "synchronized"
- val tail: NameType = "tail"
- val this_ : NameType = "this"
- val throw_ : NameType = "throw"
- val toArray: NameType = "toArray"
- val toList: NameType = "toList"
- val toSeq: NameType = "toSeq"
- val toString_ : NameType = if (forMSIL) "ToString" else "toString"
- val true_ : NameType = "true"
- val unapply: NameType = "unapply"
- val unapplySeq: NameType = "unapplySeq"
- val unbox: NameType = "unbox"
- val update: NameType = "update"
- val value: NameType = "value"
- val view_ : NameType = "view"
- val wait_ : NameType = "wait"
- val withFilter: NameType = "withFilter"
- val wrapRefArray: NameType = "wrapRefArray"
- val zip: NameType = "zip"
+ val Ident: NameType = "Ident"
+ val TYPE_ : NameType = "TYPE"
+ val TypeTree: NameType = "TypeTree"
+ val UNIT : NameType = "UNIT"
+ val _isDefinedAt: NameType = "_isDefinedAt"
+ val add_ : NameType = "add"
+ val annotation: NameType = "annotation"
+ val anyValClass: NameType = "anyValClass"
+ val append: NameType = "append"
+ val apply: NameType = "apply"
+ val applyDynamic: NameType = "applyDynamic"
+ val args : NameType = "args"
+ val argv : NameType = "argv"
+ val arrayValue: NameType = "arrayValue"
+ val array_apply : NameType = "array_apply"
+ val array_clone : NameType = "array_clone"
+ val array_length : NameType = "array_length"
+ val array_update : NameType = "array_update"
+ val arraycopy: NameType = "arraycopy"
+ val asInstanceOf_ : NameType = "asInstanceOf"
+ val asTypeConstructor: NameType = "asTypeConstructor"
+ val assert_ : NameType = "assert"
+ val assume_ : NameType = "assume"
+ val box: NameType = "box"
+ val bytes: NameType = "bytes"
+ val canEqual_ : NameType = "canEqual"
+ val checkInitialized: NameType = "checkInitialized"
+ val classOf: NameType = "classOf"
+ val clone_ : NameType = if (forMSIL) "MemberwiseClone" else "clone" // sn.OClone causes checkinit failure
+ val conforms: NameType = "conforms"
+ val copy: NameType = "copy"
+ val delayedInit: NameType = "delayedInit"
+ val delayedInitArg: NameType = "delayedInit$body"
+ val drop: NameType = "drop"
+ val elem: NameType = "elem"
+ val emptyValDef: NameType = "emptyValDef"
+ val ensureAccessible : NameType = "ensureAccessible"
+ val eq: NameType = "eq"
+ val equalsNumChar : NameType = "equalsNumChar"
+ val equalsNumNum : NameType = "equalsNumNum"
+ val equalsNumObject : NameType = "equalsNumObject"
+ val equals_ : NameType = if (forMSIL) "Equals" else "equals"
+ val error: NameType = "error"
+ val ex: NameType = "ex"
+ val false_ : NameType = "false"
+ val filter: NameType = "filter"
+ val finalize_ : NameType = if (forMSIL) "Finalize" else "finalize"
+ val find_ : NameType = "find"
+ val flatMap: NameType = "flatMap"
+ val foreach: NameType = "foreach"
+ val formatted: NameType = "formatted"
+ val freeValue : NameType = "freeValue"
+ val genericArrayOps: NameType = "genericArrayOps"
+ val get: NameType = "get"
+ val glob : NameType = "glob"
+ val hasNext: NameType = "hasNext"
+ val hashCode_ : NameType = if (forMSIL) "GetHashCode" else "hashCode"
+ val hash_ : NameType = "hash"
+ val head: NameType = "head"
+ val identity: NameType = "identity"
+ val inlinedEquals: NameType = "inlinedEquals"
+ val isArray: NameType = "isArray"
+ val isDefinedAt: NameType = "isDefinedAt"
+ val isEmpty: NameType = "isEmpty"
+ val isInstanceOf_ : NameType = "isInstanceOf"
+ val java: NameType = "java"
+ val lang: NameType = "lang"
+ val length: NameType = "length"
+ val lengthCompare: NameType = "lengthCompare"
+ val lift_ : NameType = "lift"
+ val macro_ : NameType = "macro"
+ val main: NameType = "main"
+ val map: NameType = "map"
+ val mirror : NameType = "mirror"
+ val missingCase: NameType = "missingCase"
+ val ne: NameType = "ne"
+ val newArray: NameType = "newArray"
+ val newScopeWith: NameType = "newScopeWith"
+ val next: NameType = "next"
+ val notifyAll_ : NameType = "notifyAll"
+ val notify_ : NameType = "notify"
+ val null_ : NameType = "null"
+ val ofDim: NameType = "ofDim"
+ val productArity: NameType = "productArity"
+ val productElement: NameType = "productElement"
+ val productIterator: NameType = "productIterator"
+ val productPrefix: NameType = "productPrefix"
+ val readResolve: NameType = "readResolve"
+ val runOrElse: NameType = "runOrElse"
+ val runtime: NameType = "runtime"
+ val sameElements: NameType = "sameElements"
+ val scala_ : NameType = "scala"
+ val self: NameType = "self"
+ val setAccessible: NameType = "setAccessible"
+ val setAnnotations: NameType = "setAnnotations"
+ val setTypeSig: NameType = "setTypeSig"
+ val synchronized_ : NameType = "synchronized"
+ val tail: NameType = "tail"
+ val thisModuleType: NameType = "thisModuleType"
+ val this_ : NameType = "this"
+ val throw_ : NameType = "throw"
+ val toArray: NameType = "toArray"
+ val toList: NameType = "toList"
+ val toObjectArray : NameType = "toObjectArray"
+ val toSeq: NameType = "toSeq"
+ val toString_ : NameType = if (forMSIL) "ToString" else "toString"
+ val true_ : NameType = "true"
+ val typedProductIterator: NameType = "typedProductIterator"
+ val unapply: NameType = "unapply"
+ val unapplySeq: NameType = "unapplySeq"
+ val unbox: NameType = "unbox"
+ val update: NameType = "update"
+ val value: NameType = "value"
+ val valueOf : NameType = "valueOf"
+ val values : NameType = "values"
+ val view_ : NameType = "view"
+ val wait_ : NameType = "wait"
+ val withFilter: NameType = "withFilter"
+ val zip: NameType = "zip"
// unencoded operators
object raw {
@@ -316,21 +391,53 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val toLong: NameType = "toLong"
val toFloat: NameType = "toFloat"
val toDouble: NameType = "toDouble"
+
+ // primitive operation methods for structual types mostly
+ // overlap with the above, but not for these two.
+ val toCharacter: NameType = "toCharacter"
+ val toInteger: NameType = "toInteger"
}
object tpnme extends TypeNames /*with LibraryTypeNames*/ with TypeNameMangling {
type NameType = TypeName
- implicit def createNameType(name: String): TypeName = newTypeName(name)
+ protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
val REFINE_CLASS_NAME: NameType = "<refinement>"
val ANON_CLASS_NAME: NameType = "$anon"
}
+
+ /** For fully qualified type names.
+ */
+ object fulltpnme extends TypeNames {
+ type NameType = TypeName
+ protected implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
+
+ val RuntimeNothing: NameType = "scala.runtime.Nothing$"
+ val RuntimeNull: NameType = "scala.runtime.Null$"
+ val JavaLangEnum: NameType = "java.lang.Enum"
+ }
+
+ /** Java binary names, like scala/runtime/Nothing$.
+ */
+ object binarynme {
+ def toBinary(name: Name) = name mapName (_.replace('.', '/'))
+
+ val RuntimeNothing = toBinary(fulltpnme.RuntimeNothing).toTypeName
+ val RuntimeNull = toBinary(fulltpnme.RuntimeNull).toTypeName
+ }
+
+ object fullnme extends TermNames {
+ type NameType = TermName
+ protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
+
+ val MirrorPackage: NameType = "scala.reflect.mirror"
+ }
val javanme = nme.javaKeywords
object nme extends TermNames /*with LibraryTermNames*/ with TermNameMangling {
type NameType = TermName
- def createNameType(name: String): TermName = newTermName(name)
+ protected implicit def createNameType(name: String): TermName = newTermNameCached(name)
/** Translate a String into a list of simple TypeNames and TermNames.
* In all segments before the last, type/term is determined by whether
@@ -363,7 +470,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
case -1 => if (name == "") scala.Nil else scala.List(mkName(name, assumeTerm))
// otherwise, we can tell based on whether '#' or '.' is the following char.
case idx =>
- val (simple, div, rest) = (name take idx, name charAt idx, name drop (idx + 1))
+ val (simple, div, rest) = (name take idx, name charAt idx, newTermName(name) drop (idx + 1))
mkName(simple, div == '.') :: segments(rest, assumeTerm)
}
}
@@ -380,26 +487,27 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
/** The expanded name of `name` relative to this class `base` with given `separator`
*/
def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName =
- newTermName(base.fullName('$') + separator + name)
+ newTermNameCached(base.fullName('$') + separator + name)
- def moduleVarName(name: TermName): TermName = newTermName("" + name + MODULE_VAR_SUFFIX)
-
- val EXPAND_SEPARATOR_STRING = "$$"
- val LOCAL_SUFFIX_STRING = " "
+ def moduleVarName(name: TermName): TermName =
+ newTermNameCached("" + name + MODULE_VAR_SUFFIX)
+
val ROOTPKG: TermName = "_root_"
/** Base strings from which synthetic names are derived. */
- val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$"
- val DEFAULT_GETTER_STRING = "$default$"
- val DO_WHILE_PREFIX = "doWhile$"
- val EQEQ_LOCAL_VAR = "eqEqTemp$"
- val EVIDENCE_PARAM_PREFIX = "evidence$"
- val EXCEPTION_RESULT_PREFIX = "exceptionResult"
- val INTERPRETER_IMPORT_WRAPPER = "$iw"
- val INTERPRETER_LINE_PREFIX = "line"
- val INTERPRETER_VAR_PREFIX = "res"
- val INTERPRETER_WRAPPER_SUFFIX = "$object"
- val WHILE_PREFIX = "while$"
+ val CHECK_IF_REFUTABLE_STRING = "check$ifrefutable$"
+ val DEFAULT_GETTER_STRING = "$default$"
+ val DO_WHILE_PREFIX = "doWhile$"
+ val EQEQ_LOCAL_VAR_STRING = "eqEqTemp$"
+ val EVIDENCE_PARAM_PREFIX = "evidence$"
+ val EXCEPTION_RESULT_PREFIX = "exceptionResult"
+ val INTERPRETER_IMPORT_WRAPPER = "$iw"
+ val INTERPRETER_LINE_PREFIX = "line"
+ val INTERPRETER_VAR_PREFIX = "res"
+ val INTERPRETER_WRAPPER_SUFFIX = "$object"
+ val WHILE_PREFIX = "while$"
+
+ val EQEQ_LOCAL_VAR: TermName = newTermName(EQEQ_LOCAL_VAR_STRING)
def getCause = sn.GetCause
def getClass_ = sn.GetClass
@@ -424,8 +532,8 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val MUL = encode("*")
val NE = encode("!=")
val OR = encode("|")
- val PLUS = encode("+")
- val SUB = encode("-")
+ val PLUS = ADD // technically redundant, but ADD looks funny with MINUS
+ val SUB = MINUS // ... as does SUB with PLUS
val XOR = encode("^")
val ZAND = encode("&&")
val ZOR = encode("||")
@@ -435,10 +543,138 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val UNARY_+ = encode("unary_+")
val UNARY_- = encode("unary_-")
val UNARY_! = encode("unary_!")
+
+ // Grouped here so Cleanup knows what tests to perform.
+ val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE)
+ val ConversionNames = Set[Name](toByte, toChar, toDouble, toFloat, toInt, toLong, toShort)
+ val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames
+ val NumberOpNames = (
+ Set[Name](ADD, SUB, MUL, DIV, MOD, LSL, LSR, ASR, LT, LE, GE, GT)
+ ++ Set(UNARY_+, UNARY_-, UNARY_!)
+ ++ ConversionNames
+ ++ CommonOpNames
+ )
+
+ val add: NameType = "add"
+ val complement: NameType = "complement"
+ val divide: NameType = "divide"
+ val multiply: NameType = "multiply"
+ val negate: NameType = "negate"
+ val positive: NameType = "positive"
+ val shiftLogicalRight: NameType = "shiftLogicalRight"
+ val shiftSignedLeft: NameType = "shiftSignedLeft"
+ val shiftSignedRight: NameType = "shiftSignedRight"
+ val subtract: NameType = "subtract"
+ val takeAnd: NameType = "takeAnd"
+ val takeConditionalAnd: NameType = "takeConditionalAnd"
+ val takeConditionalOr: NameType = "takeConditionalOr"
+ val takeModulo: NameType = "takeModulo"
+ val takeNot: NameType = "takeNot"
+ val takeOr: NameType = "takeOr"
+ val takeXor: NameType = "takeXor"
+ val testEqual: NameType = "testEqual"
+ val testGreaterOrEqualThan: NameType = "testGreaterOrEqualThan"
+ val testGreaterThan: NameType = "testGreaterThan"
+ val testLessOrEqualThan: NameType = "testLessOrEqualThan"
+ val testLessThan: NameType = "testLessThan"
+ val testNotEqual: NameType = "testNotEqual"
+
+ val isBoxedNumberOrBoolean: NameType = "isBoxedNumberOrBoolean"
+ val isBoxedNumber: NameType = "isBoxedNumber"
+
+ def toUnaryName(name: TermName): TermName = name match {
+ case raw.MINUS => UNARY_-
+ case raw.PLUS => UNARY_+
+ case raw.TILDE => UNARY_~
+ case raw.BANG => UNARY_!
+ case _ => name
+ }
+ /** The name of a method which stands in for a primitive operation
+ * during structural type dispatch.
+ */
+ def primitiveInfixMethodName(name: Name): TermName = name match {
+ case OR => takeOr
+ case XOR => takeXor
+ case AND => takeAnd
+ case EQ => testEqual
+ case NE => testNotEqual
+ case ADD => add
+ case SUB => subtract
+ case MUL => multiply
+ case DIV => divide
+ case MOD => takeModulo
+ case LSL => shiftSignedLeft
+ case LSR => shiftLogicalRight
+ case ASR => shiftSignedRight
+ case LT => testLessThan
+ case LE => testLessOrEqualThan
+ case GE => testGreaterOrEqualThan
+ case GT => testGreaterThan
+ case ZOR => takeConditionalOr
+ case ZAND => takeConditionalAnd
+ case _ => NO_NAME
+ }
+ /** Postfix/prefix, really.
+ */
+ def primitivePostfixMethodName(name: Name): TermName = name match {
+ case UNARY_! => takeNot
+ case UNARY_+ => positive
+ case UNARY_- => negate
+ case UNARY_~ => complement
+ case `toByte` => toByte
+ case `toShort` => toShort
+ case `toChar` => toCharacter
+ case `toInt` => toInteger
+ case `toLong` => toLong
+ case `toFloat` => toFloat
+ case `toDouble` => toDouble
+ case _ => NO_NAME
+ }
+
+ val reflPolyCacheName: NameType = "reflPoly$Cache"
+ val reflClassCacheName: NameType = "reflClass$Cache"
+ val reflParamsCacheName: NameType = "reflParams$Cache"
+ val reflMethodCacheName: NameType = "reflMethod$Cache"
+ val reflMethodName: NameType = "reflMethod$Method"
+
+ private val reflectionCacheNames = Set[NameType](
+ reflPolyCacheName,
+ reflClassCacheName,
+ reflParamsCacheName,
+ reflMethodCacheName,
+ reflMethodName
+ )
+ def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _)
+
+ @switch def productAccessorName(j: Int): TermName = j match {
+ case 1 => nme._1
+ case 2 => nme._2
+ case 3 => nme._3
+ case 4 => nme._4
+ case 5 => nme._5
+ case 6 => nme._6
+ case 7 => nme._7
+ case 8 => nme._8
+ case 9 => nme._9
+ case 10 => nme._10
+ case 11 => nme._11
+ case 12 => nme._12
+ case 13 => nme._13
+ case 14 => nme._14
+ case 15 => nme._15
+ case 16 => nme._16
+ case 17 => nme._17
+ case 18 => nme._18
+ case 19 => nme._19
+ case 20 => nme._20
+ case 21 => nme._21
+ case 22 => nme._22
+ case _ => newTermName("_" + j)
+ }
}
abstract class SymbolNames {
- protected implicit def stringToTypeName(s: String): TypeName = newTypeName(s)
+ protected implicit def createNameType(s: String): TypeName = newTypeNameCached(s)
val BeanProperty : TypeName
val BooleanBeanProperty : TypeName
@@ -471,7 +707,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
class JavaKeywords {
private var kws: Set[TermName] = Set()
private def kw(s: String): TermName = {
- val result = newTermName(s)
+ val result = newTermNameCached(s)
kws = kws + result
result
}
@@ -555,12 +791,12 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
final val Throwable: TypeName = "java.lang.Throwable"
final val ValueType: TypeName = tpnme.NO_NAME
- final val ForName: TermName = "forName"
- final val GetCause: TermName = "getCause"
- final val GetClass: TermName = "getClass"
- final val GetMethod: TermName = "getMethod"
- final val Invoke: TermName = "invoke"
- final val JavaLang: TermName = "java.lang"
+ final val ForName: TermName = newTermName("forName")
+ final val GetCause: TermName = newTermName("getCause")
+ final val GetClass: TermName = newTermName("getClass")
+ final val GetMethod: TermName = newTermName("getMethod")
+ final val Invoke: TermName = newTermName("invoke")
+ final val JavaLang: TermName = newTermName("java.lang")
val Boxed = immutable.Map[TypeName, TypeName](
tpnme.Boolean -> BoxedBoolean,
@@ -593,12 +829,12 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
final val Throwable: TypeName = "System.Exception"
final val ValueType: TypeName = "System.ValueType"
- final val ForName: TermName = "GetType"
- final val GetCause: TermName = "InnerException" /* System.Reflection.TargetInvocationException.InnerException */
- final val GetClass: TermName = "GetType"
- final val GetMethod: TermName = "GetMethod"
- final val Invoke: TermName = "Invoke"
- final val JavaLang: TermName = "System"
+ final val ForName: TermName = newTermName("GetType")
+ final val GetCause: TermName = newTermName("InnerException") /* System.Reflection.TargetInvocationException.InnerException */
+ final val GetClass: TermName = newTermName("GetType")
+ final val GetMethod: TermName = newTermName("GetMethod")
+ final val Invoke: TermName = newTermName("Invoke")
+ final val JavaLang: TermName = newTermName("System")
val Boxed = immutable.Map[TypeName, TypeName](
tpnme.Boolean -> "System.Boolean",
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 0c57f0c43a..6ee061392c 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -264,7 +264,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Create a new getter for current symbol (which must be a field)
*/
final def newGetter: Symbol = (
- owner.newMethod(focusPos(pos), nme.getterName(name))
+ owner.newMethod(focusPos(pos), nme.getterName(name.toTermName))
setFlag getterFlags(flags)
setPrivateWithin privateWithin
setInfo MethodType(Nil, tpe)
@@ -409,7 +409,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isError = hasFlag(IS_ERROR)
final def isErroneous = isError || isInitialized && tpe.isErroneous
final def isTypeParameterOrSkolem = isType && hasFlag(PARAM)
- final def isHigherOrderTypeParameter = owner.isTypeParameterOrSkolem
+ final def isHigherOrderTypeParameter = (this ne NoSymbol) && owner.isTypeParameterOrSkolem
final def isTypeSkolem = isSkolem && hasFlag(PARAM)
// a type symbol bound by an existential type, for instance the T in
// List[T] forSome { type T }
@@ -430,7 +430,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isDefinedInPackage = effectiveOwner.isPackageClass
final def isJavaInterface = isJavaDefined && isTrait
- final def needsFlatClasses: Boolean = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass
+ final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass
// In java.lang, Predef, or scala package/package object
def isInDefaultNamespace = UnqualifiedOwners(effectiveOwner)
@@ -699,16 +699,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
rawowner = owner
}
- private[Symbols] def flattenName(): Name = {
- // This assertion caused me no end of trouble in the interpeter in situations
- // where everything proceeds smoothly if there's no assert. I don't think calling "name"
- // on a symbol is the right place to throw fatal exceptions if things don't look right.
- // It really hampers exploration. Finally I gave up and disabled it, and tickets like
- // SI-4874 instantly start working.
- // assert(rawowner.isClass, "fatal: %s has non-class owner %s after flatten.".format(rawname + idString, rawowner))
-
- nme.flattenedName(rawowner.name, rawname)
- }
def ownerChain: List[Symbol] = this :: owner.ownerChain
def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain
@@ -793,7 +783,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* Never adds id.
* Drops package objects.
*/
- final def fullName(separator: Char): String = nme.dropLocalSuffix(fullNameInternal(separator)).toString
+ final def fullName(separator: Char): String = fullNameAsName(separator).toString
/** Doesn't drop package objects, for those situations (e.g. classloading)
* where the true path is needed.
@@ -801,8 +791,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private def fullNameInternal(separator: Char): Name = (
if (isRoot || isRootPackage || this == NoSymbol) name
else if (owner.isEffectiveRoot) name
- else effectiveOwner.enclClass.fullName(separator) append separator append name
+ else effectiveOwner.enclClass.fullNameAsName(separator) append separator append name
)
+
+ def fullNameAsName(separator: Char): Name = nme.dropLocalSuffix(fullNameInternal(separator))
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by periods.
@@ -1244,12 +1236,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def isNestedIn(that: Symbol): Boolean =
owner == that || owner != NoSymbol && (owner isNestedIn that)
-
- /** Is this class symbol a subclass of that symbol? */
- final def isNonBottomSubClass(that: Symbol): Boolean = (
- (this eq that) || this.isError || that.isError ||
- info.baseTypeIndex(that) >= 0
- )
+
+ /** Is this class symbol a subclass of that symbol,
+ * and is this class symbol also different from Null or Nothing? */
+ def isNonBottomSubClass(that: Symbol): Boolean = false
/** Overridden in NullClass and NothingClass for custom behavior.
*/
@@ -1371,7 +1361,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The symbol accessed by this accessor function, but with given owner type. */
final def accessed(ownerTp: Type): Symbol = {
assert(hasAccessorFlag, this)
- ownerTp decl nme.getterToLocal(getterName)
+ ownerTp decl nme.getterToLocal(getterName.toTermName)
}
/** The module corresponding to this module class (note that this
@@ -1704,17 +1694,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def getter(base: Symbol): Symbol = base.info.decl(getterName) filter (_.hasAccessorFlag)
- def getterName: Name = (
- if (isSetter) nme.setterToGetter(name)
- else if (nme.isLocalName(name)) nme.localToGetter(name)
- else name
+ def getterName: TermName = (
+ if (isSetter) nme.setterToGetter(name.toTermName)
+ else if (nme.isLocalName(name)) nme.localToGetter(name.toTermName)
+ else name.toTermName
)
/** The setter of this value or getter definition, or NoSymbol if none exists */
final def setter(base: Symbol): Symbol = setter(base, false)
final def setter(base: Symbol, hasExpandedName: Boolean): Symbol = {
- var sname = nme.getterToSetter(nme.getterName(name))
+ var sname = nme.getterToSetter(nme.getterName(name.toTermName))
if (hasExpandedName) sname = nme.expandedSetterName(sname, base)
base.info.decl(sname) filter (_.hasAccessorFlag)
}
@@ -1769,7 +1759,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
getter(owner).expandName(base)
setter(owner).expandName(base)
}
- name = nme.expandedName(name, base)
+ name = nme.expandedName(name.toTermName, base)
if (isType) name = name
}
}
@@ -2003,7 +1993,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
extends Symbol(initOwner, initPos, initName) {
final override def isTerm = true
- override def name: TermName = super.name
+ override def name: TermName = rawname.toTermName
privateWithin = NoSymbol
var referenced: Symbol = NoSymbol
@@ -2090,20 +2080,20 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
class ModuleSymbol(initOwner: Symbol, initPos: Position, initName: TermName)
extends TermSymbol(initOwner, initPos, initName) {
private var flatname: TermName = null
- // This method could use a better name from someone clearer on what the condition expresses.
- private def isFlatAdjusted = !isMethod && needsFlatClasses
- override def owner: Symbol =
- if (isFlatAdjusted) rawowner.owner
+ override def owner = (
+ if (!isMethod && needsFlatClasses) rawowner.owner
else rawowner
-
- override def name: TermName =
- if (isFlatAdjusted) {
- if (flatname == null)
- flatname = flattenName().toTermName
-
+ )
+ override def name: TermName = (
+ if (!isMethod && needsFlatClasses) {
+ if (flatname eq null)
+ flatname = nme.flattenedName(rawowner.name, rawname)
+
flatname
- } else rawname
+ }
+ else rawname.toTermName
+ )
override def cloneSymbolImpl(owner: Symbol): Symbol =
new ModuleSymbol(owner, pos, name).copyAttrsFrom(this)
@@ -2226,6 +2216,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
super.info_=(tp)
}
+ final override def isNonBottomSubClass(that: Symbol): Boolean = (
+ (this eq that) || this.isError || that.isError ||
+ info.baseTypeIndex(that) >= 0
+ )
+
override def reset(completer: Type) {
super.reset(completer)
tpePeriod = NoPeriod
@@ -2297,7 +2292,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A class for class symbols */
class ClassSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
extends TypeSymbol(initOwner, initPos, initName) {
-
+ private var flatname: TypeName = null
private var source: AbstractFileType = null
private var thissym: Symbol = this
@@ -2316,20 +2311,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
thissym = this
}
- private var flatname: TypeName = null
-
- override def owner: Symbol =
- if (needsFlatClasses) rawowner.owner
- else rawowner
-
- override def name: TypeName =
- if (needsFlatClasses) {
- if (flatname == null)
- flatname = flattenName().toTypeName
- flatname
- }
- else rawname.asInstanceOf[TypeName]
-
private var thisTypeCache: Type = _
private var thisTypePeriod = NoPeriod
@@ -2345,7 +2326,19 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
thisTypeCache
}
-
+
+ override def owner: Symbol =
+ if (needsFlatClasses) rawowner.owner else rawowner
+ override def name: TypeName = (
+ if (needsFlatClasses) {
+ if (flatname eq null)
+ flatname = nme.flattenedName(rawowner.name, rawname).toTypeName
+
+ flatname
+ }
+ else rawname.toTypeName
+ )
+
/** A symbol carrying the self type of the class as its type */
override def thisSym: Symbol = thissym
@@ -2416,7 +2409,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def sourceModule_=(module: Symbol) { this.module = module }
}
- class FreeVar(name: TermName, tpe: Type, val value: Any) extends TermSymbol(definitions.RootClass, NoPosition, name) {
+ class FreeVar(name0: TermName, tpe: Type, val value: Any) extends TermSymbol(definitions.RootClass, NoPosition, name0) {
setInfo(tpe)
override def hashCode = value.hashCode
@@ -2520,6 +2513,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
val syms1 = cloneSymbolsAtOwner(syms, owner)
creator(syms1, tpe.substSym(syms, syms1))
}
+
+ /** A deep map on a symbol's paramss.
+ */
+ def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f)
/** Create a new existential type skolem with the given owner and origin.
*/
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index 14bf36fb47..e3ee39d2a0 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -192,7 +192,7 @@ abstract class TreeInfo {
def isVariableOrGetter(tree: Tree) = {
def sym = tree.symbol
def isVar = sym.isVariable
- def isGetter = mayBeVarGetter(sym) && sym.owner.info.member(nme.getterToSetter(sym.name)) != NoSymbol
+ def isGetter = mayBeVarGetter(sym) && sym.owner.info.member(nme.getterToSetter(sym.name.toTermName)) != NoSymbol
tree match {
case Ident(_) => isVar
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 566ee0e9cf..96f2c5cc45 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -160,12 +160,12 @@ trait Trees extends api.Trees { self: SymbolTable =>
*/
def ModuleDef(sym: Symbol, impl: Template): ModuleDef =
atPos(sym.pos) {
- ModuleDef(Modifiers(sym.flags), sym.name, impl) setSymbol sym
+ ModuleDef(Modifiers(sym.flags), sym.name.toTermName, impl) setSymbol sym
}
def ValDef(sym: Symbol, rhs: Tree): ValDef =
atPos(sym.pos) {
- ValDef(Modifiers(sym.flags), sym.name,
+ ValDef(Modifiers(sym.flags), sym.name.toTermName,
TypeTree(sym.tpe) setPos focusPos(sym.pos),
rhs) setSymbol sym
}
@@ -182,7 +182,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
atPos(sym.pos) {
assert(sym != NoSymbol)
DefDef(Modifiers(sym.flags),
- sym.name,
+ sym.name.toTermName,
sym.typeParams map TypeDef,
vparamss,
TypeTree(sym.tpe.finalResultType) setPos focusPos(sym.pos),
@@ -193,7 +193,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
DefDef(sym, Modifiers(sym.flags), vparamss, rhs)
def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef =
- DefDef(sym, mods, sym.paramss map (_.map(ValDef)), rhs)
+ DefDef(sym, mods, mapParamss(sym)(ValDef), rhs)
def DefDef(sym: Symbol, rhs: Tree): DefDef =
DefDef(sym, Modifiers(sym.flags), rhs)
@@ -214,7 +214,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef =
atPos(sym.pos) {
- LabelDef(sym.name, params map Ident, rhs) setSymbol sym
+ LabelDef(sym.name.toTermName, params map Ident, rhs) setSymbol sym
}
@@ -248,10 +248,13 @@ trait Trees extends api.Trees { self: SymbolTable =>
/** Block factory that flattens directly nested blocks.
*/
- def Block(stats: Tree*): Block = stats match {
- case Seq(b @ Block(_, _)) => b
- case Seq(stat) => Block(stats.toList, Literal(Constant(())))
- case Seq(_, rest @ _*) => Block(stats.init.toList, stats.last)
+ def Block(stats: Tree*): Block = {
+ if (stats.isEmpty) Block(Nil, Literal(Constant(())))
+ else stats match {
+ case Seq(b @ Block(_, _)) => b
+ case Seq(stat) => Block(stats.toList, Literal(Constant(())))
+ case Seq(_, rest @ _*) => Block(stats.init.toList, stats.last)
+ }
}
// --- specific traversers and transformers
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index a644baf9f9..4630733db4 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -87,8 +87,13 @@ trait Types extends api.Types { self: SymbolTable =>
private final def decr(depth: Int) = if (depth == AnyDepth) AnyDepth else depth - 1
private final val printLubs = sys.props contains "scalac.debug.lub"
+ private final val traceTypeVars = sys.props contains "scalac.debug.tvar"
/** In case anyone wants to turn off lub verification without reverting anything. */
private final val verifyLubs = true
+ /** In case anyone wants to turn off type parameter bounds being used
+ * to seed type constraints.
+ */
+ private final val propagateParameterBoundsToTypeVars = sys.props contains "scalac.debug.prop-constraints"
protected val enableTypeVarExperimentals = settings.Xexperimental.value
@@ -499,6 +504,9 @@ trait Types extends api.Types { self: SymbolTable =>
* Alternatives of overloaded symbol appear in the order they are declared.
*/
def decl(name: Name): Symbol = findDecl(name, 0)
+
+ /** A list of all non-private members defined or declared in this type. */
+ def nonPrivateDecls: List[Symbol] = decls filter (x => !x.isPrivate) toList
/** The non-private defined or declared members with name `name` in this type;
* an OverloadedSymbol if several exist, NoSymbol if none exist.
@@ -537,6 +545,16 @@ trait Types extends api.Types { self: SymbolTable =>
*/
def nonPrivateMember(name: Name): Symbol =
memberBasedOnName(name, BridgeAndPrivateFlags)
+
+ /** All members with the given flags, excluding bridges.
+ */
+ def membersWithFlags(requiredFlags: Long): List[Symbol] =
+ membersBasedOnFlags(BridgeFlags, requiredFlags)
+
+ /** All non-private members with the given flags, excluding bridges.
+ */
+ def nonPrivateMembersWithFlags(requiredFlags: Long): List[Symbol] =
+ membersBasedOnFlags(BridgeAndPrivateFlags, requiredFlags)
/** The non-private member with given name, admitting members with given flags `admit`.
* "Admitting" refers to the fact that members with a PRIVATE, BRIDGE, or VBRIDGE
@@ -552,7 +570,10 @@ trait Types extends api.Types { self: SymbolTable =>
* an OverloadedSymbol if several exist, NoSymbol if none exist */
def nonLocalMember(name: Name): Symbol =
memberBasedOnName(name, BridgeFlags | LOCAL)
-
+
+ /** Members excluding and requiring the given flags.
+ * Note: unfortunately it doesn't work to exclude DEFERRED this way.
+ */
def membersBasedOnFlags(excludedFlags: Long, requiredFlags: Long): List[Symbol] =
findMember(nme.ANYNAME, excludedFlags, requiredFlags, false).alternatives
@@ -1017,7 +1038,6 @@ trait Types extends api.Types { self: SymbolTable =>
baseClasses.head.newOverloaded(this, members.toList)
}
}
-
/** The existential skolems and existentially quantified variables which are free in this type */
def existentialSkolems: List[Symbol] = {
var boundSyms: List[Symbol] = List()
@@ -1298,6 +1318,7 @@ trait Types extends api.Types { self: SymbolTable =>
case TypeBounds(_, _) => that <:< this
case _ => lo <:< that && that <:< hi
}
+ def isEmptyBounds = (lo.typeSymbolDirect eq NothingClass) && (hi.typeSymbolDirect eq AnyClass)
// override def isNullable: Boolean = NullClass.tpe <:< lo;
override def safeToString = ">: " + lo + " <: " + hi
override def kind = "TypeBoundsType"
@@ -2416,31 +2437,54 @@ A type's typeSymbol should never be inspected directly.
// but pattern-matching returned the original constr0 (a bug)
// now, pattern-matching returns the most recent constr
object TypeVar {
- // encapsulate suspension so we can automatically link the suspension of cloned
- // typevars to their original if this turns out to be necessary
-/*
- def Suspension = new Suspension
- class Suspension {
- private val suspended = mutable.HashSet[TypeVar]()
- def suspend(tv: TypeVar): Unit = {
- tv.suspended = true
- suspended += tv
- }
- def resumeAll(): Unit = {
- for (tv <- suspended) {
- tv.suspended = false
+ @inline final def trace[T](action: String, msg: => String)(value: T): T = {
+ if (traceTypeVars) {
+ val s = msg match {
+ case "" => ""
+ case str => "( " + str + " )"
}
- suspended.clear()
+ Console.err.println("[%10s] %-25s%s".format(action, value, s))
}
+ value
+ }
+
+ /** Create a new TypeConstraint based on the given symbol.
+ */
+ private def deriveConstraint(tparam: Symbol): TypeConstraint = {
+ /** Must force the type parameter's info at this point
+ * or things don't end well for higher-order type params.
+ * See SI-5359.
+ */
+ val bounds = tparam.info.bounds
+ /** We can seed the type constraint with the type parameter
+ * bounds as long as the types are concrete. This should lower
+ * the complexity of the search even if it doesn't improve
+ * any results.
+ */
+ if (propagateParameterBoundsToTypeVars) {
+ val exclude = bounds.isEmptyBounds || bounds.exists(_.typeSymbolDirect.isNonClassType)
+
+ if (exclude) new TypeConstraint
+ else TypeVar.trace("constraint", "For " + tparam.fullLocationString)(new TypeConstraint(bounds))
+ }
+ else new TypeConstraint
+ }
+ def unapply(tv: TypeVar): Some[(Type, TypeConstraint)] = Some((tv.origin, tv.constr))
+ def apply(origin: Type, constr: TypeConstraint): TypeVar = apply(origin, constr, Nil, Nil)
+ def apply(tparam: Symbol): TypeVar = apply(tparam.tpeHK, deriveConstraint(tparam), Nil, tparam.typeParams)
+
+ /** This is the only place TypeVars should be instantiated.
+ */
+ def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]): TypeVar = {
+ val tv = (
+ if (args.isEmpty && params.isEmpty) new TypeVar(origin, constr)
+ else if (args.size == params.size) new AppliedTypeVar(origin, constr, params zip args)
+ else if (args.isEmpty) new HKTypeVar(origin, constr, params)
+ else throw new TypeError("Invalid TypeVar construction: " + ((origin, constr, args, params)))
+ )
+
+ trace("create", "In " + tv.originLocation)(tv)
}
-*/
- def unapply(tv: TypeVar): Some[(Type, TypeConstraint)] = Some((tv.origin, tv.constr))
- def apply(origin: Type, constr: TypeConstraint) = new TypeVar(origin, constr, List(), List())
- // TODO why not initialise TypeConstraint with bounds of tparam?
- // @PP: I tried that, didn't work out so well for me.
- def apply(tparam: Symbol) = new TypeVar(tparam.tpeHK, new TypeConstraint, List(), tparam.typeParams)
- def apply(origin: Type, constr: TypeConstraint, args: List[Type], params: List[Symbol]) =
- new TypeVar(origin, constr, args, params)
}
// TODO: I don't really know why this happens -- maybe because
@@ -2467,23 +2511,53 @@ A type's typeSymbol should never be inspected directly.
tp.typeSymbol
)
+ /** Precondition: params.nonEmpty. (args.nonEmpty enforced structurally.)
+ */
+ class HKTypeVar(
+ _origin: Type,
+ _constr: TypeConstraint,
+ override val params: List[Symbol]
+ ) extends TypeVar(_origin, _constr) {
+
+ require(params.nonEmpty, this)
+ override def isHigherKinded = true
+ override protected def typeVarString = params.map(_.name).mkString("[", ", ", "]=>" + originName)
+ }
+
+ /** Precondition: zipped params/args nonEmpty. (Size equivalence enforced structurally.)
+ */
+ class AppliedTypeVar(
+ _origin: Type,
+ _constr: TypeConstraint,
+ zippedArgs: List[(Symbol, Type)]
+ ) extends TypeVar(_origin, _constr) {
+
+ require(zippedArgs.nonEmpty, this)
+
+ override def params: List[Symbol] = zippedArgs map (_._1)
+ override def typeArgs: List[Type] = zippedArgs map (_._2)
+
+ override protected def typeVarString = (
+ zippedArgs map { case (p, a) => p.name + "=" + a } mkString (origin + "[", ", ", "]")
+ )
+ }
+
/** A class representing a type variable: not used after phase `typer`.
*
* A higher-kinded TypeVar has params (Symbols) and typeArgs (Types).
* A TypeVar with nonEmpty typeArgs can only be instantiated by a higher-kinded
* type that can be applied to those args. A TypeVar is much like a TypeRef,
* except it has special logic for equality and subtyping.
+ *
+ * Precondition for this class, enforced structurally: args.isEmpty && params.isEmpty.
*/
class TypeVar(
val origin: Type,
- val constr0: TypeConstraint,
- override val typeArgs: List[Type],
- override val params: List[Symbol]
+ val constr0: TypeConstraint
) extends Type {
- private val numArgs = typeArgs.length
- // params are needed to keep track of variance (see mapOverArgs in SubstMap)
- assert(typeArgs.isEmpty || sameLength(typeArgs, params))
- // var tid = { tidCount += 1; tidCount } //DEBUG
+ override def params: List[Symbol] = Nil
+ override def typeArgs: List[Type] = Nil
+ override def isHigherKinded = false
/** The constraint associated with the variable */
var constr = constr0
@@ -2491,7 +2565,38 @@ A type's typeSymbol should never be inspected directly.
/** The variable's skolemization level */
val level = skolemizationLevel
-
+
+ /** Two occurrences of a higher-kinded typevar, e.g. `?CC[Int]` and `?CC[String]`, correspond to
+ * ''two instances'' of `TypeVar` that share the ''same'' `TypeConstraint`.
+ *
+ * `constr` for `?CC` only tracks type constructors anyway,
+ * so when `?CC[Int] <:< List[Int]` and `?CC[String] <:< Iterable[String]`
+ * `?CC's` hibounds contains List and Iterable.
+ */
+ def applyArgs(newArgs: List[Type]): TypeVar = (
+ if (newArgs.isEmpty && typeArgs.isEmpty)
+ this
+ else if (newArgs.size == params.size) {
+ val tv = TypeVar(origin, constr, newArgs, params)
+ TypeVar.trace("applyArgs", "In " + originLocation + ", apply args " + newArgs.mkString(", ") + " to " + originName)(tv)
+ }
+ else
+ throw new TypeError("Invalid type application in TypeVar: " + params + ", " + newArgs)
+ )
+ // newArgs.length may differ from args.length (could've been empty before)
+ //
+ // !!! @PP - I need an example of this, since this exception never triggers
+ // even though I am requiring the size match.
+ //
+ // example: when making new typevars, you start out with C[A], then you replace C by ?C, which should yield ?C[A], then A by ?A, ?C[?A]
+ // we need to track a TypeVar's arguments, and map over them (see TypeMap::mapOver)
+ // TypeVars get applied to different arguments over time (in asSeenFrom)
+ // -- see pos/tcpoly_infer_implicit_tuplewrapper.scala
+ // thus: make new TypeVar's for every application of a TV to args,
+ // inference may generate several TypeVar's for a single type parameter that must be inferred,
+ // only one of them is in the set of tvars that need to be solved, but
+ // they share the same TypeConstraint instance
+
// When comparing to types containing skolems, remember the highest level
// of skolemization. If that highest level is higher than our initial
// skolemizationLevel, we can't re-use those skolems as the solution of this
@@ -2502,26 +2607,6 @@ A type's typeSymbol should never be inspected directly.
private var encounteredHigherLevel = false
private def shouldRepackType = enableTypeVarExperimentals && encounteredHigherLevel
- /** Two occurrences of a higher-kinded typevar, e.g. `?CC[Int]` and `?CC[String]`, correspond to
- * ''two instances'' of `TypeVar` that share the ''same'' `TypeConstraint`.
- *
- * `constr` for `?CC` only tracks type constructors anyway,
- * so when `?CC[Int] <:< List[Int]` and `?CC[String] <:< Iterable[String]`
- * `?CC's` hibounds contains List and Iterable.
- */
- def applyArgs(newArgs: List[Type]): TypeVar =
- if (newArgs.isEmpty) this // SubstMap relies on this (though this check is redundant when called from appliedType...)
- else TypeVar(origin, constr, newArgs, params) // @M TODO: interaction with undoLog??
- // newArgs.length may differ from args.length (could've been empty before)
- // example: when making new typevars, you start out with C[A], then you replace C by ?C, which should yield ?C[A], then A by ?A, ?C[?A]
- // we need to track a TypeVar's arguments, and map over them (see TypeMap::mapOver)
- // TypeVars get applied to different arguments over time (in asSeenFrom)
- // -- see pos/tcpoly_infer_implicit_tuplewrapper.scala
- // thus: make new TypeVar's for every application of a TV to args,
- // inference may generate several TypeVar's for a single type parameter that must be inferred,
- // only one of them is in the set of tvars that need to be solved, but
- // they share the same TypeConstraint instance
-
// <region name="constraint mutators + undoLog">
// invariant: before mutating constr, save old state in undoLog
// (undoLog is used to reset constraints to avoid piling up unrelated ones)
@@ -2530,7 +2615,8 @@ A type's typeSymbol should never be inspected directly.
undoLog record this
// if we were compared against later typeskolems, repack the existential,
// because skolems are only compatible if they were created at the same level
- constr.inst = if (shouldRepackType) repackExistential(tp) else tp
+ val res = if (shouldRepackType) repackExistential(tp) else tp
+ constr.inst = TypeVar.trace("setInst", "In " + originLocation + ", " + originName + "=" + res)(res)
}
def addLoBound(tp: Type, isNumericBound: Boolean = false) {
@@ -2607,11 +2693,10 @@ A type's typeSymbol should never be inspected directly.
* type parameter we're trying to infer (the result will be sanity-checked later).
*/
def unifyFull(tpe: Type) = {
- // Since the alias/widen variations are often no-ops, this
- // keenly collects them in a Set to avoid redundant tests.
+ // The alias/widen variations are often no-ops.
val tpes = (
- if (isLowerBound) Set(tpe, tpe.widen, tpe.dealias, tpe.widen.dealias)
- else Set(tpe)
+ if (isLowerBound) List(tpe, tpe.widen, tpe.dealias, tpe.widen.dealias).distinct
+ else List(tpe)
)
tpes exists { tp =>
val lhs = if (isLowerBound) tp.typeArgs else typeArgs
@@ -2711,32 +2796,56 @@ A type's typeSymbol should never be inspected directly.
|| !containsSkolemAboveLevel(tp) // side-effects tracking boolean
|| enableTypeVarExperimentals // -Xexperimental: always say we're relatable, track consequences
)
- override val isHigherKinded = typeArgs.isEmpty && params.nonEmpty
- override def normalize: Type =
+ override def normalize: Type = (
if (constr.instValid) constr.inst
// get here when checking higher-order subtyping of the typevar by itself
// TODO: check whether this ever happens?
else if (isHigherKinded) typeFun(params, applyArgs(params map (_.typeConstructor)))
else super.normalize
-
+ )
override def typeSymbol = origin.typeSymbol
override def isStable = origin.isStable
override def isVolatile = origin.isVolatile
- private def levelString = if (settings.explaintypes.value) level else ""
- override def safeToString = constr.inst match {
- case null => "<null " + origin + ">"
- case NoType => "?" + levelString + origin + typeArgsString(this)
- case x => "" + x
+ private def tparamsOfSym(sym: Symbol) = sym.info match {
+ case PolyType(tparams, _) if tparams.nonEmpty =>
+ tparams map (_.defString) mkString("[", ",", "]")
+ case _ => ""
+ }
+ def originName = {
+ val name = origin.typeSymbolDirect.decodedName
+ if (name contains "_$") origin.typeSymbolDirect.decodedName else name
}
+ def originLocation = {
+ val sym = origin.typeSymbolDirect
+ val encl = sym.owner.logicallyEnclosingMember
+
+ // This should display somewhere between one and three
+ // things which enclose the origin: at most, a class, a
+ // a method, and a term. At least, a class.
+ List(
+ Some(encl.enclClass),
+ if (encl.isMethod) Some(encl) else None,
+ if (sym.owner.isTerm && (sym.owner != encl)) Some(sym.owner) else None
+ ).flatten map (s => s.decodedName + tparamsOfSym(s)) mkString "#"
+ }
+ private def levelString = if (settings.explaintypes.value) level else ""
+ protected def typeVarString = originName
+ override def safeToString = (
+ if ((constr eq null) || (constr.inst eq null)) "TVar<" + originName + "=null>"
+ else if (constr.inst ne NoType) "" + constr.inst
+ else "?" + levelString + originName
+ )
override def kind = "TypeVar"
def cloneInternal = {
// cloning a suspended type variable when it's suspended will cause the clone
// to never be resumed with the current implementation
- assert(!suspended)
- TypeVar(origin, constr cloneInternal, typeArgs, params) // @M TODO: clone args/params?
+ assert(!suspended, this)
+ TypeVar.trace("clone", originLocation)(
+ TypeVar(origin, constr cloneInternal, typeArgs, params) // @M TODO: clone args/params?
+ )
}
}
@@ -2993,6 +3102,9 @@ A type's typeSymbol should never be inspected directly.
/** A creator for intersection type where intersections of a single type are
* replaced by the type itself, and repeated parent classes are merged.
+ *
+ * !!! Repeated parent classes are not merged - is this a bug in the
+ * comment or in the code?
*/
def intersectionType(tps: List[Type], owner: Symbol): Type = tps match {
case List(tp) =>
@@ -3187,7 +3299,7 @@ A type's typeSymbol should never be inspected directly.
val isType = pnames.head.isTypeName
val newParams = for (name <- pnames) yield
if (isType) owner.newTypeParameter(NoPosition, name.toTypeName)
- else owner.newValueParameter(NoPosition, name)
+ else owner.newValueParameter(NoPosition, name.toTermName)
paramStack = newParams :: paramStack
try {
(newParams, ptypes).zipped foreach ((p, t) => p setInfo this(t))
@@ -3230,10 +3342,15 @@ A type's typeSymbol should never be inspected directly.
*/
class TypeConstraint(lo0: List[Type], hi0: List[Type], numlo0: Type, numhi0: Type, avoidWidening0: Boolean = false) {
def this(lo0: List[Type], hi0: List[Type]) = this(lo0, hi0, NoType, NoType)
+ def this(bounds: TypeBounds) = this(List(bounds.lo), List(bounds.hi))
def this() = this(List(), List())
- private var lobounds = lo0
- private var hibounds = hi0
+ /** Guard these lists against AnyClass and NothingClass appearing,
+ * else loBounds.isEmpty will have different results for an empty
+ * constraint and one with Nothing as a lower bound.
+ */
+ private var lobounds = lo0 filterNot (_.typeSymbolDirect eq NothingClass)
+ private var hibounds = hi0 filterNot (_.typeSymbolDirect eq AnyClass)
private var numlo = numlo0
private var numhi = numhi0
private var avoidWidening = avoidWidening0
@@ -3249,7 +3366,8 @@ A type's typeSymbol should never be inspected directly.
else if (!isNumericSubType(tp, numlo))
numlo = numericLoBound
}
- else lobounds ::= tp
+ else if (tp.typeSymbolDirect ne NothingClass)
+ lobounds ::= tp
}
def checkWidening(tp: Type) {
@@ -3268,7 +3386,8 @@ A type's typeSymbol should never be inspected directly.
else if (!isNumericSubType(numhi, tp))
numhi = numericHiBound
}
- else hibounds ::= tp
+ else if (tp.typeSymbolDirect ne AnyClass)
+ hibounds ::= tp
}
def isWithinBounds(tp: Type): Boolean =
@@ -3287,10 +3406,18 @@ A type's typeSymbol should never be inspected directly.
tc
}
- override def toString =
- (loBounds map (_.safeToString)).mkString("[ _>:(", ",", ") ") +
- (hiBounds map (_.safeToString)).mkString("| _<:(", ",", ") ] _= ") +
- inst.safeToString
+ override def toString = {
+ val boundsStr = (
+ if (loBounds.isEmpty && hiBounds.isEmpty) "[]"
+ else {
+ val lostr = if (loBounds.isEmpty) "" else loBounds map (_.safeToString) mkString("_>:(", ", ", ")")
+ val histr = if (hiBounds.isEmpty) "" else hiBounds map (_.safeToString) mkString("_<:(", ", ", ")")
+ List(lostr, histr) filterNot (_ == "") mkString ("[", " | ", "]")
+ }
+ )
+ if (inst eq NoType) boundsStr
+ else boundsStr + " _= " + inst.safeToString
+ }
}
trait AnnotationFilter extends TypeMap {
@@ -4141,7 +4268,7 @@ A type's typeSymbol should never be inspected directly.
case WildcardType =>
TypeVar(tp, new TypeConstraint)
case BoundedWildcardType(bounds) =>
- TypeVar(tp, new TypeConstraint(List(bounds.lo), List(bounds.hi)))
+ TypeVar(tp, new TypeConstraint(bounds))
case _ =>
mapOver(tp)
}
@@ -5455,6 +5582,23 @@ A type's typeSymbol should never be inspected directly.
val formatted = tableDef.table(transposed)
println("** Depth is " + depth + "\n" + formatted)
}
+
+ /** From a list of types, find any which take type parameters
+ * where the type parameter bounds contain references to other
+ * any types in the list (including itself.)
+ *
+ * @return List of symbol pairs holding the recursive type
+ * parameter and the parameter which references it.
+ */
+ def findRecursiveBounds(ts: List[Type]): List[(Symbol, Symbol)] = {
+ if (ts.isEmpty) Nil
+ else {
+ val sym = ts.head.typeSymbol
+ require(ts.tail forall (_.typeSymbol == sym), ts)
+ for (p <- sym.typeParams ; in <- sym.typeParams ; if in.info.bounds contains p) yield
+ p -> in
+ }
+ }
/** Given a matrix `tsBts` whose columns are basetype sequences (and the symbols `tsParams` that should be interpreted as type parameters in this matrix),
* compute its least sorted upwards closed upper bound relative to the following ordering <= between lists of types:
@@ -5501,6 +5645,19 @@ A type's typeSymbol should never be inspected directly.
// merging, strip targs that refer to bound tparams (when we're computing the lub of type
// constructors.) Also filter out all types that are a subtype of some other type.
if (isUniformFrontier) {
+ if (settings.debug.value || printLubs) {
+ val fbounds = findRecursiveBounds(ts0)
+ if (fbounds.nonEmpty) {
+ println("Encountered " + fbounds.size + " recursive bounds while lubbing " + ts0.size + " types.")
+ for ((p0, p1) <- fbounds) {
+ val desc = if (p0 == p1) "its own bounds" else "the bounds of " + p1
+
+ println(" " + p0.fullLocationString + " appears in " + desc)
+ println(" " + p1 + " " + p1.info.bounds)
+ }
+ println("")
+ }
+ }
val tails = tsBts map (_.tail)
mergePrefixAndArgs(elimSub(ts0 map elimHigherOrderTypeParam, depth), 1, depth) match {
case Some(tp) => tp :: loop(tails)
@@ -5526,7 +5683,7 @@ A type's typeSymbol should never be inspected directly.
}
}
- val initialBTSes = ts map (_.baseTypeSeq.toList)
+ val initialBTSes = ts map (_.baseTypeSeq.toList filter (_.typeSymbol.isPublic))
if (printLubs)
printLubMatrix(ts zip initialBTSes toMap, depth)
@@ -5719,9 +5876,16 @@ A type's typeSymbol should never be inspected directly.
val lubType =
if (phase.erasedTypes || depth == 0) lubBase
else {
- val lubRefined = refinedType(lubParents, lubOwner)
+ val lubRefined = refinedType(lubParents, lubOwner)
val lubThisType = lubRefined.typeSymbol.thisType
- val narrowts = ts map (_.narrow)
+ val narrowts = ts map (_.narrow)
+ def excludeFromLub(sym: Symbol) = (
+ sym.isClass
+ || sym.isConstructor
+ || !sym.isPublic
+ || isGetClass(sym)
+ || narrowts.exists(t => !refines(t, sym))
+ )
def lubsym(proto: Symbol): Symbol = {
val prototp = lubThisType.memberInfo(proto)
val syms = narrowts map (t =>
@@ -5750,16 +5914,15 @@ A type's typeSymbol should never be inspected directly.
// efficiency.
alt != sym && !specializesSym(lubThisType, sym, tp, alt)))
}
- for (sym <- lubBase.nonPrivateMembers) {
- // add a refinement symbol for all non-class members of lubBase
- // which are refined by every type in ts.
- if (!sym.isClass && !sym.isConstructor && !isGetClass(sym) && (narrowts forall (t => refines(t, sym))))
- try {
- val lsym = lubsym(sym)
- if (lsym != NoSymbol) addMember(lubThisType, lubRefined, lubsym(sym))
- } catch {
- case ex: NoCommonType =>
- }
+ // add a refinement symbol for all non-class members of lubBase
+ // which are refined by every type in ts.
+ for (sym <- lubBase.nonPrivateMembers ; if !excludeFromLub(sym)) {
+ try {
+ val lsym = lubsym(sym)
+ if (lsym != NoSymbol) addMember(lubThisType, lubRefined, lsym)
+ } catch {
+ case ex: NoCommonType =>
+ }
}
if (lubRefined.decls.isEmpty) lubBase
else if (!verifyLubs) lubRefined
@@ -5977,7 +6140,7 @@ A type's typeSymbol should never be inspected directly.
// conforming to bounds.
val bounds0 = sym.typeParams map (_.info.bounds.hi) filterNot (_.typeSymbol == AnyClass)
if (bounds0.isEmpty) AnyClass.tpe
- else intersectionType(bounds0)
+ else intersectionType(bounds0 map (b => b.asSeenFrom(tps.head, sym)))
}
else if (tparam.variance == -variance) NothingClass.tpe
else NoType
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index 9927560c8c..0789f9c774 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -184,6 +184,8 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
case _ => errorBadSignature("bad name tag: " + tag)
}
}
+ protected def readTermName(): TermName = readName().toTermName
+ protected def readTypeName(): TypeName = readName().toTypeName
/** Read a symbol */
protected def readSymbol(): Symbol = {
@@ -211,7 +213,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
return NoSymbol
if (tag == EXTMODCLASSref) {
- val moduleVar = owner.info.decl(nme.moduleVarName(name))
+ val moduleVar = owner.info.decl(nme.moduleVarName(name.toTermName))
if (moduleVar.isLazyAccessor)
return moduleVar.lazyAccessor.lazyAccessor
}
@@ -223,7 +225,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
// (2) Try with expanded name. Can happen if references to private
// symbols are read from outside: for instance when checking the children
// of a class. See #1722.
- fromName(nme.expandedName(name, owner)) orElse {
+ fromName(nme.expandedName(name.toTermName, owner)) orElse {
// (3) Try as a nested object symbol.
nestedObjectSymbol orElse {
// (4) Otherwise, fail.
@@ -296,14 +298,14 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
val clazz = at(inforef, () => readType()).typeSymbol // after the NMT_TRANSITION period, we can leave off the () => ... ()
if (isModuleRoot) moduleRoot
else {
- val m = owner.newModule(name, clazz)
+ val m = owner.newModule(name.toTermName, clazz)
clazz.sourceModule = m
m
}
case VALsym =>
if (isModuleRoot) { assert(false); NoSymbol }
- else if (isMethodFlag) owner.newMethod(name)
- else owner.newValue(name)
+ else if (isMethodFlag) owner.newMethod(name.toTermName)
+ else owner.newValue(name.toTermName)
case _ =>
errorBadSignature("bad symbol tag: " + tag)
@@ -549,13 +551,13 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
case MODULEtree =>
setSymModsName()
- ModuleDef(mods, name, readTemplateRef())
+ ModuleDef(mods, name.toTermName, readTemplateRef())
case VALDEFtree =>
setSymModsName()
val tpt = readTreeRef()
val rhs = readTreeRef()
- ValDef(mods, name, tpt, rhs)
+ ValDef(mods, name.toTermName, tpt, rhs)
case DEFDEFtree =>
setSymModsName()
@@ -563,7 +565,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
val vparamss = times(readNat(), () => times(readNat(), readValDefRef))
val tpt = readTreeRef()
val rhs = readTreeRef()
- DefDef(mods, name, tparams, vparamss, tpt, rhs)
+ DefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs)
case TYPEDEFtree =>
setSymModsName()
@@ -575,7 +577,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
setSymName()
val rhs = readTreeRef()
val params = until(end, readIdentRef)
- LabelDef(name, params, rhs)
+ LabelDef(name.toTermName, params, rhs)
case IMPORTtree =>
setSym()
diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala
index 28a17c7821..94672097c4 100644
--- a/src/compiler/scala/reflect/internal/util/Collections.scala
+++ b/src/compiler/scala/reflect/internal/util/Collections.scala
@@ -21,6 +21,23 @@ trait Collections {
else !xs2.isEmpty && !xs3.isEmpty && f(xs1.head, xs2.head, xs3.head) && corresponds3(xs1.tail, xs2.tail, xs3.tail)(f)
)
+ /** All these mm methods are "deep map" style methods for
+ * mapping etc. on a list of lists.
+ */
+ final def mexists[A](xss: List[List[A]])(p: A => Boolean) =
+ xss exists (_ exists p)
+ final def mmap[A, B](xss: List[List[A]])(f: A => B) =
+ xss map (_ map f)
+ final def mforeach[A](xss: List[List[A]])(f: A => Unit) =
+ xss foreach (_ foreach f)
+ final def mfind[A](xss: List[List[A]])(p: A => Boolean): Option[A] = {
+ for (xs <- xss; x <- xs)
+ if (p(x)) return Some(x)
+ None
+ }
+ final def mfilter[A](xss: List[List[A]])(p: A => Boolean) =
+ for (xs <- xss; x <- xs; if p(x)) yield x
+
final def map2[A, B, C](xs1: List[A], xs2: List[B])(f: (A, B) => C): List[C] = {
val lb = new ListBuffer[C]
var ys1 = xs1
@@ -136,3 +153,6 @@ trait Collections {
true
}
}
+
+object Collections extends Collections { }
+
diff --git a/src/compiler/scala/tools/nsc/util/Origins.scala b/src/compiler/scala/reflect/internal/util/Origins.scala
index f8ba34ae3c..b9985c8f50 100644
--- a/src/compiler/scala/tools/nsc/util/Origins.scala
+++ b/src/compiler/scala/reflect/internal/util/Origins.scala
@@ -3,10 +3,12 @@
* @author Paul Phillips
*/
-package scala.tools.nsc
-package util
+package scala.reflect
+package internal.util
-import scala.reflect.NameTransformer._
+import NameTransformer._
+import scala.collection.{ mutable, immutable }
+import Origins._
/** A debugging class for logging from whence a method is being called.
* Say you wanted to discover who was calling phase_= in SymbolTable.
@@ -33,10 +35,6 @@ import scala.reflect.NameTransformer._
}}}
*
*/
-
-import scala.collection.{ mutable, immutable }
-import Origins._
-
abstract class Origins {
type Rep
def newRep(xs: StackSlice): Rep
@@ -94,7 +92,9 @@ object Origins {
def apply(tag: String, clazz: Class[_]): Origins = apply(tag, new OneLine(clazz))
def apply(tag: String, orElse: => Origins): Origins = {
counters find (_.tag == tag) getOrElse {
- returning(orElse setTag tag)(counters += _)
+ val res = orElse setTag tag
+ counters += res
+ res
}
}
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index aa0572aceb..9da75bf2b0 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -272,7 +272,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
*/
private def approximateMatch(sym: Symbol, jstr: String): Boolean =
(sym.name.toString == jstr) ||
- sym.isPrivate && nme.expandedName(sym.name, sym.owner).toString == jstr
+ sym.isPrivate && nme.expandedName(sym.name.toTermName, sym.owner).toString == jstr
/**
* Find declarations or definition in class `clazz` that maps to a Java
@@ -353,32 +353,28 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
* not available, wrapped from the Java reflection info.
*/
def classToScala(jclazz: jClass[_]): Symbol = classCache.toScala(jclazz) {
- if (jclazz.isMemberClass && !nme.isImplClassName(jclazz.getName)) {
- val sym = sOwner(jclazz).info.decl(newTypeName(jclazz.getSimpleName))
+ val jname = javaTypeName(jclazz)
+ def lookup = sOwner(jclazz).info.decl(newTypeName(jclazz.getSimpleName))
+
+ if (jclazz.isMemberClass && !nme.isImplClassName(jname)) {
+ val sym = lookup
assert(sym.isType, sym+"/"+jclazz+"/"+sOwner(jclazz)+"/"+jclazz.getSimpleName)
sym.asInstanceOf[ClassSymbol]
- } else if (jclazz.isLocalClass || invalidClassName(jclazz.getName)) {
+ }
+ else if (jclazz.isLocalClass || invalidClassName(jname)) {
// local classes and implementation classes not preserved by unpickling - treat as Java
jclassAsScala(jclazz)
- } else if (jclazz.isArray) {
+ }
+ else if (jclazz.isArray) {
ArrayClass
- } else jclazz match {
- case java.lang.Void.TYPE => UnitClass
- case java.lang.Byte.TYPE => ByteClass
- case java.lang.Character.TYPE => CharClass
- case java.lang.Short.TYPE => ShortClass
- case java.lang.Integer.TYPE => IntClass
- case java.lang.Long.TYPE => LongClass
- case java.lang.Float.TYPE => FloatClass
- case java.lang.Double.TYPE => DoubleClass
- case java.lang.Boolean.TYPE => BooleanClass
- case _ =>
- // jclazz is top-level - get signature
- sOwner(jclazz).info decl newTypeName(jclazz.getSimpleName)
-// val (clazz, module) = createClassModule(
-// sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _))
-// classCache enter (jclazz, clazz)
-// clazz
+ }
+ else javaTypeToValueClass(jclazz) orElse {
+ // jclazz is top-level - get signature
+ lookup
+ // val (clazz, module) = createClassModule(
+ // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _))
+ // classCache enter (jclazz, clazz)
+ // clazz
}
}
diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
index b1e4d6224c..405a00de8d 100644
--- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala
+++ b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
@@ -29,17 +29,7 @@ trait ScalaToJava extends ConversionUtil { self: SymbolTable =>
def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found")
//println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug
if (clazz.isValueClass)
- clazz match {
- case UnitClass => java.lang.Void.TYPE
- case ByteClass => java.lang.Byte.TYPE
- case CharClass => java.lang.Character.TYPE
- case ShortClass => java.lang.Short.TYPE
- case IntClass => java.lang.Integer.TYPE
- case LongClass => java.lang.Long.TYPE
- case FloatClass => java.lang.Float.TYPE
- case DoubleClass => java.lang.Double.TYPE
- case BooleanClass => java.lang.Boolean.TYPE
- }
+ valueClassToJavaType(clazz)
else if (clazz == ArrayClass)
noClass
else if (clazz.owner.isPackageClass)
@@ -54,7 +44,7 @@ trait ScalaToJava extends ConversionUtil { self: SymbolTable =>
}
private def expandedName(sym: Symbol): String =
- if (sym.isPrivate) nme.expandedName(sym.name, sym.owner).toString
+ if (sym.isPrivate) nme.expandedName(sym.name.toTermName, sym.owner).toString
else sym.name.toString
def fieldToJava(fld: Symbol): jField = fieldCache.toJava(fld) {
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index 9f44e2047a..231bcdbc0e 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -33,7 +33,7 @@ trait ToolBoxes extends { self: Universe =>
private def nextWrapperModuleName() = {
wrapCount += 1
- "__wrapper$" + wrapCount
+ newTermName("__wrapper$" + wrapCount)
}
private def moduleFileName(className: String) = className + "$"
@@ -57,8 +57,8 @@ trait ToolBoxes extends { self: Universe =>
val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), new Scope, obj.moduleClass)
obj.moduleClass setInfo minfo
obj setInfo obj.moduleClass.tpe
- val meth = obj.moduleClass.newMethod(NoPosition, wrapperMethodName)
- def makeParam(fv: Symbol) = meth.newValueParameter(NoPosition, fv.name) setInfo fv.tpe
+ val meth = obj.moduleClass.newMethod(NoPosition, newTermName(wrapperMethodName))
+ def makeParam(fv: Symbol) = meth.newValueParameter(NoPosition, fv.name.toTermName) setInfo fv.tpe
meth setInfo MethodType(fvs map makeParam, expr.tpe)
minfo.decls enter meth
trace("wrapping ")(defOwner(expr) -> meth)
diff --git a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
index 8c9e6a2565..9d66ca6c6e 100644
--- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
+++ b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala
@@ -3,11 +3,9 @@ package runtime
trait TreeBuildUtil extends Universe with api.TreeBuildUtil {
- def staticClass(fullname: String): Symbol = definitions.getClass(newTypeName(fullname))
- def staticModule(fullname: String): Symbol = definitions.getModule(newTermName(fullname))
-
- def thisModuleType(fullname: String) =
- definitions.getModule(fullname).moduleClass.thisType
+ def staticClass(fullname: String): Symbol = definitions.getRequiredClass(fullname)
+ def staticModule(fullname: String): Symbol = definitions.getRequiredModule(fullname)
+ def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType
/** Selects type symbol with given name from the defined members of prefix type
*/
@@ -41,7 +39,7 @@ trait TreeBuildUtil extends Universe with api.TreeBuildUtil {
selectIn(owner.info, idx)
}
- def freeVar(name: String, info: Type, value: Any) = new FreeVar(name, info, value)
+ def freeVar(name: String, info: Type, value: Any) = new FreeVar(newTermName(name), info, value)
def modifiersFromInternalFlags(flags: Long, privateWithin: Name, annotations: List[Tree]): Modifiers =
Modifiers(flags, privateWithin, annotations)
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 470207fd35..940d115b2f 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -74,6 +74,9 @@ trait CompilationUnits { self: Global =>
* It is empty up to phase 'icode'.
*/
val icode: LinkedHashSet[icodes.IClass] = new LinkedHashSet
+
+ def echo(pos: Position, msg: String) =
+ reporter.echo(pos, msg)
def error(pos: Position, msg: String) =
reporter.error(pos, msg)
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index b10ac78ac7..6393ade146 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -136,9 +136,9 @@ class StandardCompileServer extends SocketServer {
}
if (command.shouldStopWithInfo)
- reporter.info(null, command.getInfoMessage(newGlobal(newSettings, reporter)), true)
+ reporter.echo(command.getInfoMessage(newGlobal(newSettings, reporter)))
else if (command.files.isEmpty)
- reporter.info(null, command.usageMsg, true)
+ reporter.echo(command.usageMsg)
else {
if (isCompilerReusable) {
info("[Reusing existing Global instance.]")
diff --git a/src/compiler/scala/tools/nsc/Driver.scala b/src/compiler/scala/tools/nsc/Driver.scala
index db95c1442b..0c52954a0b 100644
--- a/src/compiler/scala/tools/nsc/Driver.scala
+++ b/src/compiler/scala/tools/nsc/Driver.scala
@@ -24,8 +24,8 @@ abstract class Driver {
protected def doCompile(compiler: Global) {
if (command.files.isEmpty) {
- reporter.info(null, command.usageMsg, true)
- reporter.info(null, compiler.pluginOptionsHelp, true)
+ reporter.echo(command.usageMsg)
+ reporter.echo(compiler.pluginOptionsHelp)
} else {
val run = new compiler.Run()
run compile command.files
@@ -40,14 +40,14 @@ abstract class Driver {
settings = command.settings
if (settings.version.value) {
- reporter.info(null, versionMsg, true)
+ reporter.echo(versionMsg)
} else if (processSettingsHook()) {
val compiler = newCompiler()
try {
if (reporter.hasErrors)
reporter.flush()
else if (command.shouldStopWithInfo)
- reporter.info(null, command.getInfoMessage(compiler), true)
+ reporter.echo(command.getInfoMessage(compiler))
else
doCompile(compiler)
} catch {
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 2dd32e355b..c388a62644 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -159,7 +159,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// nearly every trait really must go. For now using globalError.
def error(msg: String) = globalError(msg)
def globalError(msg: String) = reporter.error(NoPosition, msg)
- def inform(msg: String) = reporter.info(NoPosition, msg, true)
+ def inform(msg: String) = reporter.echo(msg)
def warning(msg: String) =
if (opt.fatalWarnings) globalError(msg)
else reporter.warning(NoPosition, msg)
diff --git a/src/compiler/scala/tools/nsc/ScalaDoc.scala b/src/compiler/scala/tools/nsc/ScalaDoc.scala
index a9330b053b..4fa2cc71e5 100644
--- a/src/compiler/scala/tools/nsc/ScalaDoc.scala
+++ b/src/compiler/scala/tools/nsc/ScalaDoc.scala
@@ -30,17 +30,17 @@ class ScalaDoc {
def hasFiles = command.files.nonEmpty || docSettings.uncompilableFiles.nonEmpty
if (docSettings.version.value)
- reporter.info(null, versionMsg, true)
+ reporter.echo(versionMsg)
else if (docSettings.Xhelp.value)
- reporter.info(null, command.xusageMsg, true)
+ reporter.echo(command.xusageMsg)
else if (docSettings.Yhelp.value)
- reporter.info(null, command.yusageMsg, true)
+ reporter.echo(command.yusageMsg)
else if (docSettings.showPlugins.value)
reporter.warning(null, "Plugins are not available when using Scaladoc")
else if (docSettings.showPhases.value)
reporter.warning(null, "Phases are restricted when using Scaladoc")
else if (docSettings.help.value || !hasFiles)
- reporter.info(null, command.usageMsg, true)
+ reporter.echo(command.usageMsg)
else try {
if (docSettings.target.value == "msil")
msilLibPath foreach (x => docSettings.assemrefs.value += (pathSeparator + x))
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index f9c818daf0..6a6379cca2 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -220,8 +220,8 @@ trait DocComments { self: Global =>
else site.info.baseClasses
searchList collectFirst { case x if defs(x) contains vble => defs(x)(vble) } match {
- case Some(str) if str startsWith '$' => lookupVariable(str.tail, site)
- case res => res orElse lookupVariable(vble, site.owner)
+ case Some(str) if str startsWith "$" => lookupVariable(str.tail, site)
+ case res => res orElse lookupVariable(vble, site.owner)
}
}
@@ -397,7 +397,7 @@ trait DocComments { self: Global =>
if (tpe != NoType) tpe
else {
val alias1 = alias.cloneSymbol(definitions.RootClass)
- alias1.name = repl.toTypeName
+ alias1.name = newTypeName(repl)
typeRef(NoPrefix, alias1, Nil)
}
case None =>
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index 752e3c6699..7b5de1f3dd 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -360,7 +360,7 @@ abstract class TreeBrowsers {
("Program", EMPTY)
case UnitTree(unit) =>
- ("CompilationUnit", unit.toString)
+ ("CompilationUnit", newTermName("" + unit))
case DocDef(comment, definition) =>
("DocDef", EMPTY)
@@ -441,7 +441,7 @@ abstract class TreeBrowsers {
("Apply", EMPTY)
case Super(qualif, mix) =>
- ("Super", "mix: " + mix)
+ ("Super", newTermName("mix: " + mix))
case This(qualifier) =>
("This", qualifier)
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index efc64dbbc5..2cfd21ecc8 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -202,7 +202,7 @@ trait TreeDSL {
class DefSymStart(val sym: Symbol) extends SymVODDStart with DefCreator {
def symType = sym.tpe.finalResultType
def tparams = sym.typeParams map TypeDef
- def vparamss = sym.paramss map (xs => xs map ValDef)
+ def vparamss = mapParamss(sym)(ValDef)
}
class ValSymStart(val sym: Symbol) extends SymVODDStart with ValCreator {
def symType = sym.tpe
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 0dc3b1fffd..e69c463e71 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -128,7 +128,7 @@ abstract class TreeGen extends reflect.internal.TreeGen {
def mkManifestFactoryCall(full: Boolean, constructor: String, tparg: Type, args: List[Tree]): Tree =
mkMethodCall(
if (full) FullManifestModule else PartialManifestModule,
- constructor,
+ newTermName(constructor),
List(tparg),
args
)
@@ -161,16 +161,10 @@ abstract class TreeGen extends reflect.internal.TreeGen {
* apply the element type directly.
*/
def mkWrapArray(tree: Tree, elemtp: Type) = {
- val sym = elemtp.typeSymbol
- val meth: Name =
- if (isValueClass(sym)) "wrap"+sym.name+"Array"
- else if ((elemtp <:< AnyRefClass.tpe) && !isPhantomClass(sym)) "wrapRefArray"
- else "genericWrapArray"
-
mkMethodCall(
PredefModule,
- meth,
- if (isValueClass(sym)) Nil else List(elemtp),
+ wrapArrayMethodName(elemtp),
+ if (isScalaValueType(elemtp)) Nil else List(elemtp),
List(tree)
)
}
@@ -179,8 +173,8 @@ abstract class TreeGen extends reflect.internal.TreeGen {
* elem type elemtp to expected type pt.
*/
def mkCastArray(tree: Tree, elemtp: Type, pt: Type) =
- if (elemtp.typeSymbol == AnyClass && isValueClass(tree.tpe.typeArgs.head.typeSymbol))
- mkCast(mkRuntimeCall("toObjectArray", List(tree)), pt)
+ if (elemtp.typeSymbol == AnyClass && isScalaValueType(tree.tpe.typeArgs.head))
+ mkCast(mkRuntimeCall(nme.toObjectArray, List(tree)), pt)
else
mkCast(tree, pt)
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 00ac3976a9..d7bfcfc314 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -314,7 +314,7 @@ self =>
val stmts = templateStatSeq(false)._2
accept(EOF)
- def mainModuleName = settings.script.value
+ def mainModuleName = newTermName(settings.script.value)
/** If there is only a single object template in the file and it has a
* suitable main method, we will use it rather than building another object
* around it. Since objects are loaded lazily the whole script would have
@@ -343,7 +343,7 @@ self =>
* whole additional parse. So instead, if the actual object's name differs from
* what the script is expecting, we transform it to match.
*/
- if (name.toString == mainModuleName) md
+ if (name == mainModuleName) md
else treeCopy.ModuleDef(md, mods, mainModuleName, template)
case _ =>
/** If we see anything but the above, fail. */
@@ -352,7 +352,7 @@ self =>
Some(makePackaging(0, emptyPkg, newStmts))
}
- if (mainModuleName == ScriptRunner.defaultScriptMain)
+ if (mainModuleName == newTermName(ScriptRunner.defaultScriptMain))
searchForMain() foreach { return _ }
/** Here we are building an AST representing the following source fiction,
@@ -384,13 +384,13 @@ self =>
// def main
def mainParamType = AppliedTypeTree(Ident(tpnme.Array), List(Ident(tpnme.String)))
- def mainParameter = List(ValDef(Modifiers(Flags.PARAM), "argv", mainParamType, EmptyTree))
- def mainSetArgv = List(ValDef(NoMods, "args", TypeTree(), Ident("argv")))
+ def mainParameter = List(ValDef(Modifiers(Flags.PARAM), nme.argv, mainParamType, EmptyTree))
+ def mainSetArgv = List(ValDef(NoMods, nme.args, TypeTree(), Ident(nme.argv)))
def mainNew = makeNew(Nil, emptyValDef, stmts, List(Nil), NoPosition, NoPosition)
def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, mainNew))
// object Main
- def moduleName = ScriptRunner scriptMain settings
+ def moduleName = newTermName(ScriptRunner scriptMain settings)
def moduleBody = Template(List(scalaScalaObjectConstr), emptyValDef, List(emptyInit, mainDef))
def moduleDef = ModuleDef(NoMods, moduleName, moduleBody)
@@ -980,6 +980,7 @@ self =>
nme.ERROR
}
def ident(): Name = ident(true)
+ def rawIdent(): Name = try in.name finally in.nextToken()
/** For when it's known already to be a type name. */
def identForType(): TypeName = ident().toTypeName
@@ -1117,7 +1118,7 @@ self =>
case LONGLIT => in.intVal(isNegated)
case FLOATLIT => in.floatVal(isNegated).toFloat
case DOUBLELIT => in.floatVal(isNegated)
- case STRINGLIT => in.strVal
+ case STRINGLIT => in.strVal.intern()
case TRUE => true
case FALSE => false
case NULL => null
@@ -1465,8 +1466,9 @@ self =>
def prefixExpr(): Tree = {
if (isUnaryOp) {
atPos(in.offset) {
- val name: Name = "unary_" + ident()
- if (in.name == raw.MINUS && isNumericLit) simpleExprRest(atPos(in.offset)(literal(true)), true)
+ val name = nme.toUnaryName(rawIdent())
+ // val name = nme.toUnaryName(ident()) // val name: Name = "unary_" + ident()
+ if (name == nme.UNARY_- && isNumericLit) simpleExprRest(atPos(in.offset)(literal(true)), true)
else Select(stripParens(simpleExpr()), name)
}
}
@@ -1533,12 +1535,12 @@ self =>
case LBRACKET =>
val t1 = stripParens(t)
t1 match {
- case Ident(_) | Select(_, _) =>
- var tapp: Tree = t1
+ case Ident(_) | Select(_, _) | Apply(_, _) =>
+ var app: Tree = t1
while (in.token == LBRACKET)
- tapp = atPos(tapp.pos.startOrPoint, in.offset)(TypeApply(tapp, exprTypeArgs()))
+ app = atPos(app.pos.startOrPoint, in.offset)(TypeApply(app, exprTypeArgs()))
- simpleExprRest(tapp, true)
+ simpleExprRest(app, true)
case _ =>
t1
}
@@ -1743,11 +1745,16 @@ self =>
* }}}
*/
def pattern1(): Tree = pattern2() match {
- case p @ Ident(name) if treeInfo.isVarPattern(p) && in.token == COLON =>
- atPos(p.pos.startOrPoint, in.skipToken()) { Typed(p, compoundType()) }
- case p =>
- p
+ case p @ Ident(name) if in.token == COLON =>
+ if (treeInfo.isVarPattern(p))
+ atPos(p.pos.startOrPoint, in.skipToken())(Typed(p, compoundType()))
+ else {
+ syntaxError(in.offset, "Pattern variables must start with a lower-case letter. (SLS 8.1.1.)")
+ p
+ }
+ case p => p
}
+
/** {{{
* Pattern2 ::= varid [ @ Pattern3 ]
* | Pattern3
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index b8fa55447a..ffe65aec63 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -58,11 +58,11 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
private object xmltypes extends XMLTypeNames {
type NameType = TypeName
- implicit def createNameType(name: String): TypeName = newTypeName(name)
+ implicit def createNameType(name: String): TypeName = newTypeNameCached(name)
}
private object xmlterms extends XMLTermNames {
type NameType = TermName
- implicit def createNameType(name: String): TermName = newTermName(name)
+ implicit def createNameType(name: String): TermName = newTermNameCached(name)
}
import xmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer,
diff --git a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
index d80a1c4f34..27df45b563 100644
--- a/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
+++ b/src/compiler/scala/tools/nsc/backend/JavaPlatform.scala
@@ -39,9 +39,9 @@ trait JavaPlatform extends Platform {
) ++ depAnalysisPhase
lazy val externalEquals = getMember(BoxesRunTimeClass, nme.equals_)
- lazy val externalEqualsNumNum = getMember(BoxesRunTimeClass, "equalsNumNum")
- lazy val externalEqualsNumChar = getMember(BoxesRunTimeClass, "equalsNumChar")
- lazy val externalEqualsNumObject = getMember(BoxesRunTimeClass, "equalsNumObject")
+ lazy val externalEqualsNumNum = getMember(BoxesRunTimeClass, nme.equalsNumNum)
+ lazy val externalEqualsNumChar = getMember(BoxesRunTimeClass, nme.equalsNumChar)
+ lazy val externalEqualsNumObject = getMember(BoxesRunTimeClass, nme.equalsNumObject)
/** We could get away with excluding BoxedBooleanClass for the
* purpose of equality testing since it need not compare equal
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index 56e05cdc04..4ab0eb0129 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -3,13 +3,12 @@
* @author Martin Odersky
*/
-
package scala.tools.nsc
package backend
package icode
import scala.collection.{ mutable, immutable }
-import mutable.{ ArrayBuffer }
+import mutable.{ ListBuffer, ArrayBuffer }
import util.{ Position, NoPosition }
import backend.icode.analysis.ProgramPoint
@@ -17,23 +16,83 @@ trait BasicBlocks {
self: ICodes =>
import opcodes._
- import global.{ settings, log, nme }
+ import global.{ ifDebug, settings, log, nme }
import nme.isExceptionResultName
+
+ object NoBasicBlock extends BasicBlock(-1, null)
/** This class represents a basic block. Each
* basic block contains a list of instructions that are
* either executed all, or none. No jumps
* to/from the "middle" of the basic block are allowed (modulo exceptions).
*/
- class BasicBlock(val label: Int, val method: IMethod)
- extends AnyRef
- with ProgramPoint[BasicBlock]
- with Seq[Instruction] {
+ class BasicBlock(val label: Int, val method: IMethod) extends ProgramPoint[BasicBlock] {
+ outer =>
import BBFlags._
def code = method.code
+ private final class SuccessorList() {
+ private var successors: List[BasicBlock] = Nil
+ private def updateConserve() {
+ var lb: ListBuffer[BasicBlock] = null
+ var matches = 0
+ var remaining = successors
+
+ def addBlock(bb: BasicBlock) {
+ if (matches < 0)
+ lb += bb
+ else if (remaining.isEmpty || bb != remaining.head) {
+ lb = ListBuffer[BasicBlock]() ++= (successors take matches) += bb
+ matches = -1
+ }
+ else {
+ matches += 1
+ remaining = remaining.tail
+ }
+ }
+
+ // exceptionSuccessors
+ method.exh foreach { handler =>
+ if (handler covers outer)
+ addBlock(handler.startBlock)
+ }
+ // directSuccessors
+ val direct = directSuccessors
+ direct foreach addBlock
+
+ /** Return a list of successors for 'b' that come from exception handlers
+ * covering b's (non-exceptional) successors. These exception handlers
+ * might not cover 'b' itself. This situation corresponds to an
+ * exception being thrown as the first thing of one of b's successors.
+ */
+ method.exh foreach { handler =>
+ direct foreach { block =>
+ if (handler covers block)
+ addBlock(handler.startBlock)
+ }
+ }
+ // Blocks did not align: create a new list.
+ if (matches < 0)
+ successors = lb.toList
+ // Blocks aligned, but more blocks remain. Take a prefix of the list.
+ else if (remaining.nonEmpty)
+ successors = successors take matches
+ // Otherwise the list is unchanged, leave it alone.
+ }
+
+ /** This is called millions of times: it is performance sensitive. */
+ def updateSuccs() {
+ if (isEmpty) {
+ if (successors.nonEmpty)
+ successors = Nil
+ }
+ else updateConserve()
+ }
+ def toList = successors
+ }
+
/** Flags of this basic block. */
private var flags: Int = 0
@@ -76,20 +135,23 @@ trait BasicBlocks {
setFlag(DIRTYSUCCS | DIRTYPREDS)
/** Cached predecessors. */
- var preds: List[BasicBlock] = null
+ var preds: List[BasicBlock] = Nil
/** Local variables that are in scope at entry of this basic block. Used
* for debugging information.
*/
- var varsInScope: mutable.Set[Local] = new mutable.LinkedHashSet()
+ val varsInScope: mutable.Set[Local] = new mutable.LinkedHashSet()
/** ICode instructions, used as temporary storage while emitting code.
* Once closed is called, only the `instrs` array should be used.
*/
private var instructionList: List[Instruction] = Nil
-
private var instrs: Array[Instruction] = _
- override def toList: List[Instruction] =
+
+ def take(n: Int): Seq[Instruction] =
+ if (closed) instrs take n else instructionList takeRight n reverse
+
+ def toList: List[Instruction] =
if (closed) instrs.toList else instructionList.reverse
/** Return an iterator over the instructions in this basic block. */
@@ -117,17 +179,37 @@ trait BasicBlocks {
}
/** Apply a function to all the instructions of the block. */
- override def foreach[U](f: Instruction => U) = {
- // !!! This appears to change behavior if I try to avoid the implicit
- // conversion and traverse the array directly, which presumably means it
- // is dependent on some mutation which is taking place during traversal.
- // Please eliminate this if humanly possible.
+ final def foreach[U](f: Instruction => U) = {
if (!closed) dumpMethodAndAbort(method, this)
else instrs foreach f
+
+ // !!! If I replace "instrs foreach f" with the following:
+ // var i = 0
+ // val len = instrs.length
+ // while (i < len) {
+ // f(instrs(i))
+ // i += 1
+ // }
+ //
+ // Then when compiling under -optimise, quick.plugins fails as follows:
+ //
+ // quick.plugins:
+ // [mkdir] Created dir: /scratch/trunk6/build/quick/classes/continuations-plugin
+ // [scalacfork] Compiling 5 files to /scratch/trunk6/build/quick/classes/continuations-plugin
+ // [scalacfork] error: java.lang.VerifyError: (class: scala/tools/nsc/typechecker/Implicits$ImplicitSearch, method: typedImplicit0 signature: (Lscala/tools/nsc/typechecker/Implicits$ImplicitInfo;Z)Lscala/tools/nsc/typechecker/Implicits$SearchResult;) Incompatible object argument for function call
+ // [scalacfork] at scala.tools.nsc.typechecker.Implicits$class.inferImplicit(Implicits.scala:67)
+ // [scalacfork] at scala.tools.nsc.Global$$anon$1.inferImplicit(Global.scala:419)
+ // [scalacfork] at scala.tools.nsc.typechecker.Typers$Typer.wrapImplicit$1(Typers.scala:170)
+ // [scalacfork] at scala.tools.nsc.typechecker.Typers$Typer.inferView(Typers.scala:174)
+ // [scalacfork] at scala.tools.nsc.typechecker.Typers$Typer.adapt(Typers.scala:963)
+ // [scalacfork] at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:4378)
+ //
+ // This is bad and should be understood/eliminated.
}
/** The number of instructions in this basic block so far. */
def length = if (closed) instrs.length else instructionList.length
+ def size = length
/** Return the n-th instruction. */
def apply(n: Int): Instruction =
@@ -208,7 +290,7 @@ trait BasicBlocks {
*/
def removeLastInstruction() {
if (closed)
- removeInstructionsAt(size)
+ removeInstructionsAt(length)
else {
instructionList = instructionList.tail
code.touched = true
@@ -321,10 +403,11 @@ trait BasicBlocks {
def clear() {
instructionList = Nil
instrs = null
- preds = null
+ preds = Nil
}
- override def isEmpty = instructionList.isEmpty
+ final def isEmpty = instructionList.isEmpty
+ final def nonEmpty = !isEmpty
/** Enter ignore mode: new 'emit'ted instructions will not be
* added to this basic block. It makes the generation of THROW
@@ -341,33 +424,33 @@ trait BasicBlocks {
/** Return the last instruction of this basic block. */
def lastInstruction =
- if (closed) instrs.last
+ if (closed) instrs(instrs.length - 1)
else instructionList.head
def firstInstruction =
if (closed) instrs(0)
else instructionList.last
+ def exceptionSuccessors: List[BasicBlock] =
+ exceptionSuccessorsForBlock(this)
+
def exceptionSuccessorsForBlock(block: BasicBlock): List[BasicBlock] =
method.exh collect { case x if x covers block => x.startBlock }
/** Cached value of successors. Must be recomputed whenever a block in the current method is changed. */
- private var succs: List[BasicBlock] = Nil
- private def updateSuccs() {
- resetFlag(DIRTYSUCCS)
- succs =
- if (isEmpty) Nil
- else exceptionSuccessors ++ directSuccessors ++ indirectExceptionSuccessors
- }
+ private val succs = new SuccessorList
- def successors : List[BasicBlock] = {
- if (touched) updateSuccs()
- succs
+ def successors: List[BasicBlock] = {
+ if (touched) {
+ succs.updateSuccs()
+ resetFlag(DIRTYSUCCS)
+ }
+ succs.toList
}
def directSuccessors: List[BasicBlock] =
if (isEmpty) Nil else lastInstruction match {
- case JUMP(whereto) => List(whereto)
+ case JUMP(whereto) => whereto :: Nil
case CJUMP(succ, fail, _, _) => fail :: succ :: Nil
case CZJUMP(succ, fail, _, _) => fail :: succ :: Nil
case SWITCH(_, labels) => labels
@@ -379,17 +462,6 @@ trait BasicBlocks {
else Nil
}
- def exceptionSuccessors: List[BasicBlock] =
- exceptionSuccessorsForBlock(this)
-
- /** Return a list of successors for 'b' that come from exception handlers
- * covering b's (non-exceptional) successors. These exception handlers
- * might not cover 'b' itself. This situation corresponds to an
- * exception being thrown as the first thing of one of b's successors.
- */
- def indirectExceptionSuccessors: List[BasicBlock] =
- directSuccessors flatMap exceptionSuccessorsForBlock distinct
-
/** Returns the predecessors of this block. */
def predecessors: List[BasicBlock] = {
if (hasFlag(DIRTYPREDS)) {
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
index 1880bdc52c..ffc6640743 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala
@@ -3,13 +3,11 @@
* @author Martin Odersky
*/
-
package scala.tools.nsc
package backend
package icode
-import scala.collection.{ mutable, immutable, generic }
-import util.{ Position, NoPosition }
+import scala.collection.{ mutable, immutable }
/**
* Exception handlers are pieces of code that `handle` exceptions on
@@ -21,10 +19,10 @@ import util.{ Position, NoPosition }
trait ExceptionHandlers {
self: ICodes =>
- import global.{ definitions, Symbol, NoSymbol }
+ import global._
import definitions.{ ThrowableClass }
- class ExceptionHandler(val method: IMethod, val label: String, val cls: Symbol, val pos: Position) {
+ class ExceptionHandler(val method: IMethod, val label: TermName, val cls: Symbol, val pos: Position) {
def loadExceptionClass = if (cls == NoSymbol) ThrowableClass else cls
private var _startBlock: BasicBlock = _;
var finalizer: Finalizer = _;
@@ -69,12 +67,12 @@ trait ExceptionHandlers {
def dup: ExceptionHandler = new ExceptionHandler(this)
}
- class Finalizer(method: IMethod, label: String, pos: Position) extends ExceptionHandler(method, label, NoSymbol, pos) {
+ class Finalizer(method: IMethod, label: TermName, pos: Position) extends ExceptionHandler(method, label, NoSymbol, pos) {
override def toString() = "finalizer_" + label
override def dup: Finalizer = new Finalizer(method, label, pos)
}
- object NoFinalizer extends Finalizer(null, "<no finalizer>", NoPosition) {
+ object NoFinalizer extends Finalizer(null, newTermNameCached("<no finalizer>"), NoPosition) {
override def startBlock: BasicBlock = sys.error("NoFinalizer cannot have a start block.");
override def setStartBlock(b: BasicBlock): Unit = sys.error("NoFinalizer cannot have a start block.");
override def dup = this
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 3f0a0fac1a..803bd05031 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -102,7 +102,7 @@ abstract class GenICode extends SubComponent {
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
debuglog("Entering method " + name)
val m = new IMethod(tree.symbol)
- m.sourceFile = unit.source.toString()
+ m.sourceFile = unit.source
m.returnType = if (tree.symbol.isConstructor) UNIT
else toTypeKind(tree.symbol.info.resultType)
ctx.clazz.addMethod(m)
@@ -1293,7 +1293,7 @@ abstract class GenICode extends SubComponent {
/** The Object => String overload.
*/
- private lazy val String_valueOf: Symbol = getMember(StringModule, "valueOf") filter (sym =>
+ private lazy val String_valueOf: Symbol = getMember(StringModule, nme.valueOf) filter (sym =>
sym.info.paramTypes match {
case List(pt) => pt.typeSymbol == ObjectClass
case _ => false
@@ -1305,7 +1305,7 @@ abstract class GenICode extends SubComponent {
// case we want to get more precise.
//
// private def valueOfForType(tp: Type): Symbol = {
- // val xs = getMember(StringModule, "valueOf") filter (sym =>
+ // val xs = getMember(StringModule, nme.valueOf) filter (sym =>
// // We always exclude the Array[Char] overload because java throws an NPE if
// // you pass it a null. It will instead find the Object one, which doesn't.
// sym.info.paramTypes match {
@@ -1352,7 +1352,7 @@ abstract class GenICode extends SubComponent {
def genScalaHash(tree: Tree, ctx: Context): Context = {
val hashMethod = {
ctx.bb.emit(LOAD_MODULE(ScalaRunTimeModule))
- getMember(ScalaRunTimeModule, "hash")
+ getMember(ScalaRunTimeModule, nme.hash_)
}
val ctx1 = genLoad(tree, ctx, ObjectReference)
@@ -1716,7 +1716,7 @@ abstract class GenICode extends SubComponent {
do {
changed = false
n += 1
- method.code.blocks foreach prune0
+ method.blocks foreach prune0
} while (changed)
debuglog("Prune fixpoint reached in " + n + " iterations.");
@@ -1924,7 +1924,7 @@ abstract class GenICode extends SubComponent {
val ctx1 = new Context(this) setMethod(m)
ctx1.labels = mutable.HashMap()
ctx1.method.code = new Code(m)
- ctx1.bb = ctx1.method.code.startBlock
+ ctx1.bb = ctx1.method.startBlock
ctx1.defdef = d
ctx1.scope = EmptyScope
ctx1.enterScope
@@ -1932,11 +1932,12 @@ abstract class GenICode extends SubComponent {
}
/** Return a new context for a new basic block. */
- def newBlock: Context = {
+ def newBlock(): Context = {
val block = method.code.newBlock
handlers foreach (_ addCoveredBlock block)
currentExceptionHandlers foreach (_ addBlock block)
- block.varsInScope = mutable.HashSet() ++= scope.varsInScope
+ block.varsInScope.clear()
+ block.varsInScope ++= scope.varsInScope
new Context(this) setBasicBlock block
}
@@ -1958,7 +1959,7 @@ abstract class GenICode extends SubComponent {
*/
private def newExceptionHandler(cls: Symbol, resultKind: TypeKind, pos: Position): ExceptionHandler = {
handlerCount += 1
- val exh = new ExceptionHandler(method, "" + handlerCount, cls, pos)
+ val exh = new ExceptionHandler(method, newTermNameCached("" + handlerCount), cls, pos)
exh.resultKind = resultKind
method.addHandler(exh)
handlers = exh :: handlers
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
index 7a0017944b..631b71d83a 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
@@ -84,15 +84,16 @@ abstract class ICodes extends AnyRef
def checkValid(m: IMethod) {
// always slightly dicey to iterate over mutable structures
- val bs = m.code.blocks.toList
- for (b <- bs ; if !b.closed) {
- // Something is leaving open/empty blocks around (see SI-4840) so
- // let's not kill the deal unless it's nonempty.
- if (b.isEmpty) {
- log("!!! Found open but empty block while inlining " + m + ": removing from block list.")
- m.code removeBlock b
+ m foreachBlock { b =>
+ if (!b.closed) {
+ // Something is leaving open/empty blocks around (see SI-4840) so
+ // let's not kill the deal unless it's nonempty.
+ if (b.isEmpty) {
+ log("!!! Found open but empty block while inlining " + m + ": removing from block list.")
+ m.code removeBlock b
+ }
+ else dumpMethodAndAbort(m, b)
}
- else dumpMethodAndAbort(m, b)
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
index 1978a23d90..f71c8de449 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
@@ -36,7 +36,7 @@ trait Linearizers {
var blocks: List[BasicBlock] = Nil
def linearize(m: IMethod): List[BasicBlock] = {
- val b = m.code.startBlock;
+ val b = m.startBlock;
blocks = Nil;
run {
@@ -106,7 +106,7 @@ trait Linearizers {
def linearize(m: IMethod): List[BasicBlock] = {
blocks = Nil;
- dfs(m.code.startBlock);
+ dfs(m.startBlock);
m.exh foreach (b => dfs(b.startBlock));
blocks.reverse
@@ -150,14 +150,14 @@ trait Linearizers {
added.clear;
m.exh foreach (b => rpo(b.startBlock));
- rpo(m.code.startBlock);
+ rpo(m.startBlock);
// if the start block has predecessors, it won't be the first one
// in the linearization, so we need to enforce it here
- if (m.code.startBlock.predecessors eq Nil)
+ if (m.startBlock.predecessors eq Nil)
blocks
else
- m.code.startBlock :: (blocks.filterNot(_ == m.code.startBlock))
+ m.startBlock :: (blocks.filterNot(_ == m.startBlock))
}
def linearizeAt(m: IMethod, start: BasicBlock): List[BasicBlock] = {
@@ -195,7 +195,7 @@ trait Linearizers {
* the last instruction being a jump).
*/
class DumpLinearizer extends Linearizer {
- def linearize(m: IMethod): List[BasicBlock] = m.code.blocks.toList
+ def linearize(m: IMethod): List[BasicBlock] = m.blocks
def linearizeAt(m: IMethod, start: BasicBlock): List[BasicBlock] = sys.error("not implemented")
}
@@ -250,7 +250,7 @@ trait Linearizers {
* @param frozen blocks can't be moved (fist block of a method, blocks directly following a try-catch)
*/
def groupBlocks(method: IMethod, blocks: List[BasicBlock], handlers: List[ExceptionHandler], frozen: mutable.HashSet[BasicBlock]) = {
- assert(blocks.head == method.code.startBlock, method)
+ assert(blocks.head == method.startBlock, method)
// blocks before the try, and blocks for the try
val beforeAndTry = new ListBuffer[BasicBlock]()
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
index b2cc4cdd5b..2668e7f29f 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
@@ -3,13 +3,13 @@
* @author Martin Odersky
*/
-
package scala.tools.nsc
package backend
package icode
import java.io.PrintWriter
import scala.collection.{ mutable, immutable }
+import util.{ SourceFile, NoSourceFile }
import symtab.Flags.{ DEFERRED }
trait ReferenceEquality {
@@ -17,29 +17,34 @@ trait ReferenceEquality {
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
}
-trait Members { self: ICodes =>
+trait Members {
+ self: ICodes =>
+
import global._
+
+ object NoCode extends Code(null, "NoCode") {
+ override def blocksList: List[BasicBlock] = Nil
+ }
/**
* This class represents the intermediate code of a method or
* other multi-block piece of code, like exception handlers.
*/
- class Code(method: IMethod) {
- private[this] val name = method.symbol.decodedName.toString.intern
+ class Code(method: IMethod, name: String) {
+ def this(method: IMethod) = this(method, method.symbol.decodedName.toString.intern)
/** The set of all blocks */
val blocks = mutable.ListBuffer[BasicBlock]()
/** The start block of the method */
- var startBlock: BasicBlock = null
-
- /** The stack produced by this method */
- var producedStack: TypeStack = null
+ var startBlock: BasicBlock = NoBasicBlock
private var currentLabel: Int = 0
private var _touched = false
- def blockCount = blocks.size
- def instructionCount = blocks map (_.length) sum
+ def blocksList: List[BasicBlock] = blocks.toList
+ def instructions = blocksList flatMap (_.iterator)
+ def blockCount = blocks.size
+ def instructionCount = blocks map (_.length) sum
def touched = _touched
def touched_=(b: Boolean): Unit = {
@@ -82,7 +87,7 @@ trait Members { self: ICodes =>
/* Create a new block and append it to the list
*/
- def newBlock: BasicBlock = {
+ def newBlock(): BasicBlock = {
touched = true
val block = new BasicBlock(nextLabel, method);
blocks += block;
@@ -133,6 +138,8 @@ trait Members { self: ICodes =>
/** Represent a field in ICode */
class IField(val symbol: Symbol) extends IMember { }
+
+ object NoIMethod extends IMethod(NoSymbol) { }
/**
* Represents a method in ICode. Local variables contain
@@ -145,14 +152,23 @@ trait Members { self: ICodes =>
* finished (GenICode does that).
*/
class IMethod(val symbol: Symbol) extends IMember {
- var code: Code = null
+ var code: Code = NoCode
+
+ def newBlock() = code.newBlock
+ def startBlock = code.startBlock
+ def lastBlock = blocks.last
+ def blocks = code.blocksList
+ def linearizedBlocks(lin: Linearizer = self.linearizer): List[BasicBlock] = lin linearize this
+
+ def foreachBlock[U](f: BasicBlock => U): Unit = blocks foreach f
+ def foreachInstr[U](f: Instruction => U): Unit = foreachBlock(_.toList foreach f)
+
var native = false
/** The list of exception handlers, ordered from innermost to outermost. */
var exh: List[ExceptionHandler] = Nil
- var sourceFile: String = _
+ var sourceFile: SourceFile = NoSourceFile
var returnType: TypeKind = _
-
var recursive: Boolean = false
/** local variables and method parameters */
@@ -161,7 +177,8 @@ trait Members { self: ICodes =>
/** method parameters */
var params: List[Local] = Nil
- def hasCode = code != null
+ // TODO - see how null is stil arriving here
+ def hasCode = (code ne NoCode) && (code ne null)
def setCode(code: Code): IMethod = {
this.code = code;
this
@@ -199,12 +216,14 @@ trait Members { self: ICodes =>
import opcodes._
def checkLocals(): Unit = {
- def localsSet = code.blocks.flatten collect {
- case LOAD_LOCAL(l) => l
- case STORE_LOCAL(l) => l
- } toSet
+ def localsSet = (code.blocks flatMap { bb =>
+ bb.iterator collect {
+ case LOAD_LOCAL(l) => l
+ case STORE_LOCAL(l) => l
+ }
+ }).toSet
- if (code != null) {
+ if (hasCode) {
log("[checking locals of " + this + "]")
locals filterNot localsSet foreach { l =>
log("Local " + l + " is not declared in " + this)
@@ -218,7 +237,7 @@ trait Members { self: ICodes =>
*
* This method should be most effective after heavy inlining.
*/
- def normalize(): Unit = if (this.code ne null) {
+ def normalize(): Unit = if (this.hasCode) {
val nextBlock: mutable.Map[BasicBlock, BasicBlock] = mutable.HashMap.empty
for (b <- code.blocks.toList
if b.successors.length == 1;
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
index ff4abbb757..4ea253d29d 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
@@ -82,7 +82,7 @@ trait Printers { self: ICodes =>
if (!m.isAbstractMethod) {
println(" {")
println("locals: " + m.locals.mkString("", ", ", ""))
- println("startBlock: " + m.code.startBlock)
+ println("startBlock: " + m.startBlock)
println("blocks: " + m.code.blocks.mkString("[", ",", "]"))
println
lin.linearize(m) foreach printBlock
diff --git a/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala b/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala
index 45ab7ae43c..ba4b250303 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/TypeStacks.scala
@@ -21,6 +21,8 @@ trait TypeStacks {
* stack of the ICode.
*/
type Rep = List[TypeKind]
+
+ object NoTypeStack extends TypeStack(Nil) { }
class TypeStack(var types: Rep) {
if (types.nonEmpty)
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
index 5af5b05682..229bbceb36 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala
@@ -194,9 +194,9 @@ abstract class CopyPropagation {
this.method = m
init {
- worklist += m.code.startBlock
+ worklist += m.startBlock
worklist ++= (m.exh map (_.startBlock))
- m.code.blocks.foreach { b =>
+ m foreachBlock { b =>
in(b) = lattice.bottom
out(b) = lattice.bottom
assert(out.contains(b))
@@ -207,21 +207,21 @@ abstract class CopyPropagation {
}
// first block is special: it's not bottom, but a precisely defined state with no bindings
- in(m.code.startBlock) = new lattice.State(lattice.emptyBinding, Nil);
+ in(m.startBlock) = new lattice.State(lattice.emptyBinding, Nil);
}
}
override def run() {
forwardAnalysis(blockTransfer)
if (settings.debug.value) {
- linearizer.linearize(method).foreach(b => if (b != method.code.startBlock)
+ linearizer.linearize(method).foreach(b => if (b != method.startBlock)
assert(in(b) != lattice.bottom,
"Block " + b + " in " + this.method + " has input equal to bottom -- not visited?"));
}
}
def blockTransfer(b: BasicBlock, in: lattice.Elem): lattice.Elem =
- b.foldLeft(in)(interpret)
+ b.iterator.foldLeft(in)(interpret)
import opcodes._
@@ -520,8 +520,8 @@ abstract class CopyPropagation {
*/
private def getBindingsForPrimaryCtor(in: copyLattice.State, ctor: Symbol): mutable.Map[Symbol, Value] = {
val paramAccessors = ctor.owner.constrParamAccessors;
- var values = in.stack.take(1 + ctor.info.paramTypes.length).reverse.drop(1);
- val bindings = mutable.HashMap[Symbol, Value]()
+ var values = in.stack.take(1 + ctor.info.paramTypes.length).reverse.drop(1);
+ val bindings = mutable.HashMap[Symbol, Value]()
debuglog("getBindings for: " + ctor + " acc: " + paramAccessors)
@@ -562,13 +562,12 @@ abstract class CopyPropagation {
final def isPureMethod(m: Symbol): Boolean =
m.isGetter // abstract getters are still pure, as we 'know'
- final override def toString(): String = {
- var res = ""
- for (b <- this.method.code.blocks.toList)
- res = (res + "\nIN(" + b.label + "):\t Bindings: " + in(b).bindings +
- "\nIN(" + b.label +"):\t Stack: " + in(b).stack) + "\n";
- res
- }
+ final override def toString() = (
+ method.blocks map { b =>
+ "\nIN(%s):\t Bindings: %s".format(b.label, in(b).bindings) +
+ "\nIN(%s):\t Stack: %s".format(b.label, in(b).stack)
+ } mkString
+ )
} /* class CopyAnalysis */
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
index c656219dc8..49f5b51d51 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
@@ -33,10 +33,9 @@ abstract class Liveness {
final class LivenessAnalysis extends DataFlowAnalysis[livenessLattice.type] {
type P = BasicBlock
- val lattice = livenessLattice
- var method: IMethod = _
-
- val gen: mutable.Map[BasicBlock, Set[Local]] = perRunCaches.newMap()
+ val lattice = livenessLattice
+ var method: IMethod = _
+ val gen: mutable.Map[BasicBlock, Set[Local]] = perRunCaches.newMap()
val kill: mutable.Map[BasicBlock, Set[Local]] = perRunCaches.newMap()
def init(m: IMethod) {
@@ -44,14 +43,15 @@ abstract class Liveness {
gen.clear()
kill.clear()
- for (b <- m.code.blocks; (g, k) = genAndKill(b)) {
+ m foreachBlock { b =>
+ val (g, k) = genAndKill(b)
gen += (b -> g)
kill += (b -> k)
}
init {
- worklist ++= m.code.blocks.toList
- m.code.blocks.foreach { b =>
+ m foreachBlock { b =>
+ worklist += b
in(b) = lattice.bottom
out(b) = lattice.bottom
}
@@ -75,7 +75,7 @@ abstract class Liveness {
override def run() {
backwardAnalysis(blockTransfer)
if (settings.debug.value) {
- linearizer.linearize(method).foreach(b => if (b != method.code.startBlock)
+ linearizer.linearize(method).foreach(b => if (b != method.startBlock)
assert(lattice.bottom != in(b),
"Block " + b + " in " + this.method + " has input equal to bottom -- not visited?"));
}
@@ -89,29 +89,14 @@ abstract class Liveness {
* liveness *before* the given instruction `i`.
*/
def interpret(out: lattice.Elem, i: Instruction): lattice.Elem = {
- var in = out
-
- if (settings.debug.value) {
- log("- " + i)
- log("out: " + out)
- log("\n")
- }
-
+ debuglog("- " + i + "\nout: " + out + "\n")
i match {
- case LOAD_LOCAL(l) => in += l
- case STORE_LOCAL(l) => in -= l
- case _ =>
- ()
- }
- in
- } /* def interpret */
-
- override def toString(): String = {
- val buf = new StringBuilder()
- for (b <- method.code.blocks.toList) {
- buf.append("\nlive-in(" + b + ")=" + in(b) + "\nlive-out(" + b + ")=" + out(b));
+ case LOAD_LOCAL(l) => out + l
+ case STORE_LOCAL(l) => out - l
+ case _ => out
}
- buf.toString()
}
+ override def toString() =
+ method.blocks map (b => "\nlive-in(%s)=%s\nlive-out(%s)=%s".format(b, in(b), b, out(b))) mkString
} /* Liveness analysis */
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala
index eac714f999..c06bd2e097 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala
@@ -78,7 +78,10 @@ abstract class ReachingDefinitions {
drops.clear()
outStack.clear()
- for (b <- m.code.blocks.toList; (g, k) = genAndKill(b); (d, st) = dropsAndGen(b)) {
+ m foreachBlock { b =>
+ val (g, k) = genAndKill(b)
+ val (d, st) = dropsAndGen(b)
+
gen += (b -> g)
kill += (b -> k)
drops += (b -> d)
@@ -86,8 +89,8 @@ abstract class ReachingDefinitions {
}
init {
- worklist ++= m.code.blocks.toList
- m.code.blocks.foreach { b =>
+ m foreachBlock { b =>
+ worklist += b
in(b) = lattice.bottom
out(b) = lattice.bottom
}
@@ -141,7 +144,7 @@ abstract class ReachingDefinitions {
override def run() {
forwardAnalysis(blockTransfer)
if (settings.debug.value) {
- linearizer.linearize(method).foreach(b => if (b != method.code.startBlock)
+ linearizer.linearize(method).foreach(b => if (b != method.startBlock)
assert(lattice.bottom != in(b),
"Block " + b + " in " + this.method + " has input equal to bottom -- not visited? " + in(b)
+ ": bot: " + lattice.bottom
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
index a34d269cc9..937b0bdc3d 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
@@ -110,16 +110,16 @@ abstract class TypeFlowAnalysis {
this.method = m
//typeFlowLattice.lubs = 0
init {
- worklist += m.code.startBlock
+ worklist += m.startBlock
worklist ++= (m.exh map (_.startBlock))
- m.code.blocks.foreach { b =>
+ m foreachBlock { b =>
in(b) = typeFlowLattice.bottom
out(b) = typeFlowLattice.bottom
}
// start block has var bindings for each of its parameters
val entryBindings = new VarBinding ++= (m.params map (p => ((p, p.kind))))
- in(m.code.startBlock) = lattice.IState(entryBindings, typeStackLattice.bottom)
+ in(m.startBlock) = lattice.IState(entryBindings, typeStackLattice.bottom)
m.exh foreach { e =>
in(e.startBlock) = lattice.IState(in(e.startBlock).vars, typeStackLattice.exceptionHandlerStack)
@@ -132,16 +132,18 @@ abstract class TypeFlowAnalysis {
if (this.method == null || this.method.symbol != m.symbol)
init(m)
else reinit {
- for (b <- m.code.blocks; if !in.isDefinedAt(b)) {
- for (p <- b.predecessors) {
- if (out.isDefinedAt(p)) {
- in(b) = out(p)
- worklist += p
- }
-/* else
- in(b) = typeFlowLattice.bottom
-*/ }
- out(b) = typeFlowLattice.bottom
+ m foreachBlock { b =>
+ if (!in.contains(b)) {
+ for (p <- b.predecessors) {
+ if (out.isDefinedAt(p)) {
+ in(b) = out(p)
+ worklist += p
+ }
+ /* else
+ in(b) = typeFlowLattice.bottom
+ */ }
+ out(b) = typeFlowLattice.bottom
+ }
}
for (handler <- m.exh) {
val start = handler.startBlock
@@ -164,7 +166,7 @@ abstract class TypeFlowAnalysis {
forwardAnalysis(blockTransfer)
val t = timer.stop
if (settings.debug.value) {
- linearizer.linearize(method).foreach(b => if (b != method.code.startBlock)
+ linearizer.linearize(method).foreach(b => if (b != method.startBlock)
assert(visited.contains(b),
"Block " + b + " in " + this.method + " has input equal to bottom -- not visited? .." + visited));
}
@@ -174,7 +176,7 @@ abstract class TypeFlowAnalysis {
}
def blockTransfer(b: BasicBlock, in: lattice.Elem): lattice.Elem = {
- b.foldLeft(in)(interpret)
+ b.iterator.foldLeft(in)(interpret)
}
/** The flow function of a given basic block. */
/* var flowFun: immutable.Map[BasicBlock, TransferFunction] = new immutable.HashMap */
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
index 301dbd18d6..e7cf716add 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
@@ -23,15 +23,10 @@ trait GenAndroid {
* `Parcelable` interface must also have a static field called `CREATOR`,
* which is an object implementing the `Parcelable.Creator` interface.
*/
- private val fieldName = "CREATOR"
+ private val fieldName = newTermName("CREATOR")
- private lazy val AndroidParcelableInterface =
- try definitions.getClass("android.os.Parcelable")
- catch { case _: FatalError => NoSymbol }
-
- private lazy val AndroidCreatorClass =
- if (AndroidParcelableInterface == NoSymbol) NoSymbol
- else definitions.getClass("android.os.Parcelable$Creator")
+ private lazy val AndroidParcelableInterface = definitions.getClassIfDefined("android.os.Parcelable")
+ private lazy val AndroidCreatorClass = definitions.getClassIfDefined("android.os.Parcelable$Creator")
def isAndroidParcelableClass(sym: Symbol) =
(AndroidParcelableInterface != NoSymbol) &&
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index a2c4f16bf1..03d1bc3ad2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -3,7 +3,6 @@
* @author Iulian Dragos
*/
-
package scala.tools.nsc
package backend.jvm
@@ -13,6 +12,7 @@ import scala.collection.{ mutable, immutable }
import scala.reflect.internal.pickling.{ PickleFormat, PickleBuffer }
import scala.tools.reflect.SigParser
import scala.tools.nsc.symtab._
+import scala.tools.nsc.util.{ SourceFile, NoSourceFile }
import scala.reflect.internal.ClassfileConstants._
import ch.epfl.lamp.fjbg._
import JAccessFlags._
@@ -183,10 +183,15 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val MethodHandleType = new JObjectType("java.dyn.MethodHandle")
// Scala attributes
- val BeanInfoAttr = definitions.getClass("scala.beans.BeanInfo")
- val BeanInfoSkipAttr = definitions.getClass("scala.beans.BeanInfoSkip")
- val BeanDisplayNameAttr = definitions.getClass("scala.beans.BeanDisplayName")
- val BeanDescriptionAttr = definitions.getClass("scala.beans.BeanDescription")
+ val BeanInfoAttr = definitions.getRequiredClass("scala.beans.BeanInfo")
+ val BeanInfoSkipAttr = definitions.getRequiredClass("scala.beans.BeanInfoSkip")
+ val BeanDisplayNameAttr = definitions.getRequiredClass("scala.beans.BeanDisplayName")
+ val BeanDescriptionAttr = definitions.getRequiredClass("scala.beans.BeanDescription")
+
+ final val ExcludedForwarderFlags = {
+ import Flags._
+ ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | BridgeAndPrivateFlags )
+ }
// Additional interface parents based on annotations and other cues
def newParentForAttr(attr: Symbol): Option[Type] = attr match {
@@ -291,7 +296,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
*/
def scalaSignatureAddingMarker(jclass: JClass, sym: Symbol): Option[AnnotationInfo] =
currentRun.symData get sym match {
- case Some(pickle) if !nme.isModuleName(jclass.getName()) =>
+ case Some(pickle) if !nme.isModuleName(newTermName(jclass.getName)) =>
val scalaAttr =
fjbgContext.JOtherAttribute(jclass, jclass, tpnme.ScalaSignatureATTR.toString,
versionPickle.bytes, versionPickle.writeIndex)
@@ -355,7 +360,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (isTopLevelModule(c.symbol)) {
if (c.symbol.companionClass == NoSymbol)
- generateMirrorClass(c.symbol, c.cunit.source.toString)
+ generateMirrorClass(c.symbol, c.cunit.source)
else
log("No mirror class for module with linked class: " +
c.symbol.fullName)
@@ -754,7 +759,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
null
else {
val outerName = javaName(innerSym.rawowner)
- if (isTopLevelModule(innerSym.rawowner)) "" + nme.stripModuleSuffix(outerName)
+ if (isTopLevelModule(innerSym.rawowner)) "" + nme.stripModuleSuffix(newTermName(outerName))
else outerName
}
}
@@ -925,8 +930,8 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
mopt match {
case Some(m) =>
- val oldLastBlock = m.code.blocks.last
- val lastBlock = m.code.newBlock
+ val oldLastBlock = m.lastBlock
+ val lastBlock = m.newBlock()
oldLastBlock.replaceInstruction(oldLastBlock.length - 1, JUMP(lastBlock))
if (isStaticModule(clasz.symbol)) {
@@ -1044,32 +1049,20 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
val className = jclass.getName
val linkedClass = moduleClass.companionClass
val linkedModule = linkedClass.companionSymbol
+ lazy val conflictingNames: Set[Name] = {
+ linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name } toSet
+ }
+ debuglog("Potentially conflicting names for forwarders: " + conflictingNames)
- /** There was a bit of a gordian logic knot here regarding forwarders.
- * All we really have to do is exclude certain categories of symbols and
- * then all matching names.
- */
- def memberNames(sym: Symbol) = sym.info.members map (_.name.toString) toSet
- lazy val membersInCommon =
- memberNames(linkedModule) intersect memberNames(linkedClass)
-
- /** Should method `m` get a forwarder in the mirror class? */
- def shouldForward(m: Symbol): Boolean = (
- m.owner != ObjectClass
- && m.isMethod
- && m.isPublic
- && !m.hasFlag(Flags.CASE | Flags.DEFERRED | Flags.SPECIALIZED | Flags.LIFTED)
- && !m.isConstructor
- && !m.isStaticMember
- && !membersInCommon(m.name.toString)
- )
-
- for (m <- moduleClass.info.nonPrivateMembers) {
- if (shouldForward(m)) {
+ for (m <- moduleClass.info.membersBasedOnFlags(ExcludedForwarderFlags, Flags.METHOD)) {
+ if (m.isType || m.isDeferred || (m.owner eq ObjectClass) || m.isConstructor)
+ debuglog("No forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
+ else if (conflictingNames(m.name))
+ log("No forwarder for " + m + " due to conflict with " + linkedClass.info.member(m.name))
+ else {
log("Adding static forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
addForwarder(jclass, moduleClass, m)
}
- else debuglog("No forwarder for '%s' from %s to '%s'".format(m, className, moduleClass))
}
}
@@ -1079,7 +1072,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
* generated if there is no companion class: if there is, an attempt will
* instead be made to add the forwarder methods to the companion class.
*/
- def generateMirrorClass(clasz: Symbol, sourceFile: String) {
+ def generateMirrorClass(clasz: Symbol, sourceFile: SourceFile) {
import JAccessFlags._
val moduleName = javaName(clasz) // + "$"
val mirrorName = moduleName.substring(0, moduleName.length() - 1)
@@ -1087,7 +1080,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
mirrorName,
JAVA_LANG_OBJECT.getName,
JClass.NO_INTERFACES,
- sourceFile)
+ "" + sourceFile)
log("Dumping mirror class for '%s'".format(mirrorClass.getName))
addForwarders(mirrorClass, clasz)
@@ -1199,7 +1192,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
hostSymbol.info ; methodOwner.info
def isInterfaceCall(sym: Symbol) = (
- sym.isInterface
+ sym.isInterface && methodOwner != ObjectClass
|| sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass)
)
// whether to reference the type of the receiver or
@@ -1901,7 +1894,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if (sym.isInterface) ACC_INTERFACE else 0,
if (finalFlag) ACC_FINAL else 0,
if (sym.isStaticMember) ACC_STATIC else 0,
- if (sym.isBridge || sym.hasFlag(Flags.MIXEDIN) && sym.isMethod) ACC_BRIDGE else 0,
+ if (sym.isBridge) ACC_BRIDGE else 0,
if (sym.isClass && !sym.isInterface) ACC_SUPER else 0,
if (sym.isVarargsMethod) ACC_VARARGS else 0
)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
index acaf1f6cc2..93d3d19ac8 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
@@ -33,11 +33,11 @@ trait GenJVMUtil {
)
// Don't put this in per run caches.
- private val javaNameCache = new mutable.WeakHashMap[Symbol, String]() ++= List(
- NothingClass -> RuntimeNothingClass.fullName('/'),
- RuntimeNothingClass -> RuntimeNothingClass.fullName('/'),
- NullClass -> RuntimeNullClass.fullName('/'),
- RuntimeNullClass -> RuntimeNullClass.fullName('/')
+ private val javaNameCache = new mutable.WeakHashMap[Symbol, Name]() ++= List(
+ NothingClass -> binarynme.RuntimeNothing,
+ RuntimeNothingClass -> binarynme.RuntimeNothing,
+ NullClass -> binarynme.RuntimeNull,
+ RuntimeNullClass -> binarynme.RuntimeNull
)
/** This trait may be used by tools who need access to
@@ -70,7 +70,6 @@ trait GenJVMUtil {
def mkArray(xs: Traversable[JType]): Array[JType] = { val a = new Array[JType](xs.size); xs.copyToArray(a); a }
def mkArray(xs: Traversable[String]): Array[String] = { val a = new Array[String](xs.size); xs.copyToArray(a); a }
-
/** Return the a name of this symbol that can be used on the Java
* platform. It removes spaces from names.
*
@@ -86,11 +85,13 @@ trait GenJVMUtil {
*/
def javaName(sym: Symbol): String =
javaNameCache.getOrElseUpdate(sym, {
- if (sym.isClass || (sym.isModule && !sym.isMethod))
- sym.javaBinaryName
- else
- sym.javaSimpleName
- })
+ sym.name.newName(
+ if (sym.isClass || (sym.isModule && !sym.isMethod))
+ sym.javaBinaryName
+ else
+ sym.javaSimpleName
+ )
+ }).toString
def javaType(t: TypeKind): JType = (t: @unchecked) match {
case UNIT => JType.VOID
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
index e208f5a8da..d2e54ff3f1 100644
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
@@ -124,8 +124,8 @@ abstract class GenMSIL extends SubComponent {
// Scala attributes
// symtab.Definitions -> object (singleton..)
val SerializableAttr = definitions.SerializableAttr.tpe
- val CloneableAttr = definitions.getClass("scala.cloneable").tpe
- val TransientAtt = definitions.getClass("scala.transient").tpe
+ val CloneableAttr = definitions.CloneableAttr.tpe
+ val TransientAtt = definitions.TransientAttr.tpe
// remoting: the architectures are too different, no mapping (no portable code
// possible)
@@ -1898,8 +1898,8 @@ abstract class GenMSIL extends SubComponent {
val sc = iclass.lookupStaticCtor
if (sc.isDefined) {
val m = sc.get
- val oldLastBlock = m.code.blocks.last
- val lastBlock = m.code.newBlock
+ val oldLastBlock = m.lastBlock
+ val lastBlock = m.newBlock()
oldLastBlock.replaceInstruction(oldLastBlock.length - 1, JUMP(lastBlock))
// call object's private ctor from static ctor
lastBlock.emit(CIL_NEWOBJ(iclass.symbol.primaryConstructor))
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index 3e921cf472..e8abee7d06 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -94,12 +94,12 @@ abstract class ClosureElimination extends SubComponent {
import copyPropagation._
/* Some embryonic copy propagation. */
- def analyzeMethod(m: IMethod): Unit = try {if (m.code ne null) {
+ def analyzeMethod(m: IMethod): Unit = try {if (m.hasCode) {
log("Analyzing " + m)
cpp.init(m)
cpp.run
- for (bb <- linearizer.linearize(m)) {
+ m.linearizedBlocks() foreach { bb =>
var info = cpp.in(bb)
debuglog("Cpp info at entry to block " + bb + ": " + info)
@@ -201,28 +201,25 @@ abstract class ClosureElimination extends SubComponent {
/** Peephole optimization. */
abstract class PeepholeOpt {
- private var method: IMethod = null
+ private var method: IMethod = NoIMethod
/** Concrete implementations will perform their optimizations here */
def peep(bb: BasicBlock, i1: Instruction, i2: Instruction): Option[List[Instruction]]
var liveness: global.icodes.liveness.LivenessAnalysis = null
- def apply(m: IMethod): Unit = if (m.code ne null) {
+ def apply(m: IMethod): Unit = if (m.hasCode) {
method = m
liveness = new global.icodes.liveness.LivenessAnalysis
liveness.init(m)
liveness.run
- for (b <- m.code.blocks)
- transformBlock(b)
+ m foreachBlock transformBlock
}
def transformBlock(b: BasicBlock): Unit = if (b.size >= 2) {
- var newInstructions: List[Instruction] = Nil
-
- newInstructions = b.toList
-
+ var newInstructions: List[Instruction] = b.toList
var redo = false
+
do {
var h = newInstructions.head
var t = newInstructions.tail
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index 64df3b4636..5fc7329955 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -72,7 +72,7 @@ abstract class DeadCodeElimination extends SubComponent {
val dropOf: mutable.Map[(BasicBlock, Int), List[(BasicBlock, Int)]] = perRunCaches.newMap()
def dieCodeDie(m: IMethod) {
- if (m.code ne null) {
+ if (m.hasCode) {
log("dead code elimination on " + m);
dropOf.clear()
m.code.blocks.clear()
@@ -90,12 +90,12 @@ abstract class DeadCodeElimination extends SubComponent {
}
/** collect reaching definitions and initial useful instructions for this method. */
- def collectRDef(m: IMethod): Unit = if (m.code ne null) {
+ def collectRDef(m: IMethod): Unit = if (m.hasCode) {
defs = immutable.HashMap.empty; worklist.clear(); useful.clear();
rdef.init(m);
rdef.run;
- for (bb <- m.code.blocks.toList) {
+ m foreachBlock { bb =>
useful(bb) = new mutable.BitSet(bb.size)
var rd = rdef.in(bb);
for (Pair(i, idx) <- bb.toList.zipWithIndex) {
@@ -184,7 +184,7 @@ abstract class DeadCodeElimination extends SubComponent {
def sweep(m: IMethod) {
val compensations = computeCompensations(m)
- for (bb <- m.code.blocks.toList) {
+ m foreachBlock { bb =>
// Console.println("** Sweeping block " + bb + " **")
val oldInstr = bb.toList
bb.open
@@ -223,7 +223,7 @@ abstract class DeadCodeElimination extends SubComponent {
private def computeCompensations(m: IMethod): mutable.Map[(BasicBlock, Int), List[Instruction]] = {
val compensations: mutable.Map[(BasicBlock, Int), List[Instruction]] = new mutable.HashMap
- for (bb <- m.code.blocks) {
+ m foreachBlock { bb =>
assert(bb.closed, "Open block in computeCompensations")
for ((i, idx) <- bb.toList.zipWithIndex) {
if (!useful(bb)(idx)) {
diff --git a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
index 1d971beae4..a37a3406a8 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/InlineExceptionHandlers.scala
@@ -79,7 +79,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
/* Type Flow Analysis */
private val tfa: analysis.MethodTFA = new analysis.MethodTFA()
private var tfaCache: Map[Int, tfa.lattice.Elem] = Map.empty
- private var analyzedMethod: IMethod = null
+ private var analyzedMethod: IMethod = NoIMethod
/* Blocks that need to be analyzed */
private var todoBlocks: List[BasicBlock] = Nil
@@ -110,7 +110,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
* inlined blocks, so worst case scenario we double the size of the code
*/
private def applyMethod(method: IMethod): Unit = {
- if (method.code ne null) {
+ if (method.hasCode) {
// create the list of starting blocks
todoBlocks = global.icodes.linearizer.linearize(method)
@@ -127,7 +127,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
todoBlocks = Nil
// Type flow analysis cleanup
- analyzedMethod = null
+ analyzedMethod = NoIMethod
tfaCache = Map.empty
//TODO: Need a way to clear tfa structures
}
@@ -151,7 +151,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
* - we change the THROW exception to the new Clear stack + JUMP code
*/
for {
- (instr @ THROW(clazz), index) <- bblock.zipWithIndex
+ (instr @ THROW(clazz), index) <- bblock.iterator.zipWithIndex
// Decide if any handler fits this exception
// If not, then nothing to do, we cannot determine statically which handler will catch the exception
(handler, caughtException) <- findExceptionHandler(toTypeKind(clazz.tpe), bblock.exceptionSuccessors)
@@ -181,7 +181,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
if (!canReplaceHandler) {
currentClass.cunit.warning(NoPosition, "Unable to inline the exception handler inside incorrect" +
- " block:\n" + bblock.mkString("\n") + "\nwith stack: " + typeInfo + " just " +
+ " block:\n" + bblock.iterator.mkString("\n") + "\nwith stack: " + typeInfo + " just " +
"before instruction index " + index)
}
else {
@@ -261,13 +261,13 @@ abstract class InlineExceptionHandlers extends SubComponent {
private def getTypesAtBlockEntry(bblock: BasicBlock): tfa.lattice.Elem = {
// lazily perform tfa, because it's expensive
// cache results by block label, as rewriting the code messes up the block's hashCode
- if (analyzedMethod eq null) {
+ if (analyzedMethod eq NoIMethod) {
analyzedMethod = bblock.method
tfa.init(bblock.method)
tfa.run
log(" performed tfa on method: " + bblock.method)
- for (block <- bblock.method.code.blocks.sortBy(_.label))
+ for (block <- bblock.method.blocks.sortBy(_.label))
tfaCache += block.label -> tfa.in(block)
}
@@ -360,7 +360,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
val caughtException = toTypeKind(caughtClass.tpe)
// copy the exception handler code once again, dropping the LOAD_EXCEPTION
val copy = handler.code.newBlock
- copy.emitOnly(handler drop dropCount: _*)
+ copy.emitOnly(handler.iterator drop dropCount toSeq: _*)
// extend the handlers of the handler to the copy
for (parentHandler <- handler.method.exh ; if parentHandler covers handler) {
@@ -382,7 +382,7 @@ abstract class InlineExceptionHandlers extends SubComponent {
case _ =>
currentClass.cunit.warning(NoPosition, "Unable to inline the exception handler due to incorrect format:\n" +
- handler.mkString("\n"))
+ handler.iterator.mkString("\n"))
None
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index d56a0740d9..e3d21011d1 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -9,6 +9,7 @@ package backend.opt
import scala.collection.mutable
import scala.tools.nsc.symtab._
+import scala.tools.nsc.util.{ NoSourceFile }
/**
* @author Iulian Dragos
@@ -84,9 +85,9 @@ abstract class Inliners extends SubComponent {
/* fresh name counter */
val fresh = perRunCaches.newMap[String, Int]() withDefaultValue 0
- def freshName(s: String) = {
+ def freshName(s: String): TermName = {
fresh(s) += 1
- s + fresh(s)
+ newTermName(s + fresh(s))
}
private def hasInline(sym: Symbol) = sym hasAnnotation ScalaInlineClass
@@ -111,8 +112,8 @@ abstract class Inliners extends SubComponent {
private val inlinedMethodCount = perRunCaches.newMap[Symbol, Int]() withDefaultValue 0
def analyzeMethod(m: IMethod): Unit = {
- var sizeBeforeInlining = if (m.code ne null) m.code.blockCount else 0
- var instrBeforeInlining = if (m.code ne null) m.code.instructionCount else 0
+ var sizeBeforeInlining = if (m.hasCode) m.code.blockCount else 0
+ var instrBeforeInlining = if (m.hasCode) m.code.instructionCount else 0
var retry = false
var count = 0
fresh.clear()
@@ -210,11 +211,11 @@ abstract class Inliners extends SubComponent {
if (caller.inline) {
log("Not inlining into " + caller.sym.originalName.decode + " because it is marked @inline.")
}
- else if (caller.hasCode) {
+ else if (caller.m.hasCode) {
log("Analyzing " + m + " count " + count + " with " + caller.length + " blocks")
tfa init m
tfa.run
- caller.linearized foreach { bb =>
+ caller.m.linearizedBlocks() foreach { bb =>
info = tfa in bb
breakable {
@@ -311,18 +312,16 @@ abstract class Inliners extends SubComponent {
def isMonadic = isMonadicMethod(sym)
def handlers = m.exh
- def blocks = if (m.code eq null) sys.error("blocks = null + " + m) else m.code.blocks
+ def blocks = m.blocks
def locals = m.locals
def length = blocks.length
def openBlocks = blocks filterNot (_.closed)
- def instructions = blocks.flatten
+ def instructions = m.code.instructions
def linearized = linearizer linearize m
def isSmall = (length <= SMALL_METHOD_SIZE) && blocks(0).length < 10
def isLarge = length > MAX_INLINE_SIZE
def isRecursive = m.recursive
- def hasCode = m.code != null
- def hasSourceFile = m.sourceFile != null
def hasHandlers = handlers.nonEmpty
def hasNonFinalizerHandler = handlers exists {
case _: Finalizer => true
@@ -457,7 +456,7 @@ abstract class Inliners extends SubComponent {
if (retVal ne null)
caller addLocal retVal
- inc.blocks foreach { b =>
+ inc.m foreachBlock { b =>
inlinedBlock += (b -> newBlock())
inlinedBlock(b).varsInScope ++= (b.varsInScope map inlinedLocals)
}
@@ -475,11 +474,11 @@ abstract class Inliners extends SubComponent {
blockEmit(STORE_LOCAL(inlinedThis))
// jump to the start block of the callee
- blockEmit(JUMP(inlinedBlock(inc.m.code.startBlock)))
+ blockEmit(JUMP(inlinedBlock(inc.m.startBlock)))
block.close
// duplicate the other blocks in the callee
- linearizer linearize inc.m foreach { bb =>
+ inc.m.linearizedBlocks() foreach { bb =>
var info = a in bb
def emitInlined(i: Instruction) = inlinedBlock(bb).emit(i, targetPos)
def emitDrops(toDrop: Int) = info.stack.types drop toDrop foreach (t => emitInlined(DROP(t)))
@@ -511,23 +510,23 @@ abstract class Inliners extends SubComponent {
}
def isStampedForInlining(stack: TypeStack) =
- !sameSymbols && inc.hasCode && shouldInline && isSafeToInline(stack)
+ !sameSymbols && inc.m.hasCode && shouldInline && isSafeToInline(stack)
def logFailure(stack: TypeStack) = log(
"""|inline failed for %s:
| pair.sameSymbols: %s
| inc.numInlined < 2: %s
- | inc.hasCode: %s
+ | inc.m.hasCode: %s
| isSafeToInline: %s
| shouldInline: %s
""".stripMargin.format(
inc.m, sameSymbols, inc.numInlined < 2,
- inc.hasCode, isSafeToInline(stack), shouldInline
+ inc.m.hasCode, isSafeToInline(stack), shouldInline
)
)
def failureReason(stack: TypeStack) =
- if (!inc.hasCode) "bytecode was unavailable"
+ if (!inc.m.hasCode) "bytecode was unavailable"
else if (!isSafeToInline(stack)) "it is unsafe (target may reference private fields)"
else "of a bug (run with -Ylog:inline -Ydebug for more information)"
@@ -550,14 +549,14 @@ abstract class Inliners extends SubComponent {
*/
def isSafeToInline(stack: TypeStack): Boolean = {
def makePublic(f: Symbol): Boolean =
- inc.hasSourceFile && (f.isSynthetic || f.isParamAccessor) && {
+ (inc.m.sourceFile ne NoSourceFile) && (f.isSynthetic || f.isParamAccessor) && {
debuglog("Making not-private symbol out of synthetic: " + f)
f setNotFlag Flags.PRIVATE
true
}
- if (!inc.hasCode || inc.isRecursive)
+ if (!inc.m.hasCode || inc.isRecursive)
return false
val accessNeeded = usesNonPublics.getOrElseUpdate(inc.m, {
@@ -610,7 +609,7 @@ abstract class Inliners extends SubComponent {
* - it's good to inline closures functions.
* - it's bad (useless) to inline inside bridge methods
*/
- private def neverInline = caller.isBridge || !inc.hasCode || inc.noinline
+ private def neverInline = caller.isBridge || !inc.m.hasCode || inc.noinline
private def alwaysInline = inc.inline
def shouldInline: Boolean = !neverInline && (alwaysInline || {
diff --git a/src/compiler/scala/tools/nsc/dependencies/Changes.scala b/src/compiler/scala/tools/nsc/dependencies/Changes.scala
index 4c7263ef69..089ef9cf35 100644
--- a/src/compiler/scala/tools/nsc/dependencies/Changes.scala
+++ b/src/compiler/scala/tools/nsc/dependencies/Changes.scala
@@ -18,8 +18,8 @@ abstract class Changes {
abstract class Change
- private lazy val annotationsChecked =
- List(definitions.getClass("scala.specialized")) // Any others that should be checked?
+ private lazy val annotationsChecked =
+ List(definitions.SpecializedClass) // Any others that should be checked?
private val flagsToCheck = IMPLICIT | FINAL | PRIVATE | PROTECTED | SEALED |
OVERRIDE | CASE | ABSTRACT | DEFERRED | METHOD |
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index 5a510803ed..9a025b0d14 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -96,7 +96,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
val documentError: PartialFunction[Throwable, Unit] = {
case NoCompilerRunException =>
- reporter.info(NoPosition, "No documentation generated with unsucessful compiler run", false)
+ reporter.info(null, "No documentation generated with unsucessful compiler run", false)
case _: ClassNotFoundException =>
()
}
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index f900859f46..0fea0a2d92 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -818,7 +818,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
def add(sym: Symbol, pre: Type, implicitlyAdded: Boolean)(toMember: (Symbol, Type) => M) {
if ((sym.isGetter || sym.isSetter) && sym.accessed != NoSymbol) {
add(sym.accessed, pre, implicitlyAdded)(toMember)
- } else if (!sym.name.decode.containsName(Dollar) && !sym.isSynthetic && sym.hasRawInfo) {
+ } else if (!sym.name.decodedName.containsName(Dollar) && !sym.isSynthetic && sym.hasRawInfo) {
val symtpe = pre.memberType(sym) onTypeError ErrorType
matching(sym, symtpe, this(sym.name)) match {
case Some(m) =>
diff --git a/src/compiler/scala/tools/nsc/interactive/Picklers.scala b/src/compiler/scala/tools/nsc/interactive/Picklers.scala
index 2b6e793c5c..b7a9c7329c 100644
--- a/src/compiler/scala/tools/nsc/interactive/Picklers.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Picklers.scala
@@ -101,7 +101,7 @@ trait Picklers { self: Global =>
if (sym1.isOverloaded) {
val index = sym1.alternatives.indexOf(sym)
assert(index >= 0, sym1+" not found in alternatives "+sym1.alternatives)
- buf += index.toString
+ buf += newTermName(index.toString)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala
index 81d4faa36e..1d78cc6e1c 100644
--- a/src/compiler/scala/tools/nsc/interactive/REPL.scala
+++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala
@@ -37,7 +37,7 @@ object REPL {
reporter = new ConsoleReporter(settings)
val command = new CompilerCommand(args.toList, settings)
if (command.settings.version.value)
- reporter.info(null, versionMsg, true)
+ reporter.echo(versionMsg)
else {
try {
object compiler extends Global(command.settings, reporter) {
@@ -48,7 +48,7 @@ object REPL {
return
}
if (command.shouldStopWithInfo) {
- reporter.info(null, command.getInfoMessage(compiler), true)
+ reporter.echo(command.getInfoMessage(compiler))
} else {
run(compiler)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala b/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala
index 2c556656ca..d889cadf47 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala
@@ -12,6 +12,7 @@ trait Dossiers {
import intp._
import intp.global._
+ import definitions._
trait Dossier {
def symbol: Symbol
@@ -34,7 +35,7 @@ trait Dossiers {
class TermDossier(val symbol: TermSymbol, val staticType: Type, val value: AnyRef) extends Dossier {
def runtimeClass: JClass = value.getClass
- def runtimeSymbol: Symbol = safeClass(runtimeClass.getName) getOrElse NoSymbol
+ def runtimeSymbol: Symbol = getClassIfDefined(runtimeClass.getName)
def runtimeType: Type = runtimeSymbol.tpe
def runtimeTypeString = TypeStrings.fromClazz(runtimeClass)
diff --git a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala
index 115cef7f00..9f5fde70d8 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ExprTyper.scala
@@ -15,6 +15,7 @@ trait ExprTyper {
import repl._
import replTokens.{ Tokenizer }
import global.{ reporter => _, Import => _, _ }
+ import definitions._
import syntaxAnalyzer.{ UnitParser, UnitScanner, token2name }
import naming.freshInternalVarName
@@ -70,30 +71,29 @@ trait ExprTyper {
// 2) A path loadable via getModule.
// 3) Try interpreting it as an expression.
private var typeOfExpressionDepth = 0
- def typeOfExpression(expr: String, silent: Boolean = true): Option[Type] = {
+ def typeOfExpression(expr: String, silent: Boolean = true): Type = {
repltrace("typeOfExpression(" + expr + ")")
if (typeOfExpressionDepth > 2) {
repldbg("Terminating typeOfExpression recursion for expression: " + expr)
- return None
+ return NoType
}
- def asQualifiedImport = {
+ def asQualifiedImport: Type = {
val name = expr.takeWhile(_ != '.')
- importedTermNamed(name) flatMap { sym =>
- typeOfExpression(sym.fullName + expr.drop(name.length), true)
- }
+ typeOfExpression(importedTermNamed(name).fullName + expr.drop(name.length), true)
}
- def asModule = safeModule(expr) map (_.tpe)
- def asExpr = {
+ def asModule: Type = getModuleIfDefined(expr).tpe
+ def asExpr: Type = {
val lhs = freshInternalVarName()
val line = "lazy val " + lhs + " =\n" + expr
interpret(line, true) match {
case IR.Success => typeOfExpression(lhs, true)
- case _ => None
+ case _ => NoType
}
}
- def evaluate() = {
+
+ def evaluate(): Type = {
typeOfExpressionDepth += 1
try typeOfTerm(expr) orElse asModule orElse asExpr orElse asQualifiedImport
finally typeOfExpressionDepth -= 1
@@ -107,26 +107,27 @@ trait ExprTyper {
if (!silent)
evaluate()
- None
+ NoType
}
}
// Since people will be giving us ":t def foo = 5" even though that is not an
// expression, we have a means of typing declarations too.
- private def typeOfDeclaration(code: String): Option[Type] = {
+ private def typeOfDeclaration(code: String): Type = {
repltrace("typeOfDeclaration(" + code + ")")
val obname = freshInternalVarName()
interpret("object " + obname + " {\n" + code + "\n}\n", true) match {
case IR.Success =>
val sym = symbolOfTerm(obname)
- if (sym == NoSymbol) None else {
+ if (sym == NoSymbol) NoType else {
// TODO: bitmap$n is not marked synthetic.
val decls = sym.tpe.decls.toList filterNot (x => x.isConstructor || x.isPrivate || (x.name.toString contains "$"))
repltrace("decls: " + decls)
- decls.lastOption map (decl => typeCleanser(sym, decl.name))
+ if (decls.isEmpty) NoType
+ else typeCleanser(sym, decls.last.name)
}
case _ =>
- None
+ NoType
}
}
// def compileAndTypeExpr(expr: String): Option[Typer] = {
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 2159ecbb8a..0dc51d5eb0 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -53,6 +53,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
def isAsync = !settings.Yreplsync.value
lazy val power = new Power(intp, new StdReplVals(this))
+ lazy val NoType = intp.global.NoType
// TODO
// object opt extends AestheticSettings
@@ -436,9 +437,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
// Still todo: modules.
private def typeCommand(line: String): Result = {
if (line.trim == "") ":type <expression>"
- else intp.typeOfExpression(line, false) match {
- case Some(tp) => intp.afterTyper(tp.toString)
- case _ => "" // the error message was already printed
+ else {
+ val tp = intp.typeOfExpression(line, false)
+ if (tp == NoType) "" // the error message was already printed
+ else intp.afterTyper(tp.toString)
}
}
private def warningsCommand(): Result = {
@@ -485,13 +487,14 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
case wrapper :: Nil =>
intp.typeOfExpression(wrapper) match {
- case Some(PolyType(List(targ), MethodType(List(arg), restpe))) =>
+ case PolyType(List(targ), MethodType(List(arg), restpe)) =>
intp setExecutionWrapper intp.pathToTerm(wrapper)
"Set wrapper to '" + wrapper + "'"
- case Some(x) =>
- failMsg + "\nFound: " + x
- case _ =>
- failMsg + "\nFound: <unknown>"
+ case tp =>
+ failMsg + (
+ if (tp == g.NoType) "\nFound: <unknown>"
+ else "\nFound: <unknown>"
+ )
}
case _ => failMsg
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 8e4ff8aa37..0f0ab69e6d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -188,7 +188,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
import global._
import definitions.{
ScalaPackage, JavaLangPackage, PredefModule, RootClass,
- getClassIfDefined, getModuleIfDefined
+ getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass
}
private implicit def privateTreeOps(t: Tree): List[Tree] = {
@@ -196,6 +196,12 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def foreach[U](f: Tree => U): Unit = t foreach { x => f(x) ; () }
}).toList
}
+
+ implicit def installReplTypeOps(tp: Type): ReplTypeOps = new ReplTypeOps(tp)
+ class ReplTypeOps(tp: Type) {
+ def orElse(other: => Type): Type = if (tp ne NoType) tp else other
+ def andAlso(fn: Type => Type): Type = if (tp eq NoType) tp else fn(tp)
+ }
// TODO: If we try to make naming a lazy val, we run into big time
// scalac unhappiness with what look like cycles. It has not been easy to
@@ -204,12 +210,13 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
val global: imain.global.type = imain.global
} with Naming {
// make sure we don't overwrite their unwisely named res3 etc.
- override def freshUserVarName(): String = {
- val name = super.freshUserVarName()
- if (definedNameMap contains name) freshUserVarName()
+ def freshUserTermName(): TermName = {
+ val name = newTermName(freshUserVarName())
+ if (definedNameMap contains name) freshUserTermName()
else name
}
- def isInternalVarName(name: Name): Boolean = isInternalVarName("" + name)
+ def isUserTermName(name: Name) = isUserVarName("" + name)
+ def isInternalTermName(name: Name) = isInternalVarName("" + name)
}
import naming._
@@ -359,7 +366,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
private def mostRecentlyHandledTree: Option[Tree] = {
prevRequests.reverse foreach { req =>
req.handlers.reverse foreach {
- case x: MemberDefHandler if x.definesValue && !isInternalVarName(x.name) => return Some(x.member)
+ case x: MemberDefHandler if x.definesValue && !isInternalTermName(x.name) => return Some(x.member)
case _ => ()
}
}
@@ -501,7 +508,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
trees.last match {
case _:Assign => // we don't want to include assignments
case _:TermTree | _:Ident | _:Select => // ... but do want other unnamed terms.
- val varName = if (synthetic) freshInternalVarName() else freshUserVarName()
+ val varName = if (synthetic) freshInternalVarName() else ("" + freshUserTermName())
val rewrittenLine = (
// In theory this would come out the same without the 1-specific test, but
// it's a cushion against any more sneaky parse-tree position vs. code mismatches:
@@ -643,7 +650,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def directBind(name: String, boundType: String, value: Any): IR.Result = {
val result = bind(name, boundType, value)
if (result == IR.Success)
- directlyBoundNames += name
+ directlyBoundNames += newTermName(name)
result
}
def directBind(p: NamedParam): IR.Result = directBind(p.name, p.tpe, p.value)
@@ -651,7 +658,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def rebind(p: NamedParam): IR.Result = {
val name = p.name
- val oldType = typeOfTerm(name) getOrElse { return IR.Error }
+ val oldType = typeOfTerm(name) orElse { return IR.Error }
val newType = p.tpe
val tempName = freshInternalVarName()
@@ -666,7 +673,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p))
def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
def bind[T: Manifest](name: String, value: T): IR.Result = bind((name, value))
- def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x)
+ def bindValue(x: Any): IR.Result = bindValue("" + freshUserTermName(), x)
def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x)
/** Reset this interpreter, forgetting all user-specified requests. */
@@ -789,7 +796,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
* following accessPath into the outer one.
*/
def resolvePathToSymbol(accessPath: String): Symbol = {
- val readRoot = definitions.getModule(readPath) // the outermost wrapper
+ val readRoot = getRequiredModule(readPath) // the outermost wrapper
(accessPath split '.').foldLeft(readRoot) { (sym, name) =>
if (name == "") sym else
lineAfterTyper(sym.info member newTermName(name))
@@ -1039,16 +1046,6 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def requestHistoryForName(name: Name): List[Request] =
prevRequests.toList.reverse filter (_.definedNames contains name)
- def safeClass(name: String): Option[Symbol] = {
- try Some(definitions.getClass(newTypeName(name)))
- catch { case _: MissingRequirementError => None }
- }
-
- def safeModule(name: String): Option[Symbol] = {
- try Some(definitions.getModule(newTermName(name)))
- catch { case _: MissingRequirementError => None }
- }
-
def definitionForName(name: Name): Option[MemberHandler] =
requestForName(name) flatMap { req =>
req.handlers find (_.definedNames contains name)
@@ -1060,34 +1057,32 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def classOfTerm(id: String): Option[JClass] =
valueOfTerm(id) map (_.getClass)
- def typeOfTerm(id: String): Option[Type] = newTermName(id) match {
- case nme.ROOTPKG => Some(definitions.RootClass.tpe)
- case name => requestForName(name) flatMap (_.compilerTypeOf get name)
+ def typeOfTerm(id: String): Type = newTermName(id) match {
+ case nme.ROOTPKG => definitions.RootClass.tpe
+ case name => requestForName(name) flatMap (_.compilerTypeOf get name) getOrElse NoType
}
def symbolOfTerm(id: String): Symbol =
requestForIdent(id) flatMap (_.definedSymbols get newTermName(id)) getOrElse NoSymbol
def runtimeClassAndTypeOfTerm(id: String): Option[(JClass, Type)] = {
- for {
- clazz <- classOfTerm(id)
- tpe <- runtimeTypeOfTerm(id)
- nonAnon <- clazz.supers find (!_.isScalaAnonymous)
- } yield {
- (nonAnon, tpe)
+ classOfTerm(id) flatMap { clazz =>
+ clazz.supers find (!_.isScalaAnonymous) map { nonAnon =>
+ (nonAnon, runtimeTypeOfTerm(id))
+ }
}
}
- def runtimeTypeOfTerm(id: String): Option[Type] = {
- for {
- tpe <- typeOfTerm(id)
- clazz <- classOfTerm(id)
- staticSym = tpe.typeSymbol
- runtimeSym <- safeClass(clazz.getName)
- if runtimeSym != staticSym
- if runtimeSym isSubClass staticSym
+ def runtimeTypeOfTerm(id: String): Type = {
+ typeOfTerm(id) andAlso { tpe =>
+ val clazz = classOfTerm(id) getOrElse { return NoType }
+ val staticSym = tpe.typeSymbol
+ val runtimeSym = getClassIfDefined(clazz.getName)
+
+ if ((runtimeSym != NoSymbol) && (runtimeSym != staticSym) && (runtimeSym isSubClass staticSym))
+ runtimeSym.info
+ else NoType
}
- yield runtimeSym.info
}
object replTokens extends {
@@ -1099,16 +1094,16 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
} with ExprTyper { }
def parse(line: String): Option[List[Tree]] = exprTyper.parse(line)
- def typeOfExpression(expr: String, silent: Boolean = true): Option[Type] = {
+ def typeOfExpression(expr: String, silent: Boolean = true): Type =
exprTyper.typeOfExpression(expr, silent)
- }
+
def prettyPrint(code: String) =
replTokens.prettyPrint(exprTyper tokens code)
protected def onlyTerms(xs: List[Name]) = xs collect { case x: TermName => x }
protected def onlyTypes(xs: List[Name]) = xs collect { case x: TypeName => x }
- def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalVarName
+ def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalTermName
def definedTypes = onlyTypes(allDefinedNames)
def definedSymbols = prevRequests.toSet flatMap ((x: Request) => x.definedSymbols.values)
diff --git a/src/compiler/scala/tools/nsc/interpreter/Imports.scala b/src/compiler/scala/tools/nsc/interpreter/Imports.scala
index 10e3796404..d34ca8bbca 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Imports.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Imports.scala
@@ -34,8 +34,9 @@ trait Imports {
def languageWildcards: List[Type] = languageWildcardSyms map (_.tpe)
def languageWildcardHandlers = languageWildcardSyms map makeWildcardImportHandler
- def importedTerms = onlyTerms(importHandlers flatMap (_.importedNames))
- def importedTypes = onlyTypes(importHandlers flatMap (_.importedNames))
+ def allImportedNames = importHandlers flatMap (_.importedNames)
+ def importedTerms = onlyTerms(allImportedNames)
+ def importedTypes = onlyTypes(allImportedNames)
/** Types which have been wildcard imported, such as:
* val x = "abc" ; import x._ // type java.lang.String
@@ -49,10 +50,7 @@ trait Imports {
* into the compiler scopes.
*/
def sessionWildcards: List[Type] = {
- importHandlers flatMap {
- case x if x.importsWildcard => x.targetType
- case _ => None
- } distinct
+ importHandlers filter (_.importsWildcard) map (_.targetType) distinct
}
def wildcardTypes = languageWildcards ++ sessionWildcards
@@ -63,14 +61,15 @@ trait Imports {
def importedTypeSymbols = importedSymbols collect { case x: TypeSymbol => x }
def implicitSymbols = importedSymbols filter (_.isImplicit)
- def importedTermNamed(name: String) = importedTermSymbols find (_.name.toString == name)
+ def importedTermNamed(name: String): Symbol =
+ importedTermSymbols find (_.name.toString == name) getOrElse NoSymbol
/** Tuples of (source, imported symbols) in the order they were imported.
*/
def importedSymbolsBySource: List[(Symbol, List[Symbol])] = {
val lang = languageWildcardSyms map (sym => (sym, membersAtPickler(sym)))
- val session = importHandlers filter (_.targetType.isDefined) map { mh =>
- (mh.targetType.get.typeSymbol, mh.importedSymbols)
+ val session = importHandlers filter (_.targetType != NoType) map { mh =>
+ (mh.targetType.typeSymbol, mh.importedSymbols)
}
lang ++ session
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
index 9c5299b633..d96e8b07fc 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -16,7 +16,7 @@ import collection.mutable.ListBuffer
class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput {
val global: intp.global.type = intp.global
import global._
- import definitions.{ PredefModule, RootClass, AnyClass, AnyRefClass, ScalaPackage, JavaLangPackage }
+ import definitions.{ PredefModule, RootClass, AnyClass, AnyRefClass, ScalaPackage, JavaLangPackage, getModuleIfDefined }
type ExecResult = Any
import intp.{ debugging, afterTyper }
@@ -24,14 +24,13 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
private var verbosity: Int = 0
def resetVerbosity() = verbosity = 0
- def getType(name: String, isModule: Boolean) = {
- val f = if (isModule) definitions.getModule(_: Name) else definitions.getClass(_: Name)
- try Some(f(name).tpe)
- catch { case _: MissingRequirementError => None }
- }
-
- def typeOf(name: String) = getType(name, false)
- def moduleOf(name: String) = getType(name, true)
+ def getSymbol(name: String, isModule: Boolean) = (
+ if (isModule) getModuleIfDefined(name)
+ else getModuleIfDefined(name)
+ )
+ def getType(name: String, isModule: Boolean) = getSymbol(name, isModule).tpe
+ def typeOf(name: String) = getType(name, false)
+ def moduleOf(name: String) = getType(name, true)
trait CompilerCompletion {
def tp: Type
@@ -46,9 +45,9 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
private def anyMembers = AnyClass.tpe.nonPrivateMembers
def anyRefMethodsToShow = Set("isInstanceOf", "asInstanceOf", "toString")
- def tos(sym: Symbol) = sym.name.decode.toString
- def memberNamed(s: String) = members find (x => tos(x) == s)
- def hasMethod(s: String) = methods exists (x => tos(x) == s)
+ def tos(sym: Symbol): String = sym.decodedName
+ def memberNamed(s: String) = afterTyper(effectiveTp member newTermName(s))
+ def hasMethod(s: String) = memberNamed(s).isMethod
// XXX we'd like to say "filterNot (_.isDeprecated)" but this causes the
// compiler to crash for reasons not yet known.
@@ -62,6 +61,13 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
def packageNames = packages map tos
def aliasNames = aliases map tos
}
+
+ object NoTypeCompletion extends TypeMemberCompletion(NoType) {
+ override def memberNamed(s: String) = NoSymbol
+ override def members = Nil
+ override def follow(s: String) = None
+ override def alternativesFor(id: String) = Nil
+ }
object TypeMemberCompletion {
def apply(tp: Type, runtimeType: Type, param: NamedParam): TypeMemberCompletion = {
@@ -90,7 +96,8 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
}
}
def apply(tp: Type): TypeMemberCompletion = {
- if (tp.typeSymbol.isPackageClass) new PackageCompletion(tp)
+ if (tp eq NoType) NoTypeCompletion
+ else if (tp.typeSymbol.isPackageClass) new PackageCompletion(tp)
else new TypeMemberCompletion(tp)
}
def imported(tp: Type) = new ImportCompletion(tp)
@@ -118,7 +125,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
debugging(tp + " completions ==> ")(filtered(memberNames))
override def follow(s: String): Option[CompletionAware] =
- debugging(tp + " -> '" + s + "' ==> ")(memberNamed(s) map (x => TypeMemberCompletion(x.tpe)))
+ debugging(tp + " -> '" + s + "' ==> ")(Some(TypeMemberCompletion(memberNamed(s).tpe)) filterNot (_ eq NoTypeCompletion))
override def alternativesFor(id: String): List[String] =
debugging(id + " alternatives ==> ") {
@@ -155,28 +162,29 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
object ids extends CompletionAware {
override def completions(verbosity: Int) = intp.unqualifiedIds ++ List("classOf") //, "_root_")
// now we use the compiler for everything.
- override def follow(id: String) = {
- if (completions(0) contains id) {
- intp typeOfExpression id map { tpe =>
- def default = TypeMemberCompletion(tpe)
-
- // only rebinding vals in power mode for now.
- if (!isReplPower) default
- else intp runtimeClassAndTypeOfTerm id match {
- case Some((clazz, runtimeType)) =>
- val sym = intp.symbolOfTerm(id)
- if (sym.isStable) {
- val param = new NamedParam.Untyped(id, intp valueOfTerm id getOrElse null)
- TypeMemberCompletion(tpe, runtimeType, param)
- }
- else default
- case _ =>
- default
+ override def follow(id: String): Option[CompletionAware] = {
+ if (!completions(0).contains(id))
+ return None
+
+ val tpe = intp typeOfExpression id
+ if (tpe == NoType)
+ return None
+
+ def default = Some(TypeMemberCompletion(tpe))
+
+ // only rebinding vals in power mode for now.
+ if (!isReplPower) default
+ else intp runtimeClassAndTypeOfTerm id match {
+ case Some((clazz, runtimeType)) =>
+ val sym = intp.symbolOfTerm(id)
+ if (sym.isStable) {
+ val param = new NamedParam.Untyped(id, intp valueOfTerm id getOrElse null)
+ Some(TypeMemberCompletion(tpe, runtimeType, param))
}
- }
+ else default
+ case _ =>
+ default
}
- else
- None
}
override def toString = "<repl ids> (%s)".format(completions(0).size)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
index b64f14e929..c742ab89c0 100644
--- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -169,7 +169,7 @@ trait MemberHandlers {
class ImportHandler(imp: Import) extends MemberHandler(imp) {
val Import(expr, selectors) = imp
- def targetType = intp.typeOfExpression("" + expr)
+ def targetType: Type = intp.typeOfExpression("" + expr)
override def isLegalTopLevel = true
def createImportForName(name: Name): String = {
@@ -199,10 +199,10 @@ trait MemberHandlers {
def importedSymbols = individualSymbols ++ wildcardSymbols
lazy val individualSymbols: List[Symbol] =
- atPickler(targetType.toList flatMap (tp => individualNames map (tp nonPrivateMember _)))
+ atPickler(individualNames map (targetType nonPrivateMember _))
lazy val wildcardSymbols: List[Symbol] =
- if (importsWildcard) atPickler(targetType.toList flatMap (_.nonPrivateMembers))
+ if (importsWildcard) atPickler(targetType.nonPrivateMembers)
else Nil
/** Complete list of names imported by a wildcard */
diff --git a/src/compiler/scala/tools/nsc/interpreter/Naming.scala b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
index 7377953263..8e215cf63b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Naming.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
@@ -84,7 +84,7 @@ trait Naming {
var x = 0
() => { x += 1 ; x }
}
- def freshUserVarName() = userVar()
+ def freshUserVarName() = userVar()
def freshInternalVarName() = internalVar()
def resetAllCreators() {
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 82a466a7e5..b4a9b9b0e3 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -353,7 +353,7 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl
def source(code: String) = new BatchSourceFile("<console>", code)
def unit(code: String) = new CompilationUnit(source(code))
def trees(code: String) = parse(code) getOrElse Nil
- def typeOf(id: String): Type = intp.typeOfExpression(id) getOrElse NoType
+ def typeOf(id: String) = intp.typeOfExpression(id)
override def toString = """
|** Power mode status **
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 742e9e03ca..0d7afdc4ec 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -547,7 +547,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
if (parentToken == AT && in.token == DEFAULT) {
val annot =
atPos(pos) {
- New(Select(scalaDot(newTermName("runtime")), tpnme.AnnotationDefaultATTR), List(List()))
+ New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), List(List()))
}
mods1 = mods1 withAnnotations List(annot)
skipTo(SEMI)
@@ -794,9 +794,9 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
accept(INTERFACE)
val pos = in.currentPos
val name = identForType()
- val parents = List(scalaDot(newTypeName("Annotation")),
- Select(javaLangDot(newTermName("annotation")), newTypeName("Annotation")),
- scalaDot(newTypeName("ClassfileAnnotation")))
+ val parents = List(scalaDot(tpnme.Annotation),
+ Select(javaLangDot(nme.annotation), tpnme.Annotation),
+ scalaDot(tpnme.ClassfileAnnotation))
val (statics, body) = typeBody(AT, name)
def getValueMethodType(tree: Tree) = tree match {
case DefDef(_, nme.value, _, _, tpt, _) => Some(tpt.duplicate)
@@ -838,18 +838,18 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
}
val predefs = List(
DefDef(
- Modifiers(Flags.JAVA | Flags.STATIC), newTermName("values"), List(),
+ Modifiers(Flags.JAVA | Flags.STATIC), nme.values, List(),
List(List()),
arrayOf(enumType),
blankExpr),
DefDef(
- Modifiers(Flags.JAVA | Flags.STATIC), newTermName("valueOf"), List(),
+ Modifiers(Flags.JAVA | Flags.STATIC), nme.valueOf, List(),
List(List(makeParam("x", TypeTree(StringClass.tpe)))),
enumType,
blankExpr))
accept(RBRACE)
val superclazz =
- AppliedTypeTree(javaLangDot(newTypeName("Enum")), List(enumType))
+ AppliedTypeTree(javaLangDot(tpnme.Enum), List(enumType))
addCompanionObject(consts ::: statics ::: predefs, atPos(pos) {
ClassDef(mods, name, List(),
makeTemplate(superclazz :: interfaces, body))
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 420fba911b..e5748b7c23 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -36,6 +36,9 @@ trait Patterns extends ast.TreeDSL {
// case _ => NoSymbol
// }
+ private lazy val dummyMethod =
+ new TermSymbol(NoSymbol, NoPosition, newTermName("matching$dummy"))
+
// Fresh patterns
def emptyPatterns(i: Int): List[Pattern] = List.fill(i)(NoPattern)
def emptyTrees(i: Int): List[Tree] = List.fill(i)(EmptyTree)
@@ -191,9 +194,9 @@ trait Patterns extends ast.TreeDSL {
// As yet I can't testify this is doing any good relative to using
// tpt.tpe, but it doesn't seem to hurt either.
private lazy val packedType = global.typer.computeType(tpt, tpt.tpe)
- private lazy val consRef = typeRef(NoPrefix, ConsClass, List(packedType))
- private lazy val listRef = typeRef(NoPrefix, ListClass, List(packedType))
- private lazy val seqRef = typeRef(NoPrefix, SeqClass, List(packedType))
+ private lazy val consRef = appliedType(ConsClass.typeConstructor, List(packedType))
+ private lazy val listRef = appliedType(ListClass.typeConstructor, List(packedType))
+ private lazy val seqRef = appliedType(SeqClass.typeConstructor, List(packedType))
private def thisSeqRef = {
val tc = (tree.tpe baseType SeqClass).typeConstructor
@@ -205,7 +208,6 @@ trait Patterns extends ast.TreeDSL {
private def listFolder(hd: Tree, tl: Tree): Tree = unbind(hd) match {
case t @ Star(_) => moveBindings(hd, WILD(t.tpe))
case _ =>
- val dummyMethod = new TermSymbol(NoSymbol, NoPosition, "matching$dummy")
val consType = MethodType(dummyMethod newSyntheticValueParams List(packedType, listRef), consRef)
Apply(TypeTree(consType), List(hd, tl)) setType consRef
diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
index 12306606e4..f19a285d7c 100644
--- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
@@ -47,14 +47,23 @@ abstract class Reporter {
finally incompleteHandler = saved
}
- var cancelled = false
- def hasErrors = ERROR.count > 0 || cancelled
- def hasWarnings = WARNING.count > 0
+ var cancelled = false
+ def hasErrors = ERROR.count > 0 || cancelled
+ def hasWarnings = WARNING.count > 0
- def info(pos: Position, msg: String, force: Boolean) { info0(pos, msg, INFO, force) }
- def warning(pos: Position, msg: String ) { withoutTruncating(info0(pos, msg, WARNING, false)) }
- def error(pos: Position, msg: String ) { withoutTruncating(info0(pos, msg, ERROR, false)) }
- def incompleteInputError(pos: Position, msg: String ) {
+ /** For sending a message which should not be labeled as a warning/error,
+ * but also shouldn't require -verbose to be visible.
+ */
+ def echo(msg: String): Unit = info(NoPosition, msg, true)
+ def echo(pos: Position, msg: String): Unit = info(pos, msg, true)
+
+ /** Informational messages, suppressed unless -verbose or force=true. */
+ def info(pos: Position, msg: String, force: Boolean): Unit = info0(pos, msg, INFO, force)
+
+ /** Warnings and errors. */
+ def warning(pos: Position, msg: String): Unit = withoutTruncating(info0(pos, msg, WARNING, false))
+ def error(pos: Position, msg: String): Unit = withoutTruncating(info0(pos, msg, ERROR, false))
+ def incompleteInputError(pos: Position, msg: String): Unit = {
if (incompleteHandled) incompleteHandler(pos, msg)
else error(pos, msg)
}
diff --git a/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala b/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala
index 800af55861..f55d0684c8 100644
--- a/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ReporterTimer.scala
@@ -13,8 +13,6 @@ import scala.tools.util.AbstractTimer
* timings.
*/
class ReporterTimer(reporter: Reporter) extends AbstractTimer {
-
def issue(msg: String, duration: Long) =
reporter.info(null, "[" + msg + " in " + duration + "ms]", false)
-
}
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 7fcfb6fc6d..efd5323ce2 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -67,6 +67,8 @@ trait ScalaSettings extends AbsScalaSettings
val future = BooleanSetting ("-Xfuture", "Turn on future language features.")
val genPhaseGraph = StringSetting ("-Xgenerate-phase-graph", "file", "Generate the phase graphs (outputs .dot files) to fileX.dot.", "")
val XlogImplicits = BooleanSetting ("-Xlog-implicits", "Show more detail on why some implicits are not applicable.")
+ val logImplicitConv = BooleanSetting ("-Xlog-implicit-conversions", "Print a message whenever an implicit conversion is inserted.")
+ val logReflectiveCalls = BooleanSetting("-Xlog-reflective-calls", "Print a message when a reflective method call is generated")
val maxClassfileName = IntSetting ("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, Some((72, 255)), _ => None)
val Xmigration28 = BooleanSetting ("-Xmigration", "Warn about constructs whose behavior may have changed between 2.7 and 2.8.")
val nouescape = BooleanSetting ("-Xno-uescape", "Disable handling of \\u unicode escapes.")
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 94eb6d2afd..a158012f9f 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -439,19 +439,20 @@ abstract class ClassfileParser {
/** Return the class symbol of the given name. */
def classNameToSymbol(name: Name): Symbol = {
- def loadClassSymbol(name: Name) = {
- val s = name.toString
- val file = global.classPath findSourceFile s getOrElse {
- MissingRequirementError.notFound("class " + s)
+ def loadClassSymbol(name: Name): Symbol = {
+ val file = global.classPath findSourceFile ("" +name) getOrElse {
+ warning("Class " + name + " not found - continuing with a stub.")
+ return NoSymbol.newClass(name.toTypeName)
}
- val completer = new global.loaders.ClassfileLoader(file)
+ val completer = new global.loaders.ClassfileLoader(file)
var owner: Symbol = definitions.RootClass
- var sym: Symbol = NoSymbol
- var ss: String = null
- var start = 0
- var end = s indexOf '.'
+ var sym: Symbol = NoSymbol
+ var ss: Name = null
+ var start = 0
+ var end = name indexOf '.'
+
while (end > 0) {
- ss = s.substring(start, end)
+ ss = name.subName(start, end)
sym = owner.info.decls lookup ss
if (sym == NoSymbol) {
sym = owner.newPackage(NoPosition, ss) setInfo completer
@@ -460,17 +461,16 @@ abstract class ClassfileParser {
}
owner = sym.moduleClass
start = end + 1
- end = s.indexOf('.', start)
+ end = name.indexOf('.', start)
}
- ss = s substring start
- sym = owner.info.decls lookup ss
- if (sym == NoSymbol) {
- sym = owner.newClass(NoPosition, newTypeName(ss)) setInfo completer
- owner.info.decls enter sym
- if (settings.debug.value && settings.verbose.value)
+ ss = name.subName(0, start)
+ owner.info.decls lookup ss orElse {
+ sym = owner.newClass(NoPosition, ss.toTypeName) setInfo completer
+ if (opt.verboseDebug)
println("loaded "+sym+" from file "+file)
+
+ owner.info.decls enter sym
}
- sym
}
def lookupClass(name: Name) = try {
@@ -718,7 +718,12 @@ abstract class ClassfileParser {
index += 1
val bounds = variance match {
case '+' => TypeBounds.upper(objToAny(sig2type(tparams, skiptvs)))
- case '-' => TypeBounds.lower(sig2type(tparams, skiptvs))
+ case '-' =>
+ val tp = sig2type(tparams, skiptvs)
+ // sig2type seems to return AnyClass regardless of the situation:
+ // we don't want Any as a LOWER bound.
+ if (tp.typeSymbol == definitions.AnyClass) TypeBounds.empty
+ else TypeBounds.lower(tp)
case '*' => TypeBounds.empty
}
val newtparam = sym.newExistential(sym.pos, newTypeName("?"+i)) setInfo bounds
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index a203b8a78b..0b64a49a2c 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -25,10 +25,7 @@ abstract class ICodeReader extends ClassfileParser {
var instanceCode: IClass = null // the ICode class for the current symbol
var staticCode: IClass = null // the ICode class static members
- var method: IMethod = _ // the current IMethod
-
- val nothingName = newTermName(SCALA_NOTHING)
- val nullName = newTermName(SCALA_NULL)
+ var method: IMethod = NoIMethod // the current IMethod
var isScalaModule = false
/** Read back bytecode for the given class symbol. It returns
@@ -182,9 +179,9 @@ abstract class ICodeReader extends ClassfileParser {
}
override def classNameToSymbol(name: Name) = {
- val sym = if (name == nothingName)
+ val sym = if (name == fulltpnme.RuntimeNothing)
definitions.NothingClass
- else if (name == nullName)
+ else if (name == fulltpnme.RuntimeNull)
definitions.NullClass
else if (nme.isImplClassName(name)) {
val iface = definitions.getClass(nme.interfaceName(name))
@@ -194,7 +191,7 @@ abstract class ICodeReader extends ClassfileParser {
}
else if (nme.isModuleName(name)) {
val strippedName = nme.stripModuleSuffix(name)
- val sym = forceMangledName(strippedName.decode, true)
+ val sym = forceMangledName(newTermName(strippedName.decode), true)
if (sym == NoSymbol) definitions.getModule(strippedName)
else sym
@@ -629,7 +626,7 @@ abstract class ICodeReader extends ClassfileParser {
skipAttributes()
code.toBasicBlock
- assert(method.code ne null)
+ assert(method.hasCode, method)
// reverse parameters, as they were prepended during code generation
method.params = method.params.reverse
@@ -692,7 +689,7 @@ abstract class ICodeReader extends ClassfileParser {
mutable.Map(jmpTargets.toSeq map (_ -> code.newBlock): _*)
val blocks = makeBasicBlocks
- var otherBlock: BasicBlock = null
+ var otherBlock: BasicBlock = NoBasicBlock
var disableJmpTarget = false
for ((pc, instr) <- instrs.iterator) {
@@ -991,7 +988,7 @@ abstract class ICodeReader extends ClassfileParser {
/** Return a fresh Local variable for the given index.
*/
private def freshLocal(idx: Int, kind: TypeKind, isArg: Boolean) = {
- val sym = method.symbol.newVariable(NoPosition, "loc" + idx).setInfo(kind.toType);
+ val sym = method.symbol.newVariable(NoPosition, newTermName("loc" + idx)).setInfo(kind.toType);
val l = new Local(sym, kind, isArg)
method.addLocal(l)
l
@@ -1008,7 +1005,7 @@ abstract class ICodeReader extends ClassfileParser {
/** add a method param with the given index. */
def enterParam(idx: Int, kind: TypeKind) = {
- val sym = method.symbol.newVariable(NoPosition, "par" + idx).setInfo(kind.toType)
+ val sym = method.symbol.newVariable(NoPosition, newTermName("par" + idx)).setInfo(kind.toType)
val l = new Local(sym, kind, true)
assert(!locals.isDefinedAt(idx))
locals += (idx -> List((l, kind)))
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
index 728593abe7..676c8f09da 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala
@@ -49,7 +49,7 @@ abstract class MetaParser{
val sym = locals.lookup(newTypeName(str))
if (sym != NoSymbol) sym.tpe
else {
- val tp = definitions.getClass(str).tpe;
+ val tp = definitions.getRequiredClass(str).tpe;
if (token != "[") tp
else {
val args = new ListBuffer[Type];
diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
index 95ef799720..e0cb0848be 100644
--- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala
@@ -34,6 +34,8 @@ abstract class TypeParser {
protected var busy: Boolean = false // lock to detect recursive reads
+ private implicit def stringToTermName(s: String): TermName = newTermName(s)
+
private object unpickler extends UnPickler {
val global: TypeParser.this.global.type = TypeParser.this.global
}
@@ -153,8 +155,8 @@ abstract class TypeParser {
val canBeTakenAddressOf = (typ.IsValueType || typ.IsEnum) && (typ.FullName != "System.Enum")
if(canBeTakenAddressOf) {
- clazzBoxed = clazz.owner.newClass(clazz.name.toTypeName append "Boxed")
- clazzMgdPtr = clazz.owner.newClass(clazz.name.toTypeName append "MgdPtr")
+ clazzBoxed = clazz.owner.newClass(clazz.name.toTypeName append newTypeName("Boxed"))
+ clazzMgdPtr = clazz.owner.newClass(clazz.name.toTypeName append newTypeName("MgdPtr"))
clrTypes.mdgptrcls4clssym(clazz) = clazzMgdPtr
/* adding typMgdPtr to clrTypes.sym2type should happen early (before metadata for supertypes is parsed,
before metadata for members are parsed) so that clazzMgdPtr can be found by getClRType. */
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 98345dd01e..034628e95f 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -22,9 +22,35 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
new CleanUpTransformer(unit)
class CleanUpTransformer(unit: CompilationUnit) extends Transformer {
- private val newStaticMembers = mutable.Buffer.empty[Tree]
- private val newStaticInits = mutable.Buffer.empty[Tree]
+ private val newStaticMembers = mutable.Buffer.empty[Tree]
+ private val newStaticInits = mutable.Buffer.empty[Tree]
private val symbolsStoredAsStatic = mutable.Map.empty[String, Symbol]
+ private def clearStatics() {
+ newStaticMembers.clear()
+ newStaticInits.clear()
+ symbolsStoredAsStatic.clear()
+ }
+ private def savingStatics[T](body: => T): T = {
+ val savedNewStaticMembers : mutable.Buffer[Tree] = newStaticMembers.clone()
+ val savedNewStaticInits : mutable.Buffer[Tree] = newStaticInits.clone()
+ val savedSymbolsStoredAsStatic : mutable.Map[String, Symbol] = symbolsStoredAsStatic.clone()
+ val result = body
+
+ clearStatics()
+ newStaticMembers ++= savedNewStaticMembers
+ newStaticInits ++= savedNewStaticInits
+ symbolsStoredAsStatic ++= savedSymbolsStoredAsStatic
+
+ result
+ }
+ private def transformTemplate(tree: Tree) = {
+ val Template(parents, self, body) = tree
+ clearStatics()
+ val newBody = transformTrees(body)
+ val templ = treeCopy.Template(tree, parents, self, transformTrees(newStaticMembers.toList) ::: newBody)
+ try addStaticInits(templ) // postprocess to include static ctors
+ finally clearStatics()
+ }
private def mkTerm(prefix: String): TermName = unit.freshTermName(prefix)
/** Kludge to provide a safe fix for #4560:
@@ -60,7 +86,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
}
private def typedWithPos(pos: Position)(tree: Tree) =
- localTyper typed { atPos(pos)(tree) }
+ localTyper.typedPos(pos)(tree)
/** A value class is defined to be only Java-compatible values: unit is
* not part of it, as opposed to isValueClass in definitions. scala.Int is
@@ -71,7 +97,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/** The boxed type if it's a primitive; identity otherwise.
*/
def toBoxedType(tp: Type) = if (isJavaValueType(tp)) boxedClass(tp.typeSymbol).tpe else tp
-
+
override def transform(tree: Tree): Tree = tree match {
/* Transforms dynamic calls (i.e. calls to methods that are undefined
@@ -106,6 +132,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* refinement, where the refinement defines a parameter based on a
* type variable. */
case ad@ApplyDynamic(qual0, params) =>
+ if (settings.logReflectiveCalls.value)
+ unit.echo(ad.pos, "method invocation uses reflection")
+
val typedPos = typedWithPos(ad.pos) _
assert(ad.symbol.isPublic)
@@ -113,11 +142,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* ### CREATING THE METHOD CACHE ### */
- def addStaticVariableToClass(forName: String, forType: Type, forInit: Tree, isFinal: Boolean): Symbol = {
+ def addStaticVariableToClass(forName: TermName, forType: Type, forInit: Tree, isFinal: Boolean): Symbol = {
val varSym = (
- currentClass.newVariable(ad.pos, mkTerm(forName))
- setFlag (PRIVATE | STATIC | SYNTHETIC)
- setInfo (forType)
+ currentClass.newVariable(ad.pos, mkTerm("" + forName))
+ setFlag PRIVATE | STATIC | SYNTHETIC
+ setInfo forType
)
if (isFinal) varSym setFlag FINAL
else varSym.addAnnotation(VolatileAttr)
@@ -165,9 +194,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
*/
val reflParamsCacheSym: Symbol =
- addStaticVariableToClass("reflParams$Cache", theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
+ addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
- addStaticMethodToClass("reflMethod$Method", List(ClassClass.tpe), MethodClass.tpe) {
+ addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) {
case Pair(reflMethodSym, List(forReceiverSym)) =>
(REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))
}
@@ -194,18 +223,18 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
*/
val reflParamsCacheSym: Symbol =
- addStaticVariableToClass("reflParams$Cache", theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
+ addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
val reflMethodCacheSym: Symbol =
- addStaticVariableToClass("reflMethod$Cache", MethodClass.tpe, NULL, false)
+ addStaticVariableToClass(nme.reflMethodCacheName, MethodClass.tpe, NULL, false)
val reflClassCacheSym: Symbol =
- addStaticVariableToClass("reflClass$Cache", SoftReferenceClass.tpe, NULL, false)
+ addStaticVariableToClass(nme.reflClassCacheName, SoftReferenceClass.tpe, NULL, false)
def isCacheEmpty(receiver: Symbol): Tree =
reflClassCacheSym.IS_NULL() OR (reflClassCacheSym.GET() OBJ_NE REF(receiver))
- addStaticMethodToClass("reflMethod$Method", List(ClassClass.tpe), MethodClass.tpe) {
+ addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) {
case Pair(reflMethodSym, List(forReceiverSym)) =>
BLOCK(
IF (isCacheEmpty(forReceiverSym)) THEN BLOCK(
@@ -241,13 +270,15 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
*/
val reflParamsCacheSym: Symbol =
- addStaticVariableToClass("reflParams$Cache", theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
+ addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
def mkNewPolyCache = gen.mkSoftRef(NEW(TypeTree(EmptyMethodCacheClass.tpe)))
- val reflPolyCacheSym: Symbol = addStaticVariableToClass("reflPoly$Cache", SoftReferenceClass.tpe, mkNewPolyCache, false)
+ val reflPolyCacheSym: Symbol = (
+ addStaticVariableToClass(nme.reflPolyCacheName, SoftReferenceClass.tpe, mkNewPolyCache, false)
+ )
def getPolyCache = gen.mkCast(fn(safeREF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe)
- addStaticMethodToClass("reflMethod$Method", List(ClassClass.tpe), MethodClass.tpe)
+ addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe)
{ case Pair(reflMethodSym, List(forReceiverSym)) =>
val methodSym = reflMethodSym.newVariable(ad.pos, mkTerm("method")) setInfo MethodClass.tpe
@@ -271,59 +302,14 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* ### HANDLING METHODS NORMALLY COMPILED TO OPERATORS ### */
- val testForNumber: Tree => Tree = {
- qual1 => (qual1 IS_OBJ BoxedNumberClass.tpe) OR (qual1 IS_OBJ BoxedCharacterClass.tpe)
- }
- val testForBoolean: Tree => Tree = {
- qual1 => (qual1 IS_OBJ BoxedBooleanClass.tpe)
- }
- val testForNumberOrBoolean: Tree => Tree = {
- qual1 => testForNumber(qual1) OR testForBoolean(qual1)
- }
-
- def postfixTest(name: Name): Option[(String, Tree => Tree)] = {
- var runtimeTest: Tree => Tree = testForNumber
- val newName = name match {
- case nme.UNARY_! => runtimeTest = testForBoolean ; "takeNot"
- case nme.UNARY_+ => "positive"
- case nme.UNARY_- => "negate"
- case nme.UNARY_~ => "complement"
- case nme.toByte => "toByte"
- case nme.toShort => "toShort"
- case nme.toChar => "toCharacter"
- case nme.toInt => "toInteger"
- case nme.toLong => "toLong"
- case nme.toFloat => "toFloat"
- case nme.toDouble => "toDouble"
- case _ => return None
- }
- Some((newName, runtimeTest))
- }
- def infixTest(name: Name): Option[(String, Tree => Tree)] = {
- val (newName, runtimeTest) = name match {
- case nme.OR => ("takeOr", testForNumberOrBoolean)
- case nme.XOR => ("takeXor", testForNumberOrBoolean)
- case nme.AND => ("takeAnd", testForNumberOrBoolean)
- case nme.EQ => ("testEqual", testForNumberOrBoolean)
- case nme.NE => ("testNotEqual", testForNumberOrBoolean)
- case nme.ADD => ("add", testForNumber)
- case nme.SUB => ("subtract", testForNumber)
- case nme.MUL => ("multiply", testForNumber)
- case nme.DIV => ("divide", testForNumber)
- case nme.MOD => ("takeModulo", testForNumber)
- case nme.LSL => ("shiftSignedLeft", testForNumber)
- case nme.LSR => ("shiftLogicalRight", testForNumber)
- case nme.ASR => ("shiftSignedRight", testForNumber)
- case nme.LT => ("testLessThan", testForNumber)
- case nme.LE => ("testLessOrEqualThan", testForNumber)
- case nme.GE => ("testGreaterOrEqualThan", testForNumber)
- case nme.GT => ("testGreaterThan", testForNumber)
- case nme.ZOR => ("takeConditionalOr", testForBoolean)
- case nme.ZAND => ("takeConditionalAnd", testForBoolean)
- case _ => return None
- }
- Some((newName, runtimeTest))
- }
+ def testForName(name: Name): Tree => Tree = t => (
+ if (nme.CommonOpNames(name))
+ gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean), t :: Nil)
+ else if (nme.BooleanOpNames(name))
+ t IS_OBJ BoxedBooleanClass.tpe
+ else
+ gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumber), t :: Nil)
+ )
/** The Tree => Tree function in the return is necessary to prevent the original qual
* from being duplicated in the resulting code. It may be a side-effecting expression,
@@ -332,12 +318,13 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* (If the compiler can verify qual is safe to inline, it will not create the block.)
*/
def getPrimitiveReplacementForStructuralCall(name: Name): Option[(Symbol, Tree => Tree)] = {
- val opt = (
- if (params.isEmpty) postfixTest(name)
- else if (params.tail.isEmpty) infixTest(name)
- else None
+ val methodName = (
+ if (params.isEmpty) nme.primitivePostfixMethodName(name)
+ else if (params.tail.isEmpty) nme.primitiveInfixMethodName(name)
+ else nme.NO_NAME
)
- opt map { case (name, fn) => (getMember(BoxesRunTimeClass, name), fn) }
+ if (methodName == nme.NO_NAME) None
+ else Some((getMember(BoxesRunTimeClass, methodName), testForName(name)))
}
/* ### BOXING PARAMS & UNBOXING RESULTS ### */
@@ -502,7 +489,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* expected to be an AnyRef. */
val t: Tree = ad.symbol.tpe match {
case MethodType(mparams, resType) =>
- assert(params.length == mparams.length)
+ assert(params.length == mparams.length, mparams)
+
typedPos {
val sym = currentOwner.newValue(ad.pos, mkTerm("qual")) setInfo qual0.tpe
qual = safeREF(sym)
@@ -554,31 +542,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* constructor. */
case Template(parents, self, body) =>
localTyper = typer.atOwner(tree, currentClass)
- var savedNewStaticMembers : mutable.Buffer[Tree] = null
- var savedNewStaticInits : mutable.Buffer[Tree] = null
- var savedSymbolsStoredAsStatic : mutable.Map[String, Symbol] = null
- if(forMSIL) {
- savedNewStaticMembers = newStaticMembers.clone
- savedNewStaticInits = newStaticInits.clone
- savedSymbolsStoredAsStatic = symbolsStoredAsStatic.clone
- }
- newStaticMembers.clear
- newStaticInits.clear
- symbolsStoredAsStatic.clear
- val transformedTemplate: Template = {
- var newBody = transformTrees(body)
- treeCopy.Template(tree, parents, self, transformTrees(newStaticMembers.toList) ::: newBody)
- }
- val res = addStaticInits(transformedTemplate) // postprocess to include static ctors
- newStaticMembers.clear
- newStaticInits.clear
- symbolsStoredAsStatic.clear
- if(forMSIL) {
- newStaticMembers ++= savedNewStaticMembers
- newStaticInits ++= savedNewStaticInits
- symbolsStoredAsStatic ++= savedSymbolsStoredAsStatic
- }
- res
+ if (forMSIL) savingStatics( transformTemplate(tree) )
+ else transformTemplate(tree)
case Literal(c) if (c.tag == ClassTag) && !forMSIL=>
val tpe = c.typeValue
@@ -641,15 +606,12 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* And, finally, be advised - scala symbol literal and the Symbol class of the compiler
* have little in common.
*/
- case symapp @ Apply(Select(Select(a @ Ident(nme.scala_), b @ nme.Symbol), nme.apply),
- List(Literal(Constant(symname: String)))) =>
+ case Apply(fn, (arg @ Literal(Constant(symname: String))) :: Nil) if fn.symbol == Symbol_apply =>
// add the symbol name to a map if it's not there already
- val rhs = gen.mkCast(Apply(gen.scalaDot(nme.Symbol), List(Literal(Constant(symname)))), symbolType)
- val staticFieldSym = getSymbolStaticField(symapp.pos, symname, rhs, symapp)
-
+ val rhs = gen.mkMethodCall(Symbol_apply, arg :: Nil)
+ val staticFieldSym = getSymbolStaticField(tree.pos, symname, rhs, tree)
// create a reference to a static field
- val ntree = typedWithPos(symapp.pos)(safeREF(staticFieldSym))
-
+ val ntree = typedWithPos(tree.pos)(safeREF(staticFieldSym))
super.transform(ntree)
// This transform replaces Array(Predef.wrapArray(Array(...)), <manifest>)
@@ -669,19 +631,21 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* If it doesn't exist, i.e. the symbol is encountered the first time,
* it creates a new static field definition and initialization and returns it.
*/
- private def getSymbolStaticField(pos: Position, symname: String, rhs: Tree, tree: Tree): Symbol =
+ private def getSymbolStaticField(pos: Position, symname: String, rhs: Tree, tree: Tree): Symbol = {
symbolsStoredAsStatic.getOrElseUpdate(symname, {
val theTyper = typer.atOwner(tree, currentClass)
// create a symbol for the static field
- val stfieldSym = currentClass.newVariable(pos, mkTerm("symbol$"))
- .setFlag(PRIVATE | STATIC | SYNTHETIC | FINAL)
- .setInfo(symbolType)
+ val stfieldSym = (
+ currentClass.newVariable(pos, mkTerm("symbol$"))
+ setFlag PRIVATE | STATIC | SYNTHETIC | FINAL
+ setInfo SymbolClass.tpe
+ )
currentClass.info.decls enter stfieldSym
// create field definition and initialization
- val stfieldDef = theTyper.typed { atPos(pos)(VAL(stfieldSym) === rhs) }
- val stfieldInit = theTyper.typed { atPos(pos)(safeREF(stfieldSym) === rhs) }
+ val stfieldDef = theTyper.typedPos(pos)(VAL(stfieldSym) === rhs)
+ val stfieldInit = theTyper.typedPos(pos)(safeREF(stfieldSym) === rhs)
// add field definition to new defs
newStaticMembers append stfieldDef
@@ -689,6 +653,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
stfieldSym
})
+ }
/* finds the static ctor DefDef tree within the template if it exists. */
private def findStaticCtor(template: Template): Option[Tree] =
@@ -700,7 +665,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* changes the template for the class so that it contains a static constructor with symbol fields inits,
* augments an existing static ctor if one already existed.
*/
- private def addStaticInits(template: Template): Template =
+ private def addStaticInits(template: Template): Template = {
if (newStaticInits.isEmpty)
template
else {
@@ -722,11 +687,12 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
// create new static ctor
val staticCtorSym = currentClass.newStaticConstructor(template.pos)
val rhs = Block(newStaticInits.toList, Literal(Constant()))
- val staticCtorTree = DefDef(staticCtorSym, rhs)
- localTyper.typed { atPos(template.pos)(staticCtorTree) }
+
+ localTyper.typedPos(template.pos)(DefDef(staticCtorSym, rhs))
}
treeCopy.Template(template, template.parents, template.self, newCtor :: template.body)
}
+ }
} // CleanUpTransformer
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 342c298e1d..4d4f4f4c27 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -254,26 +254,18 @@ abstract class Constructors extends Transform with ast.TreeDSL {
for ((accSym, accBody) <- outerAccessors)
if (mustbeKept(accSym)) accessTraverser.traverse(accBody)
- // Conflicting symbol list from parents: see bug #1960.
- // It would be better to mangle the constructor parameter name since
- // it can only be used internally, but I think we need more robust name
- // mangling before we introduce more of it.
- val parentSymbols = Map((for {
- p <- impl.parents
- if p.symbol.isTrait
- sym <- p.symbol.info.nonPrivateMembers
- if sym.isGetter && !sym.isOuterField
- } yield sym.name -> p): _*)
-
// Initialize all parameters fields that must be kept.
- val paramInits =
- for (acc <- paramAccessors if mustbeKept(acc)) yield {
- if (parentSymbols contains acc.name)
- unit.error(acc.pos, "parameter '%s' requires field but conflicts with %s in '%s'".format(
- acc.name, acc.name, parentSymbols(acc.name)))
-
- copyParam(acc, parameter(acc))
- }
+ val paramInits = paramAccessors filter mustbeKept map { acc =>
+ // Check for conflicting symbol amongst parents: see bug #1960.
+ // It would be better to mangle the constructor parameter name since
+ // it can only be used internally, but I think we need more robust name
+ // mangling before we introduce more of it.
+ val conflict = clazz.info.nonPrivateMember(acc.name) filter (s => s.isGetter && !s.isOuterField && s.enclClass.isTrait)
+ if (conflict ne NoSymbol)
+ unit.error(acc.pos, "parameter '%s' requires field but conflicts with %s".format(acc.name, conflict.fullLocationString))
+
+ copyParam(acc, parameter(acc))
+ }
/** Return a single list of statements, merging the generic class constructor with the
* specialized stats. The original statements are retyped in the current class, and
@@ -299,11 +291,10 @@ abstract class Constructors extends Transform with ast.TreeDSL {
* be an error to pass it to array_update(.., .., Object).
*/
def rewriteArrayUpdate(tree: Tree): Tree = {
- val array_update = definitions.ScalaRunTimeModule.info.member("array_update")
val adapter = new Transformer {
override def transform(t: Tree): Tree = t match {
- case Apply(fun @ Select(receiver, method), List(xs, idx, v)) if fun.symbol == array_update =>
- localTyper.typed(Apply(gen.mkAttributedSelect(xs, definitions.Array_update), List(idx, v)))
+ case Apply(fun @ Select(receiver, method), List(xs, idx, v)) if fun.symbol == arrayUpdateMethod =>
+ localTyper.typed(Apply(gen.mkAttributedSelect(xs, arrayUpdateMethod), List(idx, v)))
case _ => super.transform(t)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 1a421eb82f..f3b1e77c8d 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -866,7 +866,7 @@ abstract class Erasure extends AddInterfaces
unboundedGenericArrayLevel(arg.tpe) > 0) =>
val level = unboundedGenericArrayLevel(arg.tpe)
def isArrayTest(arg: Tree) =
- gen.mkRuntimeCall("isArray", List(arg, Literal(Constant(level))))
+ gen.mkRuntimeCall(nme.isArray, List(arg, Literal(Constant(level))))
global.typer.typedPos(tree.pos) {
if (level == 1) isArrayTest(qual)
@@ -887,19 +887,30 @@ abstract class Erasure extends AddInterfaces
fun.symbol != Object_isInstanceOf) =>
// leave all other type tests/type casts, remove all other type applications
preErase(fun)
- case Apply(fn @ Select(qual, name), args) if (fn.symbol.owner == ArrayClass) =>
- if (unboundedGenericArrayLevel(qual.tpe.widen) == 1)
+ case Apply(fn @ Select(qual, name), args) if fn.symbol.owner == ArrayClass =>
+ // Have to also catch calls to abstract types which are bounded by Array.
+ if (unboundedGenericArrayLevel(qual.tpe.widen) == 1 || qual.tpe.typeSymbol.isAbstractType) {
// convert calls to apply/update/length on generic arrays to
// calls of ScalaRunTime.array_xxx method calls
- global.typer.typedPos(tree.pos) { gen.mkRuntimeCall("array_"+name, qual :: args) }
- else
+ global.typer.typedPos(tree.pos)({
+ val arrayMethodName = name match {
+ case nme.apply => nme.array_apply
+ case nme.length => nme.array_length
+ case nme.update => nme.array_update
+ case nme.clone_ => nme.array_clone
+ case _ => unit.error(tree.pos, "Unexpected array member, no translation exists.") ; nme.NO_NAME
+ }
+ gen.mkRuntimeCall(arrayMethodName, qual :: args)
+ })
+ }
+ else {
// store exact array erasure in map to be retrieved later when we might
// need to do the cast in adaptMember
treeCopy.Apply(
tree,
SelectFromArray(qual, name, erasure(tree.symbol, qual.tpe)).copyAttrs(fn),
args)
-
+ }
case Apply(fn @ Select(qual, _), Nil) if interceptedMethods(fn.symbol) =>
if (fn.symbol == Any_## || fn.symbol == Object_##) {
// This is unattractive, but without it we crash here on ().## because after
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index fcc03a82d0..cf7d6c94fe 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -68,6 +68,8 @@ abstract class ExplicitOuter extends InfoTransform
result
}
+
+ private val innerClassConstructorParamName: TermName = newTermName("arg" + nme.OUTER)
class RemoveBindingsTransformer(toRemove: Set[Symbol]) extends Transformer {
override def transform(tree: Tree) = tree match {
@@ -134,7 +136,7 @@ abstract class ExplicitOuter extends InfoTransform
}
if (sym.owner.isTrait) sym setNotFlag PROTECTED // 6
if (sym.isClassConstructor && isInner(sym.owner)) { // 1
- val p = sym.newValueParameter(sym.pos, "arg" + nme.OUTER)
+ val p = sym.newValueParameter(sym.pos, innerClassConstructorParamName)
.setInfo(sym.owner.outerClass.thisType)
MethodType(p :: params, restpe)
} else if (restpe ne restpe1)
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index 171d1df975..bc7d1754d4 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -165,9 +165,6 @@ abstract class LiftCode extends Transform with TypingTransformers {
*/
class Reifier() {
- final val mirrorFullName = "scala.reflect.mirror"
- final val mirrorShortName = "$mr"
- final val mirrorPrefix = mirrorShortName + "."
final val scalaPrefix = "scala."
final val localPrefix = "$local"
final val memoizerName = "$memo"
@@ -217,16 +214,20 @@ abstract class LiftCode extends Transform with TypingTransformers {
// helper methods
- private def localName(sym: Symbol) = localPrefix + symIndex(sym)
+ private def localName(sym: Symbol): TermName =
+ newTermName(localPrefix + symIndex(sym))
private def call(fname: String, args: Tree*): Tree =
Apply(termPath(fname), args.toList)
private def mirrorSelect(name: String): Tree =
- termPath(mirrorPrefix + name)
+ termPath(nme.MIRROR_PREFIX + name)
+
+ private def mirrorCall(name: TermName, args: Tree*): Tree =
+ call("" + (nme.MIRROR_PREFIX append name), args: _*)
private def mirrorCall(name: String, args: Tree*): Tree =
- call(mirrorPrefix + name, args: _*)
+ call(nme.MIRROR_PREFIX + name, args: _*)
private def mirrorFactoryCall(value: Product, args: Tree*): Tree =
mirrorCall(value.productPrefix, args: _*)
@@ -322,15 +323,15 @@ abstract class LiftCode extends Transform with TypingTransformers {
* Generate code to add type and annotation info to a reified symbol
*/
private def fillInSymbol(sym: Symbol): Tree = {
- val rset = Apply(Select(reifySymRef(sym), "setTypeSig"), List(reifyType(sym.info)))
+ val rset = Apply(Select(reifySymRef(sym), nme.setTypeSig), List(reifyType(sym.info)))
if (sym.annotations.isEmpty) rset
- else Apply(Select(rset, "setAnnotations"), List(reify(sym.annotations)))
+ else Apply(Select(rset, nme.setAnnotations), List(reify(sym.annotations)))
}
/** Reify a scope */
private def reifyScope(scope: Scope): Tree = {
scope foreach registerReifiableSymbol
- mirrorCall("newScopeWith", scope.toList map reifySymRef: _*)
+ mirrorCall(nme.newScopeWith, scope.toList map reifySymRef: _*)
}
/** Reify a list of symbols that need to be created */
@@ -348,14 +349,14 @@ abstract class LiftCode extends Transform with TypingTransformers {
val tpe = tpe0.normalize
val tsym = tpe.typeSymbol
if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic)
- Select(reifySymRef(tpe.typeSymbol), "asTypeConstructor")
+ Select(reifySymRef(tpe.typeSymbol), nme.asTypeConstructor)
else tpe match {
case t @ NoType =>
reifyMirrorObject(t)
case t @ NoPrefix =>
reifyMirrorObject(t)
case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic =>
- mirrorCall("thisModuleType", reify(clazz.fullName))
+ mirrorCall(nme.thisModuleType, reify(clazz.fullName))
case t @ RefinedType(parents, decls) =>
registerReifiableSymbol(tpe.typeSymbol)
mirrorFactoryCall(t, reify(parents), reify(decls), reify(t.typeSymbol))
@@ -387,13 +388,13 @@ abstract class LiftCode extends Transform with TypingTransformers {
case tt: TypeTree if (tt.tpe != null) =>
if (!(boundSyms exists (tt.tpe contains _))) mirrorCall("TypeTree", reifyType(tt.tpe))
else if (tt.original != null) reify(tt.original)
- else mirrorCall("TypeTree")
+ else mirrorCall(nme.TypeTree)
case ta @ TypeApply(hk, ts) =>
val thereAreOnlyTTs = ts collect { case t if !t.isInstanceOf[TypeTree] => t } isEmpty;
val ttsAreNotEssential = ts collect { case tt: TypeTree => tt } find { tt => tt.original != null } isEmpty;
if (thereAreOnlyTTs && ttsAreNotEssential) reifyTree(hk) else reifyProduct(ta)
case global.emptyValDef =>
- mirrorSelect("emptyValDef")
+ mirrorSelect(nme.emptyValDef)
case _ =>
if (tree.isDef)
boundSyms += tree.symbol
@@ -403,8 +404,8 @@ abstract class LiftCode extends Transform with TypingTransformers {
if (tree.isDef || tree.isInstanceOf[Function])
registerReifiableSymbol(tree.symbol)
if (tree.hasSymbol)
- rtree = Apply(Select(rtree, "setSymbol"), List(reifySymRef(tree.symbol)))
- Apply(Select(rtree, "setType"), List(reifyType(tree.tpe)))
+ rtree = Apply(Select(rtree, nme.setSymbol), List(reifySymRef(tree.symbol)))
+ Apply(Select(rtree, nme.setType), List(reifyType(tree.tpe)))
*/
}
@@ -413,7 +414,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
* to a global value, or else a mirror Literal.
*/
private def reifyFree(tree: Tree): Tree =
- mirrorCall("Ident", reifySymRef(tree.symbol))
+ mirrorCall(nme.Ident, reifySymRef(tree.symbol))
// todo: consider whether we should also reify positions
private def reifyPosition(pos: Position): Tree =
@@ -443,7 +444,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
case sym: Symbol => reifySymRef(sym)
case tpe: Type => reifyType(tpe)
case xs: List[_] => reifyList(xs)
- case xs: Array[_] => scalaFactoryCall("Array", xs map reify: _*)
+ case xs: Array[_] => scalaFactoryCall(nme.Array, xs map reify: _*)
case scope: Scope => reifyScope(scope)
case x: Name => reifyName(x)
case x: Position => reifyPosition(x)
@@ -475,7 +476,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
private def typePath(fullname: String): Tree = path(fullname, newTypeName)
private def mirrorAlias =
- ValDef(NoMods, mirrorShortName, TypeTree(), termPath(mirrorFullName))
+ ValDef(NoMods, nme.MIRROR_SHORT, TypeTree(), termPath(fullnme.MirrorPackage))
/**
* Generate code that generates a symbol table of all symbols registered in `reifiableSyms`
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index bbe803a3fb..99b0a82690 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -572,8 +572,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// resolved by the type checker. Later on, erasure re-typechecks everything and
// chokes if it finds default parameters for specialized members, even though
// they are never needed.
- sym.info.paramss.flatten foreach (_.resetFlag(DEFAULTPARAM))
-
+ mapParamss(sym)(_ resetFlag DEFAULTPARAM)
decls1.enter(subst(fullEnv)(sym))
}
@@ -1235,7 +1234,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
debuglog("!!! adding body of a defdef %s, symbol %s: %s".format(tree, tree.symbol, rhs))
body(tree.symbol) = rhs
// body(tree.symbol) = tree // whole method
- parameters(tree.symbol) = vparamss map (_ map (_.symbol))
+ parameters(tree.symbol) = mmap(vparamss)(_.symbol)
concreteSpecMethods -= tree.symbol
} // no need to descend further down inside method bodies
@@ -1609,7 +1608,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
if (m.isClassConstructor) {
val origParamss = parameters(info(m).target)
val vparams = (
- for ((tp, sym) <- m.info.paramTypes zip origParamss(0)) yield (
+ map2(m.info.paramTypes, origParamss(0))((tp, sym) =>
m.newValue(sym.pos, specializedName(sym, typeEnv(cls)))
.setInfo(tp)
.setFlag(sym.flags)
@@ -1625,7 +1624,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
// ctor
- mbrs += atPos(m.pos)(DefDef(m, Modifiers(m.flags), List(vparams) map (_ map ValDef), EmptyTree))
+ mbrs += atPos(m.pos)(DefDef(m, Modifiers(m.flags), mmap(List(vparams))(ValDef), EmptyTree))
} else {
mbrs += atPos(m.pos)(DefDef(m, { paramss => EmptyTree }))
}
@@ -1671,7 +1670,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
private def forwardCall(pos: util.Position, receiver: Tree, paramss: List[List[ValDef]]): Tree = {
- val argss = paramss map (_ map (x => Ident(x.symbol)))
+ val argss = mmap(paramss)(x => Ident(x.symbol))
atPos(pos) { (receiver /: argss) (Apply) }
}
@@ -1708,11 +1707,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
&& clazz.info.decl(f.name).suchThat(_.isGetter) != NoSymbol
)
- val argss = paramss map (_ map (x =>
+ val argss = mmap(paramss)(x =>
if (initializesSpecializedField(x.symbol))
gen.mkAsInstanceOf(Literal(Constant(null)), x.symbol.tpe)
else
- Ident(x.symbol))
+ Ident(x.symbol)
)
atPos(pos) { (receiver /: argss) (Apply) }
}
diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
index ca16e491e2..e2cd0a8402 100644
--- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala
+++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala
@@ -128,7 +128,7 @@ abstract class TailCalls extends Transform {
* the label field.
*/
this.label = {
- val label = method.newLabel(method.pos, "_" + method.name)
+ val label = method.newLabel(method.pos, newTermName("_" + method.name))
val thisParam = method.newSyntheticValueParam(currentClass.typeOfThis)
label setInfo MethodType(thisParam :: method.tpe.params, method.tpe.finalResultType)
}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 13516037f5..adb408f7e4 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -357,7 +357,7 @@ abstract class UnCurry extends InfoTransform
case Apply(Apply(TypeApply(Select(tgt, nme.runOrElse), targs), args_scrut), args_pm) if opt.virtPatmat =>
object noOne extends Transformer {
override val treeCopy = newStrictTreeCopier // must duplicate everything
- val one = tgt.tpe member "one".toTermName
+ val one = tgt.tpe member newTermName("one")
override def transform(tree: Tree): Tree = tree match {
case Apply(fun, List(a)) if fun.symbol == one =>
// blow one's argument away since all we want to know is whether the match succeeds or not
@@ -367,7 +367,7 @@ abstract class UnCurry extends InfoTransform
super.transform(tree)
}
}
- substTree(Apply(Apply(TypeApply(Select(tgt.duplicate, tgt.tpe.member("isSuccess".toTermName)), targs map (_.duplicate)), args_scrut map (_.duplicate)), args_pm map (noOne.transform)))
+ substTree(Apply(Apply(TypeApply(Select(tgt.duplicate, tgt.tpe.member(newTermName("isSuccess"))), targs map (_.duplicate)), args_scrut map (_.duplicate)), args_pm map (noOne.transform)))
// for the optimized version of virtpatmat
case Block((zero: ValDef) :: (x: ValDef) :: (matchRes: ValDef) :: (keepGoing: ValDef) :: stats, _) if opt.virtPatmat =>
dupVirtMatch(zero, x, matchRes, keepGoing, stats)
@@ -452,7 +452,7 @@ abstract class UnCurry extends InfoTransform
atPhase(phase.next) {
if (isJava && isPrimitiveArray(suffix.tpe) && isArrayOfSymbol(fun.tpe.params.last.tpe, ObjectClass)) {
suffix = localTyper.typedPos(pos) {
- gen.mkRuntimeCall("toObjectArray", List(suffix))
+ gen.mkRuntimeCall(nme.toObjectArray, List(suffix))
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index d54cb248cf..3b90eaeed7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -214,10 +214,10 @@ trait Implicits {
/** An extractor for types of the form ? { name: (? >: argtpe <: Any*)restp }
*/
object HasMethodMatching {
+ val dummyMethod = new TermSymbol(NoSymbol, NoPosition, newTermName("typer$dummy"))
+ def templateArgType(argtpe: Type) = new BoundedWildcardType(TypeBounds.lower(argtpe))
+
def apply(name: Name, argtpes: List[Type], restpe: Type): Type = {
- def templateArgType(argtpe: Type) =
- new BoundedWildcardType(TypeBounds(argtpe, AnyClass.tpe))
- val dummyMethod = new TermSymbol(NoSymbol, NoPosition, "typer$dummy")
val mtpe = MethodType(dummyMethod.newSyntheticValueParams(argtpes map templateArgType), restpe)
memberWildcardType(name, mtpe)
}
@@ -816,7 +816,14 @@ trait Implicits {
val newPending = undoLog undo {
is filterNot (alt => alt == i || {
try improves(i, alt)
- catch { case e: CyclicReference => true }
+ catch {
+ case e: CyclicReference =>
+ if (printInfers) {
+ println(i+" discarded because cyclic reference occurred")
+ e.printStackTrace()
+ }
+ true
+ }
})
}
rankImplicits(newPending, i :: acc)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 2bd307e31a..295b66b17f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1447,8 +1447,17 @@ trait Infer {
/** A traverser to collect type parameters referred to in a type
*/
object freeTypeParamsOfTerms extends SymCollector {
- protected def includeCondition(sym: Symbol): Boolean =
- sym.isAbstractType && sym.owner.isTerm
+ // An inferred type which corresponds to an unknown type
+ // constructor creates a file/declaration order-dependent crasher
+ // situation, the behavior of which depends on the state at the
+ // time the typevar is created. Until we can deal with these
+ // properly, we can avoid it by ignoring type parameters which
+ // have type constructors amongst their bounds. See SI-4070.
+ protected def includeCondition(sym: Symbol) = (
+ sym.isAbstractType
+ && sym.owner.isTerm
+ && !sym.info.bounds.exists(_.typeParams.nonEmpty)
+ )
}
/** A traverser to collect type parameters referred to in a type
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 99ba0e0971..b9264aae55 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -7,13 +7,10 @@ trait Macros { self: Analyzer =>
import global._
import definitions._
- def macroMethName(name: Name) =
- newTermName((if (name.isTypeName) "type" else "def") + "macro$" + name)
-
def macroMeth(mac: Symbol): Symbol = {
var owner = mac.owner
if (!owner.isModuleClass) owner = owner.companionModule.moduleClass
- owner.info.decl(macroMethName(mac.name))
+ owner.info.decl(nme.macroMethodName(mac.name))
}
/**
@@ -37,21 +34,21 @@ trait Macros { self: Analyzer =>
def macroMethDef(mdef: DefDef): Tree = {
def paramDef(name: Name, tpt: Tree) = ValDef(Modifiers(PARAM), name, tpt, EmptyTree)
val universeType = TypeTree(ReflectApiUniverse.tpe)
- val globParamSec = List(paramDef("glob", universeType))
- def globSelect(name: Name) = Select(Ident("glob"), name)
+ val globParamSec = List(paramDef(nme.glob, universeType))
+ def globSelect(name: Name) = Select(Ident(nme.glob), name)
def globTree = globSelect(newTypeName("Tree"))
def globType = globSelect(newTypeName("Type"))
- val thisParamSec = if (mdef.symbol.owner.isModuleClass) List() else List(paramDef("_this", globTree))
+ val thisParamSec = if (mdef.symbol.owner.isModuleClass) List() else List(paramDef(newTermName("_this"), globTree))
def tparamInMacro(tdef: TypeDef) = paramDef(tdef.name.toTermName, globType)
def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, globTree)
def wrapImplicit(tree: Tree) = atPos(tree.pos) {
- Block(List(ValDef(Modifiers(IMPLICIT), "$glob", universeType, Ident("glob"))), tree)
+ Block(List(ValDef(Modifiers(IMPLICIT), newTermName("$" + nme.glob), universeType, Ident(nme.glob))), tree)
}
atPos(mdef.pos) {
new DefDef( // can't call DefDef here; need to find out why
mods = mdef.mods &~ MACRO,
- name = macroMethName(mdef.name),
+ name = nme.macroMethodName(mdef.name),
tparams = List(),
vparamss = globParamSec :: thisParamSec :: (mdef.tparams map tparamInMacro) ::
(mdef.vparamss map (_ map vparamInMacro)),
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 7915a64e21..62393befd2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -9,22 +9,6 @@ import symtab.Flags._
import scala.collection.{ mutable, immutable }
import scala.tools.util.StringOps.{ ojoin }
-object listutil {
- def mexists[T](xss: List[List[T]])(p: T => Boolean) =
- xss exists (_ exists p)
- def mmap[T, U](xss: List[List[T]])(f: T => U) =
- xss map (_ map f)
- def mforeach[T](xss: List[List[T]])(f: T => Unit) =
- xss foreach (_ foreach f)
- def mfind[T](xss: List[List[T]])(p: T => Boolean): Option[T] = {
- for (xs <- xss; x <- xs)
- if (p(x)) return Some(x)
- None
- }
- def mfilter[T](xss: List[List[T]])(p: T => Boolean) =
- for (xs <- xss; x <- xs; if p(x)) yield x
-}
-
/** Logic related to method synthesis which involves cooperation between
* Namer and Typer.
*/
@@ -264,7 +248,7 @@ trait MethodSynthesis {
}
sealed abstract class BeanAccessor(bean: String) extends DerivedFromValDef {
- def name = bean + tree.name.toString.capitalize
+ val name = newTermName(bean + tree.name.toString.capitalize)
def flagsMask = BeanPropertyFlags
def flagsExtra = 0
override def derivedSym = enclClass.info decl name
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 364e887939..200191fa13 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -99,7 +99,7 @@ trait Namers extends MethodSynthesis {
}
def enterValueParams(vparamss: List[List[ValDef]]): List[List[Symbol]] = {
- listutil.mmap(vparamss) { param =>
+ mmap(vparamss) { param =>
val sym = assignSymbol(param, param.name, mask = ValueParameterFlags)
setPrivateWithin(param, sym)
enterInScope(sym)
@@ -522,13 +522,13 @@ trait Namers extends MethodSynthesis {
val vparamss = tree match { case x: DefDef => x.vparamss ; case _ => Nil }
val cparamss = constructorType.paramss
- for ((vparams, cparams) <- vparamss zip cparamss) {
- for ((param, cparam) <- vparams zip cparams) {
+ map2(vparamss, cparamss)((vparams, cparams) =>
+ map2(vparams, cparams)((param, cparam) =>
// need to clone the type cparam.tpe???
// problem is: we don't have the new owner yet (the new param symbol)
param.tpt setType subst(cparam.tpe)
- }
- }
+ )
+ )
}
sym setInfo {
mkTypeCompleter(tree) { copySym =>
@@ -579,7 +579,7 @@ trait Namers extends MethodSynthesis {
// via "x$lzy" as can be seen in test #3927.
val sym = (
if (owner.isClass) createFieldSymbol(tree)
- else owner.newValue(tree.pos, tree.name + "$lzy") setFlag tree.mods.flags resetFlag IMPLICIT
+ else owner.newValue(tree.pos, tree.name append nme.LAZY_LOCAL) setFlag tree.mods.flags resetFlag IMPLICIT
)
enterValSymbol(tree, sym setFlag MUTABLE setLazyAccessor lazyAccessor)
}
@@ -627,7 +627,7 @@ trait Namers extends MethodSynthesis {
classOfModuleClass(m.moduleClass) = new WeakReference(tree)
}
val hasDefault = impl.body exists {
- case DefDef(_, nme.CONSTRUCTOR, _, vparamss, _, _) => listutil.mexists(vparamss)(_.mods.hasDefault)
+ case DefDef(_, nme.CONSTRUCTOR, _, vparamss, _, _) => mexists(vparamss)(_.mods.hasDefault)
case _ => false
}
if (hasDefault) {
@@ -953,9 +953,9 @@ trait Namers extends MethodSynthesis {
// def overriddenSymbol = meth.nextOverriddenSymbol
// fill in result type and parameter types from overridden symbol if there is a unique one.
- if (clazz.isClass && (tpt.isEmpty || listutil.mexists(vparamss)(_.tpt.isEmpty))) {
+ if (clazz.isClass && (tpt.isEmpty || mexists(vparamss)(_.tpt.isEmpty))) {
// try to complete from matching definition in base type
- listutil.mforeach(vparamss)(v => if (v.tpt.isEmpty) v.symbol setInfo WildcardType)
+ mforeach(vparamss)(v => if (v.tpt.isEmpty) v.symbol setInfo WildcardType)
val overridden = overriddenSymbol
if (overridden != NoSymbol && !overridden.isOverloaded) {
overridden.cookJavaRawInfo() // #3404 xform java rawtypes into existentials
@@ -993,7 +993,7 @@ trait Namers extends MethodSynthesis {
_.info.isInstanceOf[MethodType])) {
vparamSymss = List(List())
}
- listutil.mforeach(vparamss) { vparam =>
+ mforeach(vparamss) { vparam =>
if (vparam.tpt.isEmpty) {
context.error(vparam.pos, "missing parameter type")
vparam.tpt defineType ErrorType
@@ -1073,7 +1073,7 @@ trait Namers extends MethodSynthesis {
// Create trees for the defaultGetter. Uses tools from Unapplies.scala
var deftParams = tparams map copyUntyped[TypeDef]
- val defvParamss = listutil.mmap(previous) { p =>
+ val defvParamss = mmap(previous) { p =>
// in the default getter, remove the default parameter
val p1 = atPos(p.pos.focus) { ValDef(p.mods &~ DEFAULTPARAM, p.name, p.tpt.duplicate, EmptyTree) }
UnTyper.traverse(p1)
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
index 75a5ad6f8a..440db4300c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala
@@ -46,8 +46,6 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
import global._
import definitions._
- private lazy val matchingStrategyTycon = definitions.getClass("scala.MatchingStrategy").typeConstructor
-
class MatchTranslator(typer: Typer) extends MatchCodeGen {
def typed(tree: Tree, mode: Int, pt: Type): Tree = typer.typed(tree, mode, pt) // for MatchCodeGen -- imports don't provide implementations for abstract members
@@ -55,7 +53,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
import typeDebug.{ ptTree, ptBlock, ptLine }
def solveContextBound(contextBoundTp: Type): (Tree, Type) = {
- val solSym = NoSymbol.newTypeParameter(NoPosition, "SolveImplicit$".toTypeName)
+ val solSym = NoSymbol.newTypeParameter(NoPosition, newTypeName("SolveImplicit$"))
val param = solSym.setInfo(contextBoundTp.typeSymbol.typeParams(0).info.cloneInfo(solSym)) // TypeBounds(NothingClass.typeConstructor, baseTp)
val pt = appliedType(contextBoundTp, List(param.tpeHK))
val savedUndets = context.undetparams
@@ -67,7 +65,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer =>
(result.tree, result.subst.to(result.subst.from indexOf param))
}
- lazy val (matchingStrategy, matchingMonadType) = solveContextBound(matchingStrategyTycon)
+ lazy val (matchingStrategy, matchingMonadType) = solveContextBound(MatchingStrategyClass.typeConstructor)
/** Implement a pattern match by turning its cases (including the implicit failure case)
* into the corresponding (monadic) extractors, and combining them with the `orElse` combinator.
@@ -1482,19 +1480,18 @@ defined class Foo */
}
object vpmName {
- val one = "one".toTermName
- val drop = "drop".toTermName
- val flatMap = "flatMap".toTermName
- val get = "get".toTermName
- val guard = "guard".toTermName
- val isEmpty = "isEmpty".toTermName
- val orElse = "orElse".toTermName
- val outer = "<outer>".toTermName
- val runOrElse = "runOrElse".toTermName
- val zero = "zero".toTermName
-
- def counted(str: String, i: Int) = (str+i).toTermName
- def tupleIndex(i: Int) = ("_"+i).toTermName
+ val one = newTermName("one")
+ val drop = newTermName("drop")
+ val flatMap = newTermName("flatMap")
+ val get = newTermName("get")
+ val guard = newTermName("guard")
+ val isEmpty = newTermName("isEmpty")
+ val orElse = newTermName("orElse")
+ val outer = newTermName("<outer>")
+ val runOrElse = newTermName("runOrElse")
+ val zero = newTermName("zero")
+
+ def counted(str: String, i: Int) = newTermName(str+i)
}
@@ -1503,7 +1500,7 @@ defined class Foo */
trait CommonCodeGen extends AbsCodeGen { self: CommonCodeGen with MatchingStrategyGen with MonadInstGen =>
def fun(arg: Symbol, body: Tree): Tree = Function(List(ValDef(arg)), body)
def genTypeApply(tfun: Tree, args: Type*): Tree = if(args contains NoType) tfun else TypeApply(tfun, args.toList map TypeTree)
- def tupleSel(binder: Symbol)(i: Int): Tree = (REF(binder) DOT vpmName.tupleIndex(i)) // make tree that accesses the i'th component of the tuple referenced by binder
+ def tupleSel(binder: Symbol)(i: Int): Tree = (REF(binder) DOT nme.productAccessorName(i)) // make tree that accesses the i'th component of the tuple referenced by binder
def index(tgt: Tree)(i: Int): Tree = tgt APPLY (LIT(i))
def drop(tgt: Tree)(n: Int): Tree = (tgt DOT vpmName.drop) (LIT(n))
def _equals(checker: Tree, binder: Symbol): Tree = checker MEMBER_== REF(binder) // NOTE: checker must be the target of the ==, that's the patmat semantics for ya
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index ace38bb4cb..8f9cd46611 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -154,7 +154,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
def isJavaVarargsAncestor(clazz: Symbol) = (
clazz.isClass
&& clazz.isJavaDefined
- && (clazz.info.nonPrivateMembers exists isJavaVarArgsMethod)
+ && (clazz.info.nonPrivateDecls exists isJavaVarArgsMethod)
)
/** Add bridges for vararg methods that extend Java vararg methods
@@ -1347,7 +1347,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
}
// types of the value parameters
- member.paramss.flatten foreach (p => checkAccessibilityOfType(p.tpe))
+ mapParamss(member)(p => checkAccessibilityOfType(p.tpe))
// upper bounds of type parameters
member.typeParams.map(_.info.bounds.hi.widen) foreach checkAccessibilityOfType
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index a0ef2f5e2e..cde531adc1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -321,12 +321,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
val code = DefDef(protAcc, {
val (receiver :: _) :: tail = protAcc.paramss
val base: Tree = Select(Ident(receiver), sym)
- val allParamTypes = sym.tpe.paramss map (xs => xs map (_.tpe))
-
- (tail zip allParamTypes).foldLeft(base) {
- case (fn, (params, tpes)) =>
- Apply(fn, params zip tpes map { case (p, tp) => makeArg(p, receiver, tp) })
- }
+ val allParamTypes = mapParamss(sym)(_.tpe)
+ val args = map2(tail, allParamTypes)((params, tpes) => map2(params, tpes)(makeArg(_, receiver, _)))
+ args.foldLeft(base)(Apply(_, _))
})
debuglog("" + code)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 3d4f5e8724..92e4e257bf 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -39,10 +39,6 @@ trait SyntheticMethods extends ast.TreeDSL {
private object util {
private type CM[T] = ClassManifest[T]
- lazy val IteratorModule = getModule("scala.collection.Iterator")
- lazy val Iterator_apply = getMember(IteratorModule, nme.apply)
- def iteratorOfType(tp: Type) = appliedType(IteratorClass.typeConstructor, List(tp))
-
def ValOrDefDef(sym: Symbol, body: Tree) =
if (sym.isLazy) ValDef(sym, body)
else DefDef(sym, body)
@@ -76,11 +72,11 @@ trait SyntheticMethods extends ast.TreeDSL {
}
def manifestToSymbol(m: CM[_]): Symbol = m match {
- case x: scala.reflect.AnyValManifest[_] => definitions.getClass("scala." + x)
+ case x: scala.reflect.AnyValManifest[_] => getMember(ScalaPackageClass, newTermName("" + x))
case _ => getClassIfDefined(m.erasure.getName)
}
def companionType[T](implicit m: CM[T]) =
- getModule(m.erasure.getName).tpe
+ getRequiredModule(m.erasure.getName).tpe
// Use these like `applyType[List, Int]` or `applyType[Map, Int, String]`
def applyType[M](implicit m1: CM[M]): Type =
@@ -202,7 +198,7 @@ trait SyntheticMethods extends ast.TreeDSL {
// in the original order.
def accessors = clazz.caseFieldAccessors sortBy { acc =>
originalAccessors indexWhere { orig =>
- (acc.name == orig.name) || (acc.name startsWith (orig.name + "$").toTermName)
+ (acc.name == orig.name) || (acc.name startsWith (orig.name append "$"))
}
}
val arity = accessors.size
@@ -225,7 +221,7 @@ trait SyntheticMethods extends ast.TreeDSL {
)
def forwardToRuntime(method: Symbol): Tree =
- forwardMethod(method, getMember(ScalaRunTimeModule, "_" + method.name toTermName))(This(clazz) :: _)
+ forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(This(clazz) :: _)
// Any member, including private
def hasConcreteImpl(name: Name) =
@@ -238,14 +234,14 @@ trait SyntheticMethods extends ast.TreeDSL {
}
}
def readConstantValue[T](name: String, default: T = null.asInstanceOf[T]): T = {
- clazzMember(name.toTermName).info match {
+ clazzMember(newTermName(name)).info match {
case NullaryMethodType(ConstantType(Constant(value))) => value.asInstanceOf[T]
case _ => default
}
}
def productIteratorMethod = {
createMethod(nme.productIterator, iteratorOfType(accessorLub))(_ =>
- gen.mkMethodCall(ScalaRunTimeModule, "typedProductIterator", List(accessorLub), List(This(clazz)))
+ gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(This(clazz)))
)
}
def projectionMethod(accessor: Symbol, num: Int) = {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9991836344..5ccf27ded9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -969,7 +969,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
return typed(Select(tree, meth), mode, pt)
}
if (coercion != EmptyTree) {
- debuglog("inferred view from " + tree.tpe + " to " + pt + " = " + coercion + ":" + coercion.tpe)
+ def msg = "inferred view from " + tree.tpe + " to " + pt + " = " + coercion + ":" + coercion.tpe
+ if (settings.logImplicitConv.value)
+ unit.echo(tree.pos, msg)
+
+ debuglog(msg)
return newTyper(context.makeImplicit(context.reportAmbiguousErrors)).typed(
new ApplyImplicitView(coercion, List(tree)) setPos tree.pos, mode, pt)
}
@@ -1056,7 +1060,13 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
inferView(qual, qual.tpe, searchTemplate, true) match {
case EmptyTree => qual
- case coercion => typedQualifier(atPos(qual.pos)(new ApplyImplicitView(coercion, List(qual))))
+ case coercion =>
+ if (settings.logImplicitConv.value)
+ unit.echo(qual.pos,
+ "applied implicit conversion from %s to %s = %s".format(
+ qual.tpe, searchTemplate, coercion.symbol.defString))
+
+ typedQualifier(atPos(qual.pos)(new ApplyImplicitView(coercion, List(qual))))
}
}
else qual
@@ -3468,7 +3478,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case ex: TypeError =>
fun match {
case Select(qual, name)
- if !isPatternMode && nme.isOpAssignmentName(name.decode) =>
+ if !isPatternMode && nme.isOpAssignmentName(newTermName(name.decode)) =>
val qual1 = typedQualifier(qual)
if (treeInfo.isVariableOrGetter(qual1)) {
stopTimer(failedOpEqNanos, opeqStart)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 4f7e6225e1..fd6f972ffc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -21,6 +21,8 @@ trait Unapplies extends ast.TreeDSL
import CODE.{ CASE => _, _ }
import treeInfo.{ isRepeatedParamType, isByNameParamType }
+ private val unapplyParamName = newTermName("x$0")
+
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
assert(ufn.isMethod)
@@ -112,7 +114,7 @@ trait Unapplies extends ast.TreeDSL
private def constrParamss(cdef: ClassDef): List[List[ValDef]] = {
val DefDef(_, _, _, vparamss, _, _) = treeInfo firstConstructor cdef.impl.body
- vparamss map (_ map copyUntyped[ValDef])
+ mmap(vparamss)(copyUntyped[ValDef])
}
/** The return value of an unapply method of a case class C[Ts]
@@ -165,7 +167,7 @@ trait Unapplies extends ast.TreeDSL
val cparamss = constrParamss(cdef)
atPos(cdef.pos.focus)(
DefDef(caseMods, nme.apply, tparams, cparamss, classType(cdef, tparams),
- New(classType(cdef, tparams), cparamss map (_ map gen.paramToArg)))
+ New(classType(cdef, tparams), mmap(cparamss)(gen.paramToArg)))
)
}
@@ -173,14 +175,13 @@ trait Unapplies extends ast.TreeDSL
*/
def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = {
val tparams = cdef.tparams map copyUntypedInvariant
- val paramName = newTermName("x$0")
val method = constrParamss(cdef) match {
case xs :: _ if xs.nonEmpty && isRepeatedParamType(xs.last.tpt) => nme.unapplySeq
case _ => nme.unapply
}
- val cparams = List(ValDef(Modifiers(PARAM | SYNTHETIC), paramName, classType(cdef, tparams), EmptyTree))
+ val cparams = List(ValDef(Modifiers(PARAM | SYNTHETIC), unapplyParamName, classType(cdef, tparams), EmptyTree))
val ifNull = if (constrParamss(cdef).head.isEmpty) FALSE else REF(NoneModule)
- val body = nullSafe({ case Ident(x) => caseClassUnapplyReturnValue(x, cdef.symbol) }, ifNull)(Ident(paramName))
+ val body = nullSafe({ case Ident(x) => caseClassUnapplyReturnValue(x, cdef.symbol) }, ifNull)(Ident(unapplyParamName))
atPos(cdef.pos.focus)(
DefDef(caseMods, method, tparams, List(cparams), TypeTree(), body)
@@ -201,12 +202,12 @@ trait Unapplies extends ast.TreeDSL
def paramWithDefault(vd: ValDef) =
treeCopy.ValDef(vd, vd.mods | DEFAULTPARAM, vd.name, atPos(vd.pos.focus)(TypeTree() setOriginal vd.tpt), toIdent(vd))
- val paramss = cparamss map (_ map paramWithDefault)
+ val paramss = mmap(cparamss)(paramWithDefault)
val classTpe = classType(cdef, tparams)
Some(atPos(cdef.pos.focus)(
DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, paramss, classTpe,
- New(classTpe, paramss map (_ map toIdent)))
+ New(classTpe, mmap(paramss)(toIdent)))
))
}
}
diff --git a/src/compiler/scala/tools/nsc/util/ProxyReport.scala b/src/compiler/scala/tools/nsc/util/ProxyReport.scala
index 86cf2006bb..2f4f029308 100644
--- a/src/compiler/scala/tools/nsc/util/ProxyReport.scala
+++ b/src/compiler/scala/tools/nsc/util/ProxyReport.scala
@@ -13,7 +13,7 @@ import scala.collection.{ mutable, immutable, generic }
trait ProxyReport {
val global: Global
import global._
- import definitions.{ getClass => gc, _ }
+ import definitions._
private object classes {
def isIgnorable(sym: Symbol) = sym :: sym.allOverriddenSymbols exists { s =>
@@ -26,13 +26,13 @@ trait ProxyReport {
methods foreach (m => m.initialize.info.paramss.flatten foreach (_.initialize))
methods
}
- lazy val GlobalClass = gc(classOf[Global].getName)
- lazy val GenericClass = getModule("scala.collection.generic").moduleClass
- lazy val CollectionClass = getModule("scala.collection").moduleClass
+ lazy val GlobalClass = getRequiredClass(classOf[Global].getName)
+ lazy val GenericClass = getRequiredModule("scala.collection.generic").moduleClass
+ lazy val CollectionClass = getRequiredModule("scala.collection").moduleClass
- def getType(name: String) = getMember(GlobalClass, name.toTypeName)
- def getColl(name: String) = getMember(CollectionClass, name.toTypeName)
- def getGeneric(name: String) = getMember(GenericClass, name.toTypeName)
+ def getType(name: String) = getMember(GlobalClass, newTypeName(name))
+ def getColl(name: String) = getMember(CollectionClass, newTypeName(name))
+ def getGeneric(name: String) = getMember(GenericClass, newTypeName(name))
// the following operations + those in RewrappingTypeProxy are all operations
// in class Type that are overridden in some subclass
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
index f4481b800e..8bbda5dd05 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala
@@ -12,22 +12,37 @@ trait CPSUtils {
var cpsEnabled = true
val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true"
def vprintln(x: =>Any): Unit = if (verbose) println(x)
+
+ object cpsNames {
+ val catches = newTermName("$catches")
+ val ex = newTermName("$ex")
+ val flatMapCatch = newTermName("flatMapCatch")
+ val getTrivialValue = newTermName("getTrivialValue")
+ val isTrivial = newTermName("isTrivial")
+ val reify = newTermName("reify")
+ val reifyR = newTermName("reifyR")
+ val shift = newTermName("shift")
+ val shiftR = newTermName("shiftR")
+ val shiftSuffix = newTermName("$shift")
+ val shiftUnit = newTermName("shiftUnit")
+ val shiftUnitR = newTermName("shiftUnitR")
+ }
- lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym")
- lazy val MarkerCPSTypes = definitions.getClass("scala.util.continuations.cpsParam")
- lazy val MarkerCPSSynth = definitions.getClass("scala.util.continuations.cpsSynth")
- lazy val MarkerCPSAdaptPlus = definitions.getClass("scala.util.continuations.cpsPlus")
- lazy val MarkerCPSAdaptMinus = definitions.getClass("scala.util.continuations.cpsMinus")
-
- lazy val Context = definitions.getClass("scala.util.continuations.ControlContext")
- lazy val ModCPS = definitions.getModule("scala.util.continuations")
-
- lazy val MethShiftUnit = definitions.getMember(ModCPS, "shiftUnit")
- lazy val MethShiftUnitR = definitions.getMember(ModCPS, "shiftUnitR")
- lazy val MethShift = definitions.getMember(ModCPS, "shift")
- lazy val MethShiftR = definitions.getMember(ModCPS, "shiftR")
- lazy val MethReify = definitions.getMember(ModCPS, "reify")
- lazy val MethReifyR = definitions.getMember(ModCPS, "reifyR")
+ lazy val MarkerCPSSym = definitions.getRequiredClass("scala.util.continuations.cpsSym")
+ lazy val MarkerCPSTypes = definitions.getRequiredClass("scala.util.continuations.cpsParam")
+ lazy val MarkerCPSSynth = definitions.getRequiredClass("scala.util.continuations.cpsSynth")
+ lazy val MarkerCPSAdaptPlus = definitions.getRequiredClass("scala.util.continuations.cpsPlus")
+ lazy val MarkerCPSAdaptMinus = definitions.getRequiredClass("scala.util.continuations.cpsMinus")
+
+ lazy val Context = definitions.getRequiredClass("scala.util.continuations.ControlContext")
+ lazy val ModCPS = definitions.getRequiredModule("scala.util.continuations")
+
+ lazy val MethShiftUnit = definitions.getMember(ModCPS, cpsNames.shiftUnit)
+ lazy val MethShiftUnitR = definitions.getMember(ModCPS, cpsNames.shiftUnitR)
+ lazy val MethShift = definitions.getMember(ModCPS, cpsNames.shift)
+ lazy val MethShiftR = definitions.getMember(ModCPS, cpsNames.shiftR)
+ lazy val MethReify = definitions.getMember(ModCPS, cpsNames.reify)
+ lazy val MethReifyR = definitions.getMember(ModCPS, cpsNames.reifyR)
lazy val allCPSAnnotations = List(MarkerCPSSym, MarkerCPSTypes, MarkerCPSSynth,
MarkerCPSAdaptPlus, MarkerCPSAdaptMinus)
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index b383227243..585dc3fbe8 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -355,7 +355,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val valueTpe = removeAllCPSAnnotations(expr.tpe)
- val sym = currentOwner.newValue(tree.pos, unit.fresh.newName("tmp"))
+ val sym = currentOwner.newValue(tree.pos, newTermName(unit.fresh.newName("tmp")))
.setInfo(valueTpe)
.setFlag(Flags.SYNTHETIC)
.setAnnotations(List(AnnotationInfo(MarkerCPSSym.tpe, Nil, Nil)))
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
index f0c389bb11..960b27c52f 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
@@ -192,21 +192,21 @@ abstract class SelectiveCPSTransform extends PluginComponent with
// val expr2 = if (catches.nonEmpty) {
val pos = catches.head.pos
- val argSym = currentOwner.newValueParameter(pos, "$ex").setInfo(ThrowableClass.tpe)
+ val argSym = currentOwner.newValueParameter(pos, cpsNames.ex).setInfo(ThrowableClass.tpe)
val rhs = Match(Ident(argSym), catches1)
val fun = Function(List(ValDef(argSym)), rhs)
- val funSym = currentOwner.newValueParameter(pos, "$catches").setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp)))
+ val funSym = currentOwner.newValueParameter(pos, cpsNames.catches).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp)))
val funDef = localTyper.typed(atPos(pos) { ValDef(funSym, fun) })
- val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member("flatMapCatch")), List(Ident(funSym))) })
+ val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym))) })
argSym.owner = fun.symbol
val chown = new ChangeOwnerTraverser(currentOwner, fun.symbol)
chown.traverse(rhs)
- val exSym = currentOwner.newValueParameter(pos, "$ex").setInfo(ThrowableClass.tpe)
+ val exSym = currentOwner.newValueParameter(pos, cpsNames.ex).setInfo(ThrowableClass.tpe)
val catch2 = { localTyper.typedCases(tree, List(
CaseDef(Bind(exSym, Typed(Ident("_"), TypeTree(ThrowableClass.tpe))),
- Apply(Select(Ident(funSym), "isDefinedAt"), List(Ident(exSym))),
+ Apply(Select(Ident(funSym), nme.isDefinedAt), List(Ident(exSym))),
Apply(Ident(funSym), List(Ident(exSym))))
), ThrowableClass.tpe, targettp) }
@@ -317,11 +317,11 @@ abstract class SelectiveCPSTransform extends PluginComponent with
log("fun.tpe:"+fun.tpe)
log("return type of fun:"+body1.tpe)
- var methodName = "map"
+ var methodName = nme.map
if (body1.tpe != null) {
if (body1.tpe.typeSymbol == Context)
- methodName = "flatMap"
+ methodName = nme.flatMap
}
else
unit.error(rhs.pos, "cannot compute type for CPS-transformed function result")
@@ -347,14 +347,14 @@ abstract class SelectiveCPSTransform extends PluginComponent with
// val <lhs> = ctx.getTrivialValue; ... <--- TODO: try/catch ??? don't bother for the moment...
// else
// ctx.flatMap { <lhs> => ... }
- val ctxSym = currentOwner.newValue(vd.symbol.name + "$shift").setInfo(rhs1.tpe)
+ val ctxSym = currentOwner.newValue(vd.symbol.name append cpsNames.shiftSuffix).setInfo(rhs1.tpe)
val ctxDef = localTyper.typed(ValDef(ctxSym, rhs1))
def ctxRef = localTyper.typed(Ident(ctxSym))
val argSym = currentOwner.newValue(vd.symbol.name).setInfo(tpe)
- val argDef = localTyper.typed(ValDef(argSym, Select(ctxRef, ctxRef.tpe.member("getTrivialValue"))))
+ val argDef = localTyper.typed(ValDef(argSym, Select(ctxRef, ctxRef.tpe.member(cpsNames.getTrivialValue))))
val switchExpr = localTyper.typed(atPos(vd.symbol.pos) {
val body2 = mkBlock(bodyStms, bodyExpr).duplicate // dup before typing!
- If(Select(ctxRef, ctxSym.tpe.member("isTrivial")),
+ If(Select(ctxRef, ctxSym.tpe.member(cpsNames.isTrivial)),
applyTrivial(argSym, mkBlock(argDef::bodyStms, bodyExpr)),
applyCombinatorFun(ctxRef, body2))
})
diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala
index bd498de847..6db4904b93 100644
--- a/src/library/scala/Option.scala
+++ b/src/library/scala/Option.scala
@@ -192,6 +192,13 @@ sealed abstract class Option[+A] extends Product with Serializable {
@inline final def exists(p: A => Boolean): Boolean =
!isEmpty && p(this.get)
+ /** Returns true if this option is empty '''or''' the predicate
+ * $p returns true when applied to this $option's value.
+ *
+ * @param p the predicate to test
+ */
+ @inline final def forall(p: A => Boolean): Boolean = isEmpty || p(this.get)
+
/** Apply the given procedure $f to the option's value,
* if it is nonempty. Otherwise, do nothing.
*
diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala
index 8a17ae87b0..8851f1ab91 100644
--- a/src/library/scala/Symbol.scala
+++ b/src/library/scala/Symbol.scala
@@ -31,8 +31,8 @@ final class Symbol private (val name: String) extends Serializable {
override def equals(other: Any) = this eq other.asInstanceOf[AnyRef]
}
-object Symbol extends UniquenessCache[String, Symbol]
-{
+object Symbol extends UniquenessCache[String, Symbol] {
+ override def apply(name: String): Symbol = super.apply(name)
protected def valueFromKey(name: String): Symbol = new Symbol(name)
protected def keyFromValue(sym: Symbol): Option[String] = Some(sym.name)
}
diff --git a/src/library/scala/collection/parallel/mutable/ParHashMap.scala b/src/library/scala/collection/parallel/mutable/ParHashMap.scala
index 37065e32fc..31750b0b0d 100644
--- a/src/library/scala/collection/parallel/mutable/ParHashMap.scala
+++ b/src/library/scala/collection/parallel/mutable/ParHashMap.scala
@@ -190,7 +190,7 @@ extends collection.parallel.BucketCombiner[(K, V), ParHashMap[K, V], DefaultEntr
} else {
// construct a normal table and fill it sequentially
// TODO parallelize by keeping separate sizemaps and merging them
- val table = new HashTable[K, DefaultEntry[K, V]] {
+ object table extends HashTable[K, DefaultEntry[K, V]] {
def insertEntry(e: DefaultEntry[K, V]) = if (super.findEntry(e.key) eq null) super.addEntry(e)
sizeMapInit(table.length)
}
@@ -201,8 +201,7 @@ extends collection.parallel.BucketCombiner[(K, V), ParHashMap[K, V], DefaultEntr
}
i += 1
}
- val c = table.hashTableContents
- new ParHashMap(c)
+ new ParHashMap(table.hashTableContents)
}
/* classes */
diff --git a/src/library/scala/io/Codec.scala b/src/library/scala/io/Codec.scala
index fa17f3eaeb..1a27df1c10 100644
--- a/src/library/scala/io/Codec.scala
+++ b/src/library/scala/io/Codec.scala
@@ -110,7 +110,15 @@ object Codec extends LowPriorityCodecImplicits {
@migration("This method was previously misnamed `fromUTF8`. Converts from character sequence to Array[Byte].", "2.9.0")
def toUTF8(cs: CharSequence): Array[Byte] = {
- val cbuffer = java.nio.CharBuffer wrap cs
+ val cbuffer = java.nio.CharBuffer.wrap(cs, 0, cs.length)
+ val bbuffer = UTF8.charSet encode cbuffer
+ val bytes = new Array[Byte](bbuffer.remaining())
+ bbuffer get bytes
+
+ bytes
+ }
+ def toUTF8(chars: Array[Char], offset: Int, len: Int): Array[Byte] = {
+ val cbuffer = java.nio.CharBuffer.wrap(chars, offset, len)
val bbuffer = UTF8.charSet encode cbuffer
val bytes = new Array[Byte](bbuffer.remaining())
bbuffer get bytes
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala
index acd28f04f5..466b57dea7 100644
--- a/src/library/scala/reflect/ClassManifest.scala
+++ b/src/library/scala/reflect/ClassManifest.scala
@@ -127,7 +127,7 @@ trait ClassManifest[T] extends OptManifest[T] with Equals with Serializable {
java.lang.reflect.Array.newInstance(tp, 0).getClass.asInstanceOf[jClass[Array[T]]]
def arrayManifest: ClassManifest[Array[T]] =
- ClassManifest.classType[Array[T]](arrayClass[T](erasure))
+ ClassManifest.classType[Array[T]](arrayClass[T](erasure), this)
def newArray(len: Int): Array[T] =
java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]]
@@ -220,7 +220,7 @@ object ClassManifest {
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match {
- case NoManifest => Object.asInstanceOf[ClassManifest[Array[T]]]
+ case NoManifest => Object.asInstanceOf[ClassManifest[Array[T]]]
case m: ClassManifest[_] => m.asInstanceOf[ClassManifest[T]].arrayManifest
}
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala
index df5f64cdf6..be08409636 100644
--- a/src/library/scala/reflect/Manifest.scala
+++ b/src/library/scala/reflect/Manifest.scala
@@ -44,7 +44,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals {
override def typeArguments: List[Manifest[_]] = Nil
override def arrayManifest: Manifest[Array[T]] =
- Manifest.classType[Array[T]](arrayClass[T](erasure))
+ Manifest.classType[Array[T]](arrayClass[T](erasure), this)
override def canEqual(that: Any): Boolean = that match {
case _: Manifest[_] => true
@@ -60,7 +60,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals {
override def hashCode = this.erasure.##
}
-trait AnyValManifest[T] extends Manifest[T] with Equals {
+sealed abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
override def <:<(that: ClassManifest[_]): Boolean =
(that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal)
override def canEqual(other: Any) = other match {
@@ -68,7 +68,7 @@ trait AnyValManifest[T] extends Manifest[T] with Equals {
case _ => false
}
override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
- override def hashCode = System.identityHashCode(this)
+ override val hashCode = System.identityHashCode(this)
}
/** The object `Manifest` defines factory methods for manifests.
@@ -76,127 +76,104 @@ trait AnyValManifest[T] extends Manifest[T] with Equals {
* in client code.
*/
object Manifest {
- private def ObjectClass = classOf[java.lang.Object]
+ def valueManifests: List[AnyValManifest[_]] =
+ List(Byte, Short, Char, Int, Long, Float, Double, Boolean, Unit)
- val Byte: AnyValManifest[Byte] = new AnyValManifest[scala.Byte] {
+ val Byte: AnyValManifest[Byte] = new AnyValManifest[scala.Byte]("Byte") {
def erasure = java.lang.Byte.TYPE
- override def toString = "Byte"
override def newArray(len: Int): Array[Byte] = new Array[Byte](len)
override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len))
override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte()
private def readResolve(): Any = Manifest.Byte
}
- val Short: AnyValManifest[Short] = new AnyValManifest[scala.Short] {
+ val Short: AnyValManifest[Short] = new AnyValManifest[scala.Short]("Short") {
def erasure = java.lang.Short.TYPE
- override def toString = "Short"
override def newArray(len: Int): Array[Short] = new Array[Short](len)
override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len))
override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort()
private def readResolve(): Any = Manifest.Short
}
- val Char: AnyValManifest[Char] = new AnyValManifest[scala.Char] {
+ val Char: AnyValManifest[Char] = new AnyValManifest[scala.Char]("Char") {
def erasure = java.lang.Character.TYPE
- override def toString = "Char"
override def newArray(len: Int): Array[Char] = new Array[Char](len)
override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len))
override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar()
private def readResolve(): Any = Manifest.Char
}
- val Int: AnyValManifest[Int] = new AnyValManifest[scala.Int] {
+ val Int: AnyValManifest[Int] = new AnyValManifest[scala.Int]("Int") {
def erasure = java.lang.Integer.TYPE
- override def toString = "Int"
override def newArray(len: Int): Array[Int] = new Array[Int](len)
override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len))
override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt()
private def readResolve(): Any = Manifest.Int
}
- val Long: AnyValManifest[Long] = new AnyValManifest[scala.Long] {
+ val Long: AnyValManifest[Long] = new AnyValManifest[scala.Long]("Long") {
def erasure = java.lang.Long.TYPE
- override def toString = "Long"
override def newArray(len: Int): Array[Long] = new Array[Long](len)
override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len))
override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong()
private def readResolve(): Any = Manifest.Long
}
- val Float: AnyValManifest[Float] = new AnyValManifest[scala.Float] {
+ val Float: AnyValManifest[Float] = new AnyValManifest[scala.Float]("Float") {
def erasure = java.lang.Float.TYPE
- override def toString = "Float"
override def newArray(len: Int): Array[Float] = new Array[Float](len)
override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len))
override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat()
private def readResolve(): Any = Manifest.Float
}
- val Double: AnyValManifest[Double] = new AnyValManifest[scala.Double] {
+ val Double: AnyValManifest[Double] = new AnyValManifest[scala.Double]("Double") {
def erasure = java.lang.Double.TYPE
- override def toString = "Double"
override def newArray(len: Int): Array[Double] = new Array[Double](len)
override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len))
override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble()
private def readResolve(): Any = Manifest.Double
}
- val Boolean: AnyValManifest[Boolean] = new AnyValManifest[scala.Boolean] {
+ val Boolean: AnyValManifest[Boolean] = new AnyValManifest[scala.Boolean]("Boolean") {
def erasure = java.lang.Boolean.TYPE
- override def toString = "Boolean"
override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len)
override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len))
override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean()
private def readResolve(): Any = Manifest.Boolean
}
- val Unit: AnyValManifest[Unit] = new AnyValManifest[scala.Unit] {
+ val Unit: AnyValManifest[Unit] = new AnyValManifest[scala.Unit]("Unit") {
def erasure = java.lang.Void.TYPE
- override def toString = "Unit"
override def newArray(len: Int): Array[Unit] = new Array[Unit](len)
override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len))
override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit()
private def readResolve(): Any = Manifest.Unit
}
- val Any: Manifest[Any] = new ClassTypeManifest[scala.Any](None, ObjectClass, Nil) {
- override def toString = "Any"
+ val Any: Manifest[scala.Any] = new PhantomManifest[scala.Any]("Any") {
override def <:<(that: ClassManifest[_]): Boolean = (that eq this)
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
- override def hashCode = System.identityHashCode(this)
private def readResolve(): Any = Manifest.Any
}
- val Object: Manifest[Object] = new ClassTypeManifest[java.lang.Object](None, ObjectClass, Nil) {
- override def toString = "Object"
+ val Object: Manifest[java.lang.Object] = new PhantomManifest[java.lang.Object]("Object") {
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
- override def hashCode = System.identityHashCode(this)
private def readResolve(): Any = Manifest.Object
}
- val AnyVal: Manifest[AnyVal] = new ClassTypeManifest[scala.AnyVal](None, ObjectClass, Nil) {
- override def toString = "AnyVal"
+ val AnyVal: Manifest[scala.AnyVal] = new PhantomManifest[scala.AnyVal]("AnyVal") {
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any)
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
- override def hashCode = System.identityHashCode(this)
private def readResolve(): Any = Manifest.AnyVal
}
- val Null: Manifest[Null] = new ClassTypeManifest[scala.Null](None, ObjectClass, Nil) {
- override def toString = "Null"
+ val Null: Manifest[scala.Null] = new PhantomManifest[scala.Null]("Null") {
override def <:<(that: ClassManifest[_]): Boolean =
(that ne null) && (that ne Nothing) && !(that <:< AnyVal)
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
- override def hashCode = System.identityHashCode(this)
private def readResolve(): Any = Manifest.Null
}
- val Nothing: Manifest[Nothing] = new ClassTypeManifest[scala.Nothing](None, ObjectClass, Nil) {
- override def toString = "Nothing"
+ val Nothing: Manifest[scala.Nothing] = new PhantomManifest[scala.Nothing]("Nothing") {
override def <:<(that: ClassManifest[_]): Boolean = (that ne null)
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
- override def hashCode = System.identityHashCode(this)
private def readResolve(): Any = Manifest.Nothing
}
@@ -231,6 +208,11 @@ object Manifest {
def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] =
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
+ private abstract class PhantomManifest[T](override val toString: String) extends ClassTypeManifest[T](None, classOf[java.lang.Object], Nil) {
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
+ override val hashCode = System.identityHashCode(this)
+ }
+
/** Manifest for the class type `clazz[args]`, where `clazz` is
* a top-level or static class. */
private class ClassTypeManifest[T](prefix: Option[Manifest[_]],
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index e5502acb20..2394925657 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -542,12 +542,18 @@ trait Trees /*extends reflect.generic.Trees*/ { self: Universe =>
case class Select(qualifier: Tree, name: Name)
extends RefTree
+ def Select(qualifier: Tree, name: String): Select =
+ Select(qualifier, newTermName(name))
+
def Select(qualifier: Tree, sym: Symbol): Select =
Select(qualifier, sym.name) setSymbol sym
/** Identifier <name> */
case class Ident(name: Name) extends RefTree { }
+ def Ident(name: String): Ident =
+ Ident(newTermName(name))
+
def Ident(sym: Symbol): Ident =
Ident(sym.name) setSymbol sym
diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala
index f48d99f5af..cbe778f09b 100644
--- a/src/library/scala/runtime/AbstractPartialFunction.scala
+++ b/src/library/scala/runtime/AbstractPartialFunction.scala
@@ -26,7 +26,7 @@ abstract class AbstractPartialFunction[-T1, +R]
private var fallBackField: PartialFunction[T1 @uncheckedVariance, R @uncheckedVariance] = _
def fallBack: PartialFunction[T1, R] = synchronized {
- if (fallBackField == null) fallBackField = PartialFunction.empty
+ if (fallBackField eq null) fallBackField = PartialFunction.empty
fallBackField
}
@@ -38,7 +38,7 @@ abstract class AbstractPartialFunction[-T1, +R]
override def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = {
val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
result.synchronized {
- result.fallBackField = this.fallBackField orElse that
+ result.fallBackField = if (this.fallBackField eq null) that else this.fallBackField orElse that
result
}
}
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index c726c56d0e..b19c8d086c 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -769,6 +769,24 @@ public final class BoxesRunTime
}
throw new NoSuchMethodException();
}
+
+ public static boolean isBoxedNumberOrBoolean(Object arg) {
+ if (arg instanceof java.lang.Boolean)
+ return true;
+ else
+ return isBoxedNumber(arg);
+ }
+ public static boolean isBoxedNumber(Object arg) {
+ return (
+ (arg instanceof java.lang.Integer)
+ || (arg instanceof java.lang.Long)
+ || (arg instanceof java.lang.Double)
+ || (arg instanceof java.lang.Float)
+ || (arg instanceof java.lang.Short)
+ || (arg instanceof java.lang.Character)
+ || (arg instanceof java.lang.Byte)
+ );
+ }
/** arg.toChar */
public static java.lang.Character toCharacter(Object arg) throws NoSuchMethodException {
diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala
index 127e6e0ab7..df52b34f87 100644
--- a/src/library/scala/xml/Elem.scala
+++ b/src/library/scala/xml/Elem.scala
@@ -41,7 +41,7 @@ object Elem {
class Elem(
override val prefix: String,
val label: String,
- override val attributes: MetaData,
+ attributes1: MetaData,
override val scope: NamespaceBinding,
val child: Node*)
extends Node with Serializable
@@ -49,6 +49,8 @@ extends Node with Serializable
final override def doCollectNamespaces = true
final override def doTransform = true
+ override val attributes = MetaData.normalize(attributes1, scope)
+
if (prefix == "")
throw new IllegalArgumentException("prefix of zero length, use null instead")
diff --git a/src/library/scala/xml/MetaData.scala b/src/library/scala/xml/MetaData.scala
index 98e863eb37..c516747bae 100644
--- a/src/library/scala/xml/MetaData.scala
+++ b/src/library/scala/xml/MetaData.scala
@@ -38,8 +38,8 @@ object MetaData {
def iterate(md: MetaData, normalized_attribs: MetaData, set: Set[String]): MetaData = {
lazy val key = getUniversalKey(md, scope)
if (md eq Null) normalized_attribs
- else if (set(key)) iterate(md.next, normalized_attribs, set)
- else iterate(md.next, md copy normalized_attribs, set + key)
+ else if ((md.value eq null) || set(key)) iterate(md.next, normalized_attribs, set)
+ else md copy iterate(md.next, normalized_attribs, set + key)
}
iterate(attribs, Null, Set())
}
diff --git a/src/library/scala/xml/PrefixedAttribute.scala b/src/library/scala/xml/PrefixedAttribute.scala
index 436dfcda43..b80d6a1c73 100644
--- a/src/library/scala/xml/PrefixedAttribute.scala
+++ b/src/library/scala/xml/PrefixedAttribute.scala
@@ -13,22 +13,25 @@ package scala.xml
*
* @param pre ...
* @param key ...
- * @param value the attribute value, which may not be null
+ * @param value the attribute value
* @param next ...
*/
class PrefixedAttribute(
val pre: String,
val key: String,
val value: Seq[Node],
- val next: MetaData)
+ val next1: MetaData)
extends Attribute
{
- if (value eq null)
- throw new UnsupportedOperationException("value is null")
+ val next = if (value ne null) next1 else next1.remove(key)
- /** same as this(key, Utility.parseAttributeValue(value), next) */
+ /** same as this(pre, key, Text(value), next), or no attribute if value is null */
def this(pre: String, key: String, value: String, next: MetaData) =
- this(pre, key, Text(value), next)
+ this(pre, key, if (value ne null) Text(value) else null: NodeSeq, next)
+
+ /** same as this(pre, key, value.get, next), or no attribute if value is None */
+ def this(pre: String, key: String, value: Option[Seq[Node]], next: MetaData) =
+ this(pre, key, value.orNull, next)
/** Returns a copy of this unprefixed attribute with the given
* next field.
diff --git a/src/library/scala/xml/UnprefixedAttribute.scala b/src/library/scala/xml/UnprefixedAttribute.scala
index c56fba1e6c..b6800d5ed1 100644
--- a/src/library/scala/xml/UnprefixedAttribute.scala
+++ b/src/library/scala/xml/UnprefixedAttribute.scala
@@ -22,7 +22,7 @@ extends Attribute
final val pre = null
val next = if (value ne null) next1 else next1.remove(key)
- /** same as this(key, Text(value), next) */
+ /** same as this(key, Text(value), next), or no attribute if value is null */
def this(key: String, value: String, next: MetaData) =
this(key, if (value ne null) Text(value) else null: NodeSeq, next)
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index 9b48f4e1bb..fc20b892b9 100644
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -61,7 +61,7 @@ object Utility extends AnyRef with parsing.TokenTests {
val key = md.key
val smaller = sort(md.filter { m => m.key < key })
val greater = sort(md.filter { m => m.key > key })
- smaller.append( Null ).append(md.copy ( greater ))
+ smaller.copy(md.copy ( greater ))
}
/** Return the node with its attribute list sorted alphabetically
diff --git a/src/scalap/scala/tools/scalap/JavaWriter.scala b/src/scalap/scala/tools/scalap/JavaWriter.scala
index db9d6c5ed9..02b940ab16 100644
--- a/src/scalap/scala/tools/scalap/JavaWriter.scala
+++ b/src/scalap/scala/tools/scalap/JavaWriter.scala
@@ -9,7 +9,7 @@
package scala.tools.scalap
import java.io._
-
+import scala.reflect.NameTransformer
class JavaWriter(classfile: Classfile, writer: Writer) extends CodeWriter(writer) {
@@ -32,22 +32,22 @@ class JavaWriter(classfile: Classfile, writer: Writer) extends CodeWriter(writer
}
def nameToClass(str: String): String = {
- val res = Names.decode(str.replace('/', '.'))
+ val res = NameTransformer.decode(str.replace('/', '.'))
if (res == "java.lang.Object") "scala.Any" else res
}
def nameToClass0(str: String) = {
- val res = Names.decode(str.replace('/', '.'))
+ val res = NameTransformer.decode(str.replace('/', '.'))
if (res == "java.lang.Object") "scala.AnyRef" else res
}
def nameToSimpleClass(str: String) =
- Names.decode(str.substring(str.lastIndexOf('/') + 1))
+ NameTransformer.decode(str.substring(str.lastIndexOf('/') + 1))
def nameToPackage(str: String) = {
val inx = str.lastIndexOf('/')
val name = if (inx == -1) str else str.substring(0, inx).replace('/', '.')
- Names.decode(name)
+ NameTransformer.decode(name)
}
def sigToType(str: String): String =
@@ -119,9 +119,9 @@ class JavaWriter(classfile: Classfile, writer: Writer) extends CodeWriter(writer
def printField(flags: Int, name: Int, tpe: Int, attribs: List[cf.Attribute]) {
print(flagsToStr(false, flags))
if ((flags & 0x0010) != 0)
- print("val " + Names.decode(getName(name)))
+ print("val " + NameTransformer.decode(getName(name)))
else
- print("final var " + Names.decode(getName(name)))
+ print("final var " + NameTransformer.decode(getName(name)))
print(": " + getType(tpe) + ";").newline
}
@@ -139,20 +139,20 @@ class JavaWriter(classfile: Classfile, writer: Writer) extends CodeWriter(writer
if (getName(name) == "<init>") {
print("def this" + getType(tpe) + ";").newline
} else {
- print("def " + Names.decode(getName(name)))
+ print("def " + NameTransformer.decode(getName(name)))
print(getType(tpe) + ";").newline
}
case Some(str) =>
if (getName(name) == "<init>")
print("def this" + str + ";").newline
else
- print("def " + Names.decode(getName(name)) + str + ";").newline
+ print("def " + NameTransformer.decode(getName(name)) + str + ";").newline
}
case None =>
if (getName(name) == "<init>") {
print("def this" + getType(tpe) + ";").newline
} else {
- print("def " + Names.decode(getName(name)))
+ print("def " + NameTransformer.decode(getName(name)))
print(getType(tpe) + ";").newline
}
}
diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala
index 7254b00480..a8a9c65f63 100644
--- a/src/scalap/scala/tools/scalap/Main.scala
+++ b/src/scalap/scala/tools/scalap/Main.scala
@@ -8,6 +8,7 @@
package scala.tools.scalap
import java.io.{ PrintStream, OutputStreamWriter, ByteArrayOutputStream }
+import scala.reflect.NameTransformer
import scalax.rules.scalasig._
import tools.nsc.util.{ ClassPath, JavaClassPath }
import tools.util.PathResolver
@@ -96,7 +97,7 @@ class Main {
*/
def process(args: Arguments, path: ClassPath[AbstractFile])(classname: String): Unit = {
// find the classfile
- val encName = Names.encode(
+ val encName = NameTransformer.encode(
if (classname == "scala.AnyRef") "java.lang.Object"
else classname)
val cls = path.findClass(encName)
diff --git a/src/scalap/scala/tools/scalap/Names.scala b/src/scalap/scala/tools/scalap/Names.scala
deleted file mode 100644
index 1d66b31ce3..0000000000
--- a/src/scalap/scala/tools/scalap/Names.scala
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ___ ____ ___ __ ___ ___
-** / _// __// _ | / / / _ | / _ \ Scala classfile decoder
-** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003-2011, LAMP/EPFL
-** /____/\___/_/ |_/____/_/ |_/_/ http://scala-lang.org/
-**
-*/
-
-
-package scala.tools.scalap
-
-
-object Names {
-
- val operatorName = new Array[String](128)
- operatorName('$') = "$"
- operatorName('~') = "$tilde"
- operatorName('=') = "$eq"
- operatorName('<') = "$less"
- operatorName('>') = "$greater"
- operatorName('!') = "$bang"
- operatorName('#') = "$hash"
- operatorName('%') = "$percent"
- operatorName('^') = "$up"
- operatorName('&') = "$amp"
- operatorName('|') = "$bar"
- operatorName('*') = "$times"
- operatorName('/') = "$div"
- operatorName('\\') = "$bslash"
- operatorName('+') = "$plus"
- operatorName('-') = "$minus"
- operatorName(':') = "$colon"
-
- /** Replace operator symbols by corresponding "$op_name" in names.
- */
- def encode(name: String): String = {
- var i = 0
- val len = name.length()
- val res = new StringBuffer()
- while (i < len) {
- val c = name.charAt(i)
- if (c < 128) {
- val nop = operatorName(c)
- if (nop == null)
- res.append(c)
- else
- res.append(nop)
- } else
- res.append(c)
- i = i + 1
- }
- res.toString()
- }
-
- /** Replace "$op_name" by corresponding operator symbols in names.
- */
- def decode(name: String): String = {
- var i = 0
- val len = name.length()
- val res = new StringBuffer()
- while (i < len) {
- val c = name.charAt(i)
- if (c == '$') {
- var j = len
- while (j > i) {
- val prefix = name.substring(i, j)
- val c = lookup(prefix)
- if (c != null) {
- i = j
- res.append(c)
- } else
- j = j - 1
- }
- } else {
- i = i + 1
- res.append(c)
- }
- }
- res.toString()
- }
-
- /** Looks up the array entry for the operator name.
- */
- def lookup(string: String): String = {
- var i = 0
- var res: String = null
- while (i < 128) {
- if (string.equals(operatorName(i))) {
- res = String.valueOf(i.asInstanceOf[Char])
- i = 128
- }
- i = i + 1
- }
- res
- }
-
-}
diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala
index df78bad25e..aa454934c1 100644
--- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala
+++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSigPrinter.scala
@@ -13,9 +13,8 @@ package scalasig
import java.io.{PrintStream, ByteArrayOutputStream}
import java.util.regex.Pattern
-
import scala.tools.scalap.scalax.util.StringUtil
-import reflect.NameTransformer
+import scala.reflect.NameTransformer
import java.lang.String
class ScalaSigPrinter(stream: PrintStream, printPrivates: Boolean) {