summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android-library/scala/ScalaObject.scala13
-rw-r--r--src/build/genprod.scala2
-rw-r--r--src/build/maven/maven-deploy.xml38
-rw-r--r--src/build/pack.xml4
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala164
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala4
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala4
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/compiler/scala/reflect/internal/SymbolTable.scala10
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala25
-rw-r--r--src/compiler/scala/reflect/internal/TreeGen.scala44
-rw-r--r--src/compiler/scala/reflect/internal/TreeInfo.scala12
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala5
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala60
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala104
-rw-r--r--src/compiler/scala/reflect/internal/pickling/UnPickler.scala1
-rw-r--r--src/compiler/scala/reflect/internal/transform/Erasure.scala203
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala6
-rw-r--r--src/compiler/scala/reflect/runtime/ScalaToJava.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/Universe.scala6
-rw-r--r--src/compiler/scala/tools/cmd/gen/AnyVals.scala6
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala62
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala122
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala35
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala11
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala61
-rwxr-xr-x[-rw-r--r--]src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala57
-rwxr-xr-x[-rw-r--r--]src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala10
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala11
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala4
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala11
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala26
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala6
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala37
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala15
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala257
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala159
-rw-r--r--src/compiler/scala/tools/nsc/transform/InlineErasure.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala6
-rw-r--r--src/compiler/scala/tools/nsc/transform/PostErasure.scala68
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala59
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala29
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala125
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala106
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala3
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala2
-rwxr-xr-xsrc/compiler/scala/tools/nsc/util/DocStrings.scala87
-rw-r--r--src/detach/plugin/scala/tools/detach/Detach.scala8
-rw-r--r--src/library/scala/AnyVal.scala6
-rw-r--r--src/library/scala/Boolean.scala2
-rw-r--r--src/library/scala/BoxingConversions.scala5
-rw-r--r--src/library/scala/Byte.scala2
-rw-r--r--src/library/scala/Char.scala2
-rw-r--r--src/library/scala/Double.scala2
-rw-r--r--src/library/scala/Equals.scala2
-rw-r--r--src/library/scala/Float.scala2
-rw-r--r--src/library/scala/Int.scala2
-rw-r--r--src/library/scala/Long.scala2
-rw-r--r--src/library/scala/NotNull.scala4
-rw-r--r--src/library/scala/Predef.scala11
-rw-r--r--src/library/scala/Product.scala2
-rw-r--r--src/library/scala/Product1.scala6
-rw-r--r--src/library/scala/Product10.scala6
-rw-r--r--src/library/scala/Product11.scala6
-rw-r--r--src/library/scala/Product12.scala6
-rw-r--r--src/library/scala/Product13.scala6
-rw-r--r--src/library/scala/Product14.scala6
-rw-r--r--src/library/scala/Product15.scala6
-rw-r--r--src/library/scala/Product16.scala6
-rw-r--r--src/library/scala/Product17.scala6
-rw-r--r--src/library/scala/Product18.scala6
-rw-r--r--src/library/scala/Product19.scala6
-rw-r--r--src/library/scala/Product2.scala6
-rw-r--r--src/library/scala/Product20.scala6
-rw-r--r--src/library/scala/Product21.scala6
-rw-r--r--src/library/scala/Product22.scala6
-rw-r--r--src/library/scala/Product3.scala6
-rw-r--r--src/library/scala/Product4.scala6
-rw-r--r--src/library/scala/Product5.scala6
-rw-r--r--src/library/scala/Product6.scala6
-rw-r--r--src/library/scala/Product7.scala6
-rw-r--r--src/library/scala/Product8.scala6
-rw-r--r--src/library/scala/Product9.scala6
-rw-r--r--src/library/scala/Proxy.scala10
-rw-r--r--src/library/scala/ScalaObject.scala13
-rw-r--r--src/library/scala/Serializable.scala2
-rw-r--r--src/library/scala/Short.scala2
-rw-r--r--src/library/scala/Tuple1.scala2
-rw-r--r--src/library/scala/Tuple10.scala2
-rw-r--r--src/library/scala/Tuple11.scala2
-rw-r--r--src/library/scala/Tuple12.scala2
-rw-r--r--src/library/scala/Tuple13.scala2
-rw-r--r--src/library/scala/Tuple14.scala2
-rw-r--r--src/library/scala/Tuple15.scala2
-rw-r--r--src/library/scala/Tuple16.scala2
-rw-r--r--src/library/scala/Tuple17.scala2
-rw-r--r--src/library/scala/Tuple18.scala2
-rw-r--r--src/library/scala/Tuple19.scala2
-rw-r--r--src/library/scala/Tuple2.scala2
-rw-r--r--src/library/scala/Tuple20.scala2
-rw-r--r--src/library/scala/Tuple21.scala2
-rw-r--r--src/library/scala/Tuple22.scala2
-rw-r--r--src/library/scala/Tuple3.scala2
-rw-r--r--src/library/scala/Tuple4.scala2
-rw-r--r--src/library/scala/Tuple5.scala2
-rw-r--r--src/library/scala/Tuple6.scala2
-rw-r--r--src/library/scala/Tuple7.scala2
-rw-r--r--src/library/scala/Tuple8.scala2
-rw-r--r--src/library/scala/Tuple9.scala2
-rw-r--r--src/library/scala/Unit.scala2
-rw-r--r--src/library/scala/collection/GenIterableLike.scala2
-rw-r--r--src/library/scala/collection/GenSeqLike.scala2
-rw-r--r--src/library/scala/collection/GenTraversableLike.scala2
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala3
-rw-r--r--src/library/scala/collection/IndexedSeqLike.scala2
-rwxr-xr-xsrc/library/scala/collection/IndexedSeqOptimized.scala2
-rw-r--r--src/library/scala/collection/IterableLike.scala2
-rw-r--r--src/library/scala/collection/Parallelizable.scala2
-rw-r--r--src/library/scala/collection/SeqLike.scala2
-rw-r--r--src/library/scala/collection/TraversableLike.scala3
-rw-r--r--src/library/scala/collection/TraversableOnce.scala5
-rwxr-xr-xsrc/library/scala/collection/generic/FilterMonadic.scala2
-rwxr-xr-xsrc/library/scala/collection/generic/HasNewBuilder.scala2
-rw-r--r--src/library/scala/collection/immutable/StringLike.scala2
-rw-r--r--src/library/scala/collection/immutable/StringOps.scala2
-rw-r--r--src/library/scala/collection/mutable/ArrayBuilder.scala2
-rw-r--r--src/library/scala/collection/mutable/ConcurrentTrieMap.scala (renamed from src/library/scala/collection/mutable/Ctrie.scala)100
-rw-r--r--src/library/scala/collection/mutable/FlatArray.scala150
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala4
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala10
-rw-r--r--src/library/scala/collection/parallel/Tasks.scala2
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashMap.scala4
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashSet.scala1
-rw-r--r--src/library/scala/collection/parallel/immutable/ParRange.scala1
-rw-r--r--src/library/scala/collection/parallel/mutable/ParArray.scala2
-rw-r--r--src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala (renamed from src/library/scala/collection/parallel/mutable/ParCtrie.scala)54
-rw-r--r--src/library/scala/math/Equiv.scala2
-rw-r--r--src/library/scala/math/Ordered.scala2
-rw-r--r--src/library/scala/reflect/ClassManifest.scala8
-rwxr-xr-xsrc/library/scala/reflect/api/StandardDefinitions.scala2
-rw-r--r--src/library/scala/reflect/api/Trees.scala18
-rwxr-xr-xsrc/library/scala/reflect/api/Types.scala2
-rw-r--r--src/library/scala/runtime/ScalaNumberProxy.scala4
-rw-r--r--src/library/scala/runtime/StringAdd.scala14
-rw-r--r--src/library/scala/runtime/StringFormat.scala27
-rw-r--r--src/library/scala/util/Properties.scala26
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/Elem.scala35
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/Node.scala2
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/PrettyPrinter.scala2
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/Utility.scala63
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/XML.scala19
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/factory/Binder.scala10
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/ConstructingHandler.scala4
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/DefaultMarkupHandler.scala2
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/MarkupHandler.scala3
-rwxr-xr-x[-rw-r--r--]src/library/scala/xml/parsing/MarkupParser.scala2
-rwxr-xr-xsrc/library/scala/xml/pull/XMLEventReader.scala2
174 files changed, 2113 insertions, 928 deletions
diff --git a/src/android-library/scala/ScalaObject.scala b/src/android-library/scala/ScalaObject.scala
deleted file mode 100644
index f44116d1ce..0000000000
--- a/src/android-library/scala/ScalaObject.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala
-
-trait ScalaObject extends AnyRef
diff --git a/src/build/genprod.scala b/src/build/genprod.scala
index cce00321df..6016f6fb92 100644
--- a/src/build/genprod.scala
+++ b/src/build/genprod.scala
@@ -608,7 +608,7 @@ object {className} {{
/** {className} is a cartesian product of {i} component{s}.
* @since 2.3
*/
-trait {className}{covariantArgs} extends Product {{
+trait {className}{covariantArgs} extends Any with Product {{
/** The arity of this product.
* @return {i}
*/
diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml
index 2e490163e0..e0f31a5db2 100644
--- a/src/build/maven/maven-deploy.xml
+++ b/src/build/maven/maven-deploy.xml
@@ -16,10 +16,15 @@
<property name="local.release.repository" value="${user.home}/.m2/repository" />
<property name="repository.credentials.id" value="sonatype-nexus" />
<property name="settings.file" value="${user.home}/.m2/settings.xml" />
-
+ <condition property="version.is.snapshot">
+ <contains string="${maven.version.number}" substring="-SNAPSHOT"/>
+ </condition>
+
<echo>Using server[${repository.credentials.id}] for maven repository credentials.
Please make sure that your ~/.m2/settings.xml has the needed username/password for this server id
</echo>
+
+
</target>
<target name="init.maven" depends="init.properties">
@@ -241,28 +246,31 @@
</target>
<!-- Local Targets -->
- <target name="deploy.snapshot.local" depends="deploy.local.init" description="Deploys the bundled snapshot of the Scala Lanaguage to a local maven repository">
- <deploy-local-all version="${maven.snapshot.version.number}" repository="${local.snapshot.repository}" />
+ <target name="deploy.snapshot.local" depends="deploy.local.init" if="version.is.snapshot" description="Deploys the bundled snapshot of the Scala Lanaguage to a local maven repository">
+ <deploy-local-all version="${maven.version.number}" repository="${local.snapshot.repository}" />
</target>
- <target name="deploy.release.local" depends="deploy.local.init" description="Deploys the bundled files as a release into the local Maven repository">
- <deploy-local-all version="${version.number}" repository="${local.release.repository}" />
+ <target name="deploy.release.local" depends="deploy.local.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the local Maven repository">
+ <deploy-local-all version="${maven.version.number}" repository="${local.release.repository}" />
</target>
+ <target name="deploy.local" depends="deploy.snapshot.local, deploy.release.local" description="Deploys the bundle files to the local maven repo."/>
- <!-- Remote Targets -->
- <target name="deploy.signed.snapshot" depends="deploy.remote.init" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
- <deploy-remote-signed-all version="${maven.snapshot.version.number}" repository="${remote.snapshot.repository}" />
+ <!-- Remote Signed Targets -->
+ <target name="deploy.signed.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
+ <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.snapshot.repository}" />
</target>
- <target name="deploy.signed.release" depends="deploy.remote.init" description="Deploys the bundled files as a release into the desired remote Maven repository">
- <deploy-remote-signed-all version="${version.number}" repository="${remote.release.repository}" />
+ <target name="deploy.signed.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository">
+ <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.release.repository}" />
</target>
-
- <target name="deploy.snapshot" depends="deploy.remote.init" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
- <deploy-remote-all version="${maven.snapshot.version.number}" repository="${remote.snapshot.repository}" />
+ <target name="deploy.signed" depends="deploy.signed.release, deploy.signed.snapshot" description="Deploys signed bundles to remote repo"/>
+ <!-- Remote unsigned targets -->
+ <target name="deploy.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
+ <deploy-remote-all version="${maven.version.number}" repository="${remote.snapshot.repository}" />
</target>
- <target name="deploy.release" depends="deploy.remote.init" description="Deploys the bundled files as a release into the desired remote Maven repository">
- <deploy-remote-all version="${version.number}" repository="${remote.release.repository}" />
+ <target name="deploy.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository">
+ <deploy-remote-all version="${maven.version.number}" repository="${remote.release.repository}" />
</target>
+ <target name="deploy" depends="deploy.snapshot, deploy.release" description="Deploys unsigned artifacts to the maven repo."/>
</project>
diff --git a/src/build/pack.xml b/src/build/pack.xml
index 90aec8e25b..e79895e3a8 100644
--- a/src/build/pack.xml
+++ b/src/build/pack.xml
@@ -299,7 +299,7 @@ MAIN DISTRIBUTION SBAZ
<target name="pack-maven.latest.unix" depends="pack-maven.docs" unless="os.win">
<symlink link="${dists.dir}/maven/latest"
- resource="${dists.dir}/maven/${version.number}"
+ resource="${version.number}"
overwrite="yes"/>
</target>
@@ -315,8 +315,6 @@ MAIN DISTRIBUTION SBAZ
<copy tofile="${dists.dir}/maven/${version.number}/build.xml"
file="${src.dir}/build/maven/maven-deploy.xml"/>
<!-- export properties for use when deploying -->
- <property name="maven.snapshot.version.number"
- value="${version.major}.${version.minor}.${version.patch}-SNAPSHOT"/>
<echoproperties destfile="${dists.dir}/maven/${version.number}/build.properties"/>
</target>
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index ec171c5f2c..1d53b83b75 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -22,15 +22,17 @@ trait Definitions extends reflect.api.StandardDefinitions {
*/
private type PolyMethodCreator = List[Symbol] => (Option[List[Type]], Type)
- private def newClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = {
+ private def enterNewClass(owner: Symbol, name: TypeName, parents: List[Type], flags: Long = 0L): Symbol = {
val clazz = owner.newClassSymbol(name, NoPosition, flags)
clazz setInfoAndEnter ClassInfoType(parents, newScope, clazz)
}
private def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol = {
val msym = owner.newMethod(name.encode, NoPosition, flags)
val params = msym.newSyntheticValueParams(formals)
- msym setInfoAndEnter MethodType(params, restpe)
+ msym setInfo MethodType(params, restpe)
}
+ private def enterNewMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type, flags: Long = 0L): Symbol =
+ owner.info.decls enter newMethod(owner, name, formals, restpe, flags)
// the scala value classes
trait ValueClassDefinitions {
@@ -101,7 +103,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isGetClass(sym: Symbol) =
(sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty)
- lazy val AnyValClass = valueCache(tpnme.AnyVal)
lazy val UnitClass = valueCache(tpnme.Unit)
lazy val ByteClass = valueCache(tpnme.Byte)
lazy val ShortClass = valueCache(tpnme.Short)
@@ -205,8 +206,20 @@ trait Definitions extends reflect.api.StandardDefinitions {
case _ => null
}
+ private def fixupAsAnyTrait(tpe: Type): Type = tpe match {
+ case ClassInfoType(parents, decls, clazz) =>
+ if (parents.head.typeSymbol == AnyClass) tpe
+ else {
+ assert(parents.head.typeSymbol == ObjectClass, parents)
+ ClassInfoType(AnyClass.tpe :: parents.tail, decls, clazz)
+ }
+ case PolyType(tparams, restpe) =>
+ PolyType(tparams, fixupAsAnyTrait(restpe))
+// case _ => tpe
+ }
+
// top types
- lazy val AnyClass = newClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT)
+ lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT)
lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor)
lazy val ObjectClass = getClass(sn.Object)
@@ -216,6 +229,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
@deprecated("Use AnyRefModule", "2.10.0")
def Predef_AnyRef = AnyRefModule
+ lazy val AnyValClass = ScalaPackageClass.info member tpnme.AnyVal orElse {
+ val anyval = enterNewClass(ScalaPackageClass, tpnme.AnyVal, List(AnyClass.tpe, NotNullClass.tpe), ABSTRACT)
+ val av_constr = anyval.newClassConstructor(NoPosition)
+ anyval.info.decls enter av_constr
+ anyval
+ }
+ lazy val AnyVal_getClass = enterNewMethod(AnyValClass, nme.getClass_, Nil, getClassReturnType(AnyValClass.tpe))
+
// bottom types
lazy val RuntimeNothingClass = getClass(fulltpnme.RuntimeNothing)
lazy val RuntimeNullClass = getClass(fulltpnme.RuntimeNull)
@@ -248,7 +269,6 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val UninitializedErrorClass = getRequiredClass("scala.UninitializedFieldError")
// fundamental reference classes
- lazy val ScalaObjectClass = getMember(ScalaPackageClass, tpnme.ScalaObject)
lazy val PartialFunctionClass = getRequiredClass("scala.PartialFunction")
lazy val AbstractPartialFunctionClass = getRequiredClass("scala.runtime.AbstractPartialFunction")
lazy val SymbolClass = getRequiredClass("scala.Symbol")
@@ -319,10 +339,10 @@ trait Definitions extends reflect.api.StandardDefinitions {
// .setInfo(UnitClass.tpe)
lazy val TypeConstraintClass = getRequiredClass("scala.annotation.TypeConstraint")
- lazy val SingletonClass = newClass(ScalaPackageClass, tpnme.Singleton, anyparam, ABSTRACT | TRAIT | FINAL)
+ lazy val SingletonClass = enterNewClass(ScalaPackageClass, tpnme.Singleton, anyparam, ABSTRACT | TRAIT | FINAL)
lazy val SerializableClass = getRequiredClass("scala.Serializable")
- lazy val JavaSerializableClass = getClass(sn.JavaSerializable)
- lazy val ComparableClass = getRequiredClass("java.lang.Comparable")
+ lazy val JavaSerializableClass = getClass(sn.JavaSerializable) modifyInfo fixupAsAnyTrait
+ lazy val ComparableClass = getRequiredClass("java.lang.Comparable") modifyInfo fixupAsAnyTrait
lazy val JavaCloneableClass = getRequiredClass("java.lang.Cloneable")
lazy val RemoteInterfaceClass = getRequiredClass("java.rmi.Remote")
lazy val RemoteExceptionClass = getRequiredClass("java.rmi.RemoteException")
@@ -351,7 +371,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
def isPrimitiveArray(tp: Type) = tp match {
- case TypeRef(_, ArrayClass, arg :: Nil) => isValueClass(arg.typeSymbol)
+ case TypeRef(_, ArrayClass, arg :: Nil) => isPrimitiveValueClass(arg.typeSymbol)
case _ => false
}
def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match {
@@ -660,12 +680,12 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
// members of class scala.Any
- lazy val Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL)
- lazy val Any_!= = newMethod(AnyClass, nme.NE, anyparam, booltype, FINAL)
- lazy val Any_equals = newMethod(AnyClass, nme.equals_, anyparam, booltype)
- lazy val Any_hashCode = newMethod(AnyClass, nme.hashCode_, Nil, inttype)
- lazy val Any_toString = newMethod(AnyClass, nme.toString_, Nil, stringtype)
- lazy val Any_## = newMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL)
+ lazy val Any_== = enterNewMethod(AnyClass, nme.EQ, anyparam, booltype, FINAL)
+ lazy val Any_!= = enterNewMethod(AnyClass, nme.NE, anyparam, booltype, FINAL)
+ lazy val Any_equals = enterNewMethod(AnyClass, nme.equals_, anyparam, booltype)
+ lazy val Any_hashCode = enterNewMethod(AnyClass, nme.hashCode_, Nil, inttype)
+ lazy val Any_toString = enterNewMethod(AnyClass, nme.toString_, Nil, stringtype)
+ lazy val Any_## = enterNewMethod(AnyClass, nme.HASHHASH, Nil, inttype, FINAL)
// Any_getClass requires special handling. The return type is determined on
// a per-call-site basis as if the function being called were actually:
@@ -676,22 +696,89 @@ trait Definitions extends reflect.api.StandardDefinitions {
// Since getClass is not actually a polymorphic method, this requires compiler
// participation. At the "Any" level, the return type is Class[_] as it is in
// java.lang.Object. Java also special cases the return type.
- lazy val Any_getClass = newMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
+ lazy val Any_getClass = enterNewMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED)
lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype)
lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor)
+ // A type function from T => Class[U], used to determine the return
+ // type of getClass calls. The returned type is:
+ //
+ // 1. If T is a value type, Class[T].
+ // 2. If T is a phantom type (Any or AnyVal), Class[_].
+ // 3. If T is a local class, Class[_ <: |T|].
+ // 4. Otherwise, Class[_ <: T].
+ //
+ // Note: AnyVal cannot be Class[_ <: AnyVal] because if the static type of the
+ // receiver is AnyVal, it implies the receiver is boxed, so the correct
+ // class object is that of java.lang.Integer, not Int.
+ //
+ // TODO: If T is final, return type could be Class[T]. Should it?
+ def getClassReturnType(tp: Type): Type = {
+ val sym = tp.typeSymbol
+
+ if (phase.erasedTypes) ClassClass.tpe
+ else if (isPrimitiveValueClass(sym)) ClassType(tp.widen)
+ else {
+ val eparams = typeParamsToExistentials(ClassClass, ClassClass.typeParams)
+ val upperBound = (
+ if (isPhantomClass(sym)) AnyClass.tpe
+ else if (sym.isLocalClass) erasure.intersectionDominator(tp.parents)
+ else tp.widen
+ )
+
+ existentialAbstraction(
+ eparams,
+ ClassType(eparams.head setInfo TypeBounds.upper(upperBound) tpe)
+ )
+ }
+ }
+
+ /** Remove references to class Object (other than the head) in a list of parents */
+ def removeLaterObjects(tps: List[Type]): List[Type] = tps match {
+ case Nil => Nil
+ case x :: xs => x :: xs.filterNot(_.typeSymbol == ObjectClass)
+ }
+ /** Remove all but one reference to class Object from a list of parents. */
+ def removeRedundantObjects(tps: List[Type]): List[Type] = tps match {
+ case Nil => Nil
+ case x :: xs =>
+ if (x.typeSymbol == ObjectClass)
+ x :: xs.filterNot(_.typeSymbol == ObjectClass)
+ else
+ x :: removeRedundantObjects(xs)
+ }
+ /** Order a list of types with non-trait classes before others. */
+ def classesFirst(tps: List[Type]): List[Type] = {
+ val (classes, others) = tps partition (t => t.typeSymbol.isClass && !t.typeSymbol.isTrait)
+ if (classes.isEmpty || others.isEmpty || (tps startsWith classes)) tps
+ else classes ::: others
+ }
+ /** The following transformations applied to a list of parents.
+ * If any parent is a class/trait, all parents which normalize to
+ * Object are discarded. Otherwise, all parents which normalize
+ * to Object except the first one found are discarded.
+ */
+ def normalizedParents(parents: List[Type]): List[Type] = {
+ if (parents exists (t => (t.typeSymbol ne ObjectClass) && t.typeSymbol.isClass))
+ parents filterNot (_.typeSymbol eq ObjectClass)
+ else
+ removeRedundantObjects(parents)
+ }
+ def parentsString(parents: List[Type]) =
+ normalizedParents(parents) mkString " with "
+
// members of class java.lang.{ Object, String }
- lazy val Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL)
- lazy val Object_== = newMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL)
- lazy val Object_!= = newMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL)
- lazy val Object_eq = newMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL)
- lazy val Object_ne = newMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL)
+ lazy val Object_## = enterNewMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL)
+ lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL)
+ lazy val Object_!= = enterNewMethod(ObjectClass, nme.NE, anyrefparam, booltype, FINAL)
+ lazy val Object_eq = enterNewMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL)
+ lazy val Object_ne = enterNewMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL)
lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass, nme.isInstanceOf_Ob, FINAL | SYNTHETIC)(_ => booltype)
lazy val Object_asInstanceOf = newT1NoParamsMethod(ObjectClass, nme.asInstanceOf_Ob, FINAL | SYNTHETIC)(_.typeConstructor)
lazy val Object_synchronized = newPolyMethod(1, ObjectClass, nme.synchronized_, FINAL)(tps =>
(Some(List(tps.head.typeConstructor)), tps.head.typeConstructor)
)
- lazy val String_+ = newMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL)
+ lazy val String_+ = enterNewMethod(StringClass, nme.raw.PLUS, anyparam, stringtype, FINAL)
def Object_getClass = getMember(ObjectClass, nme.getClass_)
def Object_clone = getMember(ObjectClass, nme.clone_)
@@ -776,7 +863,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
)
lazy val AnnotationDefaultAttr: Symbol = {
- val attr = newClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.typeConstructor))
+ val attr = enterNewClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.typeConstructor))
// This attribute needs a constructor so that modifiers in parsed Java code make sense
attr.info.decls enter attr.newClassConstructor(NoPosition)
attr
@@ -853,11 +940,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
owner.newAliasType(name) setInfoAndEnter alias
private def specialPolyClass(name: TypeName, flags: Long)(parentFn: Symbol => Type): Symbol = {
- val clazz = newClass(ScalaPackageClass, name, Nil)
+ val clazz = enterNewClass(ScalaPackageClass, name, Nil)
val tparam = clazz.newSyntheticTypeParam("T0", flags)
val parents = List(AnyRefClass.tpe, parentFn(tparam))
- clazz setInfo polyType(List(tparam), ClassInfoType(parents, newScope, clazz))
+ clazz setInfo GenPolyType(List(tparam), ClassInfoType(parents, newScope, clazz))
}
def newPolyMethod(typeParamCount: Int, owner: Symbol, name: TermName, flags: Long)(createFn: PolyMethodCreator): Symbol = {
@@ -890,14 +977,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
/** Is the symbol that of a parent which is added during parsing? */
lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass
- private lazy val scalaValueClassesSet = ScalaValueClasses.toSet
+ lazy val scalaValueClassesSet = ScalaValueClasses.toSet
private lazy val boxedValueClassesSet = boxedClass.values.toSet + BoxedUnitClass
/** Is symbol a value class? */
- def isValueClass(sym: Symbol) = scalaValueClassesSet(sym)
- def isNonUnitValueClass(sym: Symbol) = isValueClass(sym) && (sym != UnitClass)
- def isSpecializableClass(sym: Symbol) = isValueClass(sym) || (sym == AnyRefClass)
- def isScalaValueType(tp: Type) = scalaValueClassesSet(tp.typeSymbol)
+ def isPrimitiveValueClass(sym: Symbol) = scalaValueClassesSet(sym)
+ def isNonUnitValueClass(sym: Symbol) = isPrimitiveValueClass(sym) && (sym != UnitClass)
+ def isSpecializableClass(sym: Symbol) = isPrimitiveValueClass(sym) || (sym == AnyRefClass)
+ def isScalaValueType(tp: Type) = scalaValueClassesSet(tp.typeSymbol)
/** Is symbol a boxed value class, e.g. java.lang.Integer? */
def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym)
@@ -906,7 +993,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
* value class. Otherwise, NoSymbol.
*/
def unboxedValueClass(sym: Symbol): Symbol =
- if (isValueClass(sym)) sym
+ if (isPrimitiveValueClass(sym)) sym
else if (sym == BoxedUnitClass) UnitClass
else boxedClass.map(_.swap).getOrElse(sym, NoSymbol)
@@ -929,7 +1016,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
else flatNameString(sym.owner, separator) + nme.NAME_JOIN_STRING + sym.simpleName
def signature1(etp: Type): String = {
if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head))
- else if (isValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString()
+ else if (isPrimitiveValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString()
else "L" + flatNameString(etp.typeSymbol, '/') + ";"
}
val etp = erasure(tp)
@@ -1007,16 +1094,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
Object_synchronized,
Object_isInstanceOf,
Object_asInstanceOf,
- String_+
+ String_+,
+ ComparableClass,
+ JavaSerializableClass
)
- /** Removing the anyref parent they acquire from having a source file.
- */
- setParents(AnyValClass, anyparam)
- ScalaValueClasses foreach { sym =>
- setParents(sym, anyvalparam)
- }
-
isInitialized = true
} //init
@@ -1029,7 +1111,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
// 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
- val newCaller = newMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC)
+ val newCaller = enterNewMethod(DelegateClass, name, paramTypes, delegateType, FINAL | STATIC)
// val newCaller = newPolyMethod(DelegateClass, name,
// tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC)
Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller)
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 1ae4f755ed..1003fa804f 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -88,7 +88,7 @@ trait Importers { self: SymbolTable =>
case from.PolyType(_, res) => res
case result => result
}
- s setInfo polyType(mytypeParams, importType(result))
+ s setInfo GenPolyType(mytypeParams, importType(result))
s setAnnotations (sym.annotations map importAnnotationInfo)
}
}
@@ -200,7 +200,7 @@ trait Importers { self: SymbolTable =>
val myclazz = importSymbol(clazz)
val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope
val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz)
- myclazz setInfo polyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope
+ myclazz setInfo GenPolyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope
decls foreach importSymbol // will enter itself into myclazz
myclazzTpe
case from.RefinedType(parents, decls) =>
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index 12f56976c9..48f21721da 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -80,9 +80,9 @@ trait NameManglers {
val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
val SETTER_SUFFIX: TermName = encode("_=")
- @deprecated("2.10.0", "Use SPECIALIZED_SUFFIX")
+ @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0")
def SPECIALIZED_SUFFIX_STRING = SPECIALIZED_SUFFIX.toString
- @deprecated("2.10.0", "Use SPECIALIZED_SUFFIX")
+ @deprecated("Use SPECIALIZED_SUFFIX", "2.10.0")
def SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX.toTermName
def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index ef2114b608..84007425ed 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -145,7 +145,6 @@ trait StdNames extends NameManglers { self: SymbolTable =>
final val Object: NameType = "Object"
final val PartialFunction: NameType = "PartialFunction"
final val Product: NameType = "Product"
- final val ScalaObject: NameType = "ScalaObject"
final val Serializable: NameType = "Serializable"
final val Singleton: NameType = "Singleton"
final val String: NameType = "String"
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala
index ce54c32273..b58a0ef7d5 100644
--- a/src/compiler/scala/reflect/internal/SymbolTable.scala
+++ b/src/compiler/scala/reflect/internal/SymbolTable.scala
@@ -37,7 +37,7 @@ abstract class SymbolTable extends api.Universe
def log(msg: => AnyRef): Unit
def abort(msg: String): Nothing = throw new FatalError(supplementErrorMessage(msg))
- @deprecated("2.10.0", "Give us a reason")
+ @deprecated("Give us a reason", "2.10.0")
def abort(): Nothing = abort("unknown error")
/** Override with final implementation for inlining. */
@@ -128,6 +128,10 @@ abstract class SymbolTable extends api.Universe
final def period(rid: RunId, pid: Phase#Id): Period =
(rid << 8) + pid
+ /** Are we later than given phase in compilation? */
+ final def isAtPhaseAfter(p: Phase) =
+ p != NoPhase && phase.id > p.id
+
/** Perform given operation at given phase. */
@inline final def atPhase[T](ph: Phase)(op: => T): T = {
val saved = pushPhase(ph)
@@ -145,7 +149,7 @@ abstract class SymbolTable extends api.Universe
@inline final def beforePrevPhase[T](op: => T): T = atPhase(phase.prev)(op)
@inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T =
- if (target != NoPhase && phase.id > target.id) atPhase(target)(op) else op
+ if (isAtPhaseAfter(target)) atPhase(target)(op) else op
final def isValid(period: Period): Boolean =
period != 0 && runId(period) == currentRunId && {
@@ -184,7 +188,7 @@ abstract class SymbolTable extends api.Universe
}
// enter decls of parent classes
for (p <- container.parentSymbols) {
- if (p != definitions.ObjectClass && p != definitions.ScalaObjectClass) {
+ if (p != definitions.ObjectClass) {
openPackageModule(p, dest)
}
}
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index de490074b0..9678d2b8cd 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -441,7 +441,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME
final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!!
final def isTypeParameter = isType && isParameter && !isSkolem
- final def isValueClass = definitions.isValueClass(this)
+ final def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this)
final def isVarargsMethod = isMethod && hasFlag(VARARGS)
/** Package tests */
@@ -499,6 +499,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor
final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR)
+ final def isDerivedValueClass =
+ isClass && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass
+
+ final def isMethodWithExtension =
+ isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR)
+
final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME)
final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
@@ -1598,7 +1604,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else owner.logicallyEnclosingMember
/** Kept for source compatibility with 2.9. Scala IDE for Eclipse relies on this. */
- @deprecated("Use enclosingTopLevelClass")
+ @deprecated("Use enclosingTopLevelClass", "2.10.0")
def toplevelClass: Symbol = enclosingTopLevelClass
/** The top-level class containing this symbol. */
@@ -1835,7 +1841,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
base.info.decl(sname) filter (_.hasAccessorFlag)
}
- /** The case module corresponding to this case class
+ /** Return the accessor method of the first parameter of this class.
+ * or NoSymbol if it does not exist.
+ */
+ def firstParamAccessor: Symbol = NoSymbol
+
+ /** The case module corresponding to this case class
* @pre case class is a member of some other class or package
*/
final def caseModule: Symbol = {
@@ -2510,7 +2521,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final override def isAbstractType = false
final override def isAliasType = false
- override def existentialBound = polyType(this.typeParams, TypeBounds.upper(this.classBound))
+ override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound))
override def sourceFile =
if (owner.isPackageClass) source
@@ -2585,6 +2596,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def sourceModule =
if (isModuleClass) companionModule else NoSymbol
+ override def firstParamAccessor =
+ info.decls.find(m => (m hasFlag PARAMACCESSOR) && m.isMethod) getOrElse NoSymbol
+
+
private[this] var childSet: Set[Symbol] = Set()
override def children = childSet
override def addChild(sym: Symbol) { childSet = childSet + sym }
@@ -2742,7 +2757,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** An exception for cyclic references of symbol definitions */
case class CyclicReference(sym: Symbol, info: Type)
extends TypeError("illegal cyclic reference involving " + sym) {
- // printStackTrace() // debug
+ if (settings.debug.value) printStackTrace()
}
case class InvalidCompanions(sym1: Symbol, sym2: Symbol) extends Throwable(
diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala
index 8c2a067d4d..141ff12f8a 100644
--- a/src/compiler/scala/reflect/internal/TreeGen.scala
+++ b/src/compiler/scala/reflect/internal/TreeGen.scala
@@ -10,11 +10,10 @@ abstract class TreeGen {
def rootId(name: Name) = Select(Ident(nme.ROOTPKG), name)
def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name)
def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name)
- def scalaAnyRefConstr = scalaDot(tpnme.AnyRef)
- def scalaUnitConstr = scalaDot(tpnme.Unit)
- def scalaScalaObjectConstr = scalaDot(tpnme.ScalaObject)
- def productConstr = scalaDot(tpnme.Product)
- def serializableConstr = scalaDot(tpnme.Serializable)
+ def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) setSymbol AnyRefClass
+ def scalaUnitConstr = scalaDot(tpnme.Unit) setSymbol UnitClass
+ def productConstr = scalaDot(tpnme.Product) setSymbol ProductRootClass
+ def serializableConstr = scalaDot(tpnme.Serializable) setSymbol SerializableClass
def scalaFunctionConstr(argtpes: List[Tree], restpe: Tree, abstractFun: Boolean = false): Tree = {
val cls = if (abstractFun)
@@ -149,22 +148,6 @@ abstract class TreeGen {
None
}
- /** Cast `tree` to type `pt` */
- def mkCast(tree: Tree, pt: Type): Tree = {
- debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase)
- assert(!tree.tpe.isInstanceOf[MethodType], tree)
- assert(!pt.typeSymbol.isPackageClass && !pt.typeSymbol.isPackageObjectClass, pt)
- // called during (at least): typer, uncurry, explicitouter, cleanup.
- // TODO: figure out the truth table for any/wrapInApply
- // - the `any` flag seems to relate to erasure's adaptMember: "x.asInstanceOf[T] becomes x.$asInstanceOf[T]",
- // where asInstanceOf is Any_asInstanceOf and $asInstanceOf is Object_asInstanceOf
- // erasure will only unbox the value in a tree made by mkCast if `any && wrapInApply`
- // - the `wrapInApply` flag need not be true if the tree will be adapted to have the empty argument list added before it gets to erasure
- // in fact, I think it should be false for trees that will be type checked during typer
- assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize))
- atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = false, wrapInApply = true))
- }
-
/** Builds a reference with stable type to given symbol */
def mkAttributedStableRef(pre: Type, sym: Symbol): Tree =
stabilize(mkAttributedRef(pre, sym))
@@ -268,25 +251,6 @@ abstract class TreeGen {
case _ => Constant(null)
}
- def mkZeroContravariantAfterTyper(tp: Type): Tree = {
- // contravariant -- for replacing an argument in a method call
- // must use subtyping, as otherwise we miss types like `Any with Int`
- val tree =
- if (NullClass.tpe <:< tp) Literal(Constant(null))
- else if (UnitClass.tpe <:< tp) Literal(Constant())
- else if (BooleanClass.tpe <:< tp) Literal(Constant(false))
- else if (FloatClass.tpe <:< tp) Literal(Constant(0.0f))
- else if (DoubleClass.tpe <:< tp) Literal(Constant(0.0d))
- else if (ByteClass.tpe <:< tp) Literal(Constant(0.toByte))
- else if (ShortClass.tpe <:< tp) Literal(Constant(0.toShort))
- else if (IntClass.tpe <:< tp) Literal(Constant(0))
- else if (LongClass.tpe <:< tp) Literal(Constant(0L))
- else if (CharClass.tpe <:< tp) Literal(Constant(0.toChar))
- else mkCast(Literal(Constant(null)), tp)
-
- tree
- }
-
/** Builds a tuple */
def mkTuple(elems: List[Tree]): Tree =
if (elems.isEmpty) Literal(Constant())
diff --git a/src/compiler/scala/reflect/internal/TreeInfo.scala b/src/compiler/scala/reflect/internal/TreeInfo.scala
index 3252b970d1..769d7a9ed1 100644
--- a/src/compiler/scala/reflect/internal/TreeInfo.scala
+++ b/src/compiler/scala/reflect/internal/TreeInfo.scala
@@ -440,15 +440,6 @@ abstract class TreeInfo {
EmptyTree
}
- /** Is the tree Predef, scala.Predef, or _root_.scala.Predef?
- */
- def isPredefExpr(t: Tree) = t match {
- case Ident(nme.Predef) => true
- case Select(Ident(nme.scala_), nme.Predef) => true
- case Select(Select(Ident(nme.ROOTPKG), nme.scala_), nme.Predef) => true
- case _ => false
- }
-
/** Does list of trees start with a definition of
* a class of module with given name (ignoring imports)
*/
@@ -468,7 +459,7 @@ abstract class TreeInfo {
// Top-level definition whose leading imports include Predef.
def containsLeadingPredefImport(defs: List[Tree]): Boolean = defs match {
case PackageDef(_, defs1) :: _ => containsLeadingPredefImport(defs1)
- case Import(expr, _) :: rest => isPredefExpr(expr) || containsLeadingPredefImport(rest)
+ case Import(expr, _) :: rest => isReferenceToPredef(expr) || containsLeadingPredefImport(rest)
case _ => false
}
@@ -479,7 +470,6 @@ abstract class TreeInfo {
}
( isUnitInScala(body, nme.Predef)
- || isUnitInScala(body, tpnme.ScalaObject)
|| containsLeadingPredefImport(List(body)))
}
diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala
index 2b1d833c73..f823110440 100644
--- a/src/compiler/scala/reflect/internal/TreePrinters.scala
+++ b/src/compiler/scala/reflect/internal/TreePrinters.scala
@@ -242,6 +242,10 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
case Template(parents, self, body) =>
val currentOwner1 = currentOwner
if (tree.symbol != NoSymbol) currentOwner = tree.symbol.owner
+// if (parents exists isReferenceToAnyVal) {
+// print("AnyVal")
+// }
+// else {
printRow(parents, " with ")
if (!body.isEmpty) {
if (self.name != nme.WILDCARD) {
@@ -253,6 +257,7 @@ trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
}
printColumn(body, "", ";", "}")
}
+// }
currentOwner = currentOwner1
case Block(stats, expr) =>
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 54cc53aaac..9b1712b790 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -11,6 +11,18 @@ import api.Modifier
trait Trees extends api.Trees { self: SymbolTable =>
+ // Belongs in TreeInfo but then I can't reach it from TreePrinters.
+ def isReferenceToScalaMember(t: Tree, Id: Name) = t match {
+ case Ident(Id) => true
+ case Select(Ident(nme.scala_), Id) => true
+ case Select(Select(Ident(nme.ROOTPKG), nme.scala_), Id) => true
+ case _ => false
+ }
+ /** Is the tree Predef, scala.Predef, or _root_.scala.Predef?
+ */
+ def isReferenceToPredef(t: Tree) = isReferenceToScalaMember(t, nme.Predef)
+ def isReferenceToAnyVal(t: Tree) = isReferenceToScalaMember(t, tpnme.AnyVal)
+
// --- modifiers implementation ---------------------------------------
/** @param privateWithin the qualifier for a private (a type name)
@@ -122,11 +134,14 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
- def substTreeSyms(pairs: (Symbol, Symbol)*): Tree = {
- val list = pairs.toList
- val subst = new TreeSymSubstituter(list map (_._1), list map (_._2))
- subst(tree)
- }
+ def substTreeSyms(pairs: (Symbol, Symbol)*): Tree =
+ substTreeSyms(pairs.map(_._1).toList, pairs.map(_._2).toList)
+
+ def substTreeSyms(from: List[Symbol], to: List[Symbol]): Tree =
+ new TreeSymSubstituter(from, to)(tree)
+
+ def substTreeThis(clazz: Symbol, to: Tree): Tree = new ThisSubstituter(clazz, to) transform tree
+
def shallowDuplicate: Tree = new ShallowDuplicator(tree) transform tree
def shortClass: String = tree.getClass.getName split "[.$]" last
@@ -268,10 +283,16 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
- private object posAssigner extends Traverser {
+ trait PosAssigner extends Traverser {
+ var pos: Position
+ }
+ protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner
+
+ protected class DefaultPosAssigner extends PosAssigner {
var pos: Position = _
override def traverse(t: Tree) {
- if (t != EmptyTree && t.pos == NoPosition) {
+ if (t eq EmptyTree) ()
+ else if (t.pos == NoPosition) {
t.setPos(pos)
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
// @PP: it's pruning whenever it encounters a node with a
@@ -303,10 +324,14 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser {
- def changeOwner(tree: Tree) = {
- if ((tree.isDef || tree.isInstanceOf[Function]) &&
- tree.symbol != NoSymbol && tree.symbol.owner == oldowner)
- tree.symbol.owner = newowner
+ def changeOwner(tree: Tree) = tree match {
+ case Return(expr) =>
+ if (tree.symbol == oldowner)
+ tree.symbol = newowner
+ case _: DefTree | _: Function =>
+ if (tree.symbol != NoSymbol && tree.symbol.owner == oldowner)
+ tree.symbol.owner = newowner
+ case _ =>
}
override def traverse(tree: Tree) {
changeOwner(tree)
@@ -342,6 +367,19 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def toString = substituterString("Symbol", "Tree", from, to)
}
+ /** Substitute clazz.this with `to`. `to` must be an attributed tree.
+ */
+ class ThisSubstituter(clazz: Symbol, to: => Tree) extends Transformer {
+ val newtpe = to.tpe
+ override def transform(tree: Tree) = {
+ if (tree.tpe ne null) tree.tpe = tree.tpe.substThis(clazz, newtpe)
+ tree match {
+ case This(_) if tree.symbol == clazz => to
+ case _ => super.transform(tree)
+ }
+ }
+ }
+
class TypeMapTreeSubstituter(val typeMap: TypeMap) extends Traverser {
override def traverse(tree: Tree) {
if (tree.tpe ne null)
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index b7b7ca5840..2382413a9a 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -65,6 +65,8 @@ import util.Statistics._
// inst is the instantiation and constr is a list of bounds.
case DeBruijnIndex(level, index)
// for dependent method types: a type referring to a method parameter.
+ case ErasedValueType(tp)
+ // only used during erasure of derived value classes.
*/
trait Types extends api.Types { self: SymbolTable =>
@@ -410,6 +412,11 @@ trait Types extends api.Types { self: SymbolTable =>
* The empty list for all other types */
def parents: List[Type] = List()
+ /** For a class with nonEmpty parents, the first parent.
+ * Otherwise some specific fixed top type.
+ */
+ def firstParent = if (parents.nonEmpty) parents.head else ObjectClass.tpe
+
/** For a typeref or single-type, the prefix of the normalized type (@see normalize).
* NoType for all other types. */
def prefix: Type = NoType
@@ -1418,14 +1425,14 @@ trait Types extends api.Types { self: SymbolTable =>
// override def isNullable: Boolean =
// parents forall (p => p.isNullable && !p.typeSymbol.isAbstractType);
- override def safeToString: String =
- parents.mkString(" with ") +
+ override def safeToString: String = parentsString(parents) + (
(if (settings.debug.value || parents.isEmpty || (decls.elems ne null))
decls.mkString("{", "; ", "}") else "")
+ )
}
protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = {
- val period = tpe.baseTypeSeqPeriod;
+ val period = tpe.baseTypeSeqPeriod
if (period != currentPeriod) {
tpe.baseTypeSeqPeriod = currentPeriod
if (!isValidForBaseClasses(period)) {
@@ -1483,7 +1490,7 @@ trait Types extends api.Types { self: SymbolTable =>
else {
//Console.println("computing base classes of " + typeSymbol + " at phase " + phase);//DEBUG
// optimized, since this seems to be performance critical
- val superclazz = tpe.parents.head
+ val superclazz = tpe.firstParent
var mixins = tpe.parents.tail
val sbcs = superclazz.baseClasses
var bcs = sbcs
@@ -1530,7 +1537,7 @@ trait Types extends api.Types { self: SymbolTable =>
)
override def typeParams =
- if (isHigherKinded) parents.head.typeParams
+ if (isHigherKinded) firstParent.typeParams
else super.typeParams
//@M may result in an invalid type (references to higher-order args become dangling )
@@ -2099,7 +2106,7 @@ trait Types extends api.Types { self: SymbolTable =>
!sym.isTypeParameter && pre.isTrivial && args.forall(_.isTrivial)
override def isNotNull =
- sym.isModuleClass || sym == NothingClass || isValueClass(sym) || super.isNotNull
+ sym.isModuleClass || sym == NothingClass || (sym isNonBottomSubClass NotNullClass) || super.isNotNull
override def parents: List[Type] = {
val cache = parentsCache
@@ -2148,12 +2155,12 @@ trait Types extends api.Types { self: SymbolTable =>
)
else ""
)
+
private def finishPrefix(rest: String) = (
if (sym.isPackageClass) packagePrefix + rest
else if (sym.isModuleClass) objectPrefix + rest
else if (!sym.isInitialized) rest
- else if (sym.isAnonymousClass && !phase.erasedTypes)
- thisInfo.parents.mkString("", " with ", refinementString)
+ else if (sym.isAnonymousClass && !phase.erasedTypes) parentsString(thisInfo.parents) + refinementString
else if (sym.isRefinementClass) "" + thisInfo
else rest
)
@@ -3088,6 +3095,17 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ abstract case class ErasedValueType(sym: Symbol) extends Type {
+ override def safeToString = sym.name+"$unboxed"
+ }
+
+ final class UniqueErasedValueType(sym: Symbol) extends ErasedValueType(sym) with UniqueType
+
+ object ErasedValueType {
+ def apply(sym: Symbol): Type =
+ unique(new UniqueErasedValueType(sym))
+ }
+
/** A class representing an as-yet unevaluated type.
*/
abstract class LazyType extends Type {
@@ -3234,11 +3252,21 @@ trait Types extends api.Types { self: SymbolTable =>
* comment or in the code?
*/
def intersectionType(tps: List[Type], owner: Symbol): Type = tps match {
- case List(tp) =>
- tp
- case _ =>
- refinedType(tps, owner)
-/*
+ case tp :: Nil => tp
+ case _ => refinedType(tps, owner)
+ }
+ /** A creator for intersection type where intersections of a single type are
+ * replaced by the type itself.
+ */
+ def intersectionType(tps: List[Type]): Type = tps match {
+ case tp :: Nil => tp
+ case _ => refinedType(tps, commonOwner(tps))
+ }
+
+/**** This implementation to merge parents was checked in in commented-out
+ form and has languished unaltered for five years. I think we should
+ use it or lose it.
+
def merge(tps: List[Type]): List[Type] = tps match {
case tp :: tps1 =>
val tps1a = tps1 filter (_.typeSymbol.==(tp.typeSymbol))
@@ -3253,14 +3281,6 @@ trait Types extends api.Types { self: SymbolTable =>
}
refinedType(merge(tps), owner)
*/
- }
-
- /** A creator for intersection type where intersections of a single type are
- * replaced by the type itself. */
- def intersectionType(tps: List[Type]): Type = tps match {
- case List(tp) => tp
- case _ => refinedType(tps, commonOwner(tps))
- }
/** A creator for type applications */
def appliedType(tycon: Type, args: List[Type]): Type =
@@ -3299,7 +3319,7 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
- /** A creator for type parameterizations that strips empty type parameter lists.
+ /** A creator and extractor for type parameterizations that strips empty type parameter lists.
* Use this factory method to indicate the type has kind * (it's a polymorphic value)
* until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty).
*
@@ -3308,9 +3328,18 @@ trait Types extends api.Types { self: SymbolTable =>
* can we instead say this is the canonical creator for polyTypes which
* may or may not be poly? (It filched the standard "canonical creator" name.)
*/
- def polyType(tparams: List[Symbol], tpe: Type): Type =
+ object GenPolyType {
+ def apply(tparams: List[Symbol], tpe: Type): Type =
if (tparams nonEmpty) typeFun(tparams, tpe)
else tpe // it's okay to be forgiving here
+ def unapply(tpe: Type): Option[(List[Symbol], Type)] = tpe match {
+ case PolyType(tparams, restpe) => Some(tparams, restpe)
+ case _ => Some(List(), tpe)
+ }
+ }
+
+ @deprecated("use GenPolyType(...) instead")
+ def polyType(params: List[Symbol], tpe: Type): Type = GenPolyType(params, tpe)
/** A creator for anonymous type functions, where the symbol for the type function still needs to be created.
*
@@ -3762,6 +3791,7 @@ trait Types extends api.Types { self: SymbolTable =>
case WildcardType => tp
case NoType => tp
case NoPrefix => tp
+ case ErasedSingleType(sym) => tp
*/
case _ =>
tp
@@ -4519,9 +4549,7 @@ trait Types extends api.Types { self: SymbolTable =>
else {
commonOwnerMap.clear()
tps foreach (commonOwnerMap traverse _)
- val result = if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol
- debuglog(tps.mkString("commonOwner(", ", ", ") == " + result))
- result
+ if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol
}
}
@@ -5419,8 +5447,7 @@ trait Types extends api.Types { self: SymbolTable =>
case NullClass =>
tp2 match {
case TypeRef(_, sym2, _) =>
- sym2.isClass && (sym2 isNonBottomSubClass ObjectClass) &&
- !(tp2.normalize.typeSymbol isNonBottomSubClass NotNullClass)
+ containsNull(sym2)
case _ =>
isSingleType(tp2) && tp1 <:< tp2.widen
}
@@ -5451,6 +5478,11 @@ trait Types extends api.Types { self: SymbolTable =>
firstTry
}
+ private def containsNull(sym: Symbol): Boolean =
+ sym.isClass && sym != NothingClass &&
+ !(sym isNonBottomSubClass AnyValClass) &&
+ !(sym isNonBottomSubClass NotNullClass)
+
/** Are `tps1` and `tps2` lists of equal length such that all elements
* of `tps1` conform to corresponding elements of `tps2`?
*/
@@ -5462,7 +5494,7 @@ trait Types extends api.Types { self: SymbolTable =>
*/
def specializesSym(tp: Type, sym: Symbol): Boolean =
tp.typeSymbol == NothingClass ||
- tp.typeSymbol == NullClass && (sym.owner isSubClass ObjectClass) ||
+ tp.typeSymbol == NullClass && containsNull(sym.owner) ||
(tp.nonPrivateMember(sym.name).alternatives exists
(alt => sym == alt || specializesSym(tp.narrow, alt, sym.owner.thisType, sym)))
@@ -5853,14 +5885,6 @@ trait Types extends api.Types { self: SymbolTable =>
loop(initialBTSes)
}
- // @AM the following problem is solved by elimHOTparams in lublist
- // @PP lubLists gone bad: lubList(List(
- // List(scala.collection.generic.GenericCompanion[scala.collection.immutable.Seq], ScalaObject, java.lang.Object, Any)
- // List(scala.collection.generic.GenericCompanion[scala.collection.mutable.Seq], ScalaObject, java.lang.Object, Any)
- // )) == (
- // List(scala.collection.generic.GenericCompanion[Seq**[Any]**], ScalaObject, java.lang.Object, Any)
- // )
-
/** The minimal symbol (wrt Symbol.isLess) of a list of types */
private def minSym(tps: List[Type]): Symbol =
(tps.head.typeSymbol /: tps.tail) {
@@ -6310,7 +6334,7 @@ trait Types extends api.Types { self: SymbolTable =>
} else {
val args = argss map (_.head)
if (args.tail forall (_ =:= args.head)) Some(typeRef(pre, sym, List(args.head)))
- else if (args exists (arg => isValueClass(arg.typeSymbol))) Some(ObjectClass.tpe)
+ else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) Some(ObjectClass.tpe)
else Some(typeRef(pre, sym, List(lub(args))))
}
}
@@ -6441,7 +6465,9 @@ trait Types extends api.Types { self: SymbolTable =>
// but that would be a big change. Left for further refactoring.
/** An exception for cyclic references from which we can recover */
case class RecoverableCyclicReference(sym: Symbol)
- extends TypeError("illegal cyclic reference involving " + sym)
+ extends TypeError("illegal cyclic reference involving " + sym) {
+ if (settings.debug.value) printStackTrace()
+ }
class NoCommonType(tps: List[Type]) extends Throwable(
"lub/glb of incompatible types: " + tps.mkString("", " and ", "")) with ControlThrowable
diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
index 34163d54f8..f1ec64bda9 100644
--- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala
@@ -229,6 +229,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ {
// (3) Try as a nested object symbol.
nestedObjectSymbol orElse {
// (4) Otherwise, fail.
+ //System.err.println("missing "+name+" in "+owner+"/"+owner.id+" "+owner.info.decls)
adjust(errorMissingRequirement(name, owner))
}
}
diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala
index d59fc6d564..e87de8db80 100644
--- a/src/compiler/scala/reflect/internal/transform/Erasure.scala
+++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala
@@ -2,6 +2,8 @@ package scala.reflect
package internal
package transform
+import Flags.PARAMACCESSOR
+
trait Erasure {
val global: SymbolTable
@@ -63,49 +65,62 @@ trait Erasure {
if (cls.owner.isClass) cls.owner.tpe else pre // why not cls.isNestedClass?
}
+ def underlyingOfValueClass(clazz: Symbol): Type =
+ clazz.firstParamAccessor.tpe.resultType
+
abstract class ErasureMap extends TypeMap {
def mergeParents(parents: List[Type]): Type
- def apply(tp: Type): Type = {
- tp match {
- case ConstantType(_) =>
- tp
- case st: SubType =>
- apply(st.supertype)
- case TypeRef(pre, sym, args) =>
- if (sym == ArrayClass)
- if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe
- else if (args.head.typeSymbol.isBottomClass) ObjectArray
- else typeRef(apply(pre), sym, args map this)
- else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass)
- else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass)
- else if (sym.isRefinementClass) apply(mergeParents(tp.parents))
- else if (sym.isClass) typeRef(apply(rebindInnerClass(pre, sym)), sym, List()) // #2585
- else apply(sym.info) // alias type or abstract type
- case PolyType(tparams, restpe) =>
- apply(restpe)
- case ExistentialType(tparams, restpe) =>
- apply(restpe)
- case mt @ MethodType(params, restpe) =>
- MethodType(
- cloneSymbolsAndModify(params, ErasureMap.this),
- if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass)
- // this replaces each typeref that refers to an argument
- // by the type `p.tpe` of the actual argument p (p in params)
- else apply(mt.resultType(params map (_.tpe))))
- case RefinedType(parents, decls) =>
- apply(mergeParents(parents))
- case AnnotatedType(_, atp, _) =>
- apply(atp)
- case ClassInfoType(parents, decls, clazz) =>
- ClassInfoType(
- if (clazz == ObjectClass || isValueClass(clazz)) Nil
- else if (clazz == ArrayClass) List(erasedTypeRef(ObjectClass))
- else removeDoubleObject(parents map this),
- decls, clazz)
- case _ =>
- mapOver(tp)
- }
+ def eraseNormalClassRef(pre: Type, clazz: Symbol): Type =
+ typeRef(apply(rebindInnerClass(pre, clazz)), clazz, List()) // #2585
+
+ protected def eraseDerivedValueClassRef(clazz: Symbol): Type =
+ scalaErasure(underlyingOfValueClass(clazz))
+
+ def apply(tp: Type): Type = tp match {
+ case ConstantType(_) =>
+ tp
+ case st: SubType =>
+ apply(st.supertype)
+ case TypeRef(pre, sym, args) =>
+ if (sym == ArrayClass)
+ if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe
+ else if (args.head.typeSymbol.isBottomClass) ObjectArray
+ else typeRef(apply(pre), sym, args map applyInArray)
+ else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass)
+ else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass)
+ else if (sym.isRefinementClass) apply(mergeParents(tp.parents))
+ else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(sym)
+ else if (sym.isClass) eraseNormalClassRef(pre, sym)
+ else apply(sym.info) // alias type or abstract type
+ case PolyType(tparams, restpe) =>
+ apply(restpe)
+ case ExistentialType(tparams, restpe) =>
+ apply(restpe)
+ case mt @ MethodType(params, restpe) =>
+ MethodType(
+ cloneSymbolsAndModify(params, ErasureMap.this),
+ if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass)
+ // this replaces each typeref that refers to an argument
+ // by the type `p.tpe` of the actual argument p (p in params)
+ else apply(mt.resultType(params map (_.tpe))))
+ case RefinedType(parents, decls) =>
+ apply(mergeParents(parents))
+ case AnnotatedType(_, atp, _) =>
+ apply(atp)
+ case ClassInfoType(parents, decls, clazz) =>
+ ClassInfoType(
+ if (clazz == ObjectClass || isPrimitiveValueClass(clazz)) Nil
+ else if (clazz == ArrayClass) List(erasedTypeRef(ObjectClass))
+ else removeLaterObjects(parents map this),
+ decls, clazz)
+ case _ =>
+ mapOver(tp)
+ }
+
+ def applyInArray(tp: Type): Type = tp match {
+ case TypeRef(pre, sym, args) if (sym.isDerivedValueClass) => eraseNormalClassRef(pre, sym)
+ case _ => apply(tp)
}
}
@@ -138,17 +153,41 @@ trait Erasure {
* parents |Ps|, but with duplicate references of Object removed.
* - for all other types, the type itself (with any sub-components erased)
*/
- def erasure(sym: Symbol, tp: Type): Type = {
- if (sym != NoSymbol && sym.enclClass.isJavaDefined) {
- val res = javaErasure(tp)
- if (verifyJavaErasure && sym.isMethod) {
- val old = scalaErasure(tp)
- if (!(res =:= old))
- log("Identified divergence between java/scala erasure:\n scala: " + old + "\n java: " + res)
- }
- res
+ def erasure(sym: Symbol): ErasureMap =
+ if (sym == NoSymbol || !sym.enclClass.isJavaDefined) scalaErasure
+ else if (verifyJavaErasure && sym.isMethod) verifiedJavaErasure
+ else javaErasure
+
+ /** This is used as the Scala erasure during the erasure phase itself
+ * It differs from normal erasure in that value classes are erased to ErasedValueTypes which
+ * are then later converted to the underlying parameter type in phase posterasure.
+ */
+ def specialErasure(sym: Symbol)(tp: Type): Type =
+ if (sym != NoSymbol && sym.enclClass.isJavaDefined)
+ erasure(sym)(tp)
+ else if (sym.isTerm && sym.owner.isDerivedValueClass)
+ specialErasureAvoiding(sym.owner, tp)
+ else if (sym.isValue && sym.owner.isMethodWithExtension)
+ specialErasureAvoiding(sym.owner.owner, tp)
+ else
+ specialScalaErasure(tp)
+
+ def specialErasureAvoiding(clazz: Symbol, tpe: Type): Type = {
+ tpe match {
+ case PolyType(tparams, restpe) =>
+ specialErasureAvoiding(clazz, restpe)
+ case ExistentialType(tparams, restpe) =>
+ specialErasureAvoiding(clazz, restpe)
+ case mt @ MethodType(params, restpe) =>
+ MethodType(
+ cloneSymbolsAndModify(params, specialErasureAvoiding(clazz, _)),
+ if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass)
+ else specialErasureAvoiding(clazz, (mt.resultType(params map (_.tpe)))))
+ case TypeRef(pre, `clazz`, args) =>
+ typeRef(pre, clazz, List())
+ case _ =>
+ specialScalaErasure(tpe)
}
- else scalaErasure(tp)
}
/** Scala's more precise erasure than java's is problematic as follows:
@@ -163,7 +202,7 @@ trait Erasure {
* For this reason and others (such as distinguishing constructors from other methods)
* erasure is now (Symbol, Type) => Type rather than Type => Type.
*/
- object scalaErasure extends ErasureMap {
+ class ScalaErasureMap extends ErasureMap {
/** In scala, calculate a useful parent.
* An intersection such as `Object with Trait` erases to Trait.
*/
@@ -171,6 +210,37 @@ trait Erasure {
intersectionDominator(parents)
}
+ class JavaErasureMap extends ErasureMap {
+ /** In java, always take the first parent.
+ * An intersection such as `Object with Trait` erases to Object.
+ */
+ def mergeParents(parents: List[Type]): Type =
+ if (parents.isEmpty) ObjectClass.tpe
+ else parents.head
+ }
+
+ object scalaErasure extends ScalaErasureMap
+
+ /** This is used as the Scala erasure during the erasure phase itself
+ * It differs from normal erasure in that value classes are erased to ErasedValueTypes which
+ * are then later converted to the underlying parameter type in phase posterasure.
+ */
+ object specialScalaErasure extends ScalaErasureMap {
+ override def eraseDerivedValueClassRef(clazz: Symbol): Type = ErasedValueType(clazz)
+ }
+
+ object javaErasure extends JavaErasureMap
+
+ object verifiedJavaErasure extends JavaErasureMap {
+ override def apply(tp: Type): Type = {
+ val res = javaErasure(tp)
+ val old = scalaErasure(tp)
+ if (!(res =:= old))
+ log("Identified divergence between java/scala erasure:\n scala: " + old + "\n java: " + res)
+ res
+ }
+ }
+
/** The intersection dominator (SLS 3.7) of a list of types is computed as follows.
*
* - If the list contains one or more occurrences of scala.Array with
@@ -206,26 +276,9 @@ trait Erasure {
}
}
- object javaErasure extends ErasureMap {
- /** In java, always take the first parent.
- * An intersection such as `Object with Trait` erases to Object.
- */
- def mergeParents(parents: List[Type]): Type =
- if (parents.isEmpty) ObjectClass.tpe
- else parents.head
- }
-
/** Type reference after erasure */
def erasedTypeRef(sym: Symbol): Type =
- typeRef(erasure(sym, sym.owner.tpe), sym, List())
-
- /** Remove duplicate references to class Object in a list of parent classes */
- private def removeDoubleObject(tps: List[Type]): List[Type] = tps match {
- case List() => List()
- case tp :: tps1 =>
- if (tp.typeSymbol == ObjectClass) tp :: tps1.filter(_.typeSymbol != ObjectClass)
- else tp :: removeDoubleObject(tps1)
- }
+ typeRef(erasure(sym)(sym.owner.tpe), sym, Nil)
/** The symbol's erased info. This is the type's erasure, except for the following symbols:
*
@@ -239,25 +292,25 @@ trait Erasure {
if (sym == Object_asInstanceOf)
sym.info
else if (sym == Object_isInstanceOf || sym == ArrayClass)
- PolyType(sym.info.typeParams, erasure(sym, sym.info.resultType))
+ PolyType(sym.info.typeParams, specialErasure(sym)(sym.info.resultType))
else if (sym.isAbstractType)
TypeBounds(WildcardType, WildcardType)
else if (sym.isTerm && sym.owner == ArrayClass) {
if (sym.isClassConstructor)
tp match {
case MethodType(params, TypeRef(pre, sym1, args)) =>
- MethodType(cloneSymbolsAndModify(params, erasure(sym, _)),
- typeRef(erasure(sym, pre), sym1, args))
+ MethodType(cloneSymbolsAndModify(params, specialErasure(sym)),
+ typeRef(specialErasure(sym)(pre), sym1, args))
}
else if (sym.name == nme.apply)
tp
else if (sym.name == nme.update)
(tp: @unchecked) match {
case MethodType(List(index, tvar), restpe) =>
- MethodType(List(index.cloneSymbol.setInfo(erasure(sym, index.tpe)), tvar),
+ MethodType(List(index.cloneSymbol.setInfo(specialErasure(sym)(index.tpe)), tvar),
erasedTypeRef(UnitClass))
}
- else erasure(sym, tp)
+ else specialErasure(sym)(tp)
} else if (
sym.owner != NoSymbol &&
sym.owner.owner == ArrayClass &&
@@ -267,7 +320,7 @@ trait Erasure {
// symbol here
tp
} else {
- erasure(sym, tp)
+ specialErasure(sym)(tp)
}
}
}
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index 4c49c0221f..89fd6bab64 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -186,7 +186,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
} finally {
parentsLevel -= 1
}
- clazz setInfo polyType(tparams, new ClassInfoType(parents, newScope, clazz))
+ clazz setInfo GenPolyType(tparams, new ClassInfoType(parents, newScope, clazz))
if (module != NoSymbol) {
module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass)
}
@@ -534,7 +534,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
}
private def setMethType(meth: Symbol, tparams: List[Symbol], paramtpes: List[Type], restpe: Type) = {
- meth setInfo polyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe))
+ meth setInfo GenPolyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe))
}
/**
@@ -572,7 +572,7 @@ trait JavaToScala extends ConversionUtil { self: SymbolTable =>
val tparams = jconstr.getTypeParameters.toList map createTypeParameter
val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala
setMethType(constr, tparams, paramtpes, clazz.tpe)
- constr setInfo polyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe))
+ constr setInfo GenPolyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe))
copyAnnotations(constr, jconstr)
constr
}
diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
index 405a00de8d..87cdd11652 100644
--- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala
+++ b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
@@ -28,7 +28,7 @@ trait ScalaToJava extends ConversionUtil { self: SymbolTable =>
def classToJava(clazz: Symbol): jClass[_] = classCache.toJava(clazz) {
def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found")
//println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug
- if (clazz.isValueClass)
+ if (clazz.isPrimitiveValueClass)
valueClassToJavaType(clazz)
else if (clazz == ArrayClass)
noClass
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index f52662ce6f..8cc4d5f788 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -59,7 +59,7 @@ trait ToolBoxes extends { self: Universe =>
def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = {
val obj = EmptyPackageClass.newModule(nextWrapperModuleName())
- val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), newScope, obj.moduleClass)
+ val minfo = ClassInfoType(List(ObjectClass.tpe), newScope, obj.moduleClass)
obj.moduleClass setInfo minfo
obj setInfo obj.moduleClass.tpe
val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala
index 700f819226..324fee87ab 100644
--- a/src/compiler/scala/reflect/runtime/Universe.scala
+++ b/src/compiler/scala/reflect/runtime/Universe.scala
@@ -37,6 +37,12 @@ class Universe extends SymbolTable {
type Position = String // source file?
val NoPosition = ""
+ definitions.AnyValClass // force it.
+
// establish root association to avoid cyclic dependency errors later
classToScala(classOf[java.lang.Object]).initialize
+
+// println("initializing definitions")
+ definitions.init()
+
}
diff --git a/src/compiler/scala/tools/cmd/gen/AnyVals.scala b/src/compiler/scala/tools/cmd/gen/AnyVals.scala
index 7c9599dc45..0869350dd3 100644
--- a/src/compiler/scala/tools/cmd/gen/AnyVals.scala
+++ b/src/compiler/scala/tools/cmd/gen/AnyVals.scala
@@ -182,7 +182,7 @@ trait AnyValReps {
def classLines: List[String]
def objectLines: List[String]
def commonClassLines = List(
- "def getClass(): Class[@name@]"
+ "override def getClass(): Class[@name@]"
)
def lcname = name.toLowerCase
@@ -429,7 +429,7 @@ def &(x: Boolean): Boolean = sys.error("stub")
*/
def ^(x: Boolean): Boolean = sys.error("stub")
-def getClass(): Class[Boolean] = sys.error("stub")
+override def getClass(): Class[Boolean] = sys.error("stub")
""".trim.lines.toList
def objectLines = interpolate(allCompanions).lines.toList
@@ -443,7 +443,7 @@ def getClass(): Class[Boolean] = sys.error("stub")
*/
"""
def classLines = List(
- """def getClass(): Class[Unit] = sys.error("stub")"""
+ """override def getClass(): Class[Unit] = sys.error("stub")"""
)
def objectLines = interpolate(allCompanions).lines.toList
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 552479bc0b..bc2cc8191c 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -456,141 +456,155 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
// phaseName = "superaccessors"
object superAccessors extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("typer")
+ val runsAfter = List("typer")
val runsRightAfter = None
} with SuperAccessors
+ // phaseName = "extmethods"
+ object extensionMethods extends {
+ val global: Global.this.type = Global.this
+ val runsAfter = List("superaccessors")
+ val runsRightAfter = None
+ } with ExtensionMethods
+
// phaseName = "pickler"
object pickler extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("superaccessors")
+ val runsAfter = List("extmethods")
val runsRightAfter = None
} with Pickler
// phaseName = "refchecks"
override object refChecks extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("pickler")
+ val runsAfter = List("pickler")
val runsRightAfter = None
} with RefChecks
// phaseName = "uncurry"
override object uncurry extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("refchecks")
+ val runsAfter = List("refchecks")
val runsRightAfter = None
} with UnCurry
// phaseName = "tailcalls"
object tailCalls extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("uncurry")
+ val runsAfter = List("uncurry")
val runsRightAfter = None
} with TailCalls
// phaseName = "explicitouter"
object explicitOuter extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("tailcalls")
+ val runsAfter = List("tailcalls")
val runsRightAfter = None
} with ExplicitOuter
// phaseName = "specialize"
object specializeTypes extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("")
+ val runsAfter = List("")
val runsRightAfter = Some("tailcalls")
} with SpecializeTypes
// phaseName = "erasure"
override object erasure extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("explicitouter")
+ val runsAfter = List("explicitouter")
val runsRightAfter = Some("explicitouter")
} with Erasure
+ // phaseName = "posterasure"
+ object postErasure extends {
+ val global: Global.this.type = Global.this
+ val runsAfter = List("erasure")
+ val runsRightAfter = Some("erasure")
+ } with PostErasure
+
// phaseName = "lazyvals"
object lazyVals extends {
final val FLAGS_PER_WORD = 32
val global: Global.this.type = Global.this
- val runsAfter = List[String]("erasure")
+ val runsAfter = List("erasure")
val runsRightAfter = None
} with LazyVals
// phaseName = "lambdalift"
object lambdaLift extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("lazyvals")
+ val runsAfter = List("lazyvals")
val runsRightAfter = None
} with LambdaLift
// phaseName = "constructors"
object constructors extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("lambdalift")
+ val runsAfter = List("lambdalift")
val runsRightAfter = None
} with Constructors
// phaseName = "flatten"
object flatten extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("constructors")
+ val runsAfter = List("constructors")
val runsRightAfter = None
} with Flatten
// phaseName = "mixin"
object mixer extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("flatten", "constructors")
+ val runsAfter = List("flatten", "constructors")
val runsRightAfter = None
} with Mixin
// phaseName = "cleanup"
object cleanup extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("mixin")
+ val runsAfter = List("mixin")
val runsRightAfter = None
} with CleanUp
// phaseName = "icode"
object genicode extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("cleanup")
+ val runsAfter = List("cleanup")
val runsRightAfter = None
} with GenICode
// phaseName = "inliner"
object inliner extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("icode")
+ val runsAfter = List("icode")
val runsRightAfter = None
} with Inliners
// phaseName = "inlineExceptionHandlers"
object inlineExceptionHandlers extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("inliner")
+ val runsAfter = List("inliner")
val runsRightAfter = None
} with InlineExceptionHandlers
// phaseName = "closelim"
object closureElimination extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("inlineExceptionHandlers")
+ val runsAfter = List("inlineExceptionHandlers")
val runsRightAfter = None
} with ClosureElimination
// phaseName = "dce"
object deadCode extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("closelim")
+ val runsAfter = List("closelim")
val runsRightAfter = None
} with DeadCodeElimination
// phaseName = "jvm"
object genJVM extends {
val global: Global.this.type = Global.this
- val runsAfter = List[String]("dce")
+ val runsAfter = List("dce")
val runsRightAfter = None
} with GenJVM
@@ -606,7 +620,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
object terminal extends {
val global: Global.this.type = Global.this
val phaseName = "terminal"
- val runsAfter = List[String]("jvm", "msil")
+ val runsAfter = List("jvm", "msil")
val runsRightAfter = None
} with SubComponent {
private var cache: Option[GlobalPhase] = None
@@ -660,6 +674,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
analyzer.packageObjects -> "load package objects",
analyzer.typerFactory -> "the meat and potatoes: type the trees",
superAccessors -> "add super accessors in traits and nested classes",
+ extensionMethods -> "add extension methods for inline classes",
pickler -> "serialize symbol tables",
refChecks -> "reference/override checking, translate nested objects",
uncurry -> "uncurry, translate function values to anonymous classes",
@@ -667,6 +682,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
specializeTypes -> "@specialized-driven class and method specialization",
explicitOuter -> "this refs to outer pointers, translate patterns",
erasure -> "erase types, add interfaces for traits",
+ postErasure -> "clean up erased inline classes",
lazyVals -> "allocate bitmaps, translate lazy vals into lazified defs",
lambdaLift -> "move nested functions to top level",
constructors -> "move field definitions into constructors",
@@ -1102,6 +1118,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
val namerPhase = phaseNamed("namer")
// val packageobjectsPhase = phaseNamed("packageobjects")
val typerPhase = phaseNamed("typer")
+ val inlineclassesPhase = phaseNamed("inlineclasses")
// val superaccessorsPhase = phaseNamed("superaccessors")
val picklerPhase = phaseNamed("pickler")
val refchecksPhase = phaseNamed("refchecks")
@@ -1433,7 +1450,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/**
* Re-orders the source files to
- * 1. ScalaObject
+ * 1. This Space Intentionally Left Blank
* 2. LowPriorityImplicits / EmbeddedControls (i.e. parents of Predef)
* 3. the rest
*
@@ -1461,7 +1478,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def rank(f: SourceFile) = {
if (f.file.container.name != "scala") goLast
else f.file.name match {
- case "ScalaObject.scala" => 1
case "LowPriorityImplicits.scala" => 2
case "StandardEmbeddings.scala" => 2
case "EmbeddedControls.scala" => 2
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index 6a6379cca2..678f7b3028 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -19,6 +19,8 @@ import scala.collection.mutable
*/
trait DocComments { self: Global =>
+ var cookedDocComments = Map[Symbol, String]()
+
def reporter: Reporter
/** The raw doc comment map */
@@ -50,21 +52,29 @@ trait DocComments { self: Global =>
else sym.owner.ancestors map (sym overriddenSymbol _) filter (_ != NoSymbol)
}
- /** The raw doc comment of symbol `sym`, minus @usecase and @define sections, augmented by
+ /** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by
* missing sections of an inherited doc comment.
* If a symbol does not have a doc comment but some overridden version of it does,
* the doc comment of the overridden version is copied instead.
*/
- def cookedDocComment(sym: Symbol, docStr: String = ""): String = {
- val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse ""
- else DocComment(docStr).template
- superComment(sym) match {
- case None =>
- ownComment
- case Some(sc) =>
- if (ownComment == "") sc
- else merge(sc, ownComment, sym)
- }
+ def cookedDocComment(sym: Symbol, docStr: String = ""): String = cookedDocComments.get(sym) match {
+ case Some(comment) =>
+ comment
+ case None =>
+ val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse ""
+ else DocComment(docStr).template
+ val comment = superComment(sym) match {
+ case None =>
+ if (ownComment.indexOf("@inheritdoc") != -1)
+ reporter.warning(sym.pos, "The comment for " + sym +
+ " contains @inheritdoc, but no parent comment is available to inherit from.")
+ ownComment.replaceAllLiterally("@inheritdoc", "<invalid inheritdoc annotation>")
+ case Some(sc) =>
+ if (ownComment == "") sc
+ else expandInheritdoc(sc, merge(sc, ownComment, sym), sym)
+ }
+ cookedDocComments += (sym -> comment)
+ comment
}
/** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing.
@@ -99,10 +109,18 @@ trait DocComments { self: Global =>
*/
def useCases(sym: Symbol, site: Symbol): List[(Symbol, String, Position)] = {
def getUseCases(dc: DocComment) = {
- for (uc <- dc.useCases; defn <- uc.expandedDefs(sym, site)) yield
- (defn,
- expandVariables(merge(cookedDocComment(sym), uc.comment.raw, defn), sym, site),
- uc.pos)
+ val fullSigComment = cookedDocComment(sym)
+ for (uc <- dc.useCases; defn <- uc.expandedDefs(sym, site)) yield {
+ // use cases comments go through a series of transformations:
+ // 1 - filling in missing sections from the full signature
+ // 2 - expanding explicit inheritance @inheritdoc tags
+ // 3 - expanding variables like $COLL
+ val useCaseCommentRaw = uc.comment.raw
+ val useCaseCommentMerged = merge(fullSigComment, useCaseCommentRaw, defn)
+ val useCaseCommentInheritdoc = expandInheritdoc(fullSigComment, useCaseCommentMerged, sym)
+ val useCaseCommentVariables = expandVariables(useCaseCommentInheritdoc, sym, site)
+ (defn, useCaseCommentVariables, uc.pos)
+ }
}
getDocComment(sym) map getUseCases getOrElse List()
}
@@ -201,6 +219,80 @@ trait DocComments { self: Global =>
}
}
+ /**
+ * Expand inheritdoc tags
+ * - for the main comment we transform the inheritdoc into the super variable,
+ * and the variable expansion can expand it further
+ * - for the param, tparam and throws sections we must replace comments on the spot
+ *
+ * This is done separately, for two reasons:
+ * 1. It takes longer to run compared to merge
+ * 2. The inheritdoc annotation should not be used very often, as building the comment from pieces severely
+ * impacts performance
+ */
+ def expandInheritdoc(src: String, dst: String, sym: Symbol): String =
+ if (dst.indexOf("@inheritdoc") == -1)
+ dst
+ else {
+ val srcSections = tagIndex(src)
+ val dstSections = tagIndex(dst)
+ val srcTagMap = sectionTagMap(src, srcSections)
+ val srcNamedParams = Map() +
+ ("@param" -> paramDocs(src, "@param", srcSections)) +
+ ("@tparam" -> paramDocs(src, "@tparam", srcSections)) +
+ ("@throws" -> paramDocs(src, "@throws", srcSections))
+
+ val out = new StringBuilder
+
+ def replaceInheritdoc(src: String, dst: String) =
+ if (dst.indexOf("@inheritdoc") == -1)
+ dst
+ else
+ dst.replaceAllLiterally("@inheritdoc", src)
+
+ def getSourceSection(section: (Int, Int)): String = {
+
+ def getSectionHeader = extractSectionTag(dst, section) match {
+ case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(dst, section)
+ case other => other
+ }
+
+ def sectionString(param: String, paramMap: Map[String, (Int, Int)]): String =
+ paramMap.get(param) match {
+ case Some(section) =>
+ // Cleanup the section tag and parameter
+ val sectionTextBounds = extractSectionText(src, section)
+ cleanupSectionText(src.substring(sectionTextBounds._1, sectionTextBounds._2))
+ case None =>
+ reporter.info(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym +
+ " comment contains @inheritdoc, but the corresponding section in the parent is not defined.", true)
+ "<invalid inheritdoc annotation>"
+ }
+
+ dst.substring(section._1, section._1 + 7) match {
+ case param@("@param "|"@tparam"|"@throws") => sectionString(extractSectionParam(dst, section), srcNamedParams(param.trim))
+ case _ => sectionString(extractSectionTag(dst, section), srcTagMap)
+ }
+ }
+
+ def mainComment(str: String, sections: List[(Int, Int)]): String =
+ if (str.trim.length > 3)
+ str.trim.substring(3, startTag(str, sections))
+ else
+ ""
+
+ // Append main comment
+ out.append("/**")
+ out.append(replaceInheritdoc(mainComment(src, srcSections), mainComment(dst, dstSections)))
+
+ // Append sections
+ for (section <- dstSections)
+ out.append(replaceInheritdoc(getSourceSection(section), dst.substring(section._1, section._2)))
+
+ out.append("*/")
+ out.toString
+ }
+
/** Maps symbols to the variable -> replacement maps that are defined
* in their doc comments
*/
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index d7159c5fa8..6d95b6ffdd 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -263,6 +263,22 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
)
}
+ /** Cast `tree` to type `pt` by creating
+ * one of the calls of the form
+ *
+ * x.asInstanceOf[`pt`] up to phase uncurry
+ * x.asInstanceOf[`pt`]() if after uncurry but before erasure
+ * x.$asInstanceOf[`pt`]() if at or after erasure
+ */
+ def mkCast(tree: Tree, pt: Type): Tree = {
+ debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase)
+ assert(!tree.tpe.isInstanceOf[MethodType], tree)
+ assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize))
+ atPos(tree.pos) {
+ mkAsInstanceOf(tree, pt, any = !phase.next.erasedTypes, wrapInApply = isAtPhaseAfter(currentRun.uncurryPhase))
+ }
+ }
+
/** Generate a cast for tree Tree representing Array with
* elem type elemtp to expected type pt.
*/
@@ -272,6 +288,25 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
else
mkCast(tree, pt)
+ def mkZeroContravariantAfterTyper(tp: Type): Tree = {
+ // contravariant -- for replacing an argument in a method call
+ // must use subtyping, as otherwise we miss types like `Any with Int`
+ val tree =
+ if (NullClass.tpe <:< tp) Literal(Constant(null))
+ else if (UnitClass.tpe <:< tp) Literal(Constant())
+ else if (BooleanClass.tpe <:< tp) Literal(Constant(false))
+ else if (FloatClass.tpe <:< tp) Literal(Constant(0.0f))
+ else if (DoubleClass.tpe <:< tp) Literal(Constant(0.0d))
+ else if (ByteClass.tpe <:< tp) Literal(Constant(0.toByte))
+ else if (ShortClass.tpe <:< tp) Literal(Constant(0.toShort))
+ else if (IntClass.tpe <:< tp) Literal(Constant(0))
+ else if (LongClass.tpe <:< tp) Literal(Constant(0L))
+ else if (CharClass.tpe <:< tp) Literal(Constant(0.toChar))
+ else mkCast(Literal(Constant(null)), tp)
+
+ tree
+ }
+
/** Translate names in Select/Ident nodes to type names.
*/
def convertToTypeName(tree: Tree): Option[RefTree] = tree match {
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index b16b3c89a0..9f361e5bcc 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -6,6 +6,7 @@
package scala.tools.nsc
package ast
+import reflect.internal.HasFlags
import reflect.internal.Flags._
import symtab._
@@ -41,4 +42,14 @@ abstract class TreeInfo extends reflect.internal.TreeInfo {
case ClassDef(_, `name`, _, _) :: Nil => true
case _ => super.firstDefinesClassOrObject(trees, name)
}
+
+ def isInterface(mods: HasFlags, body: List[Tree]) =
+ mods.hasTraitFlag && (body forall isInterfaceMember)
+
+ def isAllowedInUniversalTrait(stat: Tree): Boolean = stat match {
+ case _: ValDef => false
+ case Import(_, _) | EmptyTree => true
+ case _: DefTree => true
+ case _ => false
+ }
}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index ad87889145..43c231cf2d 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -16,6 +16,47 @@ import scala.reflect.internal.Flags.TRAIT
trait Trees extends reflect.internal.Trees { self: Global =>
+ def treeLine(t: Tree): String =
+ if (t.pos.isDefined && t.pos.isRange) t.pos.lineContent.drop(t.pos.column - 1).take(t.pos.end - t.pos.start + 1)
+ else t.summaryString
+
+ def treeStatus(t: Tree, enclosingTree: Tree = null) = {
+ val parent = if (enclosingTree eq null) " " else " P#%5s".format(enclosingTree.id)
+
+ "[L%4s%8s] #%-6s %-15s %-10s // %s".format(t.pos.safeLine, parent, t.id, t.pos.show, t.shortClass, treeLine(t))
+ }
+ def treeSymStatus(t: Tree) = {
+ val line = if (t.pos.isDefined) "line %-4s".format(t.pos.safeLine) else " "
+ "#%-5s %s %-10s // %s".format(t.id, line, t.shortClass,
+ if (t.symbol ne NoSymbol) "(" + t.symbol.fullLocationString + ")"
+ else treeLine(t)
+ )
+ }
+
+ class ValidatingPosAssigner extends PosAssigner {
+ var pos: Position = _
+ override def traverse(t: Tree) {
+ if (t eq EmptyTree) ()
+ else if (t.pos == NoPosition) super.traverse(t setPos pos)
+ else if (globalPhase.id <= currentRun.picklerPhase.id) {
+ // When we prune due to encountering a position, traverse the
+ // pruned children so we can warn about those lacking positions.
+ t.children foreach { c =>
+ if ((c eq EmptyTree) || (c eq emptyValDef)) ()
+ else if (c.pos == NoPosition) {
+ reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase)
+ inform("parent: " + treeSymStatus(t))
+ inform(" child: " + treeSymStatus(c) + "\n")
+ }
+ }
+ }
+ }
+ }
+
+ override protected[this] lazy val posAssigner: PosAssigner =
+ if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner
+ else new DefaultPosAssigner
+
// --- additional cases --------------------------------------------------------
/** Only used during parsing */
case class Parens(args: List[Tree]) extends Tree
@@ -34,6 +75,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type)
extends TermTree with RefTree
+ /** Derived value class injection (equivalent to: new C(arg) after easure); only used during erasure
+ * The class C is stored as the symbol of the tree node.
+ */
+ case class InjectDerivedValue(arg: Tree)
+ extends SymTree
+
/** emitted by typer, eliminated by refchecks */
case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree
@@ -149,6 +196,8 @@ trait Trees extends reflect.internal.Trees { self: Global =>
traverser.traverse(definition)
case SelectFromArray(qualifier, selector, erasure) =>
traverser.traverse(qualifier)
+ case InjectDerivedValue(arg) =>
+ traverser.traverse(arg)
case ReferenceToBoxed(idt) =>
traverser.traverse(idt)
case TypeTreeWithDeferredRefCheck() =>
@@ -159,6 +208,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
trait TreeCopier extends super.TreeCopierOps {
def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef
def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray
+ def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue
def ReferenceToBoxed(tree: Tree, idt: Ident): ReferenceToBoxed
def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck
}
@@ -171,6 +221,8 @@ trait Trees extends reflect.internal.Trees { self: Global =>
new DocDef(comment, definition).copyAttrs(tree)
def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) =
new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree)
+ def InjectDerivedValue(tree: Tree, arg: Tree) =
+ new InjectDerivedValue(arg)
def ReferenceToBoxed(tree: Tree, idt: Ident) =
new ReferenceToBoxed(idt).copyAttrs(tree)
def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
@@ -189,6 +241,11 @@ trait Trees extends reflect.internal.Trees { self: Global =>
if (qualifier0 == qualifier) && (selector0 == selector) => t
case _ => this.treeCopy.SelectFromArray(tree, qualifier, selector, erasure)
}
+ def InjectDerivedValue(tree: Tree, arg: Tree) = tree match {
+ case t @ InjectDerivedValue(arg0)
+ if (arg0 == arg) => t
+ case _ => this.treeCopy.InjectDerivedValue(tree, arg)
+ }
def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match {
case t @ ReferenceToBoxed(idt0)
if (idt0 == idt) => t
@@ -217,6 +274,9 @@ trait Trees extends reflect.internal.Trees { self: Global =>
case SelectFromArray(qualifier, selector, erasure) =>
transformer.treeCopy.SelectFromArray(
tree, transformer.transform(qualifier), selector, erasure)
+ case InjectDerivedValue(arg) =>
+ transformer.treeCopy.InjectDerivedValue(
+ tree, transformer.transform(arg))
case ReferenceToBoxed(idt) =>
transformer.treeCopy.ReferenceToBoxed(
tree, transformer.transform(idt) match { case idt1: Ident => idt1 })
@@ -333,6 +393,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
case DocDef(comment, defn) => (eliminated by typer)
case TypeTreeWithDeferredRefCheck() => (created and eliminated by typer)
case SelectFromArray(_, _, _) => (created and eliminated by erasure)
+ case InjectDerivedValue(_) => (created and eliminated by erasure)
*/
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
index 46ade7d889..93fa9a60f6 100644..100755
--- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
@@ -267,7 +267,7 @@ trait MarkupParsers {
val (qname, attrMap) = xTag(())
if (ch == '/') { // empty element
xToken("/>")
- handle.element(r2p(start, start, curOffset), qname, attrMap, new ListBuffer[Tree])
+ handle.element(r2p(start, start, curOffset), qname, attrMap, true, new ListBuffer[Tree])
}
else { // handle content
xToken('>')
@@ -281,7 +281,7 @@ trait MarkupParsers {
val pos = r2p(start, start, curOffset)
qname match {
case "xml:group" => handle.group(pos, ts)
- case _ => handle.element(pos, qname, attrMap, ts)
+ case _ => handle.element(pos, qname, attrMap, false, ts)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 077f0f9c0e..ccebcfa54d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -249,6 +249,8 @@ self =>
final val InBlock = 1
final val InTemplate = 2
+ lazy val ScalaValueClassNames: Set[Name] = definitions.scalaValueClassesSet map (_.name)
+
import nme.raw
abstract class Parser extends ParserCommon {
@@ -290,11 +292,11 @@ self =>
inScalaPackage = false
currentPackage = ""
}
- private lazy val anyValNames: Set[Name] = tpnme.ScalaValueNames.toSet + tpnme.AnyVal
+ private lazy val primitiveNames: Set[Name] = tpnme.ScalaValueNames.toSet
private def inScalaRootPackage = inScalaPackage && currentPackage == "scala"
private def isScalaArray(name: Name) = inScalaRootPackage && name == tpnme.Array
- private def isAnyValType(name: Name) = inScalaRootPackage && anyValNames(name)
+ private def isPrimitiveType(name: Name) = inScalaRootPackage && primitiveNames(name)
def parseStartRule: () => Tree
@@ -392,7 +394,7 @@ self =>
// object Main
def moduleName = newTermName(ScriptRunner scriptMain settings)
- def moduleBody = Template(List(scalaScalaObjectConstr), emptyValDef, List(emptyInit, mainDef))
+ def moduleBody = Template(List(atPos(o2p(in.offset))(scalaAnyRefConstr)), emptyValDef, List(emptyInit, mainDef))
def moduleDef = ModuleDef(NoMods, moduleName, moduleBody)
// package <empty> { ... }
@@ -2722,23 +2724,6 @@ self =>
* }}}
*/
def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = {
- /** Extra parents for case classes. */
- def caseParents() = (
- if (mods.isCase) {
- val arity = if (vparamss.isEmpty || vparamss.head.isEmpty) 0 else vparamss.head.size
- productConstr :: serializableConstr :: {
- Nil
- // if (arity == 0 || settings.YnoProductN.value) Nil
- // else List(
- // AppliedTypeTree(
- // productConstrN(arity),
- // vparamss.head map (vd => vd.tpt.duplicate setPos vd.tpt.pos.focus)
- // )
- // )
- }
- }
- else Nil
- )
val (parents0, argss, self, body) = (
if (in.token == EXTENDS || in.token == SUBTYPE && mods.hasTraitFlag) {
in.nextToken()
@@ -2750,21 +2735,27 @@ self =>
(List(), List(List()), self, body)
}
)
-
+ def anyrefParents() = {
+ val caseParents = if (mods.isCase) List(productConstr, serializableConstr) else Nil
+ parents0 ::: caseParents match {
+ case Nil => List(atPos(o2p(in.offset))(scalaAnyRefConstr))
+ case ps => ps
+ }
+ }
+ def anyvalConstructor() = (
+ // Not a well-formed constructor, has to be finished later - see note
+ // regarding AnyVal constructor in AddInterfaces.
+ DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(Nil), TypeTree(), Block(Nil, Literal(Constant())))
+ )
val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart
+
atPos(tstart0) {
- if (isAnyValType(name)) {
- val parent = if (name == tpnme.AnyVal) tpnme.Any else tpnme.AnyVal
- Template(List(scalaDot(parent)), self, body)
- }
- else {
- val parents = (
- if (!isInterface(mods, body) && !isScalaArray(name)) parents0 :+ scalaScalaObjectConstr
- else if (parents0.isEmpty) List(scalaAnyRefConstr)
- else parents0
- ) ++ caseParents()
- Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart))
- }
+ // [Martin to Paul: This needs to be refined. We should only include the 9 primitive classes,
+ // not any other value classes that happen to be defined in the Scala package.
+ if (inScalaRootPackage && (name == tpnme.AnyVal || (ScalaValueClassNames contains name)))
+ Template(parents0, self, anyvalConstructor :: body)
+ else
+ Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart))
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index ffe65aec63..849437e4ff 100644..100755
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -101,7 +101,8 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
pre: Tree,
label: Tree,
attrs: Tree,
- scope:Tree,
+ scope: Tree,
+ empty: Boolean,
children: Seq[Tree]): Tree =
{
def starArgs =
@@ -109,7 +110,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
else List(Typed(makeXMLseq(pos, children), wildStar))
def pat = Apply(_scala_xml__Elem, List(pre, label, wild, wild) ::: convertToTextPat(children))
- def nonpat = New(_scala_xml_Elem, List(List(pre, label, attrs, scope) ::: starArgs))
+ def nonpat = New(_scala_xml_Elem, List(List(pre, label, attrs, scope, if (empty) Literal(Constant(true)) else Literal(Constant(false))) ::: starArgs))
atPos(pos) { if (isPattern) pat else nonpat }
}
@@ -140,7 +141,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
case (Some(pre), rest) => (const(pre), const(rest))
case _ => (wild, const(n))
}
- mkXML(pos, true, prepat, labpat, null, null, args)
+ mkXML(pos, true, prepat, labpat, null, null, false, args)
}
protected def convertToTextPat(t: Tree): Tree = t match {
@@ -188,7 +189,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
def unparsed(pos: Position, str: String): Tree =
atPos(pos)( New(_scala_xml_Unparsed, LL(const(str))) )
- def element(pos: Position, qname: String, attrMap: mutable.Map[String, Tree], args: Seq[Tree]): Tree = {
+ def element(pos: Position, qname: String, attrMap: mutable.Map[String, Tree], empty: Boolean, args: Seq[Tree]): Tree = {
def handleNamespaceBinding(pre: String, z: String): Tree = {
def mkAssign(t: Tree): Tree = Assign(
Ident(_tmpscope),
@@ -259,6 +260,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
const(newlabel),
makeSymbolicAttrs,
Ident(_scope),
+ empty,
args
)
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index ad93b4753f..0d2fbc5372 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -29,12 +29,13 @@ abstract class TreeBuilder {
def rootId(name: Name) = gen.rootId(name)
def rootScalaDot(name: Name) = gen.rootScalaDot(name)
def scalaDot(name: Name) = gen.scalaDot(name)
- def scalaAnyRefConstr = gen.scalaAnyRefConstr
- def scalaUnitConstr = gen.scalaUnitConstr
- def scalaScalaObjectConstr = gen.scalaScalaObjectConstr
- def productConstr = gen.productConstr
+ def scalaAnyRefConstr = scalaDot(tpnme.AnyRef)
+ def scalaAnyValConstr = scalaDot(tpnme.AnyVal)
+ def scalaAnyConstr = scalaDot(tpnme.Any)
+ def scalaUnitConstr = scalaDot(tpnme.Unit)
+ def productConstr = scalaDot(tpnme.Product)
def productConstrN(n: Int) = scalaDot(newTypeName("Product" + n))
- def serializableConstr = gen.serializableConstr
+ def serializableConstr = scalaDot(tpnme.Serializable)
def convertToTypeName(t: Tree) = gen.convertToTypeName(t)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index c609f126d3..4c77cb7082 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -746,7 +746,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
if ((settings.check.value contains "genjvm")) {
val normalizedTpe = beforeErasure(erasure.prepareSigMap(memberTpe))
val bytecodeTpe = owner.thisType.memberInfo(sym)
- if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym, normalizedTpe) =:= bytecodeTpe)) {
+ if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym)(normalizedTpe) =:= bytecodeTpe)) {
clasz.cunit.warning(sym.pos,
"""|compiler bug: created generic signature for %s in %s that does not conform to its erasure
|signature: %s
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index 5e5320ca9a..e35286b281 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -438,7 +438,9 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
if(!comment.throws.isEmpty) {
<dt>Exceptions thrown</dt>
<dd>{
- val exceptionsXml: Iterable[scala.xml.NodeSeq] = (for(exception <- comment.throws ) yield <span class="cmt">{Text(exception._1) ++ bodyToHtml(exception._2)}</span> )
+ val exceptionsXml: Iterable[scala.xml.NodeSeq] =
+ for(exception <- comment.throws.toList.sortBy(_._1) ) yield
+ <span class="cmt">{Text(exception._1) ++ bodyToHtml(exception._2)}</span>
exceptionsXml.reduceLeft(_ ++ Text("") ++ _)
}</dd>
} else NodeSeq.Empty
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 127faf8ed9..496d004fd8 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -20,7 +20,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
thisFactory: ModelFactory with CommentFactory with TreeFactory =>
import global._
- import definitions.{ ObjectClass, ScalaObjectClass, RootPackage, EmptyPackage, NothingClass, AnyClass, AnyValClass, AnyRefClass }
+ import definitions.{ ObjectClass, RootPackage, EmptyPackage, NothingClass, AnyClass, AnyValClass, AnyRefClass }
private var droppedPackages = 0
def templatesCount = templatesCache.size - droppedPackages
@@ -42,7 +42,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
memberSym.isOmittablePrefix || (closestPackage(memberSym) == closestPackage(templateSym))
}
- private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass, ScalaObjectClass)
+ private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass)
/** */
def makeModel: Option[Universe] = {
@@ -217,13 +217,12 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
def parentType = {
if (sym.isPackage || sym == AnyClass) None else {
- val tps =
- (sym.tpe.parents filter (_ != ScalaObjectClass.tpe)) map { _.asSeenFrom(sym.thisType, sym) }
+ val tps = sym.tpe.parents map { _.asSeenFrom(sym.thisType, sym) }
Some(makeType(RefinedType(tps, EmptyScope), inTpl))
}
}
val linearization: List[(TemplateEntity, TypeEntity)] = {
- sym.ancestors filter (_ != ScalaObjectClass) map { ancestor =>
+ sym.ancestors map { ancestor =>
val typeEntity = makeType(sym.info.baseType(ancestor), this)
val tmplEntity = makeTemplate(ancestor) match {
case tmpl: DocTemplateImpl => tmpl registerSubClass this ; tmpl
@@ -316,7 +315,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def normalizeTemplate(aSym: Symbol): Symbol = aSym match {
case null | EmptyPackage | NoSymbol =>
normalizeTemplate(RootPackage)
- case ScalaObjectClass | ObjectClass =>
+ case ObjectClass =>
normalizeTemplate(AnyRefClass)
case _ if aSym.isPackageObject =>
aSym
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index efa524503c..b088c643cb 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -38,7 +38,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
val key = (sym, inTpl)
if (commentCache isDefinedAt key)
Some(commentCache(key))
- else { // not reached for use-case comments
+ else {
val c = defineComment(sym, inTpl)
if (c isDefined) commentCache += (sym, inTpl) -> c.get
c
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index d1f738a435..d08a363a9d 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -168,7 +168,7 @@ self: scala.tools.nsc.Global =>
/** Position a tree.
* This means: Set position of a node and position all its unpositioned children.
*/
- override def atPos[T <: Tree](pos: Position)(tree: T): T =
+ override def atPos[T <: Tree](pos: Position)(tree: T): T = {
if (pos.isOpaqueRange) {
if (!tree.isEmpty && tree.pos == NoPosition) {
tree.setPos(pos)
@@ -182,6 +182,7 @@ self: scala.tools.nsc.Global =>
} else {
super.atPos(pos)(tree)
}
+ }
// ---------------- Validating positions ----------------------------------
@@ -190,26 +191,33 @@ self: scala.tools.nsc.Global =>
val source = if (tree.pos.isDefined) tree.pos.source else ""
inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source)
inform("")
- inform(tree.toString)
+ inform(treeStatus(tree))
inform("")
}
def positionError(msg: String)(body : => Unit) {
- inform("======= Bad positions: "+msg)
- inform("")
+ inform("======= Position error\n" + msg)
body
- inform("=== While validating")
- inform("")
- inform(tree.toString)
- inform("")
+ inform("\nWhile validating #" + tree.id)
+ inform(treeStatus(tree))
+ inform("\nChildren:")
+ tree.children map (t => " " + treeStatus(t, tree)) foreach inform
inform("=======")
throw new ValidateException(msg)
}
def validate(tree: Tree, encltree: Tree): Unit = {
+
if (!tree.isEmpty) {
+ if (settings.Yposdebug.value && (settings.verbose.value || settings.Yrangepos.value))
+ println("[%10s] %s".format("validate", treeStatus(tree, encltree)))
+
if (!tree.pos.isDefined)
- positionError("Unpositioned tree ["+tree.id+"]") { reportTree("Unpositioned", tree) }
+ positionError("Unpositioned tree #"+tree.id) {
+ inform("%15s %s".format("unpositioned", treeStatus(tree, encltree)))
+ inform("%15s %s".format("enclosing", treeStatus(encltree)))
+ encltree.children foreach (t => inform("%15s %s".format("sibling", treeStatus(t, encltree))))
+ }
if (tree.pos.isRange) {
if (!encltree.pos.isRange)
positionError("Synthetic tree ["+encltree.id+"] contains nonsynthetic tree ["+tree.id+"]") {
diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
index 7e032753f2..68bfeafbc6 100644
--- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -183,7 +183,7 @@ trait MemberHandlers {
// TODO: Need to track these specially to honor Predef masking attempts,
// because they must be the leading imports in the code generated for each
// line. We can use the same machinery as Contexts now, anyway.
- def isPredefImport = treeInfo.isPredefExpr(expr)
+ def isPredefImport = isReferenceToPredef(expr)
// wildcard imports, e.g. import foo._
private def selectorWild = selectors filter (_.name == nme.USCOREkw)
diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
index e72a0007a0..ef17367ce0 100644
--- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
@@ -20,7 +20,7 @@ trait MatrixAdditions extends ast.TreeDSL {
import CODE._
import Debug._
import treeInfo._
- import definitions.{ isValueClass }
+ import definitions.{ isPrimitiveValueClass }
/** The Squeezer, responsible for all the squeezing.
*/
@@ -141,7 +141,7 @@ trait MatrixAdditions extends ast.TreeDSL {
(sym.isMutable) && // indicates that have not yet checked exhaustivity
!(sym hasFlag NO_EXHAUSTIVE) && // indicates @unchecked
(sym.tpe.typeSymbol.isSealed) &&
- !isValueClass(sym.tpe.typeSymbol) // make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte
+ !isPrimitiveValueClass(sym.tpe.typeSymbol) // make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte
}
private lazy val inexhaustives: List[List[Combo]] = {
@@ -155,7 +155,7 @@ trait MatrixAdditions extends ast.TreeDSL {
pv.tpe.typeSymbol.sealedDescendants.toList sortBy (_.sealedSortName)
// symbols which are both sealed and abstract need not be covered themselves, because
// all of their children must be and they cannot otherwise be created.
- filterNot (x => x.isSealed && x.isAbstractClass && !isValueClass(x))
+ filterNot (x => x.isSealed && x.isAbstractClass && !isPrimitiveValueClass(x))
// have to filter out children which cannot match: see ticket #3683 for an example
filter (_.tpe matchesPattern pv.tpe)
)
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index e949cb3eb2..5f3c7ec32c 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -162,6 +162,7 @@ trait ScalaSettings extends AbsScalaSettings
val Ybuildmanagerdebug =
BooleanSetting ("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.")
val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignments.")
+ val Yposdebug = BooleanSetting ("-Ypos-debug", "Trace position validation.")
val Yinferdebug = BooleanSetting ("-Yinfer-debug", "Trace type inference and implicit search.")
val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.")
val Yreifycopypaste =
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 07d132f7dd..1cd4ab21ea 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -843,7 +843,7 @@ abstract class ClassfileParser {
}
ClassInfoType(parents.toList, instanceDefs, sym)
}
- polyType(ownTypeParams, tpe)
+ GenPolyType(ownTypeParams, tpe)
} // sigToType
class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType {
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 1abaf1c1d6..39e2cbe694 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -11,7 +11,7 @@ import Flags._
import scala.collection.{ mutable, immutable }
import collection.mutable.ListBuffer
-abstract class AddInterfaces extends InfoTransform {
+abstract class AddInterfaces extends InfoTransform { self: Erasure =>
import global._ // the global environment
import definitions._ // standard classes and methods
@@ -21,14 +21,6 @@ abstract class AddInterfaces extends InfoTransform {
*/
override def phaseNewFlags: Long = lateDEFERRED | lateINTERFACE
- /** Type reference after erasure; defined in Erasure.
- */
- def erasedTypeRef(sym: Symbol): Type
-
- /** Erasure calculation; defined in Erasure.
- */
- def erasure(sym: Symbol, tpe: Type): Type
-
/** A lazily constructed map that associates every non-interface trait with
* its implementation class.
*/
@@ -176,14 +168,14 @@ abstract class AddInterfaces extends InfoTransform {
/** If `tp` refers to a non-interface trait, return a
* reference to its implementation class. Otherwise return `tp`.
*/
- def mixinToImplClass(tp: Type): Type = erasure(sym,
+ def mixinToImplClass(tp: Type): Type = erasure(sym) {
tp match { //@MATN: no normalize needed (comes after erasure)
case TypeRef(pre, sym, _) if sym.needsImplClass =>
typeRef(pre, implClass(sym), Nil)
case _ =>
tp
}
- )
+ }
def implType(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, _) =>
assert(phase == implClassPhase, tp)
@@ -272,11 +264,10 @@ abstract class AddInterfaces extends InfoTransform {
else DefDef(clazz.primaryConstructor, Block(List(), Literal(Constant()))) :: stats
private def implTemplate(clazz: Symbol, templ: Template): Template = atPos(templ.pos) {
- val templ1 = atPos(templ.pos) {
- Template(templ.parents, emptyValDef,
- addMixinConstructorDef(clazz, templ.body map implMemberDef))
- .setSymbol(clazz.newLocalDummy(templ.pos))
- }
+ val templ1 = (
+ Template(templ.parents, emptyValDef, addMixinConstructorDef(clazz, templ.body map implMemberDef))
+ setSymbol clazz.newLocalDummy(templ.pos)
+ )
templ1.changeOwner(templ.symbol.owner -> clazz, templ.symbol -> templ1.symbol)
templ1
}
@@ -299,14 +290,22 @@ abstract class AddInterfaces extends InfoTransform {
}
val mixinConstructorCalls: List[Tree] = {
for (mc <- clazz.mixinClasses.reverse
- if mc.hasFlag(lateINTERFACE) && mc != ScalaObjectClass)
+ if mc.hasFlag(lateINTERFACE))
yield mixinConstructorCall(implClass(mc))
}
- (tree: @unchecked) match {
+ tree match {
+ case Block(Nil, expr) =>
+ // AnyVal constructor - have to provide a real body so the
+ // jvm doesn't throw a VerifyError. But we can't add the
+ // body until now, because the typer knows that Any has no
+ // constructor and won't accept a call to super.init.
+ assert((clazz isSubClass AnyValClass) || clazz.info.parents.isEmpty, clazz)
+ val superCall = Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil)
+ Block(List(superCall), expr)
+
case Block(stats, expr) =>
// needs `hasSymbol` check because `supercall` could be a block (named / default args)
val (presuper, supercall :: rest) = stats span (t => t.hasSymbolWhich(_ hasFlag PRESUPER))
- // assert(supercall.symbol.isClassConstructor, supercall)
treeCopy.Block(tree, presuper ::: (supercall :: mixinConstructorCalls ::: rest), expr)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index d04c6115ca..8ed44b5a31 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -94,7 +94,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
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
+ * not part of it, as opposed to isPrimitiveValueClass in definitions. scala.Int is
* a value class, java.lang.Integer is not. */
def isJavaValueClass(sym: Symbol) = boxedClass contains sym
def isJavaValueType(tp: Type) = isJavaValueClass(tp.typeSymbol)
@@ -551,7 +551,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
case Literal(c) if (c.tag == ClassTag) && !forMSIL=>
val tpe = c.typeValue
typedWithPos(tree.pos) {
- if (isValueClass(tpe.typeSymbol)) {
+ if (isPrimitiveValueClass(tpe.typeSymbol)) {
if (tpe.typeSymbol == UnitClass)
REF(BoxedUnit_TYPE)
else
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index d8f19f85c0..4f833c82d3 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -44,11 +44,14 @@ abstract class Constructors extends Transform with ast.TreeDSL {
)
// decompose primary constructor into the three entities above.
val constrInfo: ConstrInfo = {
- val primary = stats find (_.symbol.isPrimaryConstructor)
- assert(primary.isDefined, "no constructor in template: impl = " + impl)
-
- val ddef @ DefDef(_, _, _, List(vparams), _, rhs @ Block(_, _)) = primary.get
+ stats find (_.symbol.isPrimaryConstructor) match {
+ case Some(ddef @ DefDef(_, _, _, List(vparams), _, rhs @ Block(_, _))) =>
ConstrInfo(ddef, vparams map (_.symbol), rhs)
+ case x =>
+ // AnyVal constructor is OK
+ assert(clazz eq AnyValClass, "no constructor in template: impl = " + impl)
+ return impl
+ }
}
import constrInfo._
@@ -443,7 +446,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
localTyper.typed {
atPos(impl.pos) {
val closureClass = clazz.newClass(nme.delayedInitArg.toTypeName, impl.pos, SYNTHETIC | FINAL)
- val closureParents = List(AbstractFunctionClass(0).tpe, ScalaObjectClass.tpe)
+ val closureParents = List(AbstractFunctionClass(0).tpe)
closureClass setInfoAndEnter new ClassInfoType(closureParents, newScope, closureClass)
@@ -565,7 +568,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
override def transform(tree: Tree): Tree =
tree match {
- case ClassDef(_,_,_,_) if !tree.symbol.isInterface && !isValueClass(tree.symbol) =>
+ case ClassDef(_,_,_,_) if !tree.symbol.isInterface && !isPrimitiveValueClass(tree.symbol) =>
deriveClassDef(tree)(transformClassTemplate)
case _ =>
super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index d54ce78e18..a98cd5c6b1 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -31,33 +31,6 @@ abstract class Erasure extends AddInterfaces
// -------- erasure on types --------------------------------------------------------
- // A type function from T => Class[U], used to determine the return
- // type of getClass calls. The returned type is:
- //
- // 1. If T is a value type, Class[T].
- // 2. If T is a phantom type (Any or AnyVal), Class[_].
- // 3. If T is a local class, Class[_ <: |T|].
- // 4. Otherwise, Class[_ <: T].
- //
- // Note: AnyVal cannot be Class[_ <: AnyVal] because if the static type of the
- // receiver is AnyVal, it implies the receiver is boxed, so the correct
- // class object is that of java.lang.Integer, not Int.
- //
- // TODO: If T is final, return type could be Class[T]. Should it?
- def getClassReturnType(tpe: Type): Type = {
- if (phase.erasedTypes) ClassClass.tpe else {
- val tp = tpe.widen.normalize
- val sym = tp.typeSymbol
-
- if (isValueClass(sym)) ClassType(tp)
- else boundedClassType(
- if (isPhantomClass(sym)) ObjectClass.tpe
- else if (sym.isLocalClass) intersectionDominator(tp.parents)
- else tp
- )
- }
- }
-
// convert a numeric with a toXXX method
def numericConversion(tree: Tree, numericSym: Symbol): Tree = {
val mname = newTermName("to" + numericSym.name)
@@ -257,7 +230,7 @@ abstract class Erasure extends AddInterfaces
// Anything which could conceivably be a module (i.e. isn't known to be
// a type parameter or similar) must go through here or the signature is
// likely to end up with Foo<T>.Empty where it needs Foo<T>.Empty$.
- def fullNameInSig(sym: Symbol) = "L" + beforeIcode(sym.javaBinaryName.toString)
+ def fullNameInSig(sym: Symbol) = "L" + beforeIcode(sym.javaBinaryName)
def jsig(tp0: Type, existentiallyBound: List[Symbol] = Nil, toplevel: Boolean = false, primitiveOK: Boolean = true): String = {
val tp = tp0.dealias
@@ -294,7 +267,7 @@ abstract class Erasure extends AddInterfaces
jsig(RuntimeNothingClass.tpe)
else if (sym == NullClass)
jsig(RuntimeNullClass.tpe)
- else if (isValueClass(sym)) {
+ else if (isPrimitiveValueClass(sym)) {
if (!primitiveOK) jsig(ObjectClass.tpe)
else if (sym == UnitClass) jsig(BoxedUnitClass.tpe)
else abbrvTag(sym).toString
@@ -317,7 +290,7 @@ abstract class Erasure extends AddInterfaces
)
)
}
- else jsig(erasure(sym0, tp), existentiallyBound, toplevel, primitiveOK)
+ else jsig(erasure(sym0)(tp), existentiallyBound, toplevel, primitiveOK)
case PolyType(tparams, restpe) =>
assert(tparams.nonEmpty)
val poly = if (toplevel) polyParamSig(tparams) else ""
@@ -337,7 +310,7 @@ abstract class Erasure extends AddInterfaces
println("something's wrong: "+sym0+":"+sym0.tpe+" has a bounded wildcard type")
jsig(bounds.hi, existentiallyBound, toplevel, primitiveOK)
case _ =>
- val etp = erasure(sym0, tp)
+ val etp = erasure(sym0)(tp)
if (etp eq tp) throw new UnknownSig
else jsig(etp)
}
@@ -396,36 +369,79 @@ abstract class Erasure extends AddInterfaces
override def newTyper(context: Context) = new Eraser(context)
- /** An extractor object for boxed expressions
+ private def safeToRemoveUnbox(cls: Symbol): Boolean =
+ (cls == definitions.NullClass) || isBoxedValueClass(cls)
+
+ /** An extractor object for unboxed expressions (maybe subsumed by posterasure?) */
+ object Unboxed {
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case Apply(fn, List(arg)) if isUnbox(fn.symbol) && safeToRemoveUnbox(arg.tpe.typeSymbol) =>
+ Some(arg)
+ case Apply(
+ TypeApply(
+ cast @ Select(
+ Apply(
+ sel @ Select(arg, acc),
+ List()),
+ asinstanceof),
+ List(tpt)),
+ List())
+ if cast.symbol == Object_asInstanceOf &&
+ tpt.tpe.typeSymbol.isDerivedValueClass &&
+ sel.symbol == tpt.tpe.typeSymbol.firstParamAccessor =>
+ Some(arg)
+ case _ =>
+ None
+ }
+ }
+
+ /** An extractor object for boxed expressions (maybe subsumed by posterasure?) */
object Boxed {
def unapply(tree: Tree): Option[Tree] = tree match {
+ case Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)) if (tpt.tpe.typeSymbol.isDerivedValueClass) =>
+ Some(arg)
case LabelDef(name, params, Boxed(rhs)) =>
Some(treeCopy.LabelDef(tree, name, params, rhs) setType rhs.tpe)
- case Select(_, _) if tree.symbol == BoxedUnit_UNIT =>
- Some(Literal(Constant()) setPos tree.pos setType UnitClass.tpe)
- case Block(List(unboxed), ret @ Select(_, _)) if ret.symbol == BoxedUnit_UNIT =>
- Some(if (unboxed.tpe.typeSymbol == UnitClass) tree
- else Block(List(unboxed), Literal(Constant()) setPos tree.pos setType UnitClass.tpe))
- case Apply(fn, List(unboxed)) if isBox(fn.symbol) =>
- Some(unboxed)
case _ =>
None
}
}
- */
/** The modifier typer which retypes with erased types. */
class Eraser(_context: Context) extends Typer(_context) {
- private def safeToRemoveUnbox(cls: Symbol): Boolean =
- (cls == definitions.NullClass) || isBoxedValueClass(cls)
+
+ private def isPrimitiveValueType(tpe: Type) = isPrimitiveValueClass(tpe.typeSymbol)
+
+ private def isErasedValueType(tpe: Type) = tpe.isInstanceOf[ErasedValueType]
+
+ private def isDifferentErasedValueType(tpe: Type, other: Type) =
+ isErasedValueType(tpe) && (tpe ne other)
+
+ private def isPrimitiveValueMember(sym: Symbol) =
+ sym != NoSymbol && isPrimitiveValueClass(sym.owner)
+
+ private def box(tree: Tree, target: => String): Tree = {
+ val result = box1(tree)
+ log("boxing "+tree+":"+tree.tpe+" to "+target+" = "+result+":"+result.tpe)
+ result
+ }
/** Box `tree` of unboxed type */
- private def box(tree: Tree): Tree = tree match {
+ private def box1(tree: Tree): Tree = tree match {
case LabelDef(_, _, _) =>
- val ldef = deriveLabelDef(tree)(box)
+ val ldef = deriveLabelDef(tree)(box1)
ldef setType ldef.rhs.tpe
case _ =>
- typedPos(tree.pos)(tree.tpe.typeSymbol match {
+ val tree1 = tree.tpe match {
+ case ErasedValueType(clazz) =>
+ tree match {
+ case Unboxed(arg) if arg.tpe.typeSymbol == clazz =>
+ log("shortcircuiting unbox -> box "+arg); arg
+ case _ =>
+ New(clazz, cast(tree, underlyingOfValueClass(clazz)))
+ }
+ case _ =>
+ tree.tpe.typeSymbol match {
case UnitClass =>
if (treeInfo isExprSafeToInline tree) REF(BoxedUnit_UNIT)
else BLOCK(tree, REF(BoxedUnit_UNIT))
@@ -445,7 +461,15 @@ abstract class Erasure extends AddInterfaces
case _ =>
(REF(boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectClass.tpe
}
- })
+ }
+ }
+ typedPos(tree.pos)(tree1)
+ }
+
+ private def unbox(tree: Tree, pt: Type): Tree = {
+ val result = unbox1(tree, pt)
+ log("unboxing "+tree+":"+tree.tpe+" to "+pt+" = "+result+":"+result.tpe)
+ result
}
/** Unbox `tree` of boxed type to expected type `pt`.
@@ -454,7 +478,7 @@ abstract class Erasure extends AddInterfaces
* @param pt the expected type.
* @return the unboxed tree
*/
- private def unbox(tree: Tree, pt: Type): Tree = tree match {
+ private def unbox1(tree: Tree, pt: Type): Tree = tree match {
/*
case Boxed(unboxed) =>
println("unbox shorten: "+tree) // this never seems to kick in during build and test; therefore disabled.
@@ -464,7 +488,19 @@ abstract class Erasure extends AddInterfaces
val ldef = deriveLabelDef(tree)(unbox(_, pt))
ldef setType ldef.rhs.tpe
case _ =>
- typedPos(tree.pos)(pt.typeSymbol match {
+ val tree1 = pt match {
+ case ErasedValueType(clazz) =>
+ tree match {
+ case Boxed(arg) if arg.tpe.isInstanceOf[ErasedValueType] =>
+ log("shortcircuiting box -> unbox "+arg)
+ arg
+ case _ =>
+ log("not boxed: "+tree)
+ val tree0 = adaptToType(tree, clazz.tpe)
+ cast(Apply(Select(tree0, clazz.firstParamAccessor), List()), pt)
+ }
+ case _ =>
+ pt.typeSymbol match {
case UnitClass =>
if (treeInfo isExprSafeToInline tree) UNIT
else BLOCK(tree, UNIT)
@@ -472,7 +508,9 @@ abstract class Erasure extends AddInterfaces
assert(x != ArrayClass)
// don't `setType pt` the Apply tree, as the Apply's fun won't be typechecked if the Apply tree already has a type
Apply(unboxMethod(pt.typeSymbol), tree)
- })
+ }
+ }
+ typedPos(tree.pos)(tree1)
}
/** Generate a synthetic cast operation from tree.tpe to pt.
@@ -487,9 +525,6 @@ abstract class Erasure extends AddInterfaces
else gen.mkAttributedCast(tree, pt)
}
- private def isUnboxedValueMember(sym: Symbol) =
- sym != NoSymbol && isValueClass(sym.owner)
-
/** Adapt `tree` to expected type `pt`.
*
* @param tree the given tree
@@ -501,29 +536,30 @@ abstract class Erasure extends AddInterfaces
log("adapting " + tree + ":" + tree.tpe + " : " + tree.tpe.parents + " to " + pt)//debug
if (tree.tpe <:< pt)
tree
- else if (isValueClass(tree.tpe.typeSymbol) && !isValueClass(pt.typeSymbol))
- adaptToType(box(tree), pt)
- else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.params.isEmpty) {
+ else if (isDifferentErasedValueType(tree.tpe, pt))
+ adaptToType(box(tree, pt.toString), pt)
+ else if (isDifferentErasedValueType(pt, tree.tpe))
+ adaptToType(unbox(tree, pt), pt)
+ else if (isPrimitiveValueType(tree.tpe) && !isPrimitiveValueType(pt)) {
+ adaptToType(box(tree, pt.toString), pt)
+ } else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.params.isEmpty) {
assert(tree.symbol.isStable, "adapt "+tree+":"+tree.tpe+" to "+pt)
adaptToType(Apply(tree, List()) setPos tree.pos setType tree.tpe.resultType, pt)
- } else if (pt <:< tree.tpe)
- cast(tree, pt)
- else if (isValueClass(pt.typeSymbol) && !isValueClass(tree.tpe.typeSymbol))
+// } else if (pt <:< tree.tpe)
+// cast(tree, pt)
+ } else if (isPrimitiveValueType(pt) && !isPrimitiveValueType(tree.tpe))
adaptToType(unbox(tree, pt), pt)
else
cast(tree, pt)
}
- // @PP 1/25/2011: This is less inaccurate than it was (I removed
- // BoxedAnyArray, asInstanceOf$erased, and other long ago eliminated symbols)
- // but I do not think it yet describes the code beneath it.
-
/** Replace member references as follows:
*
* - `x == y` for == in class Any becomes `x equals y` with equals in class Object.
* - `x != y` for != in class Any becomes `!(x equals y)` with equals in class Object.
* - x.asInstanceOf[T] becomes x.$asInstanceOf[T]
* - x.isInstanceOf[T] becomes x.$isInstanceOf[T]
+ * - x.isInstanceOf[ErasedValueType(clazz)] becomes x.isInstanceOf[clazz.tpe]
* - x.m where m is some other member of Any becomes x.m where m is a member of class Object.
* - x.m where x has unboxed value type T and m is not a directly translated member of T becomes T.box(x).m
* - x.m where x is a reference type and m is a directly translated member of value type T becomes x.TValue().m
@@ -533,22 +569,34 @@ abstract class Erasure extends AddInterfaces
private def adaptMember(tree: Tree): Tree = {
//Console.println("adaptMember: " + tree);
tree match {
- case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List()) if tree.symbol == Any_asInstanceOf =>
+ case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List())
+ if tree.symbol == Any_asInstanceOf =>
val qual1 = typedQualifier(qual, NOmode, ObjectClass.tpe) // need to have an expected type, see #3037
val qualClass = qual1.tpe.typeSymbol
- val targClass = targ.tpe.typeSymbol
/*
+ val targClass = targ.tpe.typeSymbol
+
if (isNumericValueClass(qualClass) && isNumericValueClass(targClass))
// convert numeric type casts
atPos(tree.pos)(Apply(Select(qual1, "to" + targClass.name), List()))
else
*/
- if (isValueClass(targClass)) unbox(qual1, targ.tpe)
+ if (isPrimitiveValueType(targ.tpe) || isErasedValueType(targ.tpe)) unbox(qual1, targ.tpe)
else tree
- case Select(qual, name) if (name != nme.CONSTRUCTOR) =>
- if (tree.symbol == NoSymbol)
+ case Apply(TypeApply(sel @ Select(qual, name), List(targ)), List())
+ if tree.symbol == Any_isInstanceOf =>
+ targ.tpe match {
+ case ErasedValueType(clazz) => targ.setType(clazz.tpe)
+ case _ =>
+ }
tree
- else if (tree.symbol == Any_asInstanceOf)
+ case Select(qual, name) =>
+ if (tree.symbol == NoSymbol) {
+ tree
+ } else if (name == nme.CONSTRUCTOR) {
+ if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.primaryConstructor
+ tree
+ } else if (tree.symbol == Any_asInstanceOf)
adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf)))
else if (tree.symbol == Any_isInstanceOf)
adaptMember(atPos(tree.pos)(Select(qual, Object_isInstanceOf)))
@@ -556,12 +604,13 @@ abstract class Erasure extends AddInterfaces
adaptMember(atPos(tree.pos)(Select(qual, getMember(ObjectClass, name))))
else {
var qual1 = typedQualifier(qual)
- if ((isValueClass(qual1.tpe.typeSymbol) && !isUnboxedValueMember(tree.symbol)))
- qual1 = box(qual1)
- else if (!isValueClass(qual1.tpe.typeSymbol) && isUnboxedValueMember(tree.symbol))
+ if ((isPrimitiveValueType(qual1.tpe) && !isPrimitiveValueMember(tree.symbol)) ||
+ isErasedValueType(qual1.tpe))
+ qual1 = box(qual1, "owner "+tree.symbol.owner)
+ else if (!isPrimitiveValueType(qual1.tpe) && isPrimitiveValueMember(tree.symbol))
qual1 = unbox(qual1, tree.symbol.owner.tpe)
- if (isValueClass(tree.symbol.owner) && !isValueClass(qual1.tpe.typeSymbol))
+ if (isPrimitiveValueMember(tree.symbol) && !isPrimitiveValueType(qual1.tpe))
tree.symbol = NoSymbol
else if (qual1.tpe.isInstanceOf[MethodType] && qual1.tpe.params.isEmpty) {
assert(qual1.symbol.isStable, qual1.symbol);
@@ -590,13 +639,22 @@ abstract class Erasure extends AddInterfaces
*/
override protected def typed1(tree: Tree, mode: Int, pt: Type): Tree = {
val tree1 = try {
+ tree match {
+ case InjectDerivedValue(arg) =>
+ val clazz = tree.symbol
+ val result = typed1(arg, mode, underlyingOfValueClass(clazz)) setType ErasedValueType(clazz)
+ log("transforming inject "+arg+":"+underlyingOfValueClass(clazz)+"/"+ErasedValueType(clazz)+" = "+result)
+ return result
+
+ case _ =>
super.typed1(adaptMember(tree), mode, pt)
+ }
} catch {
case er: TypeError =>
Console.println("exception when typing " + tree)
Console.println(er.msg + " in file " + context.owner.sourceFile)
er.printStackTrace
- abort()
+ abort("unrecoverable error")
case ex: Exception =>
//if (settings.debug.value)
try Console.println("exception when typing " + tree)
@@ -646,6 +704,7 @@ abstract class Erasure extends AddInterfaces
* but their erased types are the same.
*/
private def checkNoDoubleDefs(root: Symbol) {
+ def afterErasure[T](op: => T): T = atPhase(phase.next.next)(op)
def doubleDefError(sym1: Symbol, sym2: Symbol) {
// the .toString must also be computed at the earlier phase
val tpe1 = afterRefchecks(root.thisType.memberType(sym1))
@@ -740,7 +799,7 @@ abstract class Erasure extends AddInterfaces
var bridges: List[Tree] = List()
val opc = beforeExplicitOuter {
new overridingPairs.Cursor(owner) {
- override def parents: List[Type] = List(owner.info.parents.head)
+ override def parents: List[Type] = List(owner.info.firstParent)
override def exclude(sym: Symbol): Boolean =
!sym.isMethod || sym.isPrivate || super.exclude(sym)
}
@@ -750,7 +809,7 @@ abstract class Erasure extends AddInterfaces
val other = opc.overridden
//println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString)//DEBUG
if (beforeExplicitOuter(!member.isDeferred)) {
- val otpe = erasure(owner, other.tpe)
+ val otpe = erasure(owner)(other.tpe)
val bridgeNeeded = afterErasure (
!(other.tpe =:= member.tpe) &&
!(deconstMap(other.tpe) =:= deconstMap(member.tpe)) &&
@@ -795,7 +854,7 @@ abstract class Erasure extends AddInterfaces
IF (typeTest) THEN bridgingCall ELSE REF(NoneModule)
} else bridgingCall
});
- debuglog("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(owner, member.tpe) + member.locationString + " =\n " + bridgeDef);
+ debuglog("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(owner)(member.tpe) + member.locationString + " =\n " + bridgeDef);
bridgeDef
}
} :: bridges
@@ -841,6 +900,7 @@ abstract class Erasure extends AddInterfaces
* - Given a selection q.s, where the owner of `s` is not accessible but the
* type symbol of q's type qT is accessible, insert a cast (q.asInstanceOf[qT]).s
* This prevents illegal access errors (see #4283).
+ * - Remove all instance creations new C(arg) where C is an inlined class.
* - Reset all other type attributes to null, thus enforcing a retyping.
*/
private val preTransformer = new TypingTransformer(unit) {
@@ -866,7 +926,7 @@ abstract class Erasure extends AddInterfaces
gen.mkMethodCall(
qual1(),
fun.symbol,
- List(erasure(fun.symbol, arg.tpe)),
+ List(specialErasure(fun.symbol)(arg.tpe)),
Nil
),
isArrayTest(qual1())
@@ -899,7 +959,7 @@ abstract class Erasure extends AddInterfaces
// need to do the cast in adaptMember
treeCopy.Apply(
tree,
- SelectFromArray(qual, name, erasure(tree.symbol, qual.tpe)).copyAttrs(fn),
+ SelectFromArray(qual, name, erasure(tree.symbol)(qual.tpe)).copyAttrs(fn),
args)
}
case Apply(fn @ Select(qual, _), Nil) if interceptedMethods(fn.symbol) =>
@@ -918,12 +978,18 @@ abstract class Erasure extends AddInterfaces
}
}
// Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
- else if (isValueClass(qual.tpe.typeSymbol))
+ else if (isPrimitiveValueClass(qual.tpe.typeSymbol))
global.typer.typed(gen.mkRuntimeCall(nme.anyValClass, List(qual)))
else
tree
+ case Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)) if (tpt.tpe.typeSymbol.isDerivedValueClass) =>
+ InjectDerivedValue(arg) setSymbol tpt.tpe.typeSymbol
case Apply(fn, args) =>
+ def qualifier = fn match {
+ case Select(qual, _) => qual
+ case TypeApply(Select(qual, _), _) => qual
+ }
if (fn.symbol == Any_asInstanceOf)
(fn: @unchecked) match {
case TypeApply(Select(qual, _), List(targ)) =>
@@ -938,7 +1004,7 @@ abstract class Erasure extends AddInterfaces
else if (fn.symbol == Any_isInstanceOf) {
fn match {
case TypeApply(sel @ Select(qual, name), List(targ)) =>
- if (qual.tpe != null && isValueClass(qual.tpe.typeSymbol) && targ.tpe != null && targ.tpe <:< AnyRefClass.tpe)
+ if (qual.tpe != null && isPrimitiveValueClass(qual.tpe.typeSymbol) && targ.tpe != null && targ.tpe <:< AnyRefClass.tpe)
unit.error(sel.pos, "isInstanceOf cannot test if value types are references.")
def mkIsInstanceOf(q: () => Tree)(tp: Type): Tree =
@@ -973,20 +1039,13 @@ abstract class Erasure extends AddInterfaces
}
case _ => tree
}
- }
- else {
- def doDynamic(fn: Tree, qual: Tree): Tree = {
- if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol)
- ApplyDynamic(qual, args) setSymbol fn.symbol setPos tree.pos
- else tree
- }
- fn match {
- case Select(qual, _) => doDynamic(fn, qual)
- case TypeApply(fni@Select(qual, _), _) => doDynamic(fni, qual)// type parameters are irrelevant in case of dynamic call
- case _ =>
+ } else if (fn.symbol.owner.isRefinementClass && !fn.symbol.isOverridingSymbol) {
+ ApplyDynamic(qualifier, args) setSymbol fn.symbol setPos tree.pos
+ } else if (fn.symbol.isMethodWithExtension) {
+ Apply(gen.mkAttributedRef(extensionMethods.extensionMethod(fn.symbol)), qualifier :: args)
+ } else {
tree
}
- }
case Select(qual, name) =>
val owner = tree.symbol.owner
@@ -1019,7 +1078,11 @@ abstract class Erasure extends AddInterfaces
case Literal(ct) if ct.tag == ClassTag
&& ct.typeValue.typeSymbol != definitions.UnitClass =>
- treeCopy.Literal(tree, Constant(erasure(NoSymbol, ct.typeValue)))
+ val erased = ct.typeValue match {
+ case TypeRef(pre, clazz, args) if clazz.isDerivedValueClass => scalaErasure.eraseNormalClassRef(pre, clazz)
+ case tpe => specialScalaErasure(tpe)
+ }
+ treeCopy.Literal(tree, Constant(erased))
case _ =>
tree
@@ -1037,10 +1100,13 @@ abstract class Erasure extends AddInterfaces
val tree1 = preErase(tree)
tree1 match {
case EmptyTree | TypeTree() =>
- tree1 setType erasure(NoSymbol, tree1.tpe)
+ tree1 setType specialScalaErasure(tree1.tpe)
+ case ArrayValue(elemtpt, trees) =>
+ treeCopy.ArrayValue(
+ tree1, elemtpt setType specialScalaErasure.applyInArray(elemtpt.tpe), trees map transform) setType null
case DefDef(_, _, _, _, tpt, _) =>
val result = super.transform(tree1) setType null
- tpt.tpe = erasure(tree1.symbol, tree1.symbol.tpe).resultType
+ tpt.tpe = specialErasure(tree1.symbol)(tree1.symbol.tpe).resultType
result
case _ =>
super.transform(tree1) setType null
@@ -1054,6 +1120,7 @@ abstract class Erasure extends AddInterfaces
*/
override def transform(tree: Tree): Tree = {
val tree1 = preTransformer.transform(tree)
+ log("tree after pretransform: "+tree1)
afterErasure {
val tree2 = mixinTransformer.transform(tree1)
debuglog("tree after addinterfaces: \n" + tree2)
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
new file mode 100644
index 0000000000..4c3972519a
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -0,0 +1,159 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Martin Odersky
+ */
+package scala.tools.nsc
+package transform
+
+import symtab._
+import Flags._
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable
+import scala.tools.nsc.util.FreshNameCreator
+import scala.runtime.ScalaRunTime.{ isAnyVal, isTuple }
+
+/**
+ * Perform Step 1 in the inline classes SIP: Creates extension methods for all
+ * methods in a value class, except parameter or super accessors, or constructors.
+ *
+ * @author Martin Odersky
+ * @version 2.10
+ */
+abstract class ExtensionMethods extends Transform with TypingTransformers {
+
+ import global._ // the global environment
+ import definitions._ // standard classes and methods
+ import typer.{ typed, atOwner } // methods to type trees
+
+ /** the following two members override abstract members in Transform */
+ val phaseName: String = "extmethods"
+
+ def newTransformer(unit: CompilationUnit): Transformer =
+ new Extender(unit)
+
+ /** Generate stream of possible names for the extension version of given instance method `imeth`.
+ * If the method is not overloaded, this stream consists of just "extension$imeth".
+ * If the method is overloaded, the stream has as first element "extensionX$imeth", where X is the
+ * index of imeth in the sequence of overloaded alternatives with the same name. This choice will
+ * always be picked as the name of the generated extension method.
+ * After this first choice, all other possible indices in the range of 0 until the number
+ * of overloaded alternatives are returned. The secondary choices are used to find a matching method
+ * in `extensionMethod` if the first name has the wrong type. We thereby gain a level of insensitivity
+ * of how overloaded types are ordered between phases and picklings.
+ */
+ private def extensionNames(imeth: Symbol): Stream[Name] =
+ imeth.owner.info.decl(imeth.name).tpe match {
+ case OverloadedType(_, alts) =>
+ val index = alts indexOf imeth
+ assert(index >= 0, alts+" does not contain "+imeth)
+ def altName(index: Int) = newTermName("extension"+index+"$"+imeth.name)
+ altName(index) #:: ((0 until alts.length).toStream filter (index !=) map altName)
+ case tpe =>
+ assert(tpe != NoType, imeth.name+" not found in "+imeth.owner+"'s decls: "+imeth.owner.info.decls)
+ Stream(newTermName("extension$"+imeth.name))
+ }
+
+ /** Return the extension method that corresponds to given instance method `meth`.
+ */
+ def extensionMethod(imeth: Symbol): Symbol = atPhase(currentRun.refchecksPhase) {
+ val companionInfo = imeth.owner.companionModule.info
+ val candidates = extensionNames(imeth) map (companionInfo.decl(_))
+ val matching = candidates filter (alt => normalize(alt.tpe, imeth.owner) matches imeth.tpe)
+ assert(matching.nonEmpty, "no extension method found for "+imeth+" among "+candidates+"/"+extensionNames(imeth))
+ matching.head
+ }
+
+ private def normalize(stpe: Type, clazz: Symbol): Type = stpe match {
+ case PolyType(tparams, restpe) =>
+ GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe, clazz))
+ case MethodType(tparams, restpe) =>
+ restpe
+ case _ =>
+ stpe
+ }
+
+ class Extender(unit: CompilationUnit) extends TypingTransformer(unit) {
+
+ private val extensionDefs = mutable.Map[Symbol, mutable.ListBuffer[Tree]]()
+
+ def extensionMethInfo(extensionMeth: Symbol, origInfo: Type, clazz: Symbol): Type = {
+ var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth)
+ val thisParamType = appliedType(clazz.typeConstructor, newTypeParams map (_.tpe))
+ val thisParam = extensionMeth.newValueParameter(nme.SELF, extensionMeth.pos) setInfo thisParamType
+ def transform(clonedType: Type): Type = clonedType match {
+ case MethodType(params, restpe) =>
+ // I assume it was a bug that this was dropping params... [Martin]: No, it wasn't; it's curried.
+ MethodType(List(thisParam), clonedType)
+ case NullaryMethodType(restpe) =>
+ MethodType(List(thisParam), restpe)
+ }
+ val GenPolyType(tparams, restpe) = origInfo cloneInfo extensionMeth
+ GenPolyType(tparams ::: newTypeParams, transform(restpe) substSym (clazz.typeParams, newTypeParams))
+ }
+
+ private def allParams(tpe: Type): List[Symbol] = tpe match {
+ case MethodType(params, res) => params ::: allParams(res)
+ case _ => List()
+ }
+
+ override def transform(tree: Tree): Tree = {
+ tree match {
+ case Template(_, _, _) =>
+ if (currentOwner.isDerivedValueClass) {
+ extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree]
+ super.transform(tree)
+ } else if (currentOwner.isStaticOwner) {
+ super.transform(tree)
+ } else tree
+ case DefDef(_, _, tparams, vparamss, _, rhs) if tree.symbol.isMethodWithExtension =>
+ val companion = currentOwner.companionModule
+ val origMeth = tree.symbol
+ val extensionName = extensionNames(origMeth).head
+ val extensionMeth = companion.moduleClass.newMethod(extensionName, origMeth.pos, origMeth.flags & ~OVERRIDE & ~PROTECTED | FINAL)
+ .setAnnotations(origMeth.annotations)
+ companion.info.decls.enter(extensionMeth)
+ val newInfo = extensionMethInfo(extensionMeth, origMeth.info, currentOwner)
+ extensionMeth setInfo newInfo
+ log("Value class %s spawns extension method.\n Old: %s\n New: %s".format(
+ currentOwner,
+ origMeth.defString,
+ extensionMeth.defString)) // extensionMeth.defStringSeenAs(origInfo
+
+ def thisParamRef = gen.mkAttributedIdent(extensionMeth.info.params.head setPos extensionMeth.pos)
+ val GenPolyType(extensionTpeParams, extensionMono) = extensionMeth.info
+ val origTpeParams = (tparams map (_.symbol)) ::: currentOwner.typeParams
+ val extensionBody = rhs
+ .substTreeSyms(origTpeParams, extensionTpeParams)
+ .substTreeSyms(vparamss.flatten map (_.symbol), allParams(extensionMono).tail)
+ .substTreeThis(currentOwner, thisParamRef)
+ .changeOwner((origMeth, extensionMeth))
+ extensionDefs(companion) += atPos(tree.pos) { DefDef(extensionMeth, extensionBody) }
+ val extensionCallPrefix = Apply(
+ gen.mkTypeApply(gen.mkAttributedRef(companion), extensionMeth, origTpeParams map (_.tpe)),
+ List(This(currentOwner)))
+ val extensionCall = atOwner(origMeth) {
+ localTyper.typedPos(rhs.pos) {
+ (extensionCallPrefix /: vparamss) {
+ case (fn, params) => Apply(fn, params map (param => Ident(param.symbol)))
+ }
+ }
+ }
+ deriveDefDef(tree)(_ => extensionCall)
+ case _ =>
+ super.transform(tree)
+ }
+ }
+
+ override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
+ super.transformStats(stats, exprOwner) map {
+ case md @ ModuleDef(_, _, _) if extensionDefs contains md.symbol =>
+ val defns = extensionDefs(md.symbol).toList map (member =>
+ atOwner(md.symbol)(localTyper.typedPos(md.pos.focus)(member))
+ )
+ extensionDefs -= md.symbol
+ deriveModuleDef(md)(tmpl => deriveTemplate(tmpl)(_ ++ defns))
+ case stat =>
+ stat
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/transform/InlineErasure.scala b/src/compiler/scala/tools/nsc/transform/InlineErasure.scala
new file mode 100644
index 0000000000..0af3cf732f
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/transform/InlineErasure.scala
@@ -0,0 +1,9 @@
+package scala.tools.nsc
+package transform
+
+trait InlineErasure { self: Erasure =>
+
+ import global._
+ import definitions._
+
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 570eaba3a9..13ca8e55bc 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -25,7 +25,7 @@ abstract class LambdaLift extends InfoTransform {
if (sym.isCapturedVariable) {
val symClass = tpe.typeSymbol
def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) =
- if (isValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe
+ if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe
else if (erasedTypes) objectRefClass.tpe
else appliedType(objectRefClass.typeConstructor, List(tpe))
if (sym.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass)
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index c9794cc20f..dfadd8d60e 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -86,6 +86,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
* nor do they have a setter (not if they are vals anyway). The usual
* logic for setting bitmaps does therefor not work for such fields.
* That's why they are excluded.
+ * Note: The `checkinit` option does not check if transient fields are initialized.
*/
private def needsInitFlag(sym: Symbol) = (
settings.checkInit.value
@@ -95,6 +96,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
&& !sym.accessed.hasFlag(PRESUPER)
&& !sym.isOuterAccessor
&& !(sym.owner isSubClass DelayedInitClass)
+ && !(sym.isGetter && (sym.accessed hasAnnotation TransientAttr))
)
/** Maps all parts of this type that refer to implementation classes to
@@ -448,7 +450,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
if ((sym.hasAccessorFlag || (sym.isTerm && !sym.isMethod))
&& sym.isPrivate
&& !(currentOwner.isGetter && currentOwner.accessed == sym) // getter
- && !definitions.isValueClass(sym.tpe.resultType.typeSymbol)
+ && !definitions.isPrimitiveValueClass(sym.tpe.resultType.typeSymbol)
&& sym.owner == templ.symbol.owner
&& !sym.isLazy
&& !tree.isDef) {
@@ -520,7 +522,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
localTyper = erasure.newTyper(rootContext.make(tree, currentOwner))
afterMixin(currentOwner.owner.info)//todo: needed?
- if (!currentOwner.isTrait && !isValueClass(currentOwner))
+ if (!currentOwner.isTrait && !isPrimitiveValueClass(currentOwner))
addMixedinMembers(currentOwner, unit)
else if (currentOwner hasFlag lateINTERFACE)
addLateInterfaceMembers(currentOwner)
diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala
new file mode 100644
index 0000000000..ef158a71f6
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala
@@ -0,0 +1,68 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2012 LAMP/EPFL
+ * @author Martin odersky
+ */
+package scala.tools.nsc
+package transform
+
+/** This phase maps ErasedValueTypes to the underlying unboxed representation and
+ * performs peephole optimizations.
+ */
+trait PostErasure extends InfoTransform with TypingTransformers {
+
+ val global: Global
+ import global._
+ import definitions._
+
+ val phaseName: String = "posterasure"
+
+ def newTransformer(unit: CompilationUnit): Transformer = new PostErasureTransformer(unit)
+ override def changesBaseClasses = false
+
+ object elimErasedValueType extends TypeMap {
+ def apply(tp: Type) = tp match {
+ case ErasedValueType(clazz) => erasure.underlyingOfValueClass(clazz)
+ case _ => mapOver(tp)
+ }
+ }
+
+ def transformInfo(sym: Symbol, tp: Type) = elimErasedValueType(tp)
+
+ class PostErasureTransformer(unit: CompilationUnit) extends TypingTransformer(unit) {
+
+ override def transform(tree: Tree) =
+ super.transform(tree) setType elimErasedValueType(tree.tpe) match {
+ case // new C(arg).underlying ==> arg
+ Apply(sel @ Select(
+ Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)),
+ acc), List())
+ if atPhase(currentRun.erasurePhase) {
+ tpt.tpe.typeSymbol.isDerivedValueClass &&
+ sel.symbol == tpt.tpe.typeSymbol.firstParamAccessor
+ } =>
+ if (settings.debug.value) log("Removing "+tree+" -> "+arg)
+ arg
+ case // new C(arg1) == new C(arg2) ==> arg1 == arg2
+ Apply(sel @ Select(
+ Apply(Select(New(tpt1), nme.CONSTRUCTOR), List(arg1)),
+ cmp),
+ List(Apply(Select(New(tpt2), nme.CONSTRUCTOR), List(arg2))))
+ if atPhase(currentRun.erasurePhase) {
+ tpt1.tpe.typeSymbol.isDerivedValueClass &&
+ (cmp == nme.EQ || cmp == nme.NE) &&
+ tpt2.tpe.typeSymbol == tpt1.tpe.typeSymbol
+ } =>
+ val result = Apply(Select(arg1, cmp) setPos sel.pos, List(arg2)) setPos tree.pos
+ log("shortcircuiting equality "+tree+" -> "+result)
+ localTyper.typed(result)
+
+ case // arg.asInstanceOf[T] ==> arg if arg.tpe == T
+ Apply(TypeApply(cast @ Select(arg, asinstanceof), List(tpt)), List())
+ if cast.symbol == Object_asInstanceOf && arg.tpe =:= tpt.tpe => // !!! <:< ?
+ if (settings.debug.value) log("Shortening "+tree+" -> "+arg)
+ arg
+ case tree1 =>
+ tree1
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 88ad458748..7b0f5254b6 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -66,7 +66,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
import definitions.{
RootClass, BooleanClass, UnitClass, ArrayClass,
- ScalaValueClasses, isValueClass, isScalaValueType,
+ ScalaValueClasses, isPrimitiveValueClass, isScalaValueType,
SpecializedClass, RepeatedParamClass, JavaRepeatedParamClass,
AnyRefClass, ObjectClass, AnyRefModule,
GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass
@@ -123,14 +123,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// then pos/spec-List.scala fails - why? Does this kind of check fail
// for similar reasons? Does `sym.isAbstractType` make a difference?
private def isSpecializedAnyRefSubtype(tp: Type, sym: Symbol) = {
- specializedOn(sym).exists(s => !isValueClass(s)) &&
- !isValueClass(tp.typeSymbol) &&
+ specializedOn(sym).exists(s => !isPrimitiveValueClass(s)) &&
+ !isPrimitiveValueClass(tp.typeSymbol) &&
isBoundedGeneric(tp)
//(tp <:< AnyRefClass.tpe)
}
private def isBoundedGeneric(tp: Type) = tp match {
case TypeRef(_, sym, _) if sym.isAbstractType => (tp <:< AnyRefClass.tpe)
- case TypeRef(_, sym, _) => !isValueClass(sym)
+ case TypeRef(_, sym, _) => !isPrimitiveValueClass(sym)
case _ => false
}
@@ -348,7 +348,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def specializesClass(sym: Symbol): Symbol = {
val c = sym.companionClass
- if (isValueClass(c)) c else AnyRefClass
+ if (isPrimitiveValueClass(c)) c else AnyRefClass
}
/** Return the types `sym` should be specialized at. This may be some of the primitive types
@@ -587,7 +587,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
" => " + sClass.defStringSeenAs(sClass.typeOfThis)
)
}
- polyType(newClassTParams, ClassInfoType(parents ::: extraSpecializedMixins, decls1, sClass))
+ GenPolyType(newClassTParams, ClassInfoType(parents ::: extraSpecializedMixins, decls1, sClass))
}
afterSpecialize(sClass setInfo specializedInfoType)
@@ -818,7 +818,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// the cloneInfo is necessary so that method parameter symbols are cloned at the new owner
val methodType = sym.info.resultType.instantiateTypeParams(keys ++ tps, vals ++ tps1.map(_.tpe)).cloneInfo(specMember)
- specMember setInfo polyType(tps1, methodType)
+ specMember setInfo GenPolyType(tps1, methodType)
debuglog("expanded member: " + sym + ": " + sym.info +
" -> " + specMember +
@@ -994,7 +994,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def unify(tp1: Type, tp2: Type, env: TypeEnv, strict: Boolean): TypeEnv = (tp1, tp2) match {
case (TypeRef(_, sym1, _), _) if isSpecialized(sym1) =>
debuglog("Unify - basic case: " + tp1 + ", " + tp2)
- if (isValueClass(tp2.typeSymbol))
+ if (isPrimitiveValueClass(tp2.typeSymbol) || isSpecializedAnyRefSubtype(tp2, sym1))
env + ((sym1, tp2))
else if (isSpecializedAnyRefSubtype(tp2, sym1))
env + ((sym1, tp2)) // env + ((sym1, AnyRefClass.tpe))
@@ -1130,7 +1130,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
)
val newScope = newScopeWith(specializeClass(clazz, typeEnv(clazz)) ++ specialOverrides(clazz): _*)
// If tparams.isEmpty, this is just the ClassInfoType.
- polyType(tparams, ClassInfoType(parents1, newScope, clazz))
+ GenPolyType(tparams, ClassInfoType(parents1, newScope, clazz))
case _ =>
tpe
}
@@ -1342,7 +1342,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val env = typeEnv(specMember)
val residualTargs = symbol.info.typeParams zip targs collect {
- case (tvar, targ) if !env.contains(tvar) || !isValueClass(env(tvar).typeSymbol) => targ
+ case (tvar, targ) if !env.contains(tvar) || !isPrimitiveValueClass(env(tvar).typeSymbol) => targ
}
ifDebug(assert(residualTargs.length == specMember.info.typeParams.length,
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index d7b4171c65..ed9fee986f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -442,7 +442,6 @@ trait ContextErrors {
def UnexpectedTreeAnnotationError(tree: Tree, unexpected: Tree) =
NormalTypeError(tree, "unexpected tree after typing annotation: "+ unexpected)
- // TODO no test case
//typedExistentialTypeTree
def AbstractionFromVolatileTypeError(vd: ValDef) =
issueNormalTypeError(vd, "illegal abstraction from value with volatile type "+vd.symbol.tpe)
@@ -465,8 +464,7 @@ trait ContextErrors {
def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree) =
NormalTypeError(tree, "too many arguments for "+treeSymTypeMsg(fun))
- // can it still happen? see test case neg/t960.scala
- // TODO no test case
+ // can it still happen? see test case neg/overloaded-unapply.scala
def OverloadedUnapplyError(tree: Tree) =
issueNormalTypeError(tree, "cannot resolve overloaded unapply")
@@ -499,7 +497,6 @@ trait ContextErrors {
}
//doTypedApply - patternMode
- // TODO: missing test case
def TooManyArgsPatternError(fun: Tree) =
NormalTypeError(fun, "too many arguments for unapply pattern, maximum = "+definitions.MaxTupleArity)
@@ -534,14 +531,13 @@ trait ContextErrors {
NormalTypeError(parent, "illegal inheritance from final "+mixin)
def ParentSealedInheritanceError(parent: Tree, psym: Symbol) =
- NormalTypeError(parent, "illegal inheritance from sealed " + psym + ": " + context.unit.source.file.canonicalPath + " != " + psym.sourceFile.canonicalPath)
+ NormalTypeError(parent, "illegal inheritance from sealed " + psym )
def ParentSelfTypeConformanceError(parent: Tree, selfType: Type) =
NormalTypeError(parent,
"illegal inheritance;\n self-type "+selfType+" does not conform to "+
parent +"'s selftype "+parent.tpe.typeOfThis)
- // TODO: missing test case
def ParentInheritedTwiceError(parent: Tree, parentSym: Symbol) =
NormalTypeError(parent, parentSym+" is inherited twice")
@@ -572,7 +568,6 @@ trait ContextErrors {
setError(tree)
}
- //TODO Needs test case
def ConstructorPrefixError(tree: Tree, restpe: Type) = {
issueNormalTypeError(tree, restpe.prefix+" is not a legal prefix for a constructor")
setError(tree)
@@ -597,7 +592,6 @@ trait ContextErrors {
setError(tree)
}
- // TODO needs test case
// cases where we do not necessarily return trees
def DependentMethodTpeConversionToFunctionError(tree: Tree, tp: Type) =
issueNormalTypeError(tree, "method with dependent type "+tp+" cannot be converted to function value")
@@ -606,11 +600,9 @@ trait ContextErrors {
def StarPatternWithVarargParametersError(tree: Tree) =
issueNormalTypeError(tree, "star patterns must correspond with varargs parameters")
- // TODO missing test case
def FinitaryError(tparam: Symbol) =
issueSymbolTypeError(tparam, "class graph is not finitary because type parameter "+tparam.name+" is expansively recursive")
- // TODO missing test case for a second case
def QualifyingClassError(tree: Tree, qual: Name) = {
issueNormalTypeError(tree,
if (qual.isEmpty) tree + " can be used only in a class, object, or template"
@@ -778,7 +770,7 @@ trait ContextErrors {
def PolymorphicExpressionInstantiationError(tree: Tree, undetparams: List[Symbol], pt: Type) =
issueNormalTypeError(tree,
"polymorphic expression cannot be instantiated to expected type" +
- foundReqMsg(polyType(undetparams, skipImplicit(tree.tpe)), pt))
+ foundReqMsg(GenPolyType(undetparams, skipImplicit(tree.tpe)), pt))
//checkCheckable
def TypePatternOrIsInstanceTestError(tree: Tree, tp: Type) =
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 2c564c097f..a1ba8a2982 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -43,8 +43,7 @@ trait Contexts { self: Analyzer =>
* - if option `-Yno-imports` is given, nothing is imported
* - if the unit is java defined, only `java.lang` is imported
* - if option `-Yno-predef` is given, if the unit body has an import of Predef
- * among its leading imports, or if the tree is [[scala.ScalaObject]]
- * or [[scala.Predef]], `Predef` is not imported.
+ * among its leading imports, or if the tree is [[scala.Predef]], `Predef` is not imported.
*/
protected def rootImports(unit: CompilationUnit): List[Symbol] = {
import definitions._
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 0ddacf7d36..7d1198a4a2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1094,7 +1094,11 @@ trait Implicits {
/** Creates a tree that calls the factory method called constructor in object reflect.Manifest */
def manifestFactoryCall(constructor: String, tparg: Type, args: Tree*): Tree =
if (args contains EmptyTree) EmptyTree
- else typedPos(tree.pos.focus)(gen.mkManifestFactoryCall(full, constructor, tparg, args.toList))
+ else typedPos(tree.pos.focus) {
+ val mani = gen.mkManifestFactoryCall(full, constructor, tparg, args.toList)
+ if (settings.debug.value) println("generated manifest: "+mani) // DEBUG
+ mani
+ }
/** Creates a tree representing one of the singleton manifests.*/
def findSingletonManifest(name: String) = typedPos(tree.pos.focus) {
@@ -1119,7 +1123,7 @@ trait Implicits {
case ConstantType(value) =>
manifestOfType(tp1.deconst, full)
case TypeRef(pre, sym, args) =>
- if (isValueClass(sym) || isPhantomClass(sym)) {
+ if (isPrimitiveValueClass(sym) || isPhantomClass(sym)) {
findSingletonManifest(sym.name.toString)
} else if (sym == ObjectClass || sym == AnyRefClass) {
findSingletonManifest("Object")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index c0c801910c..8b3bc253fd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -196,6 +196,10 @@ trait Infer {
/* -- Error Messages --------------------------------------------------- */
def setError[T <: Tree](tree: T): T = {
+ if (settings.debug.value) { // DEBUG
+ println("set error: "+tree);
+ throw new Error()
+ }
def name = newTermName("<error: " + tree.symbol + ">")
def errorClass = if (context.reportErrors) context.owner.newErrorClass(name.toTypeName) else stdErrorClass
def errorValue = if (context.reportErrors) context.owner.newErrorValue(name) else stdErrorValue
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 088a56cd7b..f32ad9293c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -69,6 +69,9 @@ trait MethodSynthesis {
import synthesisUtil._
class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
+ def mkThis = This(clazz) setPos clazz.pos.focus
+ def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)(Select(mkThis, sym))
+
private def isOverride(name: TermName) =
clazzMember(name).alternatives exists (sym => !sym.isDeferred && (sym.owner != clazz))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 82bcb93965..c5fb13a5a9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -73,7 +73,7 @@ trait Namers extends MethodSynthesis {
classAndNamerOfModule.clear()
}
- abstract class Namer(val context: Context) extends MethodSynth with NamerContextErrors {
+ abstract class Namer(val context: Context) extends MethodSynth with NamerContextErrors { thisNamer =>
import NamerErrorGen._
val typer = newTyper(context)
@@ -99,6 +99,13 @@ trait Namers extends MethodSynthesis {
owner.unsafeTypeParams foreach (paramContext.scope enter _)
newNamer(paramContext)
}
+
+ def enclosingNamerWithScope(scope: Scope) = {
+ var cx = context
+ while (cx != NoContext && cx.scope != scope) cx = cx.outer
+ if (cx == NoContext || cx == context) thisNamer
+ else newNamer(cx)
+ }
def enterValueParams(vparamss: List[List[ValDef]]): List[List[Symbol]] = {
mmap(vparamss) { param =>
@@ -449,7 +456,7 @@ trait Namers extends MethodSynthesis {
// The object Foo is still in scope, but because it is not compiled in current run
// it should be ditched and a new one created.
if (m != NoSymbol && currentRun.compiles(m)) m
- else enterSyntheticSym(creator(cdef))
+ else enterSyntheticSym(atPos(cdef.pos.focus)(creator(cdef)))
}
private def checkSelectors(tree: Import): Unit = {
@@ -709,6 +716,17 @@ trait Namers extends MethodSynthesis {
if (needsCycleCheck && !typer.checkNonCyclic(tree.pos, tp))
sym setInfo ErrorType
}
+ // tree match {
+ // case ClassDef(_, _, _, impl) =>
+ // val parentsOK = (
+ // treeInfo.isInterface(sym, impl.body)
+ // || (sym eq ArrayClass)
+ // || (sym isSubClass AnyValClass)
+ // )
+ // if (!parentsOK)
+ // ensureParent(sym, AnyRefClass)
+ // case _ => ()
+ // }
}
def moduleClassTypeCompleter(tree: Tree) = {
@@ -840,6 +858,7 @@ trait Namers extends MethodSynthesis {
}
val parents = typer.parentTypes(templ) map checkParent
+
enterSelf(templ.self)
val decls = newScope
@@ -890,7 +909,7 @@ trait Namers extends MethodSynthesis {
val tparams0 = typer.reenterTypeParams(tparams)
val resultType = templateSig(impl)
- polyType(tparams0, resultType)
+ GenPolyType(tparams0, resultType)
}
private def methodSig(ddef: DefDef, mods: Modifiers, tparams: List[TypeDef],
@@ -933,7 +952,7 @@ trait Namers extends MethodSynthesis {
// DEPMETTODO: check not needed when they become on by default
checkDependencies(restpe)
- polyType(
+ GenPolyType(
tparamSyms, // deSkolemized symbols -- TODO: check that their infos don't refer to method args?
if (vparamSymss.isEmpty) NullaryMethodType(restpe)
// vparamss refer (if they do) to skolemized tparams
@@ -1187,7 +1206,7 @@ trait Namers extends MethodSynthesis {
// However, separate compilation requires the symbol info to be
// loaded to do this check, but loading the info will probably
// lead to spurious cyclic errors. So omit the check.
- polyType(tparamSyms, tp)
+ GenPolyType(tparamSyms, tp)
}
/** Given a case class
@@ -1251,8 +1270,16 @@ trait Namers extends MethodSynthesis {
if (sym.isModule) annotate(sym.moduleClass)
def getSig = tree match {
- case ClassDef(_, _, tparams, impl) =>
- createNamer(tree).classSig(tparams, impl)
+ case cdef @ ClassDef(_, name, tparams, impl) =>
+ val clazz = tree.symbol
+ val result = createNamer(tree).classSig(tparams, impl)
+ clazz setInfo result
+ if (clazz.isDerivedValueClass) {
+ log("Ensuring companion for derived value class " + name + " at " + cdef.pos.show)
+ clazz setFlag FINAL
+ enclosingNamerWithScope(clazz.owner.info.decls).ensureCompanionObject(cdef)
+ }
+ result
case ModuleDef(_, _, impl) =>
val clazz = sym.moduleClass
@@ -1308,6 +1335,22 @@ trait Namers extends MethodSynthesis {
}
}
+ def includeParent(tpe: Type, parent: Symbol): Type = tpe match {
+ case PolyType(tparams, restpe) =>
+ PolyType(tparams, includeParent(restpe, parent))
+ case ClassInfoType(parents, decls, clazz) =>
+ if (parents exists (_.typeSymbol == parent)) tpe
+ else ClassInfoType(parents :+ parent.tpe, decls, clazz)
+ case _ =>
+ tpe
+ }
+
+ def ensureParent(clazz: Symbol, parent: Symbol) = {
+ val info0 = clazz.info
+ val info1 = includeParent(info0, parent)
+ if (info0 ne info1) clazz setInfo info1
+ }
+
class LogTransitions[S](onEnter: S => String, onExit: S => String) {
val enabled = settings.debug.value
@inline final def apply[T](entity: S)(body: => T): T = {
@@ -1411,7 +1454,7 @@ trait Namers extends MethodSynthesis {
checkNoConflict(PRIVATE, PROTECTED)
// checkNoConflict(PRIVATE, OVERRIDE) // this one leads to bad error messages like #4174, so catch in refchecks
// checkNoConflict(PRIVATE, FINAL) // can't do this because FINAL also means compile-time constant
- checkNoConflict(ABSTRACT, FINAL)
+ // checkNoConflict(ABSTRACT, FINAL) // this one gives a bad error for non-@inline classes which extend AnyVal
// @PP: I added this as a sanity check because these flags are supposed to be
// converted to ABSOVERRIDE before arriving here.
checkNoConflict(ABSTRACT, OVERRIDE)
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index e8d3b7a7de..c621497618 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -224,7 +224,7 @@ trait NamesDefaults { self: Analyzer =>
case Select(sp @ Super(_, _), _) if isConstr =>
// 'moduleQual' fixes #3207. selection of the companion module of the
// superclass needs to have the same prefix as the superclass.
- blockWithoutQualifier(moduleQual(baseFun.pos, sp.symbol.tpe.parents.head))
+ blockWithoutQualifier(moduleQual(baseFun.pos, sp.symbol.tpe.firstParent))
// self constructor calls (in secondary constructors)
case Select(tp, name) if isConstr =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 507ffd55d7..ec42d251ff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -525,7 +525,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
!other.isDeferred && other.isJavaDefined && {
// #3622: erasure operates on uncurried types --
// note on passing sym in both cases: only sym.isType is relevant for uncurry.transformInfo
- def uncurryAndErase(tp: Type) = erasure.erasure(sym, uncurry.transformInfo(sym, tp))
+ // !!! erasure.erasure(sym, uncurry.transformInfo(sym, tp)) gives erreneous of inaccessible type - check whether that's still the case!
+ def uncurryAndErase(tp: Type) = erasure.erasure(sym)(uncurry.transformInfo(sym, tp))
val tp1 = uncurryAndErase(clazz.thisType.memberType(sym))
val tp2 = uncurryAndErase(clazz.thisType.memberType(other))
afterErasure(tp1 matches tp2)
@@ -693,8 +694,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
if (abstractErrors.nonEmpty)
unit.error(clazz.pos, abstractErrorMessage)
- } else if (clazz.isTrait) {
- // prevent abstract methods in interfaces that override final members in Object; see #4431
+ }
+ else if (clazz.isTrait && !(clazz isSubClass AnyValClass)) {
+ // For non-AnyVal classes, prevent abstract methods in interfaces that override
+ // final members in Object; see #4431
for (decl <- clazz.info.decls.iterator) {
val overridden = decl.overriddenSymbol(ObjectClass)
if (overridden.isFinal)
@@ -1061,7 +1064,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
def isBoolean(s: Symbol) = unboxedValueClass(s) == BooleanClass
def isUnit(s: Symbol) = unboxedValueClass(s) == UnitClass
def isNumeric(s: Symbol) = isNumericValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass)
- def isSpecial(s: Symbol) = isValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) || isMaybeValue(s)
+ def isSpecial(s: Symbol) = isPrimitiveValueClass(unboxedValueClass(s)) || (s isSubClass ScalaNumberClass) || isMaybeValue(s)
def possibleNumericCount = onSyms(_ filter (x => isNumeric(x) || isMaybeValue(x)) size)
val nullCount = onSyms(_ filter (_ == NullClass) size)
@@ -1082,7 +1085,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
if (nullCount == 2)
nonSensible("", true) // null == null
else if (nullCount == 1) {
- if (onSyms(_ exists isValueClass)) // null == 5
+ if (onSyms(_ exists isPrimitiveValueClass)) // null == 5
nonSensible("", false)
else if (onTrees( _ exists isNew)) // null == new AnyRef
nonSensibleWarning("a fresh object", false)
@@ -1122,7 +1125,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
// warn only if they have no common supertype below Object
else {
val common = global.lub(List(actual.tpe, receiver.tpe))
- if (common.typeSymbol == ScalaObjectClass || (ObjectClass.tpe <:< common))
+ if (ObjectClass.tpe <:< common)
unrelatedTypes()
}
}
@@ -1470,7 +1473,10 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
if (settings.Xmigration28.value)
checkMigration(sym, tree.pos)
- if (currentClass != sym.owner && sym.hasLocalFlag) {
+ if (sym eq NoSymbol) {
+ unit.warning(tree.pos, "Select node has NoSymbol! " + tree + " / " + tree.tpe)
+ }
+ else if (currentClass != sym.owner && sym.hasLocalFlag) {
var o = currentClass
var hidden = false
while (!hidden && o != sym.owner && o != sym.owner.moduleClass && !o.isPackage) {
@@ -1517,6 +1523,14 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
case _ => ()
}
+ // Verify classes extending AnyVal meet the requirements
+ private def checkAnyValSubclass(clazz: Symbol) = {
+ if ((clazz isSubClass AnyValClass) && !isPrimitiveValueClass(clazz)) {
+ if (clazz.isTrait)
+ unit.error(clazz.pos, "Only classes (not traits) are allowed to extend AnyVal")
+ }
+ }
+
override def transform(tree: Tree): Tree = {
val savedLocalTyper = localTyper
val savedCurrentApplication = currentApplication
@@ -1548,6 +1562,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
checkOverloadedRestrictions(currentOwner)
val bridges = addVarargBridges(currentOwner)
checkAllOverrides(currentOwner)
+ checkAnyValSubclass(currentOwner)
if (bridges.nonEmpty) deriveTemplate(tree)(_ ::: bridges) else tree
case dc@TypeTreeWithDeferredRefCheck() => assert(false, "adapt should have turned dc: TypeTreeWithDeferredRefCheck into tpt: TypeTree, with tpt.original == dc"); dc
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 243e685b13..4248b6f024 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -266,6 +266,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
}
transformSuperSelect(sel)
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension =>
+ treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, withInvalidOwner(transform(rhs)))
+
case TypeApply(sel @ Select(qual, name), args) =>
mayNeedProtectedAccessor(sel, args, true)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 7559b78db3..2f4eff30d2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -39,6 +39,7 @@ trait SyntheticMethods extends ast.TreeDSL {
/** Add the synthetic methods to case classes.
*/
def addSyntheticMethods(templ: Template, clazz0: Symbol, context: Context): Template = {
+
if (phase.erasedTypes)
return templ
@@ -48,6 +49,15 @@ trait SyntheticMethods extends ast.TreeDSL {
)
import synthesizer._
+ if (clazz0 == AnyValClass || isPrimitiveValueClass(clazz0)) return {
+ if (clazz0.info member nme.getClass_ isDeferred) {
+ // XXX dummy implementation for now
+ val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe))(_ => NULL)
+ deriveTemplate(templ)(_ :+ getClassMethod)
+ }
+ else templ
+ }
+
val originalAccessors = clazz.caseFieldAccessors
// private ones will have been renamed -- make sure they are entered
// in the original order.
@@ -77,7 +87,7 @@ trait SyntheticMethods extends ast.TreeDSL {
)
def forwardToRuntime(method: Symbol): Tree =
- forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(This(clazz) :: _)
+ forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(mkThis :: _)
// Any member, including private
def hasConcreteImpl(name: Name) =
@@ -85,8 +95,8 @@ trait SyntheticMethods extends ast.TreeDSL {
def hasOverridingImplementation(meth: Symbol) = {
val sym = clazz.info nonPrivateMember meth.name
- sym.alternatives filterNot (_ eq meth) exists { m0 =>
- !m0.isDeferred && !m0.isSynthetic && (typeInClazz(m0) matches typeInClazz(meth))
+ sym.alternatives exists { m0 =>
+ (m0 ne meth) && !m0.isDeferred && !m0.isSynthetic && (m0.owner != AnyValClass) && (typeInClazz(m0) matches typeInClazz(meth))
}
}
def readConstantValue[T](name: String, default: T = null.asInstanceOf[T]): T = {
@@ -97,7 +107,7 @@ trait SyntheticMethods extends ast.TreeDSL {
}
def productIteratorMethod = {
createMethod(nme.productIterator, iteratorOfType(accessorLub))(_ =>
- gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(This(clazz)))
+ gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(mkThis))
)
}
def projectionMethod(accessor: Symbol, num: Int) = {
@@ -111,13 +121,49 @@ trait SyntheticMethods extends ast.TreeDSL {
// def productElementNameMethod = perElementMethod(nme.productElementName, StringClass.tpe)(x => LIT(x.name.toString))
+ var syntheticCanEqual = false
+
/** The canEqual method for case classes.
* def canEqual(that: Any) = that.isInstanceOf[This]
*/
- def canEqualMethod: Tree = (
+ def canEqualMethod: Tree = {
+ syntheticCanEqual = true
createMethod(nme.canEqual_, List(AnyClass.tpe), BooleanClass.tpe)(m =>
Ident(m.firstParam) IS_OBJ classExistentialType(clazz))
- )
+ }
+
+ /** (that.isInstanceOf[this.C])
+ * where that is the given methods first parameter.
+ */
+ def thatTest(eqmeth: Symbol): Tree =
+ gen.mkIsInstanceOf(Ident(eqmeth.firstParam), typeCaseType(clazz), true, false)
+
+ /** (that.asInstanceOf[this.C])
+ * where that is the given methods first parameter.
+ */
+ def thatCast(eqmeth: Symbol): Tree =
+ gen.mkCast(Ident(eqmeth.firstParam), clazz.tpe)
+
+ /** The equality method core for case classes and inline clases.
+ * 1+ args:
+ * (that.isInstanceOf[this.C]) && {
+ * val x$1 = that.asInstanceOf[this.C]
+ * (this.arg_1 == x$1.arg_1) && (this.arg_2 == x$1.arg_2) && ... && (x$1 canEqual this)
+ * }
+ * Drop canBuildFrom part if class is final and canBuildFrom is synthesized
+ */
+ def equalsCore(eqmeth: Symbol, accessors: List[Symbol]) = {
+ val otherName = context.unit.freshTermName(clazz.name + "$")
+ val otherSym = eqmeth.newValue(otherName, eqmeth.pos, SYNTHETIC) setInfo clazz.tpe
+ val pairwise = accessors map (acc => fn(Select(mkThis, acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
+ val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(mkThis))
+ val tests = if (clazz.isDerivedValueClass || clazz.isFinal && syntheticCanEqual) pairwise else pairwise :+ canEq
+
+ thatTest(eqmeth) AND Block(
+ ValDef(otherSym, thatCast(eqmeth)),
+ AND(tests: _*)
+ )
+ }
/** The equality method for case classes.
* 0 args:
@@ -130,34 +176,34 @@ trait SyntheticMethods extends ast.TreeDSL {
* }
* }
*/
- def equalsClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
- val arg0 = Ident(m.firstParam)
- val thatTest = gen.mkIsInstanceOf(arg0, classExistentialType(clazz), true, false)
- val thatCast = gen.mkCast(arg0, clazz.tpe)
-
- def argsBody: Tree = {
- val otherName = context.unit.freshTermName(clazz.name + "$")
- val otherSym = m.newValue(otherName, m.pos, SYNTHETIC) setInfo clazz.tpe
- val pairwise = accessors map (acc => fn(Select(This(clazz), acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
- val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(This(clazz)))
- def block = Block(ValDef(otherSym, thatCast), AND(pairwise :+ canEq: _*))
-
- (This(clazz) ANY_EQ arg0) OR {
- thatTest AND Block(
- ValDef(otherSym, thatCast),
- AND(pairwise :+ canEq: _*)
- )
- }
- }
+ def equalsCaseClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
if (accessors.isEmpty)
- thatTest AND ((thatCast DOT nme.canEqual_)(This(clazz)))
+ if (clazz.isFinal) thatTest(m)
+ else thatTest(m) AND ((thatCast(m) DOT nme.canEqual_)(mkThis))
else
- argsBody
+ (mkThis ANY_EQ Ident(m.firstParam)) OR equalsCore(m, accessors)
+ }
+
+ /** The equality method for value classes
+ * def equals(that: Any) = (this.asInstanceOf[AnyRef]) eq that.asInstanceOf[AnyRef]) || {
+ * (that.isInstanceOf[this.C]) && {
+ * val x$1 = that.asInstanceOf[this.C]
+ * (this.underlying == that.underlying
+ */
+ def equalsDerivedValueClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
+ equalsCore(m, List(clazz.firstParamAccessor))
+ }
+
+ /** The hashcode method for value classes
+ * def hashCode(): Int = this.underlying.hashCode
+ */
+ def hashCodeDerivedValueClassMethod: Tree = createMethod(nme.hashCode_, Nil, IntClass.tpe) { m =>
+ Select(mkThisSelect(clazz.firstParamAccessor), nme.hashCode_)
}
/** The _1, _2, etc. methods to implement ProductN.
*/
- def productNMethods = {
+ def productNMethods = {
val accs = accessors.toIndexedSeq
1 to arity map (num => productProj(arity, num) -> (() => projectionMethod(accs(num - 1), num)))
}
@@ -167,7 +213,7 @@ trait SyntheticMethods extends ast.TreeDSL {
List(
Product_productPrefix -> (() => constantNullary(nme.productPrefix, clazz.name.decode)),
Product_productArity -> (() => constantNullary(nme.productArity, arity)),
- Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(Ident)),
+ Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(mkThisSelect)),
Product_iterator -> (() => productIteratorMethod),
Product_canEqual -> (() => canEqualMethod)
// This is disabled pending a reimplementation which doesn't add any
@@ -176,10 +222,19 @@ trait SyntheticMethods extends ast.TreeDSL {
)
}
+ def valueClassMethods = List(
+ Any_hashCode -> (() => hashCodeDerivedValueClassMethod),
+ Any_equals -> (() => equalsDerivedValueClassMethod)
+ )
+
def caseClassMethods = productMethods ++ productNMethods ++ Seq(
Object_hashCode -> (() => forwardToRuntime(Object_hashCode)),
Object_toString -> (() => forwardToRuntime(Object_toString)),
- Object_equals -> (() => equalsClassMethod)
+ Object_equals -> (() => equalsCaseClassMethod)
+ )
+
+ def valueCaseClassMethods = productMethods ++ productNMethods ++ valueClassMethods ++ Seq(
+ Any_toString -> (() => forwardToRuntime(Object_toString))
)
def caseObjectMethods = productMethods ++ Seq(
@@ -203,10 +258,14 @@ trait SyntheticMethods extends ast.TreeDSL {
def synthesize(): List[Tree] = {
val methods = (
- if (!clazz.isCase) Nil
- else if (clazz.isModuleClass) caseObjectMethods
- else caseClassMethods
+ if (clazz.isCase)
+ if (clazz.isDerivedValueClass) valueCaseClassMethods
+ else if (clazz.isModuleClass) caseObjectMethods
+ else caseClassMethods
+ else if (clazz.isDerivedValueClass) valueClassMethods
+ else Nil
)
+
def impls = for ((m, impl) <- methods ; if !hasOverridingImplementation(m)) yield impl()
def extras = (
if (needsReadResolve) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9ff86e69eb..25f3e7af5c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -637,7 +637,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// to escape scope here, e.g. pos/t1107. I'm not sure how to properly handle this
// so for now it requires the type symbol be public.
&& pre.typeSymbol.isPublic)
- tree setType MethodType(Nil, erasure.getClassReturnType(pre))
+ tree setType MethodType(Nil, getClassReturnType(pre))
else
tree
}
@@ -1266,8 +1266,36 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
+ private def validateDerivedValueClass(clazz: Symbol, body: List[Tree]) = {
+ if (clazz.isTrait)
+ unit.error(clazz.pos, "only classes (not traits) are allowed to extend AnyVal")
+ if (!clazz.isStatic)
+ unit.error(clazz.pos, "value class may not be a "+
+ (if (clazz.owner.isTerm) "local class" else "member of another class"))
+ val constr = clazz.primaryConstructor
+ if ((constr hasFlag (PRIVATE | PROTECTED)) || constr.privateWithin != NoSymbol)
+ unit.error(constr.pos, "value class must have public primary constructor")
+ clazz.info.decls.toList.filter(acc => acc.isMethod && (acc hasFlag PARAMACCESSOR)) match {
+ case List(acc) =>
+ def isUnderlyingAcc(sym: Symbol) =
+ sym == acc || acc.hasAccessorFlag && sym == acc.accessed
+ if (acc.accessBoundary(clazz) != RootClass)
+ unit.error(acc.pos, "value class needs to have a publicly accessible val parameter")
+ for (stat <- body)
+ if (!treeInfo.isAllowedInUniversalTrait(stat) && !isUnderlyingAcc(stat.symbol))
+ unit.error(stat.pos,
+ if (stat.symbol hasFlag PARAMACCESSOR) "illegal parameter for value class"
+ else "this statement is not allowed in value class: "+stat)
+ case x =>
+ unit.error(clazz.pos, "value class needs to have exactly one public val parameter")
+ }
+ for (tparam <- clazz.typeParams)
+ if (tparam hasAnnotation definitions.SpecializedClass)
+ unit.error(tparam.pos, "type parameter of value class may not be specialized")
+ }
+
def parentTypes(templ: Template): List[Tree] =
- if (templ.parents.isEmpty) List()
+ if (templ.parents.isEmpty) List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
else try {
val clazz = context.owner
// Normalize supertype and mixins so that supertype is always a class, not a trait.
@@ -1279,9 +1307,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val supertpt1 = typedType(supertpt)
if (!supertpt1.isErrorTyped) {
mixins = supertpt1 :: mixins
- supertpt = TypeTree(supertpt1.tpe.parents.head) setPos supertpt.pos.focus
+ supertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
}
}
+ if (supertpt.tpe.typeSymbol == AnyClass && firstParent.isTrait)
+ supertpt.tpe = AnyRefClass.tpe
// Determine
// - supertparams: Missing type parameters from supertype
@@ -1371,12 +1401,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else xs
)
}
+
fixDuplicates(supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(clazz, tpt))
}
catch {
case ex: TypeError =>
// fallback in case of cyclic errors
// @H none of the tests enter here but I couldn't rule it out
+ log("Type error calculating parents in template " + templ)
+ log("Error: " + ex)
ParentTypesError(templ, ex)
List(TypeTree(AnyRefClass.tpe))
}
@@ -1413,13 +1446,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (psym.isFinal)
pending += ParentFinalInheritanceError(parent, psym)
- if (psym.isSealed && !phase.erasedTypes) {
- // AnyVal is sealed, but we have to let the value classes through manually
- if (context.unit.source.file == psym.sourceFile || isValueClass(context.owner))
+ if (psym.isSealed && !phase.erasedTypes)
+ if (context.unit.source.file == psym.sourceFile)
psym addChild context.owner
else
pending += ParentSealedInheritanceError(parent, psym)
- }
+
if (!(selfType <:< parent.tpe.typeOfThis) &&
!phase.erasedTypes &&
!context.owner.isSynthetic && // don't check synthetic concrete classes for virtuals (part of DEVIRTUALIZE)
@@ -1485,6 +1517,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
_.typedTemplate(cdef.impl, parentTypes(cdef.impl))
}
val impl2 = finishMethodSynthesis(impl1, clazz, context)
+ if (clazz.isTrait && clazz.info.parents.nonEmpty && clazz.info.firstParent.normalize.typeSymbol == AnyClass)
+ for (stat <- impl2.body)
+ if (!treeInfo.isAllowedInUniversalTrait(stat))
+ unit.error(stat.pos, "this statement is not allowed in universal trait extending from class Any: "+stat)
if ((clazz != ClassfileAnnotationClass) &&
(clazz isNonBottomSubClass ClassfileAnnotationClass))
restrictionWarning(cdef.pos, unit,
@@ -1601,6 +1637,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass)
unit.error(clazz.pos, "inner classes cannot be classfile annotations")
+
if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType])
@@ -1609,6 +1646,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else templ.body flatMap rewrappingWrapperTrees(namer.finishGetterSetter(Typer.this, _))
val body1 = typedStats(body, templ.symbol)
+
+ if (clazz.isDerivedValueClass)
+ validateDerivedValueClass(clazz, body1)
+
treeCopy.Template(templ, parents1, self1, body1) setType clazz.tpe
}
@@ -1682,7 +1723,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* @param rhs ...
*/
def computeParamAliases(clazz: Symbol, vparamss: List[List[ValDef]], rhs: Tree) {
- debuglog("computing param aliases for "+clazz+":"+clazz.primaryConstructor.tpe+":"+rhs)//debug
+ log("computing param aliases for "+clazz+":"+clazz.primaryConstructor.tpe+":"+rhs)//debug
def decompose(call: Tree): (Tree, List[Tree]) = call match {
case Apply(fn, args) =>
val (superConstr, args1) = decompose(fn)
@@ -1861,8 +1902,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe)
}
- if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors)
- computeParamAliases(meth.owner, vparamss1, rhs1)
+ if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors && !meth.owner.isSubClass(AnyValClass)) {
+ // At this point in AnyVal there is no supercall, which will blow up
+ // in computeParamAliases; there's nothing to be computed for Anyval anyway.
+ computeParamAliases(meth.owner, vparamss1, rhs1)
+ }
+
if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen && rhs1.tpe.typeSymbol != NothingClass)
rhs1 = checkDead(rhs1)
@@ -1881,6 +1926,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
if (meth.isStructuralRefinementMember)
checkMethodStructuralCompatible(meth)
+
treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
}
@@ -2615,8 +2661,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
/** This is translating uses of List() into Nil. This is less
* than ideal from a consistency standpoint, but it shouldn't be
* altered without due caution.
+ * ... this also causes bootstrapping cycles if List_apply is
+ * forced during kind-arity checking, so it is guarded by additional
+ * tests to ensure we're sufficiently far along.
*/
- if (fun.symbol == List_apply && args.isEmpty && !forInteractive)
+ if (args.isEmpty && !forInteractive && fun.symbol.isInitialized && ListModule.hasCompleteInfo && (fun.symbol == List_apply))
atPos(tree.pos)(gen.mkNil setType restpe)
else
constfold(treeCopy.Apply(tree, fun, args1) setType ifPatternSkipFormals(restpe))
@@ -3154,7 +3203,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// as we don't know which alternative to choose... here we do
map2Conserve(args, tparams) {
//@M! the polytype denotes the expected kind
- (arg, tparam) => typedHigherKindedType(arg, mode, polyType(tparam.typeParams, AnyClass.tpe))
+ (arg, tparam) => typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyClass.tpe))
}
} else // @M: there's probably something wrong when args.length != tparams.length... (triggered by bug #320)
// Martin, I'm using fake trees, because, if you use args or arg.map(typedType),
@@ -3217,6 +3266,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def typedAnnotated(ann: Tree, arg1: Tree): Tree = {
+ def mkTypeTree(tpe: Type) = TypeTree(tpe) setOriginal tree setPos tree.pos.focus
/** mode for typing the annotation itself */
val annotMode = mode & ~TYPEmode | EXPRmode
@@ -3262,19 +3312,20 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
arg1 // simply drop erroneous annotations
else {
ann.tpe = atype
- TypeTree(atype) setOriginal tree
+ mkTypeTree(atype)
}
} else {
// the annotation was typechecked before
- TypeTree(ann.tpe) setOriginal tree
+ mkTypeTree(ann.tpe)
}
- } else {
+ }
+ else {
if (ann.tpe == null) {
val annotInfo = typedAnnotation(ann, annotMode)
ann.tpe = arg1.tpe.withAnnotation(annotInfo)
}
val atype = ann.tpe
- Typed(arg1, TypeTree(atype) setOriginal tree setPos tree.pos.focus) setPos tree.pos setType atype
+ Typed(arg1, mkTypeTree(atype)) setPos tree.pos setType atype
}
}
@@ -3579,7 +3630,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val Select(qual, name) = fun
tryTypedArgs(args, forArgMode(fun, mode)) match {
case Some(args1) =>
- assert((args1.length == 0) || !args1.head.tpe.isErroneous, "try typed args is ok")
val qual1 =
if (!pt.isError) adaptToArguments(qual, name, args1, pt, true, true)
else qual
@@ -3756,16 +3806,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
- val owntype =
- if (mix.isEmpty) {
- if ((mode & SUPERCONSTRmode) != 0)
- if (clazz.info.parents.isEmpty) AnyRefClass.tpe // can happen due to cyclic references ==> #1036
- else clazz.info.parents.head
- else intersectionType(clazz.info.parents)
- } else {
- findMixinSuper(clazz.tpe)
- }
-
+ val owntype = (
+ if (!mix.isEmpty) findMixinSuper(clazz.tpe)
+ else if ((mode & SUPERCONSTRmode) != 0) clazz.info.firstParent
+ else intersectionType(clazz.info.parents)
+ )
treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype)
}
@@ -4149,7 +4194,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// if symbol hasn't been fully loaded, can't check kind-arity
else map2Conserve(args, tparams) { (arg, tparam) =>
//@M! the polytype denotes the expected kind
- typedHigherKindedType(arg, mode, polyType(tparam.typeParams, AnyClass.tpe))
+ typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyClass.tpe))
}
val argtypes = args1 map (_.tpe)
@@ -4317,7 +4362,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
case Typed(expr0, tpt @ Ident(tpnme.WILDCARD_STAR)) =>
val expr = typed(expr0, onlyStickyModes(mode), WildcardType)
def subArrayType(pt: Type) =
- if (isValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt)
+ if (isPrimitiveValueClass(pt.typeSymbol) || !isFullyDefined(pt)) arrayType(pt)
else {
val tparam = context.owner freshExistential "" setInfo TypeBounds.upper(pt)
newExistentialType(List(tparam), arrayType(tparam.tpe))
@@ -4362,7 +4407,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// @M maybe the well-kindedness check should be done when checking the type arguments conform to the type parameters' bounds?
val args1 = if (sameLength(args, tparams)) map2Conserve(args, tparams) {
//@M! the polytype denotes the expected kind
- (arg, tparam) => typedHigherKindedType(arg, mode, polyType(tparam.typeParams, AnyClass.tpe))
+ (arg, tparam) => typedHigherKindedType(arg, mode, GenPolyType(tparam.typeParams, AnyClass.tpe))
} else {
//@M this branch is correctly hit for an overloaded polymorphic type. It also has to handle erroneous cases.
// Until the right alternative for an overloaded method is known, be very liberal,
@@ -4682,6 +4727,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
// AnyRef, but the AnyRef type alias is entered after the scala package is
// loaded and completed, so that ScalaObject is unpickled while AnyRef is not
// yet defined )
+ // !!! TODO - revisit now that ScalaObject is gone.
result setType(restpe)
} else { // must not normalize: type application must be (bounds-)checked (during RefChecks), see #2208
// during uncurry (after refchecks), all types are normalized
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 312958feca..cc272b7b8d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -151,11 +151,10 @@ trait Unapplies extends ast.TreeDSL
}
def companionModuleDef(cdef: ClassDef, parents: List[Tree] = Nil, body: List[Tree] = Nil): ModuleDef = atPos(cdef.pos.focus) {
- val allParents = parents :+ gen.scalaScalaObjectConstr
ModuleDef(
Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
cdef.name.toTermName,
- Template(allParents, emptyValDef, NoMods, Nil, List(Nil), body, cdef.impl.pos.focus))
+ Template(parents, emptyValDef, NoMods, Nil, List(Nil), body, cdef.impl.pos.focus))
}
private val caseMods = Modifiers(SYNTHETIC | CASE)
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 622b4db2a2..ce10ee34a2 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -23,7 +23,7 @@ import java.net.MalformedURLException
* @author Stepan Koltsov
*/
object ClassPath {
- def scalaLibrary = locate[ScalaObject]
+ def scalaLibrary = locate[Option[_]]
def scalaCompiler = locate[Global]
def infoFor[T](value: T) = info(value.getClass)
diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala
index fbe92e5d84..f4ce6d6ef1 100755
--- a/src/compiler/scala/tools/nsc/util/DocStrings.scala
+++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala
@@ -26,6 +26,14 @@ object DocStrings {
if (start < str.length && isIdentifierPart(str charAt start)) skipIdent(str, start + 1)
else start
+ /** Returns index of string `str` following `start` skipping
+ * sequence of identifier characters.
+ */
+ def skipTag(str: String, start: Int): Int =
+ if (start < str.length && (str charAt start) == '@') skipIdent(str, start + 1)
+ else start
+
+
/** Returns index of string `str` after `start` skipping longest
* sequence of space and tab characters, possibly also containing
* a single `*` character or the `/``**` sequence.
@@ -68,38 +76,46 @@ object DocStrings {
/** Produces a string index, which is a list of ``sections'', i.e
* pairs of start/end positions of all tagged sections in the string.
- * Every section starts with a `@` and extends to the next `@`, or
- * to the end of the comment string, but excluding the final two
+ * Every section starts with an at sign and extends to the next at sign,
+ * or to the end of the comment string, but excluding the final two
* characters which terminate the comment.
*
* Also take usecases into account - they need to expand until the next
* usecase or the end of the string, as they might include other sections
* of their own
*/
- def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] =
- findAll(str, 0) (idx => str(idx) == '@' && p(idx)) match {
+ def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] = {
+ var indices = findAll(str, 0) (idx => str(idx) == '@' && p(idx))
+ indices = mergeUsecaseSections(str, indices)
+ indices = mergeInheritdocSections(str, indices)
+
+ indices match {
case List() => List()
- case idxs => {
- val idxs2 = mergeUsecaseSections(str, idxs)
- idxs2 zip (idxs2.tail ::: List(str.length - 2))
- }
+ case idxs => idxs zip (idxs.tail ::: List(str.length - 2))
}
+ }
/**
* Merge sections following an usecase into the usecase comment, so they
* can override the parent symbol's sections
*/
def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = {
- idxs.find(str.substring(_).startsWith("@usecase")) match {
- case Some(firstUC) =>
- val commentSections = idxs.take(idxs.indexOf(firstUC))
- val usecaseSections = idxs.drop(idxs.indexOf(firstUC)).filter(str.substring(_).startsWith("@usecase"))
+ idxs.indexWhere(str.substring(_).startsWith("@usecase")) match {
+ case firstUCIndex if firstUCIndex != -1 =>
+ val commentSections = idxs.take(firstUCIndex)
+ val usecaseSections = idxs.drop(firstUCIndex).filter(str.substring(_).startsWith("@usecase"))
commentSections ::: usecaseSections
- case None =>
+ case _ =>
idxs
}
}
+ /**
+ * Merge the inheritdoc sections, as they never make sense on their own
+ */
+ def mergeInheritdocSections(str: String, idxs: List[Int]): List[Int] =
+ idxs.filterNot(str.substring(_).startsWith("@inheritdoc"))
+
/** Does interval `iv` start with given `tag`?
*/
def startsWithTag(str: String, section: (Int, Int), tag: String): Boolean =
@@ -108,12 +124,11 @@ object DocStrings {
def startsWithTag(str: String, start: Int, tag: String): Boolean =
str.startsWith(tag, start) && !isIdentifierPart(str charAt (start + tag.length))
-
/** The first start tag of a list of tag intervals,
* or the end of the whole comment string - 2 if list is empty
*/
def startTag(str: String, sections: List[(Int, Int)]) = sections match {
- case List() => str.length - 2
+ case Nil => str.length - 2
case (start, _) :: _ => start
}
@@ -155,4 +170,46 @@ object DocStrings {
idx
}
}
+
+ /** A map from the section tag to section parameters */
+ def sectionTagMap(str: String, sections: List[(Int, Int)]): Map[String, (Int, Int)] =
+ Map() ++ {
+ for (section <- sections) yield
+ extractSectionTag(str, section) -> section
+ }
+
+ /** Extract the section tag, treating the section tag as an indentifier */
+ def extractSectionTag(str: String, section: (Int, Int)): String =
+ str.substring(section._1, skipTag(str, section._1))
+
+ /** Extract the section parameter */
+ def extractSectionParam(str: String, section: (Int, Int)): String = {
+ assert(str.substring(section._1).startsWith("@param") ||
+ str.substring(section._1).startsWith("@tparam") ||
+ str.substring(section._1).startsWith("@throws"))
+
+ val start = skipWhitespace(str, skipTag(str, section._1))
+ val finish = skipIdent(str, start)
+
+ str.substring(start, finish)
+ }
+
+ /** Extract the section text, except for the tag and comment newlines */
+ def extractSectionText(str: String, section: (Int, Int)): (Int, Int) = {
+ if (str.substring(section._1).startsWith("@param") ||
+ str.substring(section._1).startsWith("@tparam") ||
+ str.substring(section._1).startsWith("@throws"))
+ (skipWhitespace(str, skipIdent(str, skipWhitespace(str, skipTag(str, section._1)))), section._2)
+ else
+ (skipWhitespace(str, skipTag(str, section._1)), section._2)
+ }
+
+ /** Cleanup section text */
+ def cleanupSectionText(str: String) = {
+ var result = str.trim.replaceAll("\n\\s+\\*\\s+", " \n")
+ while (result.endsWith("\n"))
+ result = result.substring(0, str.length - 1)
+ result
+ }
+
}
diff --git a/src/detach/plugin/scala/tools/detach/Detach.scala b/src/detach/plugin/scala/tools/detach/Detach.scala
index fee2c5a273..41a3795a49 100644
--- a/src/detach/plugin/scala/tools/detach/Detach.scala
+++ b/src/detach/plugin/scala/tools/detach/Detach.scala
@@ -734,7 +734,7 @@ abstract class Detach extends PluginComponent
proxyOwner.newClass(clazz.pos, encode(clazz.name.decode + PROXY_SUFFIX))
iface.sourceFile = clazz.sourceFile
iface setFlag (ABSTRACT | TRAIT | INTERFACE) // Java interface
- val iparents = List(ObjectClass.tpe, RemoteClass.tpe, ScalaObjectClass.tpe)
+ val iparents = List(ObjectClass.tpe, RemoteClass.tpe)
iface setInfo ClassInfoType(iparents, newScope, iface)
// methods must throw RemoteException
iface addAnnotation remoteAnnotationInfo
@@ -744,11 +744,9 @@ abstract class Detach extends PluginComponent
iclaz.sourceFile = clazz.sourceFile
iclaz setFlag (SYNTHETIC | FINAL)
// Variant 1: rebind/unbind
- val cparents = List(UnicastRemoteObjectClass.tpe, iface.tpe,
- UnreferencedClass.tpe, ScalaObjectClass.tpe)
+ val cparents = List(UnicastRemoteObjectClass.tpe, iface.tpe, UnreferencedClass.tpe)
// Variant 2: un-/exportObject
- //val cparents = List(ObjectClass.tpe, iface.tpe,
- // UnreferencedClass.tpe, ScalaObjectClass.tpe)
+ //val cparents = List(ObjectClass.tpe, iface.tpe, UnreferencedClass.tpe)
iclaz setInfo ClassInfoType(cparents, newScope, iclaz)
val proxy = (iface, iclaz, new mutable.HashMap[Symbol, Symbol])
proxies(clazz) = proxy
diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala
index cd2c04dbd8..393f0899f4 100644
--- a/src/library/scala/AnyVal.scala
+++ b/src/library/scala/AnyVal.scala
@@ -25,4 +25,8 @@ package scala
* The ''integer types'' include the subrange types as well as [[scala.Int]] and [[scala.Long]].
* The ''floating point types'' are [[scala.Float]] and [[scala.Double]].
*/
-sealed trait AnyVal
+abstract class AnyVal extends Any with NotNull {
+ // disabled for now to make the standard build go through.
+ // Once we have a new strap we can uncomment this and delete the AnyVal_getClass entry in Definitions.
+ def getClass(): Class[_ <: AnyVal] = ???
+}
diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala
index 0adcde3aba..5078e59d28 100644
--- a/src/library/scala/Boolean.scala
+++ b/src/library/scala/Boolean.scala
@@ -107,7 +107,7 @@ final class Boolean extends AnyVal {
*/
def ^(x: Boolean): Boolean = sys.error("stub")
- def getClass(): Class[Boolean] = sys.error("stub")
+ override def getClass(): Class[Boolean] = sys.error("stub")
}
object Boolean extends AnyValCompanion {
diff --git a/src/library/scala/BoxingConversions.scala b/src/library/scala/BoxingConversions.scala
new file mode 100644
index 0000000000..fd1bd6c121
--- /dev/null
+++ b/src/library/scala/BoxingConversions.scala
@@ -0,0 +1,5 @@
+package scala
+abstract class BoxingConversions[Boxed, Unboxed] {
+ def box(x: Unboxed): Boxed
+ def unbox(x: Boxed): Unboxed
+}
diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala
index 4923cc9786..f9c5f6003e 100644
--- a/src/library/scala/Byte.scala
+++ b/src/library/scala/Byte.scala
@@ -590,7 +590,7 @@ final class Byte extends AnyVal {
*/
def %(x: Double): Double = sys.error("stub")
- def getClass(): Class[Byte] = sys.error("stub")
+ override def getClass(): Class[Byte] = sys.error("stub")
}
object Byte extends AnyValCompanion {
diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala
index b4e6445899..3d459782cd 100644
--- a/src/library/scala/Char.scala
+++ b/src/library/scala/Char.scala
@@ -590,7 +590,7 @@ final class Char extends AnyVal {
*/
def %(x: Double): Double = sys.error("stub")
- def getClass(): Class[Char] = sys.error("stub")
+ override def getClass(): Class[Char] = sys.error("stub")
}
object Char extends AnyValCompanion {
diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala
index 68a1a01299..01414265c4 100644
--- a/src/library/scala/Double.scala
+++ b/src/library/scala/Double.scala
@@ -356,7 +356,7 @@ final class Double extends AnyVal {
*/
def %(x: Double): Double = sys.error("stub")
- def getClass(): Class[Double] = sys.error("stub")
+ override def getClass(): Class[Double] = sys.error("stub")
}
object Double extends AnyValCompanion {
diff --git a/src/library/scala/Equals.scala b/src/library/scala/Equals.scala
index 8aff7af175..4545c21e45 100644
--- a/src/library/scala/Equals.scala
+++ b/src/library/scala/Equals.scala
@@ -11,7 +11,7 @@ package scala
/** An interface containing operations for equality.
* The only method not already present in class `AnyRef` is `canEqual`.
*/
-trait Equals {
+trait Equals extends Any {
/** A method that should be called from every well-designed equals method
* that is open to be overridden in a subclass. See Programming in Scala,
* Chapter 28 for discussion and design.
diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala
index 709d73d408..ff5b3cb112 100644
--- a/src/library/scala/Float.scala
+++ b/src/library/scala/Float.scala
@@ -356,7 +356,7 @@ final class Float extends AnyVal {
*/
def %(x: Double): Double = sys.error("stub")
- def getClass(): Class[Float] = sys.error("stub")
+ override def getClass(): Class[Float] = sys.error("stub")
}
object Float extends AnyValCompanion {
diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala
index 519a0486ac..316bbced2d 100644
--- a/src/library/scala/Int.scala
+++ b/src/library/scala/Int.scala
@@ -590,7 +590,7 @@ final class Int extends AnyVal {
*/
def %(x: Double): Double = sys.error("stub")
- def getClass(): Class[Int] = sys.error("stub")
+ override def getClass(): Class[Int] = sys.error("stub")
}
object Int extends AnyValCompanion {
diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala
index 9c7a803f08..ce8618c22a 100644
--- a/src/library/scala/Long.scala
+++ b/src/library/scala/Long.scala
@@ -590,7 +590,7 @@ final class Long extends AnyVal {
*/
def %(x: Double): Double = sys.error("stub")
- def getClass(): Class[Long] = sys.error("stub")
+ override def getClass(): Class[Long] = sys.error("stub")
}
object Long extends AnyValCompanion {
diff --git a/src/library/scala/NotNull.scala b/src/library/scala/NotNull.scala
index d47d47a83e..64f999a932 100644
--- a/src/library/scala/NotNull.scala
+++ b/src/library/scala/NotNull.scala
@@ -6,12 +6,10 @@
** |/ **
\* */
-
-
package scala
/**
* A marker trait for things that are not allowed to be null
* @since 2.5
*/
-trait NotNull {}
+trait NotNull extends Any {}
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index a2ee76500c..b5006e7948 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -215,7 +215,7 @@ object Predef extends LowPriorityImplicits {
throw new IllegalArgumentException("requirement failed: "+ message)
}
- final class Ensuring[A](val __resultOfEnsuring: A) {
+ final class Ensuring[A](val __resultOfEnsuring: A) extends AnyVal {
// `__resultOfEnsuring` must be a public val to allow inlining.
// See comments in ArrowAssoc for more.
@deprecated("Use __resultOfEnsuring instead", "2.10.0")
@@ -226,7 +226,7 @@ object Predef extends LowPriorityImplicits {
def ensuring(cond: A => Boolean): A = { assert(cond(__resultOfEnsuring)); __resultOfEnsuring }
def ensuring(cond: A => Boolean, msg: => Any): A = { assert(cond(__resultOfEnsuring), msg); __resultOfEnsuring }
}
- implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x)
+ @inline implicit def any2Ensuring[A](x: A): Ensuring[A] = new Ensuring(x)
/** `???` can be used for marking methods that remain to be implemented.
* @throws A `NotImplementedError`
@@ -247,7 +247,7 @@ object Predef extends LowPriorityImplicits {
def unapply[A, B, C](x: Tuple3[A, B, C]): Option[Tuple3[A, B, C]] = Some(x)
}
- final class ArrowAssoc[A](val __leftOfArrow: A) {
+ final class ArrowAssoc[A](val __leftOfArrow: A) extends AnyVal {
// `__leftOfArrow` must be a public val to allow inlining. The val
// used to be called `x`, but now goes by `__leftOfArrow`, as that
// reduces the chances of a user's writing `foo.__leftOfArrow` and
@@ -260,7 +260,7 @@ object Predef extends LowPriorityImplicits {
@inline def -> [B](y: B): Tuple2[A, B] = Tuple2(__leftOfArrow, y)
def →[B](y: B): Tuple2[A, B] = ->(y)
}
- implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
+ @inline implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)
// printing and reading -----------------------------------------------
@@ -386,7 +386,8 @@ object Predef extends LowPriorityImplicits {
// Strings and CharSequences --------------------------------------------------------------
implicit def any2stringadd(x: Any) = new runtime.StringAdd(x)
- implicit def augmentString(x: String): StringOps = new StringOps(x)
+ @inline implicit def any2stringfmt(x: Any) = new runtime.StringFormat(x)
+ @inline implicit def augmentString(x: String): StringOps = new StringOps(x)
implicit def unaugmentString(x: StringOps): String = x.repr
implicit def stringCanBuildFrom: CanBuildFrom[String, Char, String] =
diff --git a/src/library/scala/Product.scala b/src/library/scala/Product.scala
index 90ae82b6d0..1459ab9ea5 100644
--- a/src/library/scala/Product.scala
+++ b/src/library/scala/Product.scala
@@ -17,7 +17,7 @@ package scala
* @version 1.0
* @since 2.3
*/
-trait Product extends Equals {
+trait Product extends Any with Equals {
/** The n^th^ element of this product, 0-based. In other words, for a
* product `A(x,,1,,, ..., x,,k,,)`, returns `x,,(n+1),, where `0 < n < k`.
*
diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala
index ab8b0a4505..d268b35f60 100644
--- a/src/library/scala/Product1.scala
+++ b/src/library/scala/Product1.scala
@@ -17,13 +17,13 @@ object Product1 {
/** Product1 is a cartesian product of 1 component.
* @since 2.3
*/
-trait Product1[@specialized(Int, Long, Double) +T1] extends Product {
+trait Product1[@specialized(Int, Long, Double) +T1] extends Any with Product {
/** The arity of this product.
* @return 1
*/
override def productArity = 1
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product1[@specialized(Int, Long, Double) +T1] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case _ => throw new IndexOutOfBoundsException(n.toString())
}
diff --git a/src/library/scala/Product10.scala b/src/library/scala/Product10.scala
index 536fb2fed9..cae9e5a664 100644
--- a/src/library/scala/Product10.scala
+++ b/src/library/scala/Product10.scala
@@ -17,13 +17,13 @@ object Product10 {
/** Product10 is a cartesian product of 10 components.
* @since 2.3
*/
-trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Product {
+trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Any with Product {
/** The arity of this product.
* @return 10
*/
override def productArity = 10
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10] extends Produ
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product11.scala b/src/library/scala/Product11.scala
index 7d49eccc5e..0647b28414 100644
--- a/src/library/scala/Product11.scala
+++ b/src/library/scala/Product11.scala
@@ -17,13 +17,13 @@ object Product11 {
/** Product11 is a cartesian product of 11 components.
* @since 2.3
*/
-trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Product {
+trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends Any with Product {
/** The arity of this product.
* @return 11
*/
override def productArity = 11
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11] extends
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product12.scala b/src/library/scala/Product12.scala
index 0e9c4a01a2..a080aafa7a 100644
--- a/src/library/scala/Product12.scala
+++ b/src/library/scala/Product12.scala
@@ -17,13 +17,13 @@ object Product12 {
/** Product12 is a cartesian product of 12 components.
* @since 2.3
*/
-trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Product {
+trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] extends Any with Product {
/** The arity of this product.
* @return 12
*/
override def productArity = 12
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12] e
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product13.scala b/src/library/scala/Product13.scala
index a0629201d0..425aebf3e7 100644
--- a/src/library/scala/Product13.scala
+++ b/src/library/scala/Product13.scala
@@ -17,13 +17,13 @@ object Product13 {
/** Product13 is a cartesian product of 13 components.
* @since 2.3
*/
-trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Product {
+trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13] extends Any with Product {
/** The arity of this product.
* @return 13
*/
override def productArity = 13
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product14.scala b/src/library/scala/Product14.scala
index 32dda81c3e..3d7e4896ef 100644
--- a/src/library/scala/Product14.scala
+++ b/src/library/scala/Product14.scala
@@ -17,13 +17,13 @@ object Product14 {
/** Product14 is a cartesian product of 14 components.
* @since 2.3
*/
-trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Product {
+trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14] extends Any with Product {
/** The arity of this product.
* @return 14
*/
override def productArity = 14
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product15.scala b/src/library/scala/Product15.scala
index 57851f9870..7bca7a2a1b 100644
--- a/src/library/scala/Product15.scala
+++ b/src/library/scala/Product15.scala
@@ -17,13 +17,13 @@ object Product15 {
/** Product15 is a cartesian product of 15 components.
* @since 2.3
*/
-trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Product {
+trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15] extends Any with Product {
/** The arity of this product.
* @return 15
*/
override def productArity = 15
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product16.scala b/src/library/scala/Product16.scala
index 75076f3b3c..c5042cbc90 100644
--- a/src/library/scala/Product16.scala
+++ b/src/library/scala/Product16.scala
@@ -17,13 +17,13 @@ object Product16 {
/** Product16 is a cartesian product of 16 components.
* @since 2.3
*/
-trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Product {
+trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16] extends Any with Product {
/** The arity of this product.
* @return 16
*/
override def productArity = 16
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product17.scala b/src/library/scala/Product17.scala
index 9ee6072ffe..b5651ec712 100644
--- a/src/library/scala/Product17.scala
+++ b/src/library/scala/Product17.scala
@@ -17,13 +17,13 @@ object Product17 {
/** Product17 is a cartesian product of 17 components.
* @since 2.3
*/
-trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Product {
+trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17] extends Any with Product {
/** The arity of this product.
* @return 17
*/
override def productArity = 17
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product18.scala b/src/library/scala/Product18.scala
index 25d0839af1..088a48ae32 100644
--- a/src/library/scala/Product18.scala
+++ b/src/library/scala/Product18.scala
@@ -17,13 +17,13 @@ object Product18 {
/** Product18 is a cartesian product of 18 components.
* @since 2.3
*/
-trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Product {
+trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18] extends Any with Product {
/** The arity of this product.
* @return 18
*/
override def productArity = 18
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product19.scala b/src/library/scala/Product19.scala
index 5464de7264..4f4a98c6a0 100644
--- a/src/library/scala/Product19.scala
+++ b/src/library/scala/Product19.scala
@@ -17,13 +17,13 @@ object Product19 {
/** Product19 is a cartesian product of 19 components.
* @since 2.3
*/
-trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Product {
+trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19] extends Any with Product {
/** The arity of this product.
* @return 19
*/
override def productArity = 19
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala
index 8097245926..eb67e5d46e 100644
--- a/src/library/scala/Product2.scala
+++ b/src/library/scala/Product2.scala
@@ -17,13 +17,13 @@ object Product2 {
/** Product2 is a cartesian product of 2 components.
* @since 2.3
*/
-trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Product {
+trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product {
/** The arity of this product.
* @return 2
*/
override def productArity = 2
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Doub
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case _ => throw new IndexOutOfBoundsException(n.toString())
diff --git a/src/library/scala/Product20.scala b/src/library/scala/Product20.scala
index b094e09aca..80f63f1bb4 100644
--- a/src/library/scala/Product20.scala
+++ b/src/library/scala/Product20.scala
@@ -17,13 +17,13 @@ object Product20 {
/** Product20 is a cartesian product of 20 components.
* @since 2.3
*/
-trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Product {
+trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20] extends Any with Product {
/** The arity of this product.
* @return 20
*/
override def productArity = 20
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product21.scala b/src/library/scala/Product21.scala
index fa06cfb438..7056844271 100644
--- a/src/library/scala/Product21.scala
+++ b/src/library/scala/Product21.scala
@@ -17,13 +17,13 @@ object Product21 {
/** Product21 is a cartesian product of 21 components.
* @since 2.3
*/
-trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Product {
+trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21] extends Any with Product {
/** The arity of this product.
* @return 21
*/
override def productArity = 21
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product22.scala b/src/library/scala/Product22.scala
index 46038bf1a2..05e95f92dd 100644
--- a/src/library/scala/Product22.scala
+++ b/src/library/scala/Product22.scala
@@ -17,13 +17,13 @@ object Product22 {
/** Product22 is a cartesian product of 22 components.
* @since 2.3
*/
-trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Product {
+trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +T13, +T14, +T15, +T16, +T17, +T18, +T19, +T20, +T21, +T22] extends Any with Product {
/** The arity of this product.
* @return 22
*/
override def productArity = 22
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12, +
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product3.scala b/src/library/scala/Product3.scala
index 3a4cd8fc5e..91556bb962 100644
--- a/src/library/scala/Product3.scala
+++ b/src/library/scala/Product3.scala
@@ -17,13 +17,13 @@ object Product3 {
/** Product3 is a cartesian product of 3 components.
* @since 2.3
*/
-trait Product3[+T1, +T2, +T3] extends Product {
+trait Product3[+T1, +T2, +T3] extends Any with Product {
/** The arity of this product.
* @return 3
*/
override def productArity = 3
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product3[+T1, +T2, +T3] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product4.scala b/src/library/scala/Product4.scala
index a4d47457fa..1f9070c155 100644
--- a/src/library/scala/Product4.scala
+++ b/src/library/scala/Product4.scala
@@ -17,13 +17,13 @@ object Product4 {
/** Product4 is a cartesian product of 4 components.
* @since 2.3
*/
-trait Product4[+T1, +T2, +T3, +T4] extends Product {
+trait Product4[+T1, +T2, +T3, +T4] extends Any with Product {
/** The arity of this product.
* @return 4
*/
override def productArity = 4
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product4[+T1, +T2, +T3, +T4] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product5.scala b/src/library/scala/Product5.scala
index 9f25e70af0..52dd284f55 100644
--- a/src/library/scala/Product5.scala
+++ b/src/library/scala/Product5.scala
@@ -17,13 +17,13 @@ object Product5 {
/** Product5 is a cartesian product of 5 components.
* @since 2.3
*/
-trait Product5[+T1, +T2, +T3, +T4, +T5] extends Product {
+trait Product5[+T1, +T2, +T3, +T4, +T5] extends Any with Product {
/** The arity of this product.
* @return 5
*/
override def productArity = 5
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product5[+T1, +T2, +T3, +T4, +T5] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product6.scala b/src/library/scala/Product6.scala
index 87fd318c68..9624bdbe3e 100644
--- a/src/library/scala/Product6.scala
+++ b/src/library/scala/Product6.scala
@@ -17,13 +17,13 @@ object Product6 {
/** Product6 is a cartesian product of 6 components.
* @since 2.3
*/
-trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Product {
+trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Any with Product {
/** The arity of this product.
* @return 6
*/
override def productArity = 6
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product6[+T1, +T2, +T3, +T4, +T5, +T6] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product7.scala b/src/library/scala/Product7.scala
index d074503315..36d4b149db 100644
--- a/src/library/scala/Product7.scala
+++ b/src/library/scala/Product7.scala
@@ -17,13 +17,13 @@ object Product7 {
/** Product7 is a cartesian product of 7 components.
* @since 2.3
*/
-trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Product {
+trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Any with Product {
/** The arity of this product.
* @return 7
*/
override def productArity = 7
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product7[+T1, +T2, +T3, +T4, +T5, +T6, +T7] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product8.scala b/src/library/scala/Product8.scala
index bd6150c235..28c78f9c89 100644
--- a/src/library/scala/Product8.scala
+++ b/src/library/scala/Product8.scala
@@ -17,13 +17,13 @@ object Product8 {
/** Product8 is a cartesian product of 8 components.
* @since 2.3
*/
-trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Product {
+trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Any with Product {
/** The arity of this product.
* @return 8
*/
override def productArity = 8
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Product9.scala b/src/library/scala/Product9.scala
index 1f042944cc..d69c550abe 100644
--- a/src/library/scala/Product9.scala
+++ b/src/library/scala/Product9.scala
@@ -17,13 +17,13 @@ object Product9 {
/** Product9 is a cartesian product of 9 components.
* @since 2.3
*/
-trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Product {
+trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Any with Product {
/** The arity of this product.
* @return 9
*/
override def productArity = 9
-
+
/** Returns the n-th projection of this product if 0 < n <= productArity,
* otherwise throws an `IndexOutOfBoundsException`.
*
@@ -33,7 +33,7 @@ trait Product9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] extends Product {
*/
@throws(classOf[IndexOutOfBoundsException])
- override def productElement(n: Int) = n match {
+ override def productElement(n: Int) = n match {
case 0 => _1
case 1 => _2
case 2 => _3
diff --git a/src/library/scala/Proxy.scala b/src/library/scala/Proxy.scala
index 383ff5b3bb..604b2a299f 100644
--- a/src/library/scala/Proxy.scala
+++ b/src/library/scala/Proxy.scala
@@ -22,13 +22,15 @@ package scala
* @author Matthias Zenger
* @version 1.0, 26/04/2004
*/
-trait Proxy {
+trait Proxy extends Any {
def self: Any
override def hashCode: Int = self.hashCode
override def equals(that: Any): Boolean = that match {
- case null => false
- case x: AnyRef => (x eq this) || (x eq self.asInstanceOf[AnyRef]) || (x equals self)
+ case null => false
+ case _ =>
+ val x = that.asInstanceOf[AnyRef]
+ (x eq this.asInstanceOf[AnyRef]) || (x eq self.asInstanceOf[AnyRef]) || (x equals self)
}
override def toString = "" + self
}
@@ -36,7 +38,7 @@ trait Proxy {
object Proxy {
/** A proxy which exposes the type it is proxying for via a type parameter.
*/
- trait Typed[T] extends Proxy {
+ trait Typed[T] extends Any with Proxy {
def self: T
}
}
diff --git a/src/library/scala/ScalaObject.scala b/src/library/scala/ScalaObject.scala
deleted file mode 100644
index 8da0ab2cba..0000000000
--- a/src/library/scala/ScalaObject.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala
-
-trait ScalaObject extends java.lang.Object
diff --git a/src/library/scala/Serializable.scala b/src/library/scala/Serializable.scala
index 9be258bb83..9b9456e0a0 100644
--- a/src/library/scala/Serializable.scala
+++ b/src/library/scala/Serializable.scala
@@ -11,4 +11,4 @@ package scala
/**
* Classes extending this trait are serializable across platforms (Java, .NET).
*/
-trait Serializable extends java.io.Serializable
+trait Serializable extends Any with java.io.Serializable
diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala
index a9210d3555..5664c3b44c 100644
--- a/src/library/scala/Short.scala
+++ b/src/library/scala/Short.scala
@@ -590,7 +590,7 @@ final class Short extends AnyVal {
*/
def %(x: Double): Double = sys.error("stub")
- def getClass(): Class[Short] = sys.error("stub")
+ override def getClass(): Class[Short] = sys.error("stub")
}
object Short extends AnyValCompanion {
diff --git a/src/library/scala/Tuple1.scala b/src/library/scala/Tuple1.scala
index 6d31d35e51..02fdd0cba5 100644
--- a/src/library/scala/Tuple1.scala
+++ b/src/library/scala/Tuple1.scala
@@ -19,5 +19,5 @@ case class Tuple1[@specialized(Int, Long, Double) +T1](_1: T1)
extends Product1[T1]
{
override def toString() = "(" + _1 + ")"
-
+
}
diff --git a/src/library/scala/Tuple10.scala b/src/library/scala/Tuple10.scala
index 10d554d467..ba2a02a8b2 100644
--- a/src/library/scala/Tuple10.scala
+++ b/src/library/scala/Tuple10.scala
@@ -28,5 +28,5 @@ case class Tuple10[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10](_1: T1, _2
extends Product10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + ")"
-
+
}
diff --git a/src/library/scala/Tuple11.scala b/src/library/scala/Tuple11.scala
index 2065e4f017..7f51d172d4 100644
--- a/src/library/scala/Tuple11.scala
+++ b/src/library/scala/Tuple11.scala
@@ -29,5 +29,5 @@ case class Tuple11[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11](_1:
extends Product11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + ")"
-
+
}
diff --git a/src/library/scala/Tuple12.scala b/src/library/scala/Tuple12.scala
index a463986752..4bbc6a0eab 100644
--- a/src/library/scala/Tuple12.scala
+++ b/src/library/scala/Tuple12.scala
@@ -31,5 +31,5 @@ case class Tuple12[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 +
"," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + ")"
-
+
}
diff --git a/src/library/scala/Tuple13.scala b/src/library/scala/Tuple13.scala
index 2bee0d69ad..77bd59bf2e 100644
--- a/src/library/scala/Tuple13.scala
+++ b/src/library/scala/Tuple13.scala
@@ -32,5 +32,5 @@ case class Tuple13[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 +
"," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + ")"
-
+
}
diff --git a/src/library/scala/Tuple14.scala b/src/library/scala/Tuple14.scala
index 60f7c51e64..bf7a4ce016 100644
--- a/src/library/scala/Tuple14.scala
+++ b/src/library/scala/Tuple14.scala
@@ -33,5 +33,5 @@ case class Tuple14[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 +
"," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + ")"
-
+
}
diff --git a/src/library/scala/Tuple15.scala b/src/library/scala/Tuple15.scala
index fc8e30580b..582c359bc6 100644
--- a/src/library/scala/Tuple15.scala
+++ b/src/library/scala/Tuple15.scala
@@ -34,5 +34,5 @@ case class Tuple15[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 +
"," + _8 + "," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + ")"
-
+
}
diff --git a/src/library/scala/Tuple16.scala b/src/library/scala/Tuple16.scala
index 80181f6648..a1e9a790ff 100644
--- a/src/library/scala/Tuple16.scala
+++ b/src/library/scala/Tuple16.scala
@@ -35,5 +35,5 @@ case class Tuple16[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 +
"," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + ")"
-
+
}
diff --git a/src/library/scala/Tuple17.scala b/src/library/scala/Tuple17.scala
index 6236122be2..f531766c18 100644
--- a/src/library/scala/Tuple17.scala
+++ b/src/library/scala/Tuple17.scala
@@ -36,5 +36,5 @@ case class Tuple17[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 +
"," + _9 + "," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + ")"
-
+
}
diff --git a/src/library/scala/Tuple18.scala b/src/library/scala/Tuple18.scala
index dd6a819ac5..a96db25e4b 100644
--- a/src/library/scala/Tuple18.scala
+++ b/src/library/scala/Tuple18.scala
@@ -37,5 +37,5 @@ case class Tuple18[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 +
"," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + ")"
-
+
}
diff --git a/src/library/scala/Tuple19.scala b/src/library/scala/Tuple19.scala
index 65f0fd22cf..718280d68a 100644
--- a/src/library/scala/Tuple19.scala
+++ b/src/library/scala/Tuple19.scala
@@ -38,5 +38,5 @@ case class Tuple19[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 +
"," + _10 + "," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + ")"
-
+
}
diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala
index 684d2266e8..b1befca4fa 100644
--- a/src/library/scala/Tuple2.scala
+++ b/src/library/scala/Tuple2.scala
@@ -23,7 +23,7 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s
extends Product2[T1, T2]
{
override def toString() = "(" + _1 + "," + _2 + ")"
-
+
/** Swaps the elements of this `Tuple`.
* @return a new Tuple where the first element is the second element of this Tuple and the
* second element is the first element of this Tuple.
diff --git a/src/library/scala/Tuple20.scala b/src/library/scala/Tuple20.scala
index cf3626909d..4a44c0bb89 100644
--- a/src/library/scala/Tuple20.scala
+++ b/src/library/scala/Tuple20.scala
@@ -39,5 +39,5 @@ case class Tuple20[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 +
"," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + ")"
-
+
}
diff --git a/src/library/scala/Tuple21.scala b/src/library/scala/Tuple21.scala
index 78b9c585c6..580a169e39 100644
--- a/src/library/scala/Tuple21.scala
+++ b/src/library/scala/Tuple21.scala
@@ -40,5 +40,5 @@ case class Tuple21[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 +
"," + _11 + "," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + "," + _21 + ")"
-
+
}
diff --git a/src/library/scala/Tuple22.scala b/src/library/scala/Tuple22.scala
index 0993dfbbc3..fd3392ddea 100644
--- a/src/library/scala/Tuple22.scala
+++ b/src/library/scala/Tuple22.scala
@@ -41,5 +41,5 @@ case class Tuple22[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9, +T10, +T11, +T12
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + "," + _10 + "," + _11 +
"," + _12 + "," + _13 + "," + _14 + "," + _15 + "," + _16 + "," + _17 + "," + _18 + "," + _19 + "," + _20 + "," + _21 + "," + _22 + ")"
-
+
}
diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala
index dfa0c962a2..0d5399308b 100644
--- a/src/library/scala/Tuple3.scala
+++ b/src/library/scala/Tuple3.scala
@@ -24,7 +24,7 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3)
extends Product3[T1, T2, T3]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")"
-
+
@deprecated("Use `zipped` instead.", "2.9.0")
def zip[Repr1, El1, El2, El3, To](implicit w1: T1 => TLike[El1, Repr1],
diff --git a/src/library/scala/Tuple4.scala b/src/library/scala/Tuple4.scala
index a919072c88..a859078bcf 100644
--- a/src/library/scala/Tuple4.scala
+++ b/src/library/scala/Tuple4.scala
@@ -22,5 +22,5 @@ case class Tuple4[+T1, +T2, +T3, +T4](_1: T1, _2: T2, _3: T3, _4: T4)
extends Product4[T1, T2, T3, T4]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + ")"
-
+
}
diff --git a/src/library/scala/Tuple5.scala b/src/library/scala/Tuple5.scala
index 6a94f48ab4..1edfb673ee 100644
--- a/src/library/scala/Tuple5.scala
+++ b/src/library/scala/Tuple5.scala
@@ -23,5 +23,5 @@ case class Tuple5[+T1, +T2, +T3, +T4, +T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T
extends Product5[T1, T2, T3, T4, T5]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + ")"
-
+
}
diff --git a/src/library/scala/Tuple6.scala b/src/library/scala/Tuple6.scala
index 34f8224627..5b74937e58 100644
--- a/src/library/scala/Tuple6.scala
+++ b/src/library/scala/Tuple6.scala
@@ -24,5 +24,5 @@ case class Tuple6[+T1, +T2, +T3, +T4, +T5, +T6](_1: T1, _2: T2, _3: T3, _4: T4,
extends Product6[T1, T2, T3, T4, T5, T6]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + ")"
-
+
}
diff --git a/src/library/scala/Tuple7.scala b/src/library/scala/Tuple7.scala
index 6fc3477ba2..a7f572e9f0 100644
--- a/src/library/scala/Tuple7.scala
+++ b/src/library/scala/Tuple7.scala
@@ -25,5 +25,5 @@ case class Tuple7[+T1, +T2, +T3, +T4, +T5, +T6, +T7](_1: T1, _2: T2, _3: T3, _4:
extends Product7[T1, T2, T3, T4, T5, T6, T7]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + ")"
-
+
}
diff --git a/src/library/scala/Tuple8.scala b/src/library/scala/Tuple8.scala
index 1e21b684fc..9bb427d689 100644
--- a/src/library/scala/Tuple8.scala
+++ b/src/library/scala/Tuple8.scala
@@ -26,5 +26,5 @@ case class Tuple8[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8](_1: T1, _2: T2, _3: T3
extends Product8[T1, T2, T3, T4, T5, T6, T7, T8]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + ")"
-
+
}
diff --git a/src/library/scala/Tuple9.scala b/src/library/scala/Tuple9.scala
index 453cea31a1..4d50539e0c 100644
--- a/src/library/scala/Tuple9.scala
+++ b/src/library/scala/Tuple9.scala
@@ -27,5 +27,5 @@ case class Tuple9[+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9](_1: T1, _2: T2, _
extends Product9[T1, T2, T3, T4, T5, T6, T7, T8, T9]
{
override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + "," + _6 + "," + _7 + "," + _8 + "," + _9 + ")"
-
+
}
diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala
index 57970b021b..f6ed0121ab 100644
--- a/src/library/scala/Unit.scala
+++ b/src/library/scala/Unit.scala
@@ -17,7 +17,7 @@ package scala
* method which is declared `void`.
*/
final class Unit extends AnyVal {
- def getClass(): Class[Unit] = sys.error("stub")
+ override def getClass(): Class[Unit] = sys.error("stub")
}
object Unit extends AnyValCompanion {
diff --git a/src/library/scala/collection/GenIterableLike.scala b/src/library/scala/collection/GenIterableLike.scala
index 18132f0a7b..7e68733afd 100644
--- a/src/library/scala/collection/GenIterableLike.scala
+++ b/src/library/scala/collection/GenIterableLike.scala
@@ -34,7 +34,7 @@ import generic.{ CanBuildFrom => CBF, _ }
* This is a base trait for all Scala collections that define an `iterator`
* method to step through one-by-one the collection's elements.
*/
-trait GenIterableLike[+A, +Repr] extends GenTraversableLike[A, Repr] {
+trait GenIterableLike[+A, +Repr] extends Any with GenTraversableLike[A, Repr] {
def iterator: Iterator[A]
diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala
index 63e9543711..cb0e96fcbb 100644
--- a/src/library/scala/collection/GenSeqLike.scala
+++ b/src/library/scala/collection/GenSeqLike.scala
@@ -30,7 +30,7 @@ import annotation.bridge
* Sequences are special cases of iterable collections of class `Iterable`.
* Unlike iterables, sequences always have a defined order of elements.
*/
-trait GenSeqLike[+A, +Repr] extends GenIterableLike[A, Repr] with Equals with Parallelizable[A, parallel.ParSeq[A]] {
+trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equals with Parallelizable[A, parallel.ParSeq[A]] {
def seq: Seq[A]
/** Selects an element by its index in the $coll.
diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala
index 1dcc0bdac7..dd5f602c41 100644
--- a/src/library/scala/collection/GenTraversableLike.scala
+++ b/src/library/scala/collection/GenTraversableLike.scala
@@ -53,7 +53,7 @@ import annotation.migration
* @author Aleksandar Prokopec
* @since 2.9
*/
-trait GenTraversableLike[+A, +Repr] extends GenTraversableOnce[A] with Parallelizable[A, parallel.ParIterable[A]] {
+trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with Parallelizable[A, parallel.ParIterable[A]] {
def repr: Repr
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 305f8d768d..67ea4cdb00 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -41,7 +41,7 @@ package scala.collection
* @author Aleksandar Prokopec
* @since 2.9
*/
-trait GenTraversableOnce[+A] {
+trait GenTraversableOnce[+A] extends Any {
def foreach[U](f: A => U): Unit
@@ -124,6 +124,7 @@ trait GenTraversableOnce[+A] {
* scala> val b = (a /:\ 5)(_+_)
* b: Int = 15
* }}}*/
+ @deprecated("use fold instead")
def /:\[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = fold(z)(op)
/** Applies a binary operator to a start value and all elements of this $coll,
diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala
index baf5606ab5..d1f7d1cb36 100644
--- a/src/library/scala/collection/IndexedSeqLike.scala
+++ b/src/library/scala/collection/IndexedSeqLike.scala
@@ -37,7 +37,7 @@ import scala.annotation.tailrec
* @define willNotTerminateInf
* @define mayNotTerminateInf
*/
-trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] {
+trait IndexedSeqLike[+A, +Repr] extends Any with SeqLike[A, Repr] {
self =>
def seq: IndexedSeq[A]
diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala
index 196e77c91b..9d03a11db9 100755
--- a/src/library/scala/collection/IndexedSeqOptimized.scala
+++ b/src/library/scala/collection/IndexedSeqOptimized.scala
@@ -22,7 +22,7 @@ import scala.annotation.tailrec
* @define willNotTerminateInf
* @define mayNotTerminateInf
*/
-trait IndexedSeqOptimized[+A, +Repr] extends IndexedSeqLike[A, Repr] { self =>
+trait IndexedSeqOptimized[+A, +Repr] extends Any with IndexedSeqLike[A, Repr] { self =>
override /*IterableLike*/
def isEmpty: Boolean = { length == 0 }
diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala
index 4b0c5662d8..73d4efe125 100644
--- a/src/library/scala/collection/IterableLike.scala
+++ b/src/library/scala/collection/IterableLike.scala
@@ -49,7 +49,7 @@ import annotation.bridge
* @define Coll Iterable
* @define coll iterable collection
*/
-trait IterableLike[+A, +Repr] extends Equals with TraversableLike[A, Repr] with GenIterableLike[A, Repr] {
+trait IterableLike[+A, +Repr] extends Any with Equals with TraversableLike[A, Repr] with GenIterableLike[A, Repr] {
self =>
override protected[this] def thisCollection: Iterable[A] = this.asInstanceOf[Iterable[A]]
diff --git a/src/library/scala/collection/Parallelizable.scala b/src/library/scala/collection/Parallelizable.scala
index 59b37aff96..5bcefb81b2 100644
--- a/src/library/scala/collection/Parallelizable.scala
+++ b/src/library/scala/collection/Parallelizable.scala
@@ -17,7 +17,7 @@ import parallel.Combiner
* @tparam A the type of the elements in the collection
* @tparam ParRepr the actual type of the collection, which has to be parallel
*/
-trait Parallelizable[+A, +ParRepr <: Parallel] {
+trait Parallelizable[+A, +ParRepr <: Parallel] extends Any {
def seq: TraversableOnce[A]
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index b51a37cf9e..526ea7e240 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -59,7 +59,7 @@ import scala.math.Ordering
* @define orderDependent
* @define orderDependentFold
*/
-trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with GenSeqLike[A, Repr] with Parallelizable[A, ParSeq[A]] { self =>
+trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[A, Repr] with Parallelizable[A, ParSeq[A]] { self =>
override protected[this] def thisCollection: Seq[A] = this.asInstanceOf[Seq[A]]
override protected[this] def toCollection(repr: Repr): Seq[A] = repr.asInstanceOf[Seq[A]]
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 36d45c0c8a..0da1cfb913 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -64,7 +64,8 @@ import parallel.ParIterable
* @define Coll Traversable
* @define coll traversable collection
*/
-trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
+trait TraversableLike[+A, +Repr] extends Any
+ with HasNewBuilder[A, Repr]
with FilterMonadic[A, Repr]
with TraversableOnce[A]
with GenTraversableLike[A, Repr]
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index 5bb2e563f6..62ea692b90 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -56,7 +56,7 @@ import annotation.unchecked.{ uncheckedVariance => uV }
*
* Note: will not terminate for infinite-sized collections.
*/
-trait TraversableOnce[+A] extends GenTraversableOnce[A] {
+trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
self =>
/** Self-documenting abstract methods. */
@@ -360,6 +360,7 @@ trait TraversableOnce[+A] extends GenTraversableOnce[A] {
object TraversableOnce {
implicit def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T]
implicit def wrapTraversableOnce[A](trav: TraversableOnce[A]) = new MonadOps(trav)
+ implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity
implicit def flattenTraversableOnce[A, CC[_]](travs: TraversableOnce[CC[A]])(implicit ev: CC[A] => TraversableOnce[A]) =
new FlattenOps[A](travs map ev)
@@ -391,6 +392,8 @@ object TraversableOnce {
}
}
+ class ForceImplicitAmbiguity
+
class MonadOps[+A](trav: TraversableOnce[A]) {
def map[B](f: A => B): TraversableOnce[B] = trav.toIterator map f
def flatMap[B](f: A => GenTraversableOnce[B]): TraversableOnce[B] = trav.toIterator flatMap f
diff --git a/src/library/scala/collection/generic/FilterMonadic.scala b/src/library/scala/collection/generic/FilterMonadic.scala
index 4d6d9ec6a3..d79112d616 100755
--- a/src/library/scala/collection/generic/FilterMonadic.scala
+++ b/src/library/scala/collection/generic/FilterMonadic.scala
@@ -12,7 +12,7 @@ package scala.collection.generic
/** A template trait that contains just the `map`, `flatMap`, `foreach` and `withFilter` methods
* of trait `TraversableLike`.
*/
-trait FilterMonadic[+A, +Repr] {
+trait FilterMonadic[+A, +Repr] extends Any {
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
def flatMap[B, That](f: A => collection.GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That
def foreach[U](f: A => U): Unit
diff --git a/src/library/scala/collection/generic/HasNewBuilder.scala b/src/library/scala/collection/generic/HasNewBuilder.scala
index 6154a56441..8f0ce01911 100755
--- a/src/library/scala/collection/generic/HasNewBuilder.scala
+++ b/src/library/scala/collection/generic/HasNewBuilder.scala
@@ -10,7 +10,7 @@ package generic
import mutable.Builder
-trait HasNewBuilder[+A, +Repr] {
+trait HasNewBuilder[+A, +Repr] extends Any {
/** The builder that builds instances of Repr */
protected[this] def newBuilder: Builder[A, Repr]
}
diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala
index 9b52c8805c..f9697565de 100644
--- a/src/library/scala/collection/immutable/StringLike.scala
+++ b/src/library/scala/collection/immutable/StringLike.scala
@@ -40,7 +40,7 @@ import StringLike._
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-trait StringLike[+Repr] extends collection.IndexedSeqOptimized[Char, Repr] with Ordered[String] {
+trait StringLike[+Repr] extends Any with collection.IndexedSeqOptimized[Char, Repr] with Ordered[String] {
self =>
/** Creates a string builder buffer as builder for this class */
diff --git a/src/library/scala/collection/immutable/StringOps.scala b/src/library/scala/collection/immutable/StringOps.scala
index 8612357db9..97609b4c4d 100644
--- a/src/library/scala/collection/immutable/StringOps.scala
+++ b/src/library/scala/collection/immutable/StringOps.scala
@@ -28,7 +28,7 @@ import mutable.StringBuilder
* @define Coll StringOps
* @define coll string
*/
-final class StringOps(override val repr: String) extends StringLike[String] {
+final class StringOps(override val repr: String) extends AnyVal with StringLike[String] {
override protected[this] def thisCollection: WrappedString = new WrappedString(repr)
override protected[this] def toCollection(repr: String): WrappedString = new WrappedString(repr)
diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala
index f72ba78446..f0e4c79abf 100644
--- a/src/library/scala/collection/mutable/ArrayBuilder.scala
+++ b/src/library/scala/collection/mutable/ArrayBuilder.scala
@@ -76,7 +76,7 @@ object ArrayBuilder {
this
}
- override def ++=(xs: TraversableOnce[T]): this.type = (xs: AnyRef) match {
+ override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match {
case xs: WrappedArray.ofRef[_] =>
ensureSize(this.size + xs.length)
Array.copy(xs.array, 0, elems, this.size, xs.length)
diff --git a/src/library/scala/collection/mutable/Ctrie.scala b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala
index cbec118aa9..1a44c8e423 100644
--- a/src/library/scala/collection/mutable/Ctrie.scala
+++ b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala
@@ -13,7 +13,7 @@ package mutable
import java.util.concurrent.atomic._
import collection.immutable.{ ListMap => ImmutableListMap }
-import collection.parallel.mutable.ParCtrie
+import collection.parallel.mutable.ParConcurrentTrieMap
import generic._
import annotation.tailrec
import annotation.switch
@@ -31,16 +31,16 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
@inline final def CAS(old: MainNode[K, V], n: MainNode[K, V]) = INodeBase.updater.compareAndSet(this, old, n)
- final def gcasRead(ct: Ctrie[K, V]): MainNode[K, V] = GCAS_READ(ct)
+ final def gcasRead(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = GCAS_READ(ct)
- @inline final def GCAS_READ(ct: Ctrie[K, V]): MainNode[K, V] = {
+ @inline final def GCAS_READ(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = {
val m = /*READ*/mainnode
val prevval = /*READ*/m.prev
if (prevval eq null) m
else GCAS_Complete(m, ct)
}
- @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: Ctrie[K, V]): MainNode[K, V] = if (m eq null) null else {
+ @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = if (m eq null) null else {
// complete the GCAS
val prev = /*READ*/m.prev
val ctr = ct.readRoot(true)
@@ -72,7 +72,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: Ctrie[K, V]): Boolean = {
+ @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): Boolean = {
n.WRITE_PREV(old)
if (CAS(old, n)) {
GCAS_Complete(n, ct)
@@ -86,7 +86,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
nin
}
- final def copyToGen(ngen: Gen, ct: Ctrie[K, V]) = {
+ final def copyToGen(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
val nin = new INode[K, V](ngen)
val main = GCAS_READ(ct)
nin.WRITE(main)
@@ -97,7 +97,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return true if successful, false otherwise
*/
- @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Boolean = {
+ @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Boolean = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -143,7 +143,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param cond null - don't care if the key was there; KEY_ABSENT - key wasn't there; KEY_PRESENT - key was there; other value `v` - key must be bound to `v`
* @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key)
*/
- @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = {
+ @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -233,7 +233,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return null if no value has been found, RESTART if the operation wasn't successful, or any other value otherwise
*/
- @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): AnyRef = {
+ @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): AnyRef = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -276,7 +276,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param v if null, will remove the key irregardless of the value; otherwise removes only if binding contains that exact key and value
* @return null if not successful, an Option[V] indicating the previous value otherwise
*/
- final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = {
+ final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -352,7 +352,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- private def clean(nd: INode[K, V], ct: Ctrie[K, V], lev: Int) {
+ private def clean(nd: INode[K, V], ct: ConcurrentTrieMap[K, V], lev: Int) {
val m = nd.GCAS_READ(ct)
m match {
case cn: CNode[K, V] => nd.GCAS(cn, cn.toCompressed(ct, lev, gen), ct)
@@ -360,9 +360,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- final def isNullInode(ct: Ctrie[K, V]) = GCAS_READ(ct) eq null
+ final def isNullInode(ct: ConcurrentTrieMap[K, V]) = GCAS_READ(ct) eq null
- final def cachedSize(ct: Ctrie[K, V]): Int = {
+ final def cachedSize(ct: ConcurrentTrieMap[K, V]): Int = {
val m = GCAS_READ(ct)
m.cachedSize(ct)
}
@@ -438,7 +438,7 @@ extends MainNode[K, V] {
if (updmap.size > 1) new LNode(updmap)
else {
val (k, v) = updmap.iterator.next
- new TNode(k, v, Ctrie.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
+ new TNode(k, v, ConcurrentTrieMap.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
}
}
def get(k: K) = listmap.get(k)
@@ -455,7 +455,7 @@ extends CNodeBase[K, V] {
val currsz = READ_SIZE()
if (currsz != -1) currsz
else {
- val sz = computeSize(ct.asInstanceOf[Ctrie[K, V]])
+ val sz = computeSize(ct.asInstanceOf[ConcurrentTrieMap[K, V]])
while (READ_SIZE() == -1) CAS_SIZE(-1, sz)
READ_SIZE()
}
@@ -466,7 +466,7 @@ extends CNodeBase[K, V] {
// => if there are concurrent size computations, they start
// at different positions, so they are more likely to
// to be independent
- private def computeSize(ct: Ctrie[K, V]): Int = {
+ private def computeSize(ct: ConcurrentTrieMap[K, V]): Int = {
var i = 0
var sz = 0
val offset = math.abs(util.Random.nextInt()) % array.length
@@ -511,7 +511,7 @@ extends CNodeBase[K, V] {
/** Returns a copy of this cnode such that all the i-nodes below it are copied
* to the specified generation `ngen`.
*/
- final def renewed(ngen: Gen, ct: Ctrie[K, V]) = {
+ final def renewed(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
var i = 0
val arr = array
val len = arr.length
@@ -542,7 +542,7 @@ extends CNodeBase[K, V] {
// returns the version of this node with at least some null-inodes
// removed (those existing when the op began)
// - if there are only null-i-nodes below, returns null
- final def toCompressed(ct: Ctrie[K, V], lev: Int, gen: Gen) = {
+ final def toCompressed(ct: ConcurrentTrieMap[K, V], lev: Int, gen: Gen) = {
var bmp = bitmap
var i = 0
val arr = array
@@ -594,7 +594,7 @@ private[mutable] object CNode {
val yidx = (yhc >>> lev) & 0x1f
val bmp = (1 << xidx) | (1 << yidx)
if (xidx == yidx) {
- val subinode = new INode[K, V](gen)//(Ctrie.inodeupdater)
+ val subinode = new INode[K, V](gen)//(ConcurrentTrieMap.inodeupdater)
subinode.mainnode = dual(x, xhc, y, yhc, lev + 5, gen)
new CNode(bmp, Array(subinode), gen)
} else {
@@ -613,7 +613,7 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai
}
-/** A concurrent hash-trie or Ctrie is a concurrent thread-safe lock-free
+/** A concurrent hash-trie or ConcurrentTrieMap is a concurrent thread-safe lock-free
* implementation of a hash array mapped trie. It is used to implement the
* concurrent map abstraction. It has particularly scalable concurrent insert
* and remove operations and is memory-efficient. It supports O(1), atomic,
@@ -627,20 +627,20 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai
* @since 2.10
*/
@SerialVersionUID(0L - 6402774413839597105L)
-final class Ctrie[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[Ctrie[K, V], AnyRef])
+final class ConcurrentTrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[ConcurrentTrieMap[K, V], AnyRef])
extends ConcurrentMap[K, V]
- with MapLike[K, V, Ctrie[K, V]]
- with CustomParallelizable[(K, V), ParCtrie[K, V]]
+ with MapLike[K, V, ConcurrentTrieMap[K, V]]
+ with CustomParallelizable[(K, V), ParConcurrentTrieMap[K, V]]
with Serializable
{
- import Ctrie.computeHash
+ import ConcurrentTrieMap.computeHash
private var rootupdater = rtupd
@volatile var root = r
def this() = this(
INode.newRootNode,
- AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root")
+ AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
)
/* internal methods */
@@ -652,22 +652,22 @@ extends ConcurrentMap[K, V]
out.writeObject(k)
out.writeObject(v)
}
- out.writeObject(CtrieSerializationEnd)
+ out.writeObject(ConcurrentTrieMapSerializationEnd)
}
private def readObject(in: java.io.ObjectInputStream) {
root = INode.newRootNode
- rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root")
+ rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
var obj: AnyRef = null
do {
obj = in.readObject()
- if (obj != CtrieSerializationEnd) {
+ if (obj != ConcurrentTrieMapSerializationEnd) {
val k = obj.asInstanceOf[K]
val v = in.readObject().asInstanceOf[V]
update(k, v)
}
- } while (obj != CtrieSerializationEnd)
+ } while (obj != ConcurrentTrieMapSerializationEnd)
}
@inline final def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv)
@@ -760,37 +760,37 @@ extends ConcurrentMap[K, V]
override def seq = this
- override def par = new ParCtrie(this)
+ override def par = new ParConcurrentTrieMap(this)
- override def empty: Ctrie[K, V] = new Ctrie[K, V]
+ override def empty: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
final def isReadOnly = rootupdater eq null
final def nonReadOnly = rootupdater ne null
- /** Returns a snapshot of this Ctrie.
+ /** Returns a snapshot of this ConcurrentTrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * in the snapshot or this Ctrie are accessed, they are rewritten.
+ * in the snapshot or this ConcurrentTrieMap are accessed, they are rewritten.
* This means that the work of rebuilding both the snapshot and this
- * Ctrie is distributed across all the threads doing updates or accesses
+ * ConcurrentTrieMap is distributed across all the threads doing updates or accesses
* subsequent to the snapshot creation.
*/
- @tailrec final def snapshot(): Ctrie[K, V] = {
+ @tailrec final def snapshot(): ConcurrentTrieMap[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r.copyToGen(new Gen, this), rootupdater)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r.copyToGen(new Gen, this), rootupdater)
else snapshot()
}
- /** Returns a read-only snapshot of this Ctrie.
+ /** Returns a read-only snapshot of this ConcurrentTrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * of this Ctrie are accessed, it is rewritten. The work of creating
+ * of this ConcurrentTrieMap are accessed, it is rewritten. The work of creating
* the snapshot is thus distributed across subsequent updates
- * and accesses on this Ctrie by all threads.
+ * and accesses on this ConcurrentTrieMap by all threads.
* Note that the snapshot itself is never rewritten unlike when calling
* the `snapshot` method, but the obtained snapshot cannot be modified.
*
@@ -799,7 +799,7 @@ extends ConcurrentMap[K, V]
@tailrec final def readOnlySnapshot(): collection.Map[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r, null)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r, null)
else readOnlySnapshot()
}
@@ -872,7 +872,7 @@ extends ConcurrentMap[K, V]
def iterator: Iterator[(K, V)] =
if (nonReadOnly) readOnlySnapshot().iterator
- else new CtrieIterator(0, this)
+ else new ConcurrentTrieMapIterator(0, this)
private def cachedSize() = {
val r = RDCSS_READ_ROOT()
@@ -883,17 +883,17 @@ extends ConcurrentMap[K, V]
if (nonReadOnly) readOnlySnapshot().size
else cachedSize()
- override def stringPrefix = "Ctrie"
+ override def stringPrefix = "ConcurrentTrieMap"
}
-object Ctrie extends MutableMapFactory[Ctrie] {
+object ConcurrentTrieMap extends MutableMapFactory[ConcurrentTrieMap] {
val inodeupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[INodeBase[_, _]], classOf[MainNode[_, _]], "mainnode")
- implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), Ctrie[K, V]] = new MapCanBuildFrom[K, V]
+ implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), ConcurrentTrieMap[K, V]] = new MapCanBuildFrom[K, V]
- def empty[K, V]: Ctrie[K, V] = new Ctrie[K, V]
+ def empty[K, V]: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
@inline final def computeHash[K](k: K): Int = {
var hcode = k.hashCode
@@ -905,7 +905,7 @@ object Ctrie extends MutableMapFactory[Ctrie] {
}
-private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ctrie[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
+private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, private var ct: ConcurrentTrieMap[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
var stack = new Array[Array[BasicNode]](7)
var stackpos = new Array[Int](7)
var depth = -1
@@ -971,9 +971,9 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct
}
} else current = null
- protected def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new CtrieIterator[K, V](_lev, _ct, _mustInit)
+ protected def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ConcurrentTrieMapIterator[K, V](_lev, _ct, _mustInit)
- protected def dupTo(it: CtrieIterator[K, V]) = {
+ protected def dupTo(it: ConcurrentTrieMapIterator[K, V]) = {
it.level = this.level
it.ct = this.ct
it.depth = this.depth
@@ -993,7 +993,7 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct
}
/** Returns a sequence of iterators over subsets of this iterator.
- * It's used to ease the implementation of splitters for a parallel version of the Ctrie.
+ * It's used to ease the implementation of splitters for a parallel version of the ConcurrentTrieMap.
*/
protected def subdivide(): Seq[Iterator[(K, V)]] = if (subiter ne null) {
// the case where an LNode is being iterated
@@ -1043,7 +1043,7 @@ private[mutable] object RestartException extends util.control.ControlThrowable
/** Only used for ctrie serialization. */
@SerialVersionUID(0L - 7237891413820527142L)
-private[mutable] case object CtrieSerializationEnd
+private[mutable] case object ConcurrentTrieMapSerializationEnd
private[mutable] object Debug {
diff --git a/src/library/scala/collection/mutable/FlatArray.scala b/src/library/scala/collection/mutable/FlatArray.scala
new file mode 100644
index 0000000000..a7f994bf74
--- /dev/null
+++ b/src/library/scala/collection/mutable/FlatArray.scala
@@ -0,0 +1,150 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.collection
+package mutable
+
+import scala.reflect.ClassManifest
+import generic.CanBuildFrom
+
+/**
+ * A class representing `Array[T]`.
+ *
+ * @tparam T type of the elements in this wrapped array.
+ *
+ * @author Martin Odersky, Stephane Micheloud
+ * @version 1.0
+ * @since 2.8
+ * @define Coll WrappedArray
+ * @define coll wrapped array
+ * @define orderDependent
+ * @define orderDependentFold
+ * @define mayNotTerminateInf
+ * @define willNotTerminateInf
+ */
+abstract sealed class FlatArray[T]
+extends AbstractSeq[T]
+ with IndexedSeq[T]
+ with IndexedSeqOptimized[T, FlatArray[T]]
+{
+
+ override protected[this] def thisCollection: FlatArray[T] = this
+ override protected[this] def toCollection(repr: FlatArray[T]): FlatArray[T] = repr
+
+ /** The length of the array */
+ def length: Int
+
+ /** The element at given index */
+ def apply(index: Int): T
+
+ /** Update element at given index */
+ def update(index: Int, elem: T): Unit
+
+ override def stringPrefix = "FlatArray"
+
+ override protected[this] def newBuilder: Builder[T, FlatArray[T]] = ??? // implemented in FlatArray.Impl
+
+ /** Clones this object, including the underlying Array. */
+ override def clone: FlatArray[T] = ??? // implemented in FlatArray.Impl
+}
+
+
+/** A companion object used to create instances of `WrappedArray`.
+ */
+object FlatArray {
+
+ def empty[Boxed, Unboxed](elems: Boxed*)
+ (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = apply()
+
+ def apply[Boxed, Unboxed](elems: Boxed*)
+ (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): FlatArray[Boxed] = {
+ val b = newBuilder[Boxed, Unboxed]
+ b.sizeHint(elems.length)
+ b ++= elems
+ b.result
+ }
+
+ def newBuilder[Boxed, Unboxed]
+ (implicit boxings: BoxingConversions[Boxed, Unboxed], elemManifest: ClassManifest[Unboxed]): Builder[Boxed, FlatArray[Boxed]] =
+ new Bldr[Boxed, Unboxed](boxings, elemManifest)
+
+ implicit def canBuildFrom[Boxed, Unboxed](
+ implicit
+ boxings: BoxingConversions[Boxed, Unboxed],
+ elemManifest: ClassManifest[Unboxed]): CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] =
+ new CanBuildFrom[FlatArray[_], Boxed, FlatArray[Boxed]] {
+ def apply(from: FlatArray[_]): Builder[Boxed, FlatArray[Boxed]] =
+ newBuilder[Boxed, Unboxed]
+ def apply: Builder[Boxed, FlatArray[Boxed]] =
+ newBuilder[Boxed, Unboxed]
+ }
+
+ private class Bldr[Boxed, Unboxed](boxings: BoxingConversions[Boxed, Unboxed], manifest: ClassManifest[Unboxed]) extends Builder[Boxed, FlatArray[Boxed]] {
+
+ private var elems: Array[Unboxed] = _
+ private var capacity: Int = 0
+ private var size: Int = 0
+
+ private def resize(size: Int) {
+ val newelems = manifest.newArray(size)
+ if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
+ elems = newelems
+ capacity = size
+ }
+
+ override def sizeHint(size: Int) {
+ if (capacity < size) resize(size)
+ }
+
+ private def ensureSize(size: Int) {
+ if (capacity < size) {
+ var newsize = if (capacity == 0) 16 else capacity * 2
+ while (newsize < size) newsize *= 2
+ resize(newsize)
+ }
+ }
+
+ def +=(elem: Boxed): this.type = {
+ ensureSize(size + 1)
+ elems(size) = boxings.unbox(elem)
+ size += 1
+ this
+ }
+
+ def clear() {
+ size = 0
+ }
+
+ def result(): FlatArray[Boxed] = {
+ if (capacity == 0 || capacity != size) resize(size)
+ new FlatArray.Impl(elems, boxings, manifest)
+ }
+ }
+
+ private class Impl[Boxed, Unboxed](
+ elems: Array[Unboxed],
+ boxings: BoxingConversions[Boxed, Unboxed],
+ elemManifest: ClassManifest[Unboxed]) extends FlatArray[Boxed] {
+
+ def length = elems.length
+
+ def apply(idx: Int): Boxed = boxings.box(elems(idx))
+
+ def update(idx: Int, elem: Boxed) = elems(idx) = boxings.unbox(elem)
+
+ /** Creates new builder for this collection ==> move to subclasses
+ */
+ override protected[this] def newBuilder: Builder[Boxed, FlatArray[Boxed]] =
+ new Bldr[Boxed, Unboxed](boxings, elemManifest)
+
+ /** Clones this object, including the underlying Array. */
+ override def clone: FlatArray[Boxed] = new Impl[Boxed, Unboxed](elems.clone(), boxings, elemManifest)
+ }
+}
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index 037f3b2939..96e73522b6 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -175,10 +175,10 @@ final class ListBuffer[A]
}
override def ++=(xs: TraversableOnce[A]): this.type =
- if (xs eq this) ++= (this take size) else super.++=(xs)
+ if (xs.asInstanceOf[AnyRef] eq this) ++= (this take size) else super.++=(xs)
override def ++=:(xs: TraversableOnce[A]): this.type =
- if (xs eq this) ++=: (this take size) else super.++=:(xs)
+ if (xs.asInstanceOf[AnyRef] eq this) ++=: (this take size) else super.++=:(xs)
/** Clears the buffer contents.
*/
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index 5e6bf8c1a3..7e0fa366ab 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -58,7 +58,7 @@ import annotation.unchecked.uncheckedStable
* }}}
*
* which returns an instance of `IterableSplitter[T]`, which is a subtype of `Splitter[T]`.
- * Parallel iterators have a method `remaining` to check the remaining number of elements,
+ * Splitters have a method `remaining` to check the remaining number of elements,
* and method `split` which is defined by splitters. Method `split` divides the splitters
* iterate over into disjunct subsets:
*
@@ -96,7 +96,7 @@ import annotation.unchecked.uncheckedStable
* The combination of methods `toMap`, `toSeq` or `toSet` along with `par` and `seq` is a flexible
* way to change between different collection types.
*
- * Since this trait extends the `Iterable` trait, methods like `size` must also
+ * Since this trait extends the `GenIterable` trait, methods like `size` must also
* be implemented in concrete collections, while `iterator` forwards to `splitter` by
* default.
*
@@ -116,7 +116,7 @@ import annotation.unchecked.uncheckedStable
* which do not know the number of elements remaining. To do this, the new collection implementation must override
* `isStrictSplitterCollection` to `false`. This will make some operations unavailable.
*
- * To create a new parallel collection, extend the `ParIterable` trait, and implement `size`, `parallelIterator`,
+ * To create a new parallel collection, extend the `ParIterable` trait, and implement `size`, `splitter`,
* `newCombiner` and `seq`. Having an implicit combiner factory requires extending this trait in addition, as
* well as providing a companion object, as with regular collections.
*
@@ -159,6 +159,10 @@ self: ParIterableLike[T, Repr, Sequential] =>
@volatile
private var _tasksupport = defaultTaskSupport
+ protected def initTaskSupport() {
+ _tasksupport = defaultTaskSupport
+ }
+
def tasksupport = {
val ts = _tasksupport
if (ts eq null) {
diff --git a/src/library/scala/collection/parallel/Tasks.scala b/src/library/scala/collection/parallel/Tasks.scala
index 60a8bb1ed6..4a581f219e 100644
--- a/src/library/scala/collection/parallel/Tasks.scala
+++ b/src/library/scala/collection/parallel/Tasks.scala
@@ -359,7 +359,7 @@ object ThreadPoolTasks {
/** An implementation of tasks objects based on the Java thread pooling API and synchronization using futures. */
-@deprecated("This implementation is not used.")
+@deprecated("This implementation is not used.", "2.10.0")
trait FutureThreadPoolTasks extends Tasks {
import java.util.concurrent._
diff --git a/src/library/scala/collection/parallel/immutable/ParHashMap.scala b/src/library/scala/collection/parallel/immutable/ParHashMap.scala
index 266b179401..49b00bebdb 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashMap.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashMap.scala
@@ -116,7 +116,9 @@ self =>
def remaining = sz - i
override def toString = "HashTrieIterator(" + sz + ")"
}
-
+
+ /* debug */
+
private[parallel] def printDebugInfo() {
println("Parallel hash trie")
println("Top level inner trie type: " + trie.getClass)
diff --git a/src/library/scala/collection/parallel/immutable/ParHashSet.scala b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
index 0d7f04976e..11d92a27c9 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashSet.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
@@ -111,6 +111,7 @@ self =>
}
def remaining = sz - i
}
+
}
diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala
index 64e07ce4ff..9cac433460 100644
--- a/src/library/scala/collection/parallel/immutable/ParRange.scala
+++ b/src/library/scala/collection/parallel/immutable/ParRange.scala
@@ -105,6 +105,7 @@ self =>
cb
}
}
+
}
object ParRange {
diff --git a/src/library/scala/collection/parallel/mutable/ParArray.scala b/src/library/scala/collection/parallel/mutable/ParArray.scala
index 5c3da66be0..c33495bd39 100644
--- a/src/library/scala/collection/parallel/mutable/ParArray.scala
+++ b/src/library/scala/collection/parallel/mutable/ParArray.scala
@@ -672,7 +672,7 @@ self =>
private def readObject(in: java.io.ObjectInputStream) {
in.defaultReadObject
-
+
// get raw array from arrayseq
array = arrayseq.array.asInstanceOf[Array[Any]]
}
diff --git a/src/library/scala/collection/parallel/mutable/ParCtrie.scala b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala
index 470972adad..a6495161ea 100644
--- a/src/library/scala/collection/parallel/mutable/ParCtrie.scala
+++ b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala
@@ -20,12 +20,12 @@ import scala.collection.mutable.LNode
import scala.collection.mutable.CNode
import scala.collection.mutable.SNode
import scala.collection.mutable.INode
-import scala.collection.mutable.Ctrie
-import scala.collection.mutable.CtrieIterator
+import scala.collection.mutable.ConcurrentTrieMap
+import scala.collection.mutable.ConcurrentTrieMapIterator
-/** Parallel Ctrie collection.
+/** Parallel ConcurrentTrieMap collection.
*
* It has its bulk operations parallelized, but uses the snapshot operation
* to create the splitter. This means that parallel bulk operations can be
@@ -34,24 +34,24 @@ import scala.collection.mutable.CtrieIterator
* @author Aleksandar Prokopec
* @since 2.10
*/
-final class ParCtrie[K, V] private[collection] (private val ctrie: Ctrie[K, V])
+final class ParConcurrentTrieMap[K, V] private[collection] (private val ctrie: ConcurrentTrieMap[K, V])
extends ParMap[K, V]
- with GenericParMapTemplate[K, V, ParCtrie]
- with ParMapLike[K, V, ParCtrie[K, V], Ctrie[K, V]]
- with ParCtrieCombiner[K, V]
+ with GenericParMapTemplate[K, V, ParConcurrentTrieMap]
+ with ParMapLike[K, V, ParConcurrentTrieMap[K, V], ConcurrentTrieMap[K, V]]
+ with ParConcurrentTrieMapCombiner[K, V]
with Serializable
{
- def this() = this(new Ctrie)
+ def this() = this(new ConcurrentTrieMap)
- override def mapCompanion: GenericParMapCompanion[ParCtrie] = ParCtrie
+ override def mapCompanion: GenericParMapCompanion[ParConcurrentTrieMap] = ParConcurrentTrieMap
- override def empty: ParCtrie[K, V] = ParCtrie.empty
+ override def empty: ParConcurrentTrieMap[K, V] = ParConcurrentTrieMap.empty
- protected[this] override def newCombiner = ParCtrie.newCombiner
+ protected[this] override def newCombiner = ParConcurrentTrieMap.newCombiner
override def seq = ctrie
- def splitter = new ParCtrieSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[Ctrie[K, V]], true)
+ def splitter = new ParConcurrentTrieMapSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[ConcurrentTrieMap[K, V]], true)
override def clear() = ctrie.clear()
@@ -87,11 +87,11 @@ extends ParMap[K, V]
}
}
- override def stringPrefix = "ParCtrie"
+ override def stringPrefix = "ParConcurrentTrieMap"
/* tasks */
- /** Computes Ctrie size in parallel. */
+ /** Computes ConcurrentTrieMap size in parallel. */
class Size(offset: Int, howmany: Int, array: Array[BasicNode]) extends Task[Int, Size] {
var result = -1
def leaf(prev: Option[Int]) = {
@@ -118,15 +118,15 @@ extends ParMap[K, V]
}
-private[collection] class ParCtrieSplitter[K, V](lev: Int, ct: Ctrie[K, V], mustInit: Boolean)
-extends CtrieIterator[K, V](lev, ct, mustInit)
+private[collection] class ParConcurrentTrieMapSplitter[K, V](lev: Int, ct: ConcurrentTrieMap[K, V], mustInit: Boolean)
+extends ConcurrentTrieMapIterator[K, V](lev, ct, mustInit)
with IterableSplitter[(K, V)]
{
// only evaluated if `remaining` is invoked (which is not used by most tasks)
lazy val totalsize = ct.par.size
var iterated = 0
- protected override def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new ParCtrieSplitter[K, V](_lev, _ct, _mustInit)
+ protected override def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ParConcurrentTrieMapSplitter[K, V](_lev, _ct, _mustInit)
override def shouldSplitFurther[S](coll: collection.parallel.ParIterable[S], parallelismLevel: Int) = {
val maxsplits = 3 + Integer.highestOneBit(parallelismLevel)
@@ -153,15 +153,15 @@ extends CtrieIterator[K, V](lev, ct, mustInit)
}
-/** Only used within the `ParCtrie`. */
-private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[K, V]] {
+/** Only used within the `ParConcurrentTrieMap`. */
+private[mutable] trait ParConcurrentTrieMapCombiner[K, V] extends Combiner[(K, V), ParConcurrentTrieMap[K, V]] {
- def combine[N <: (K, V), NewTo >: ParCtrie[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
+ def combine[N <: (K, V), NewTo >: ParConcurrentTrieMap[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
throw new UnsupportedOperationException("This shouldn't have been called in the first place.")
- val thiz = this.asInstanceOf[ParCtrie[K, V]]
- val that = other.asInstanceOf[ParCtrie[K, V]]
- val result = new ParCtrie[K, V]
+ val thiz = this.asInstanceOf[ParConcurrentTrieMap[K, V]]
+ val that = other.asInstanceOf[ParConcurrentTrieMap[K, V]]
+ val result = new ParConcurrentTrieMap[K, V]
result ++= thiz.iterator
result ++= that.iterator
@@ -174,13 +174,13 @@ private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[
}
-object ParCtrie extends ParMapFactory[ParCtrie] {
+object ParConcurrentTrieMap extends ParMapFactory[ParConcurrentTrieMap] {
- def empty[K, V]: ParCtrie[K, V] = new ParCtrie[K, V]
+ def empty[K, V]: ParConcurrentTrieMap[K, V] = new ParConcurrentTrieMap[K, V]
- def newCombiner[K, V]: Combiner[(K, V), ParCtrie[K, V]] = new ParCtrie[K, V]
+ def newCombiner[K, V]: Combiner[(K, V), ParConcurrentTrieMap[K, V]] = new ParConcurrentTrieMap[K, V]
- implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParCtrie[K, V]] = new CanCombineFromMap[K, V]
+ implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParConcurrentTrieMap[K, V]] = new CanCombineFromMap[K, V]
}
diff --git a/src/library/scala/math/Equiv.scala b/src/library/scala/math/Equiv.scala
index 92a794578e..bd8414a18d 100644
--- a/src/library/scala/math/Equiv.scala
+++ b/src/library/scala/math/Equiv.scala
@@ -29,7 +29,7 @@ import java.util.Comparator
* @since 2.7
*/
-trait Equiv[T] {
+trait Equiv[T] extends Any {
/** Returns `true` iff `x` is equivalent to `y`.
*/
def equiv(x: T, y: T): Boolean
diff --git a/src/library/scala/math/Ordered.scala b/src/library/scala/math/Ordered.scala
index 53d618db63..b76030718f 100644
--- a/src/library/scala/math/Ordered.scala
+++ b/src/library/scala/math/Ordered.scala
@@ -50,7 +50,7 @@ package scala.math
* @author Martin Odersky
* @version 1.1, 2006-07-24
*/
-trait Ordered[A] extends java.lang.Comparable[A] {
+trait Ordered[A] extends Any with java.lang.Comparable[A] {
/** Result of comparing `this` with operand `that`.
*
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala
index d393ac47fa..37be067614 100644
--- a/src/library/scala/reflect/ClassManifest.scala
+++ b/src/library/scala/reflect/ClassManifest.scala
@@ -207,18 +207,18 @@ object ClassManifest {
* pass varargs as arrays into this, we get an infinitely recursive call
* to boxArray. (Besides, having a separate case is more efficient)
*/
- def classType[T <: AnyRef](clazz: jClass[_]): ClassManifest[T] =
+ def classType[T](clazz: jClass[_]): ClassManifest[T] =
new ClassTypeManifest[T](None, clazz, Nil)
/** ClassManifest for the class type `clazz[args]`, where `clazz` is
* a top-level or static class and `args` are its type arguments */
- def classType[T <: AnyRef](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] =
+ def classType[T](clazz: jClass[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] =
new ClassTypeManifest[T](None, clazz, arg1 :: args.toList)
/** ClassManifest for the class type `clazz[args]`, where `clazz` is
* a class with non-package prefix type `prefix` and type arguments `args`.
*/
- def classType[T <: AnyRef](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] =
+ def classType[T](prefix: OptManifest[_], clazz: jClass[_], args: OptManifest[_]*): ClassManifest[T] =
new ClassTypeManifest[T](Some(prefix), clazz, args.toList)
def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match {
@@ -251,7 +251,7 @@ object ClassManifest {
/** Manifest for the class type `clazz[args]`, where `clazz` is
* a top-level or static class: todo: we should try to merge this with Manifest's class */
-private class ClassTypeManifest[T <: AnyRef](
+private class ClassTypeManifest[T](
prefix: Option[OptManifest[_]],
val erasure: jClass[_],
override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T]
diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala
index e737b0ea4f..c3d989f971 100755
--- a/src/library/scala/reflect/api/StandardDefinitions.scala
+++ b/src/library/scala/reflect/api/StandardDefinitions.scala
@@ -61,7 +61,7 @@ trait StandardDefinitions { self: Universe =>
def vmSignature(sym: Symbol, info: Type): String
/** Is symbol one of the value classes? */
- def isValueClass(sym: Symbol): Boolean // !!! better name?
+ def isPrimitiveValueClass(sym: Symbol): Boolean // !!! better name?
/** Is symbol one of the numeric value classes? */
def isNumericValueClass(sym: Symbol): Boolean // !!! better name?
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 181ce85dac..a355207ff0 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -309,7 +309,7 @@ trait Trees { self: Universe =>
* quite frequently called modules to reduce ambiguity.
*/
case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
- extends ImplDef
+ extends ImplDef
/** A common base class for ValDefs and DefDefs.
*/
@@ -319,8 +319,13 @@ trait Trees { self: Universe =>
def rhs: Tree
}
- /** A value definition (this includes vars as well, which differ from
- * vals only in having the MUTABLE flag set in their Modifiers.)
+ /** Broadly speaking, a value definition. All these are encoded as ValDefs:
+ *
+ * - immutable values, e.g. "val x"
+ * - mutable values, e.g. "var x" - the MUTABLE flag set in mods
+ * - lazy values, e.g. "lazy val x" - the LAZY flag set in mods
+ * - method parameters, see vparamss in DefDef - the PARAM flag is set in mods
+ * - explicit self-types, e.g. class A { self: Bar => } - !!! not sure what is set.
*/
case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef
@@ -390,7 +395,6 @@ trait Trees { self: Universe =>
// {
// def bar // owner is local dummy
// }
- // System.err.println("TEMPLATE: " + parents)
}
/** Block of expressions (semicolon separated expressions) */
@@ -741,6 +745,12 @@ trait Trees { self: Universe =>
case t =>
sys.error("Not a ClassDef: " + t + "/" + t.getClass)
}
+ def deriveModuleDef(mdef: Tree)(applyToImpl: Template => Template): ModuleDef = mdef match {
+ case ModuleDef(mods0, name0, impl0) =>
+ treeCopy.ModuleDef(mdef, mods0, name0, applyToImpl(impl0))
+ case t =>
+ sys.error("Not a ModuleDef: " + t + "/" + t.getClass)
+ }
def deriveCaseDef(cdef: Tree)(applyToBody: Tree => Tree): CaseDef = cdef match {
case CaseDef(pat0, guard0, body0) =>
treeCopy.CaseDef(cdef, pat0, guard0, applyToBody(body0))
diff --git a/src/library/scala/reflect/api/Types.scala b/src/library/scala/reflect/api/Types.scala
index cc8e85b9c8..0371e2c5df 100755
--- a/src/library/scala/reflect/api/Types.scala
+++ b/src/library/scala/reflect/api/Types.scala
@@ -46,7 +46,7 @@ trait Types { self: Universe =>
/** Substitute types in `to` for corresponding occurrences of references to
* symbols `from` in this type.
*/
- def substituteTypes(from: List[Symbol], to: List[Type]): Type // !!! Too many things with names like "subst"
+ def substituteTypes(from: List[Symbol], to: List[Type]): Type
/** If this is a parameterized types, the type arguments.
* Otherwise the empty list
diff --git a/src/library/scala/runtime/ScalaNumberProxy.scala b/src/library/scala/runtime/ScalaNumberProxy.scala
index 09e1611dcd..d9b9a7843f 100644
--- a/src/library/scala/runtime/ScalaNumberProxy.scala
+++ b/src/library/scala/runtime/ScalaNumberProxy.scala
@@ -64,12 +64,12 @@ abstract class FractionalProxy[T : Fractional] extends ScalaNumberProxy[T] with
def to(end: T, step: T): NumericRange.Inclusive[T] = NumericRange.inclusive(self, end, step)
}
-trait OrderedProxy[T] extends Typed[T] with Ordered[T] {
+trait OrderedProxy[T] extends Any with Ordered[T] with Typed[T] {
protected def ord: Ordering[T]
def compare(y: T) = ord.compare(self, y)
}
-trait RangedProxy[T] extends Typed[T] {
+trait RangedProxy[T] extends Any with Typed[T] {
type ResultWithoutStep
def until(end: T): ResultWithoutStep
diff --git a/src/library/scala/runtime/StringAdd.scala b/src/library/scala/runtime/StringAdd.scala
index ae1975cb4c..a7e78ea9a3 100644
--- a/src/library/scala/runtime/StringAdd.scala
+++ b/src/library/scala/runtime/StringAdd.scala
@@ -8,13 +8,15 @@
package scala.runtime
-final class StringAdd(self: Any) {
+/** A wrapper class that adds string concatenation `+` to any value */
+final class StringAdd(val self: Any) {
+
+ // Note: The implicit conversion from Any to StringAdd is one of two
+ // implicit conversions from Any to AnyRef in Predef. It is important to have at least
+ // two such conversions, so that silent conversions from value types to AnyRef
+ // are avoided. If StringFormat should become a value class, another
+ // implicit conversion from Any to AnyRef has to be introduced in Predef
def +(other: String) = String.valueOf(self) + other
- /** Returns string formatted according to given `format` string.
- * Format strings are as for `String.format`
- * (@see java.lang.String.format).
- */
- def formatted(fmtstr: String): String = fmtstr format self
}
diff --git a/src/library/scala/runtime/StringFormat.scala b/src/library/scala/runtime/StringFormat.scala
new file mode 100644
index 0000000000..c120cbb14d
--- /dev/null
+++ b/src/library/scala/runtime/StringFormat.scala
@@ -0,0 +1,27 @@
+/* *\
+** ________ ___ __ ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ |_| **
+** **
+\* */
+
+package scala.runtime
+
+/** A wrapper class that adds a `formatted` operation to any value
+ */
+final class StringFormat(val self: Any) {
+
+ // Note: The implicit conversion from Any to StringFormat is one of two
+ // implicit conversions from Any to AnyRef in Predef. It is important to have at least
+ // two such conversions, so that silent conversions from value types to AnyRef
+ // are avoided. If StringFormat should become a value class, another
+ // implicit conversion from Any to AnyRef has to be introduced in Predef
+
+ /** Returns string formatted according to given `format` string.
+ * Format strings are as for `String.format`
+ * (@see java.lang.String.format).
+ */
+ @inline def formatted(fmtstr: String): String = fmtstr format self
+
+}
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index a62d74b1f6..38ca89b98b 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -15,7 +15,7 @@ import java.util.jar.Attributes.{ Name => AttributeName }
/** Loads `library.properties` from the jar. */
object Properties extends PropertiesTrait {
protected def propCategory = "library"
- protected def pickJarBasedOn = classOf[ScalaObject]
+ protected def pickJarBasedOn = classOf[Option[_]]
/** Scala manifest attributes.
*/
@@ -72,10 +72,11 @@ private[scala] trait PropertiesTrait {
* it is an RC, Beta, etc. or was built from source, or if the version
* cannot be read.
*/
- val releaseVersion = scalaPropOrNone("version.number") flatMap { s =>
- val segments = s split '.'
- if (segments.size == 4 && segments.last == "final") Some(segments take 3 mkString ".") else None
- }
+ val releaseVersion =
+ for {
+ v <- scalaPropOrNone("maven.version.number")
+ if !(v endsWith "-SNAPSHOT")
+ } yield v
/** The development Scala version, if this is not a final release.
* The precise contents are not guaranteed, but it aims to provide a
@@ -85,15 +86,12 @@ private[scala] trait PropertiesTrait {
* @return Some(version) if this is a non-final version, None if this
* is a final release or the version cannot be read.
*/
- val developmentVersion = scalaPropOrNone("version.number") flatMap { s =>
- val segments = s split '.'
- if (segments.isEmpty || segments.last == "final")
- None
- else if (segments.last startsWith "r")
- Some(s takeWhile (ch => ch != '-')) // Cutting e.g. 2.10.0.r24774-b20110417125606 to 2.10.0.r24774
- else
- Some(s)
- }
+ val developmentVersion =
+ for {
+ v <- scalaPropOrNone("maven.version.number")
+ if v endsWith "-SNAPSHOT"
+ ov <- scalaPropOrNone("version.number")
+ } yield ov
/** Either the development or release version if known, otherwise
* the empty string.
diff --git a/src/library/scala/xml/Elem.scala b/src/library/scala/xml/Elem.scala
index df52b34f87..cc244a5b88 100644..100755
--- a/src/library/scala/xml/Elem.scala
+++ b/src/library/scala/xml/Elem.scala
@@ -17,8 +17,18 @@ package scala.xml
* @author Burak Emir <bqe@google.com>
*/
object Elem {
- def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) =
- new Elem(prefix, label, attributes, scope, child:_*)
+ /** Build an Elem, setting its minimizeEmpty property to <code>true</code> if it has no children. Note that this
+ * default may not be exactly what you want, as some XML dialects don't permit some elements to be minimized.
+ *
+ * @deprecated This factory method is retained for backward compatibility; please use the other one, with which you
+ * can specify your own preference for minimizeEmpty.
+ */
+ @deprecated
+ def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*): Elem =
+ apply(prefix, label, attributes, scope, child.isEmpty, child: _*)
+
+ def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, child: Node*): Elem =
+ new Elem(prefix,label,attributes,scope, minimizeEmpty, child:_*)
def unapplySeq(n: Node) = n match {
case _: SpecialNode | _: Group => None
@@ -29,11 +39,13 @@ object Elem {
/** The case class `Elem` extends the `Node` class,
* providing an immutable data object representing an XML element.
*
- * @param prefix namespace prefix (may be null, but not the empty string)
- * @param label the element name
- * @param attribute the attribute map
- * @param scope the scope containing the namespace bindings
- * @param child the children of this node
+ * @param prefix namespace prefix (may be null, but not the empty string)
+ * @param label the element name
+ * @param attributes1 the attribute map
+ * @param scope the scope containing the namespace bindings
+ * @param minimizeEmpty `true` if this element should be serialized as minimized (i.e. "&lt;el/&gt;") when
+ * empty; `false` if it should be written out in long form.
+ * @param child the children of this node
*
* Copyright 2008 Google Inc. All Rights Reserved.
* @author Burak Emir <bqe@google.com>
@@ -43,9 +55,15 @@ class Elem(
val label: String,
attributes1: MetaData,
override val scope: NamespaceBinding,
+ val minimizeEmpty: Boolean,
val child: Node*)
extends Node with Serializable
{
+ @deprecated("This constructor is retained for backward compatibility. Please use the primary constructor, which lets you specify your own preference for `minimizeEmpty`.", "2.10")
+ def this(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) = {
+ this(prefix, label, attributes, scope, child.isEmpty, child: _*)
+ }
+
final override def doCollectNamespaces = true
final override def doTransform = true
@@ -83,8 +101,9 @@ extends Node with Serializable
label: String = this.label,
attributes: MetaData = this.attributes,
scope: NamespaceBinding = this.scope,
+ minimizeEmpty: Boolean = this.minimizeEmpty,
child: Seq[Node] = this.child.toSeq
- ): Elem = Elem(prefix, label, attributes, scope, child: _*)
+ ): Elem = Elem(prefix, label, attributes, scope, minimizeEmpty, child: _*)
/** Returns concatenation of `text(n)` for each child `n`.
*/
diff --git a/src/library/scala/xml/Node.scala b/src/library/scala/xml/Node.scala
index 2ead18fe08..02e34e1bdc 100644..100755
--- a/src/library/scala/xml/Node.scala
+++ b/src/library/scala/xml/Node.scala
@@ -159,7 +159,7 @@ abstract class Node extends NodeSeq {
* @return ...
*/
def buildString(stripComments: Boolean): String =
- Utility.toXML(this, stripComments = stripComments).toString
+ Utility.serialize(this, stripComments = stripComments).toString
/**
* Same as `toString('''false''')`.
diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala
index ea39b51352..64dbd00f2f 100644..100755
--- a/src/library/scala/xml/PrettyPrinter.scala
+++ b/src/library/scala/xml/PrettyPrinter.scala
@@ -161,7 +161,7 @@ class PrettyPrinter(width: Int, step: Int) {
case _ =>
val test = {
val sb = new StringBuilder()
- Utility.toXML(node, pscope, sb, false)
+ Utility.serialize(node, pscope, sb, false)
if (doPreserve(node)) sb.toString
else TextBuffer.fromString(sb.toString).toText(0).data
}
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index fc20b892b9..9f944c0e92 100644..100755
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -181,6 +181,13 @@ object Utility extends AnyRef with parsing.TokenTests {
// sb.toString()
// }
+ /**
+ * Serialize the provided Node to the provided StringBuilder.
+ * <p/>
+ * Note that calling this source-compatible method will result in the same old, arguably almost universally unwanted,
+ * behaviour.
+ */
+ @deprecated("Please use `serialize` instead and specify a `minimizeTags` parameter", "2.10")
def toXML(
x: Node,
pscope: NamespaceBinding = TopScope,
@@ -190,29 +197,51 @@ object Utility extends AnyRef with parsing.TokenTests {
preserveWhitespace: Boolean = false,
minimizeTags: Boolean = false): StringBuilder =
{
+ serialize(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, if (minimizeTags) MinimizeMode.Always else MinimizeMode.Never)
+ }
+
+ /**
+ * Serialize an XML Node to a StringBuilder.
+ *
+ * This is essentially a minor rework of `toXML` that can't have the same name due to an unfortunate
+ * combination of named/default arguments and overloading.
+ *
+ * @todo use a Writer instead
+ */
+ def serialize(
+ x: Node,
+ pscope: NamespaceBinding = TopScope,
+ sb: StringBuilder = new StringBuilder,
+ stripComments: Boolean = false,
+ decodeEntities: Boolean = true,
+ preserveWhitespace: Boolean = false,
+ minimizeTags: MinimizeMode.Value = MinimizeMode.Default): StringBuilder =
+ {
x match {
- case c: Comment => if (!stripComments) c buildString sb else sb
- case x: SpecialNode => x buildString sb
- case g: Group =>
- g.nodes foreach {toXML(_, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)}
- sb
- case _ =>
+ case c: Comment if !stripComments => c buildString sb
+ case s: SpecialNode => s buildString sb
+ case g: Group => for (c <- g.nodes) serialize(c, g.scope, sb, minimizeTags = minimizeTags) ; sb
+ case el: Elem =>
// print tag with namespace declarations
sb.append('<')
- x.nameToString(sb)
- if (x.attributes ne null) x.attributes.buildString(sb)
- x.scope.buildString(sb, pscope)
- if (x.child.isEmpty && minimizeTags) {
+ el.nameToString(sb)
+ if (el.attributes ne null) el.attributes.buildString(sb)
+ el.scope.buildString(sb, pscope)
+ if (el.child.isEmpty &&
+ (minimizeTags == MinimizeMode.Always ||
+ (minimizeTags == MinimizeMode.Default && el.minimizeEmpty)))
+ {
// no children, so use short form: <xyz .../>
- sb.append(" />")
+ sb.append("/>")
} else {
// children, so use long form: <xyz ...>...</xyz>
sb.append('>')
- sequenceToXML(x.child, x.scope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
+ sequenceToXML(el.child, el.scope, sb, stripComments)
sb.append("</")
- x.nameToString(sb)
+ el.nameToString(sb)
sb.append('>')
}
+ case _ => throw new IllegalArgumentException("Don't know how to serialize a " + x.getClass.getName)
}
}
@@ -223,20 +252,20 @@ object Utility extends AnyRef with parsing.TokenTests {
stripComments: Boolean = false,
decodeEntities: Boolean = true,
preserveWhitespace: Boolean = false,
- minimizeTags: Boolean = false): Unit =
+ minimizeTags: MinimizeMode.Value = MinimizeMode.Default): Unit =
{
if (children.isEmpty) return
else if (children forall isAtomAndNotText) { // add space
val it = children.iterator
val f = it.next
- toXML(f, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
+ serialize(f, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
while (it.hasNext) {
val x = it.next
sb.append(' ')
- toXML(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
+ serialize(x, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags)
}
}
- else children foreach { toXML(_, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) }
+ else children foreach { serialize(_, pscope, sb, stripComments, decodeEntities, preserveWhitespace, minimizeTags) }
}
/**
diff --git a/src/library/scala/xml/XML.scala b/src/library/scala/xml/XML.scala
index bc3033d081..4beba91899 100644..100755
--- a/src/library/scala/xml/XML.scala
+++ b/src/library/scala/xml/XML.scala
@@ -26,6 +26,21 @@ object Source
def fromSysId(sysID: String) = new InputSource(sysID)
def fromString(string: String) = fromReader(new StringReader(string))
}
+
+/**
+ * Governs how empty elements (i.e. those without child elements) should be serialized.
+ */
+object MinimizeMode extends Enumeration {
+ /** Minimize empty tags if they were originally empty when parsed, or if they were constructed with [[scala.xml.Elem]]`#minimizeEmpty` == true */
+ val Default = Value
+
+ /** Always minimize empty tags. Note that this may be problematic for XHTML, in which case [[scala.xml.Xhtml]]`#toXhtml` should be used instead. */
+ val Always = Value
+
+ /** Never minimize empty tags. */
+ val Never = Value
+}
+
import Source._
/** The object `XML` provides constants, and functions to load
@@ -83,10 +98,10 @@ object XML extends XMLLoader[Elem]
* @param xmlDecl if true, write xml declaration
* @param doctype if not null, write doctype declaration
*/
- final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType) {
+ final def write(w: java.io.Writer, node: Node, enc: String, xmlDecl: Boolean, doctype: dtd.DocType, minimizeTags: MinimizeMode.Value = MinimizeMode.Default) {
/* TODO: optimize by giving writer parameter to toXML*/
if (xmlDecl) w.write("<?xml version='1.0' encoding='" + enc + "'?>\n")
if (doctype ne null) w.write( doctype.toString() + "\n")
- w.write(Utility.toXML(node).toString)
+ w.write(Utility.serialize(node, minimizeTags = minimizeTags).toString)
}
}
diff --git a/src/library/scala/xml/factory/Binder.scala b/src/library/scala/xml/factory/Binder.scala
index a8b0ed585b..b4fe153bd8 100644..100755
--- a/src/library/scala/xml/factory/Binder.scala
+++ b/src/library/scala/xml/factory/Binder.scala
@@ -43,13 +43,13 @@ abstract class Binder(val preserveWS: Boolean) extends ValidatingMarkupHandler {
result &+ text(0, x.data)
case x:EntityRef =>
result &+ entityRef(0, x.entityName)
- case _ =>
- elemStart(0, n.prefix, n.label, n.attributes, n.scope)
+ case x:Elem =>
+ elemStart(0, x.prefix, x.label, x.attributes, x.scope)
val old = result
result = new NodeBuffer()
- for (m <- n.child) traverse(m)
- result = old &+ elem(0, n.prefix, n.label, n.attributes, n.scope, NodeSeq.fromSeq(result)).toList;
- elemEnd(0, n.prefix, n.label)
+ for (m <- x.child) traverse(m)
+ result = old &+ elem(0, x.prefix, x.label, x.attributes, x.scope, x.minimizeEmpty, NodeSeq.fromSeq(result)).toList;
+ elemEnd(0, x.prefix, x.label)
}
final def validate(n: Node): Node = {
diff --git a/src/library/scala/xml/parsing/ConstructingHandler.scala b/src/library/scala/xml/parsing/ConstructingHandler.scala
index 60c19138c3..7e61674682 100644..100755
--- a/src/library/scala/xml/parsing/ConstructingHandler.scala
+++ b/src/library/scala/xml/parsing/ConstructingHandler.scala
@@ -21,8 +21,8 @@ abstract class ConstructingHandler extends MarkupHandler
val preserveWS: Boolean
def elem(pos: Int, pre: String, label: String, attrs: MetaData,
- pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq =
- Elem(pre, label, attrs, pscope, nodes:_*)
+ pscope: NamespaceBinding, empty: Boolean, nodes: NodeSeq): NodeSeq =
+ Elem(pre, label, attrs, pscope, empty, nodes:_*)
def procInstr(pos: Int, target: String, txt: String) =
ProcInstr(target, txt)
diff --git a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala b/src/library/scala/xml/parsing/DefaultMarkupHandler.scala
index 699c5b2b5f..e0258ba781 100644..100755
--- a/src/library/scala/xml/parsing/DefaultMarkupHandler.scala
+++ b/src/library/scala/xml/parsing/DefaultMarkupHandler.scala
@@ -16,7 +16,7 @@ package parsing
abstract class DefaultMarkupHandler extends MarkupHandler {
def elem(pos: Int, pre: String, label: String, attrs: MetaData,
- scope:NamespaceBinding, args: NodeSeq) = NodeSeq.Empty
+ scope:NamespaceBinding, empty: Boolean, args: NodeSeq) = NodeSeq.Empty
def procInstr(pos: Int, target: String, txt: String) = NodeSeq.Empty
diff --git a/src/library/scala/xml/parsing/MarkupHandler.scala b/src/library/scala/xml/parsing/MarkupHandler.scala
index 87e785a98f..83db2f177d 100644..100755
--- a/src/library/scala/xml/parsing/MarkupHandler.scala
+++ b/src/library/scala/xml/parsing/MarkupHandler.scala
@@ -75,10 +75,11 @@ abstract class MarkupHandler extends Logged
* @param pre the prefix
* @param label the local name
* @param attrs the attributes (metadata)
+ * @param empty `true` if the element was previously empty; `false` otherwise.
* @param args the children of this element
* @return ...
*/
- def elem(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, args: NodeSeq): NodeSeq
+ def elem(pos: Int, pre: String, label: String, attrs: MetaData, scope: NamespaceBinding, empty: Boolean, args: NodeSeq): NodeSeq
/** callback method invoked by MarkupParser after parsing PI.
*/
diff --git a/src/library/scala/xml/parsing/MarkupParser.scala b/src/library/scala/xml/parsing/MarkupParser.scala
index 1de08b3025..32feaa2209 100644..100755
--- a/src/library/scala/xml/parsing/MarkupParser.scala
+++ b/src/library/scala/xml/parsing/MarkupParser.scala
@@ -569,7 +569,7 @@ trait MarkupParser extends MarkupParserCommon with TokenTests
tmp
}
}
- val res = handle.elem(pos, pre, local, aMap, scope, ts)
+ val res = handle.elem(pos, pre, local, aMap, scope, ts == NodeSeq.Empty, ts)
handle.elemEnd(pos, pre, local)
res
}
diff --git a/src/library/scala/xml/pull/XMLEventReader.scala b/src/library/scala/xml/pull/XMLEventReader.scala
index f84d91d138..c764d042c8 100755
--- a/src/library/scala/xml/pull/XMLEventReader.scala
+++ b/src/library/scala/xml/pull/XMLEventReader.scala
@@ -81,7 +81,7 @@ extends collection.AbstractIterator[XMLEvent]
// memory usage optimization return one <ignore/> for top level to satisfy
// MarkupParser.document() otherwise NodeSeq.Empty
private var ignoreWritten = false
- final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, nodes: NodeSeq): NodeSeq =
+ final def elem(pos: Int, pre: String, label: String, attrs: MetaData, pscope: NamespaceBinding, empty: Boolean, nodes: NodeSeq): NodeSeq =
if (level == 1 && !ignoreWritten) {ignoreWritten = true; <ignore/> } else NodeSeq.Empty
def procInstr(pos: Int, target: String, txt: String) = setEvent(EvProcInstr(target, txt))