summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala122
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala32
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala129
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala12
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala69
-rw-r--r--src/library/scala/collection/JavaConversions.scala2
-rwxr-xr-xsrc/library/scala/collection/JavaConverters.scala2
-rw-r--r--src/library/scala/collection/convert/DecorateAsJava.scala20
-rw-r--r--src/library/scala/collection/convert/DecorateAsScala.scala21
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala31
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala25
-rw-r--r--src/library/scala/collection/convert/Wrappers.scala51
-rw-r--r--src/library/scala/collection/mutable/HashTable.scala2
-rw-r--r--src/library/scala/concurrent/ConcurrentPackageObject.scala30
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala6
-rw-r--r--src/library/scala/concurrent/Future.scala33
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala42
-rw-r--r--src/library/scala/concurrent/impl/Future.scala30
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala2
-rw-r--r--src/library/scala/math/BigDecimal.scala15
-rw-r--r--src/library/scala/math/BigInt.scala38
-rw-r--r--test/files/neg/override-object-flag.check2
-rw-r--r--test/files/neg/override-object-no.check2
-rw-r--r--test/files/neg/t961.check2
-rw-r--r--test/files/presentation/callcc-interpreter.check2
-rw-r--r--test/files/run/concurrent-map-conversions.scala36
-rw-r--r--test/files/run/is-valid-num.scala77
-rw-r--r--test/files/run/numbereq.scala35
36 files changed, 679 insertions, 226 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 09c2228b01..8ea3cd511a 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -138,26 +138,47 @@ trait Definitions extends reflect.api.StandardDefinitions {
// symbols related to packages
var emptypackagescope: Scope = null //debug
- // This is the package _root_. The actual root cannot be referenced at
- // the source level, but _root_ is essentially a function () => <root>.
- lazy val RootPackage: Symbol = {
- val rp = (
- NoSymbol.newValue(nme.ROOTPKG, NoPosition, FINAL | MODULE | PACKAGE | JAVA)
- setInfo NullaryMethodType(RootClass.tpe)
- )
- RootClass.sourceModule = rp
- rp
+ sealed trait WellKnownSymbol extends Symbol {
+ this initFlags TopLevelCreationFlags
}
+ // Features common to RootClass and RootPackage, the roots of all
+ // type and term symbols respectively.
+ sealed trait RootSymbol extends WellKnownSymbol {
+ final override def isRootSymbol = true
+ }
+ // This is the package _root_. The actual root cannot be referenced at
+ // the source level, but _root_ is essentially a function => <root>.
+ final object RootPackage extends ModuleSymbol(NoSymbol, NoPosition, nme.ROOTPKG) with RootSymbol {
+ this setInfo NullaryMethodType(RootClass.tpe)
+ RootClass.sourceModule = this
- // This is the actual root of everything, including the package _root_.
- lazy val RootClass: ModuleClassSymbol = (
- NoSymbol.newModuleClassSymbol(tpnme.ROOT, NoPosition, FINAL | MODULE | PACKAGE | JAVA)
- setInfo rootLoader
- )
+ override def isRootPackage = true
+ }
+ // This is <root>, the actual root of everything except the package _root_.
+ // <root> and _root_ (RootPackage and RootClass) should be the only "well known"
+ // symbols owned by NoSymbol. All owner chains should go through RootClass,
+ // although it is probable that some symbols are created as direct children
+ // of NoSymbol to ensure they will not be stumbled upon. (We should designate
+ // a better encapsulated place for that.)
+ final object RootClass extends ModuleClassSymbol(NoSymbol, NoPosition, tpnme.ROOT) with RootSymbol {
+ this setInfo rootLoader
+
+ override def isRoot = true
+ override def isEffectiveRoot = true
+ override def isStatic = true
+ override def isNestedClass = false
+ override def ownerOfNewSymbols = EmptyPackageClass
+ }
// The empty package, which holds all top level types without given packages.
- lazy val EmptyPackage = RootClass.newPackage(nme.EMPTY_PACKAGE_NAME, NoPosition, FINAL)
- lazy val EmptyPackageClass = EmptyPackage.moduleClass
-
+ final object EmptyPackage extends ModuleSymbol(RootClass, NoPosition, nme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
+ override def isEmptyPackage = true
+ }
+ final object EmptyPackageClass extends ModuleClassSymbol(RootClass, NoPosition, tpnme.EMPTY_PACKAGE_NAME) with WellKnownSymbol {
+ override def isEffectiveRoot = true
+ override def isEmptyPackageClass = true
+ }
+ // It becomes tricky to create dedicated objects for other symbols because
+ // of initialization order issues.
lazy val JavaLangPackage = getModule(sn.JavaLang)
lazy val JavaLangPackageClass = JavaLangPackage.moduleClass
lazy val ScalaPackage = getModule(nme.scala_)
@@ -524,26 +545,54 @@ trait Definitions extends reflect.api.StandardDefinitions {
else nme.genericWrapArray
}
+ @deprecated("Use isTupleType", "2.10.0")
+ def isTupleTypeOrSubtype(tp: Type): Boolean = isTupleType(tp)
+
def tupleField(n: Int, j: Int) = getMember(TupleClass(n), nme.productAccessorName(j))
- def isTupleType(tp: Type): Boolean = isTupleType(tp, false)
- def isTupleTypeOrSubtype(tp: Type): Boolean = isTupleType(tp, true)
- private def isTupleType(tp: Type, subtypeOK: Boolean) = tp.normalize match {
- case TypeRef(_, sym, args) if args.nonEmpty =>
- val len = args.length
- len <= MaxTupleArity && {
- val tsym = TupleClass(len)
- (sym == tsym) || (subtypeOK && !tp.isHigherKinded && sym.isSubClass(tsym))
- }
- case _ => false
+ def isTupleSymbol(sym: Symbol) = TupleClass contains unspecializedSymbol(sym)
+
+ def unspecializedSymbol(sym: Symbol): Symbol = {
+ if (sym hasFlag SPECIALIZED) {
+ // add initialization from its generic class constructor
+ val genericName = nme.unspecializedName(sym.name)
+ val member = sym.owner.info.decl(genericName.toTypeName)
+ member
}
+ else sym
+ }
- def tupleType(elems: List[Type]) = {
- val len = elems.length
- if (len <= MaxTupleArity) {
- val sym = TupleClass(len)
- typeRef(sym.typeConstructor.prefix, sym, elems)
- } else NoType
- }
+ // Checks whether the given type is true for the given condition,
+ // or if it is a specialized subtype of a type for which it is true.
+ //
+ // Origins notes:
+ // An issue was introduced with specialization in that the implementation
+ // of "isTupleType" in Definitions relied upon sym == TupleClass(elems.length).
+ // This test is untrue for specialized tuples, causing mysterious behavior
+ // because only some tuples are specialized.
+ def isPossiblySpecializedType(tp: Type)(cond: Type => Boolean) = {
+ cond(tp) || (tp match {
+ case TypeRef(pre, sym, args) if sym hasFlag SPECIALIZED =>
+ cond(tp baseType unspecializedSymbol(sym))
+ case _ =>
+ false
+ })
+ }
+ // No normalization.
+ def isTupleTypeDirect(tp: Type) = isPossiblySpecializedType(tp) {
+ case TypeRef(_, sym, args) if args.nonEmpty =>
+ val len = args.length
+ len <= MaxTupleArity && sym == TupleClass(len)
+ case _ => false
+ }
+ def isTupleType(tp: Type) = isTupleTypeDirect(tp.normalize)
+
+ def tupleType(elems: List[Type]) = {
+ val len = elems.length
+ if (len <= MaxTupleArity) {
+ val sym = TupleClass(len)
+ typeRef(sym.typeConstructor.prefix, sym, elems)
+ } else NoType
+ }
lazy val ProductRootClass: Symbol = getRequiredClass("scala.Product")
def Product_productArity = getMember(ProductRootClass, nme.productArity)
@@ -1090,9 +1139,14 @@ trait Definitions extends reflect.api.StandardDefinitions {
def init() {
if (isInitialized) return
+ // Still fiddling with whether it's cleaner to do some of this setup here
+ // or from constructors. The latter approach tends to invite init order issues.
EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass)
EmptyPackage setInfo EmptyPackageClass.tpe
+ connectModuleToClass(EmptyPackage, EmptyPackageClass)
+ connectModuleToClass(RootPackage, RootClass)
+
RootClass.info.decls enter EmptyPackage
RootClass.info.decls enter RootPackage
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 2019b92836..4473d63f5f 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -451,12 +451,23 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isVarargsMethod = isMethod && hasFlag(VARARGS)
/** Package tests */
- final def isEmptyPackage = isPackage && name == nme.EMPTY_PACKAGE_NAME
- final def isEmptyPackageClass = isPackageClass && name == tpnme.EMPTY_PACKAGE_NAME
final def isPackage = isModule && hasFlag(PACKAGE)
final def isPackageClass = isClass && hasFlag(PACKAGE)
- final def isRoot = isPackageClass && owner == NoSymbol
- final def isRootPackage = isPackage && owner == NoSymbol
+
+ /** Overridden in custom objects in Definitions */
+ def isRoot = false
+ def isRootPackage = false
+ def isRootSymbol = false // RootPackage and RootClass. TODO: also NoSymbol.
+ def isEmptyPackage = false
+ def isEmptyPackageClass = false
+
+ /** Is this symbol an effective root for fullname string?
+ */
+ def isEffectiveRoot = false
+
+ /** For RootClass, EmptyPackageClass. For all other symbols, itself.
+ */
+ def ownerOfNewSymbols = this
/** Does this symbol denote a wrapper created by the repl? */
final def isInterpreterWrapper = (
@@ -464,9 +475,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
&& owner.isPackageClass
&& nme.isReplWrapperName(name)
)
- /** Is this symbol an effective root for fullname string?
- */
- def isEffectiveRoot = isRoot || isEmptyPackageClass
/** Term symbols with the exception of static parts of Java classes and packages.
*/
@@ -652,8 +660,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isModuleVar = hasFlag(MODULEVAR)
/** Is this symbol static (i.e. with no outer instance)? */
- final def isStatic: Boolean =
- hasFlag(STATIC) || isRoot || owner.isStaticOwner
+ def isStatic = (this hasFlag STATIC) || owner.isStaticOwner
/** Is this symbol a static constructor? */
final def isStaticConstructor: Boolean =
@@ -685,8 +692,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isConstant: Boolean = isStable && isConstantType(tpe.resultType)
/** Is this class nested in another class or module (not a package)? */
- final def isNestedClass: Boolean =
- isClass && !isRoot && !owner.isPackageClass
+ def isNestedClass = isClass && !owner.isPackageClass
/** Is this class locally defined?
* A class is local, if
@@ -2045,7 +2051,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def fullNameString: String = {
def recur(sym: Symbol): String = {
- if (sym.isRoot || sym.isRootPackage || sym == NoSymbol) sym.nameString
+ if (sym.isRootSymbol || sym == NoSymbol) sym.nameString
else if (sym.owner.isEffectiveRoot) sym.nameString
else recur(sym.effectiveOwner.enclClass) + "." + sym.nameString
}
@@ -2095,7 +2101,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
case rt => " <: " + rt
}
)
- else if (isModule) moduleClass.infoString(tp)
+ else if (isModule) "" // avoid "object X of type X.type"
else tp match {
case PolyType(tparams, res) => typeParamsString(tp) + infoString(res)
case NullaryMethodType(res) => infoString(res)
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index bb9549deba..5afa5343ed 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -904,6 +904,12 @@ trait Types extends api.Types { self: SymbolTable =>
else str
}
+ /** The string representation of this type when the direct object in a sentence.
+ * Normally this is no different from the regular representation, but modules
+ * read better as "object Foo" here and "Foo.type" the rest of the time.
+ */
+ def directObjectString = safeToString
+
/** A test whether a type contains any unification type variables. */
def isGround: Boolean = this match {
case TypeVar(_, constr) =>
@@ -1224,8 +1230,7 @@ trait Types extends api.Types { self: SymbolTable =>
else if (sym.isModuleClass) sym.fullNameString + "."
else sym.nameString + ".this."
override def safeToString: String =
- if (sym.isRoot) "<root>"
- else if (sym.isEmptyPackageClass) "<empty>"
+ if (sym.isEffectiveRoot) "" + sym.name
else super.safeToString
override def narrow: Type = this
override def kind = "ThisType"
@@ -1851,6 +1856,35 @@ trait Types extends api.Types { self: SymbolTable =>
// advantage to call TypeRef directly.
override def typeConstructor = TypeRef(pre, sym, Nil)
}
+
+ class ModuleTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef {
+ require(sym.isModuleClass, sym)
+ private[this] var narrowedCache: Type = _
+ override def isStable = true
+ override def narrow = {
+ if (narrowedCache eq null)
+ narrowedCache = singleType(pre, sym.sourceModule)
+
+ narrowedCache
+ }
+ final override def isNotNull = true
+ override protected def finishPrefix(rest: String) = objectPrefix + rest
+ override def directObjectString = super.safeToString
+ override def toLongString = toString
+ override def safeToString = narrow.toString
+ }
+ class PackageTypeRef(pre0: Type, sym0: Symbol) extends ModuleTypeRef(pre0, sym0) {
+ require(sym.isPackageClass, sym)
+ override protected def finishPrefix(rest: String) = packagePrefix + rest
+ }
+ class RefinementTypeRef(sym0: Symbol) extends NoArgsTypeRef(NoType, sym0) with ClassTypeRef {
+ require(sym.isRefinementClass, sym)
+
+ // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
+ override protected def normalizeImpl: Type = sym.info.normalize
+ override protected def finishPrefix(rest: String) = "" + thisInfo
+ }
+
class NoArgsTypeRef(pre0: Type, sym0: Symbol) extends TypeRef(pre0, sym0, Nil) with UniqueType {
// A reference (in a Scala program) to a type that has type parameters, but where the reference
// does not include type arguments. Note that it doesn't matter whether the symbol refers
@@ -1898,10 +1932,6 @@ trait Types extends api.Types { self: SymbolTable =>
// !!! There are scaladoc-created symbols arriving which violate this require.
// require(sym.isClass, sym)
- override protected def normalizeImpl: Type =
- if (sym.isRefinementClass) sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers
- else super.normalizeImpl
-
override def baseType(clazz: Symbol): Type =
if (sym == clazz) this
else transform(sym.info.baseType(clazz))
@@ -2147,12 +2177,15 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
- private def preString = (
- // ensure that symbol is not a local copy with a name coincidence
- if (!settings.debug.value && shorthands(sym.fullName) && sym.ownerChain.forall(_.isClass)) ""
- else pre.prefixString
+ // ensure that symbol is not a local copy with a name coincidence
+ private def needsPreString = (
+ settings.debug.value
+ || !shorthands(sym.fullName)
+ || sym.ownerChain.exists(s => !s.isClass)
)
+ private def preString = if (needsPreString) pre.prefixString else ""
private def argsString = if (args.isEmpty) "" else args.mkString("[", ",", "]")
+
def refinementString = (
if (sym.isStructuralRefinement) (
decls filter (sym => sym.isPossibleInRefinement && sym.isPublic)
@@ -2162,25 +2195,23 @@ 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) parentsString(thisInfo.parents) + refinementString
- else if (sym.isRefinementClass) "" + thisInfo
+ protected def finishPrefix(rest: String) = (
+ if (sym.isInitialized && sym.isAnonymousClass && !phase.erasedTypes)
+ parentsString(thisInfo.parents) + refinementString
else rest
)
private def customToString = this match {
case TypeRef(_, RepeatedParamClass, arg :: _) => arg + "*"
case TypeRef(_, ByNameParamClass, arg :: _) => "=> " + arg
case _ =>
+ def targs = normalize.typeArgs
+
if (isFunctionType(this)) {
- val targs = normalize.typeArgs
// Aesthetics: printing Function1 as T => R rather than (T) => R
// ...but only if it's not a tuple, so ((T1, T2)) => R is distinguishable
// from (T1, T2) => R.
targs match {
- case in :: out :: Nil if !isTupleTypeOrSubtype(in) =>
+ case in :: out :: Nil if !isTupleType(in) =>
// A => B => C should be (A => B) => C or A => (B => C)
val in_s = if (isFunctionType(in)) "(" + in + ")" else "" + in
val out_s = if (isFunctionType(out)) "(" + out + ")" else "" + out
@@ -2189,9 +2220,9 @@ trait Types extends api.Types { self: SymbolTable =>
xs.init.mkString("(", ", ", ")") + " => " + xs.last
}
}
- else if (isTupleTypeOrSubtype(this))
- normalize.typeArgs.mkString("(", ", ", if (hasLength(normalize.typeArgs, 1)) ",)" else ")")
- else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (normalize ne this))
+ else if (isTupleType(this))
+ targs.mkString("(", ", ", if (hasLength(targs, 1)) ",)" else ")")
+ else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (this ne this.normalize))
"" + normalize
else
""
@@ -2226,6 +2257,9 @@ trait Types extends api.Types { self: SymbolTable =>
else {
if (sym.isAliasType) new NoArgsTypeRef(pre, sym) with AliasTypeRef
else if (sym.isAbstractType) new NoArgsTypeRef(pre, sym) with AbstractTypeRef
+ else if (sym.isRefinementClass) new RefinementTypeRef(sym)
+ else if (sym.isPackageClass) new PackageTypeRef(pre, sym)
+ else if (sym.isModuleClass) new ModuleTypeRef(pre, sym)
else new NoArgsTypeRef(pre, sym) with ClassTypeRef
}
})
@@ -3615,6 +3649,23 @@ trait Types extends api.Types { self: SymbolTable =>
}
}
+ class TypeUnwrapper(poly: Boolean, existential: Boolean, annotated: Boolean, nullary: Boolean) extends (Type => Type) {
+ def apply(tp: Type): Type = tp match {
+ case AnnotatedType(_, underlying, _) if annotated => apply(underlying)
+ case ExistentialType(_, underlying) if existential => apply(underlying)
+ case PolyType(_, underlying) if poly => apply(underlying)
+ case NullaryMethodType(underlying) if nullary => apply(underlying)
+ case tp => tp
+ }
+ }
+ class ClassUnwrapper(existential: Boolean) extends TypeUnwrapper(poly = true, existential, annotated = true, nullary = false) {
+ override def apply(tp: Type) = super.apply(tp.normalize)
+ }
+
+ object unwrapToClass extends ClassUnwrapper(existential = true) { }
+ object unwrapToStableClass extends ClassUnwrapper(existential = false) { }
+ object unwrapWrapperTypes extends TypeUnwrapper(true, true, true, true) { }
+
trait AnnotationFilter extends TypeMap {
def keepAnnotation(annot: AnnotationInfo): Boolean
@@ -4585,31 +4636,22 @@ trait Types extends api.Types { self: SymbolTable =>
object adaptToNewRunMap extends TypeMap {
private def adaptToNewRun(pre: Type, sym: Symbol): Symbol = {
- if (phase.flatClasses) {
+ if (phase.flatClasses || sym.isRootSymbol || (pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass)
sym
- } else if (sym == definitions.RootClass) {
- definitions.RootClass
- } else if (sym == definitions.RootPackage) {
- definitions.RootPackage
- } else if (sym.isModuleClass) {
+ else if (sym.isModuleClass) {
val sourceModule1 = adaptToNewRun(pre, sym.sourceModule)
- var result = sourceModule1.moduleClass
- if (result == NoSymbol) result = sourceModule1.initialize.moduleClass
- if (result != NoSymbol) result
- else {
+
+ sourceModule1.moduleClass orElse sourceModule1.initialize.moduleClass orElse {
val msg = "Cannot adapt module class; sym = %s, sourceModule = %s, sourceModule.moduleClass = %s => sourceModule1 = %s, sourceModule1.moduleClass = %s"
debuglog(msg.format(sym, sym.sourceModule, sym.sourceModule.moduleClass, sourceModule1, sourceModule1.moduleClass))
sym
}
- } else if ((pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass) {
- sym
- } else {
- var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true)
- if (rebind0 == NoSymbol) {
+ }
+ else {
+ var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true) orElse {
if (sym.isAliasType) throw missingAliasException
debugwarn(pre+"."+sym+" does no longer exist, phase = "+phase)
throw new MissingTypeControl // For build manager and presentation compiler purposes
- //assert(false, pre+"."+sym+" does no longer exist, phase = "+phase)
}
/** The two symbols have the same fully qualified name */
def corresponds(sym1: Symbol, sym2: Symbol): Boolean =
@@ -4628,12 +4670,10 @@ trait Types extends api.Types { self: SymbolTable =>
", rebind = " + rebind0.fullLocationString
)
}
- val rebind = rebind0.suchThat(sym => sym.isType || sym.isStable)
- if (rebind == NoSymbol) {
+ rebind0.suchThat(sym => sym.isType || sym.isStable) orElse {
debuglog("" + phase + " " +phase.flatClasses+sym.owner+sym.name+" "+sym.isType)
throw new MalformedType(pre, sym.nameString)
}
- rebind
}
}
def apply(tp: Type): Type = tp match {
@@ -5454,9 +5494,14 @@ trait Types extends api.Types { self: SymbolTable =>
case _: ClassSymbol =>
if (isRaw(sym1, tr1.args))
isSubType(rawToExistential(tp1), tp2, depth)
- else
- sym1.name == tpnme.REFINE_CLASS_NAME &&
+ else if (sym1.isModuleClass) tp2 match {
+ case SingleType(_, sym2) => sym1 == sym2
+ case _ => false
+ }
+ else if (sym1.isRefinementClass)
isSubType(sym1.info, tp2, depth)
+ else false
+
case _: TypeSymbol =>
if (sym1 hasFlag DEFERRED) {
val tp1a = tp1.bounds.hi
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index dd1c75c322..702d643fb4 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -620,7 +620,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
case tp: TypeRef if definitions.isByNameParamType(tp) =>
nameBuffer append "⇒ "
appendType0(tp.args.head)
- case tp: TypeRef if definitions.isTupleTypeOrSubtype(tp) =>
+ case tp: TypeRef if definitions.isTupleType(tp) =>
val args = tp.normalize.typeArgs
nameBuffer append '('
appendTypes0(args, ", ")
diff --git a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala
index 015dc2a7f1..808f549304 100644
--- a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala
@@ -15,7 +15,7 @@ trait CompletionOutput {
val global: Global
import global._
- import definitions.{ isTupleTypeOrSubtype, isFunctionType, isRepeatedParamType }
+ import definitions.{ isTupleType, isFunctionType, isRepeatedParamType }
/** Reducing fully qualified noise for some common packages.
*/
@@ -48,11 +48,11 @@ trait CompletionOutput {
def typeToString(tp: Type): String = relativize(
tp match {
- case x if isFunctionType(x) => functionString(x)
- case x if isTupleTypeOrSubtype(x) => tupleString(x)
- case x if isRepeatedParamType(x) => typeToString(x.typeArgs.head) + "*"
- case mt @ MethodType(_, _) => methodTypeToString(mt)
- case x => x.toString
+ case x if isFunctionType(x) => functionString(x)
+ case x if isTupleType(x) => tupleString(x)
+ case x if isRepeatedParamType(x) => typeToString(x.typeArgs.head) + "*"
+ case mt @ MethodType(_, _) => methodTypeToString(mt)
+ case x => x.toString
}
)
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 8bdf83fda4..4f6a4c8dc0 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -343,10 +343,9 @@ trait Patterns extends ast.TreeDSL {
def apply(x: Apply): Pattern = {
val Apply(fn, args) = x
def isModule = x.symbol.isModule || x.tpe.termSymbol.isModule
- def isTuple = isTupleTypeOrSubtype(fn.tpe)
if (fn.isType) {
- if (isTuple) TuplePattern(x)
+ if (isTupleType(fn.tpe)) TuplePattern(x)
else ConstructorPattern(x)
}
else if (args.isEmpty) {
diff --git a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
index 59342a36ef..5f7deb87bd 100644
--- a/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
@@ -105,7 +105,7 @@ abstract class BrowsingLoaders extends SymbolLoaders {
*/
override def enterToplevelsFromSource(root: Symbol, name: String, src: AbstractFile) {
try {
- if (root == definitions.RootClass || root == definitions.EmptyPackageClass)
+ if (root.isEffectiveRoot) // RootClass or EmptyPackageClass
super.enterToplevelsFromSource(root, name, src)
else
browseTopLevel(root, src)
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index f9ff147e82..7eb04eaf40 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -30,15 +30,11 @@ abstract class SymbolLoaders {
member
}
- private def realOwner(root: Symbol): Symbol = {
- if (root.isRoot) definitions.EmptyPackageClass else root
- }
-
/** Enter class with given `name` into scope of `root`
* and give them `completer` as type.
*/
def enterClass(root: Symbol, name: String, completer: SymbolLoader): Symbol = {
- val owner = realOwner(root)
+ val owner = root.ownerOfNewSymbols
val clazz = owner.newClass(newTypeName(name))
clazz setInfo completer
enterIfNew(owner, clazz, completer)
@@ -48,7 +44,7 @@ abstract class SymbolLoaders {
* and give them `completer` as type.
*/
def enterModule(root: Symbol, name: String, completer: SymbolLoader): Symbol = {
- val owner = realOwner(root)
+ val owner = root.ownerOfNewSymbols
val module = owner.newModule(newTermName(name))
module setInfo completer
module.moduleClass setInfo moduleClassLoader
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 61668b1a8a..9dee441527 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -433,10 +433,7 @@ abstract class ClassfileParser {
sym.info.decl(part.encode)
}//.suchThat(module == _.isModule)
- sym = (
- if (sym1 ne NoSymbol) sym1
- else sym.info.decl(part.encode.toTypeName)
- )
+ sym = sym1 orElse sym.info.decl(part.encode.toTypeName)
}
}
sym
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 185cf4f533..1afa1dbf58 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -134,16 +134,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case _ => false
}
- def unspecializedSymbol(sym: Symbol): Symbol = {
- if (sym hasFlag SPECIALIZED) {
- // add initialization from its generic class constructor
- val genericName = nme.unspecializedName(sym.name)
- val member = sym.owner.info.decl(genericName.toTypeName)
- member
- }
- else NoSymbol
- }
-
object TypeEnv {
/** Return a new type environment binding specialized type parameters of sym to
* the given args. Expects the lists to have the same length.
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 764823d786..49ddb985dc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -317,7 +317,7 @@ trait ContextErrors {
}
withAddendum(qual.pos)(
if (name == nme.CONSTRUCTOR) target + " does not have a constructor"
- else nameString + " is not a member of " + targetKindString + target + addendum
+ else nameString + " is not a member of " + targetKindString + target.directObjectString + addendum
)
}
issueNormalTypeError(sel, errMsg)
@@ -677,7 +677,7 @@ trait ContextErrors {
def AccessError(tree: Tree, sym: Symbol, pre: Type, owner0: Symbol, explanation: String) = {
def errMsg = {
- val location = if (sym.isClassConstructor) owner0 else pre.widen
+ val location = if (sym.isClassConstructor) owner0 else pre.widen.directObjectString
underlyingSymbol(sym).fullLocationString + " cannot be accessed in " +
location + explanation
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 9177aca656..045614e773 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -267,6 +267,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
sym1.locationString +
(if (sym1.isAliasType) ", which equals "+self.memberInfo(sym1)
else if (sym1.isAbstractType) " with bounds"+self.memberInfo(sym1)
+ else if (sym1.isModule) ""
else if (sym1.isTerm) " of type "+self.memberInfo(sym1)
else "")
else "")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 7d2e587b3f..2aff00f6a5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -235,32 +235,41 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
result
}
}
+ def isNonRefinementClassType(tpe: Type) = tpe match {
+ case SingleType(_, sym) => sym.isModuleClass
+ case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass
+ case ErrorType => true
+ case _ => false
+ }
+ private def errorNotClass(tpt: Tree, found: Type) = { ClassTypeRequiredError(tpt, found); false }
+ private def errorNotStable(tpt: Tree, found: Type) = { TypeNotAStablePrefixError(tpt, found); false }
/** Check that `tpt` refers to a non-refinement class type */
- def checkClassType(tpt: Tree, existentialOK: Boolean, stablePrefix: Boolean): Boolean = {
- def errorNotClass(found: AnyRef) = { ClassTypeRequiredError(tpt, found); false }
- def check(tpe: Type): Boolean = tpe.normalize match {
- case TypeRef(pre, sym, _) if sym.isClass && !sym.isRefinementClass =>
- if (stablePrefix && !isPastTyper)
- if (!pre.isStable) {
- TypeNotAStablePrefixError(tpt, pre)
- false
- } else
- // A type projection like X#Y can get by the stable check if the
- // prefix is singleton-bounded, so peek at the tree too.
- tpt match {
- case SelectFromTypeTree(qual, _) if !isSingleType(qual.tpe) => errorNotClass(tpt)
- case _ => true
- }
- else
- true
- case ErrorType => true
- case PolyType(_, restpe) => check(restpe)
- case ExistentialType(_, restpe) if existentialOK => check(restpe)
- case AnnotatedType(_, underlying, _) => check(underlying)
- case t => errorNotClass(t)
+ def checkClassType(tpt: Tree): Boolean = {
+ val tpe = unwrapToClass(tpt.tpe)
+ isNonRefinementClassType(tpe) || errorNotClass(tpt, tpe)
+ }
+
+ /** Check that `tpt` refers to a class type with a stable prefix. */
+ def checkStablePrefixClassType(tpt: Tree): Boolean = {
+ val tpe = unwrapToStableClass(tpt.tpe)
+ def prefixIsStable = {
+ def checkPre = tpe match {
+ case TypeRef(pre, _, _) => pre.isStable || errorNotStable(tpt, pre)
+ case _ => false
+ }
+ // A type projection like X#Y can get by the stable check if the
+ // prefix is singleton-bounded, so peek at the tree too.
+ def checkTree = tpt match {
+ case SelectFromTypeTree(qual, _) => isSingleType(qual.tpe) || errorNotClass(tpt, tpe)
+ case _ => true
+ }
+ checkPre && checkTree
}
- check(tpt.tpe)
+
+ ( (isNonRefinementClassType(tpe) || errorNotClass(tpt, tpe))
+ && (isPastTyper || prefixIsStable)
+ )
}
/** Check that type <code>tp</code> is not a subtype of itself.
@@ -643,13 +652,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
- private def isNarrowable(tpe: Type): Boolean = tpe match {
+ private def isNarrowable(tpe: Type): Boolean = unwrapWrapperTypes(tpe) match {
case TypeRef(_, _, _) | RefinedType(_, _) => true
- case ExistentialType(_, tpe1) => isNarrowable(tpe1)
- case AnnotatedType(_, tpe1, _) => isNarrowable(tpe1)
- case PolyType(_, tpe1) => isNarrowable(tpe1)
- case NullaryMethodType(tpe1) => isNarrowable(tpe1)
- case _ => !phase.erasedTypes
+ case _ => !phase.erasedTypes
}
/**
@@ -1438,7 +1443,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def validateParentClass(parent: Tree, superclazz: Symbol) {
if (!parent.isErrorTyped) {
val psym = parent.tpe.typeSymbol.initialize
- checkClassType(parent, false, true)
+ checkStablePrefixClassType(parent)
if (psym != superclazz) {
if (psym.isTrait) {
val ps = psym.info.parents
@@ -3353,7 +3358,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def typedClassOf(tree: Tree, tpt: Tree, noGen: Boolean = false) =
- if (!checkClassType(tpt, true, false) && noGen) tpt
+ if (!checkClassType(tpt) && noGen) tpt
else atPos(tree.pos)(gen.mkClassOf(tpt.tpe))
protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Int): Tree = {
@@ -3665,7 +3670,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
def typedNew(tpt: Tree) = {
val tpt1 = {
val tpt0 = typedTypeConstructor(tpt)
- if (checkClassType(tpt0, false, true))
+ if (checkStablePrefixClassType(tpt0))
if (tpt0.hasSymbol && !tpt0.symbol.typeParams.isEmpty) {
context.undetparams = cloneSymbols(tpt0.symbol.typeParams)
TypeTree().setOriginal(tpt0)
diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala
index 75ab3f28f5..a978a9a783 100644
--- a/src/library/scala/collection/JavaConversions.scala
+++ b/src/library/scala/collection/JavaConversions.scala
@@ -127,3 +127,5 @@ object JavaConversions extends WrapAsScala with WrapAsJava {
@deprecated("use propertiesAsScalaMap instead", "2.9.0")
def asScalaMap(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
}
+
+
diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala
index 13f1f19f81..f8a9466caf 100755
--- a/src/library/scala/collection/JavaConverters.scala
+++ b/src/library/scala/collection/JavaConverters.scala
@@ -100,4 +100,4 @@ object JavaConverters extends DecorateAsJava with DecorateAsScala {
@deprecated("Use propertiesAsScalaMapConverter instead", "2.9.0")
def asScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] = propertiesAsScalaMapConverter(p)
-} \ No newline at end of file
+}
diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala
index 76837d937c..e05bfc41cd 100644
--- a/src/library/scala/collection/convert/DecorateAsJava.scala
+++ b/src/library/scala/collection/convert/DecorateAsJava.scala
@@ -291,6 +291,26 @@ trait DecorateAsJava {
* @return An object with an `asJava` method that returns a Java
* `ConcurrentMap` view of the argument.
*/
+ @deprecated("Use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
implicit def asJavaConcurrentMapConverter[A, B](m: mutable.ConcurrentMap[A, B]): AsJava[juc.ConcurrentMap[A, B]] =
new AsJava(asJavaConcurrentMap(m))
+
+ /**
+ * Adds an `asJava` method that implicitly converts a Scala mutable
+ * `concurrent.Map` to a Java `ConcurrentMap`.
+ *
+ * The returned Java `ConcurrentMap` is backed by the provided Scala
+ * `concurrent.Map` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `concurrent.Map` was previously obtained from an implicit or
+ * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * then the original Java `ConcurrentMap` will be returned.
+ *
+ * @param m The Scala `concurrent.Map` to be converted.
+ * @return An object with an `asJava` method that returns a Java
+ * `ConcurrentMap` view of the argument.
+ */
+ implicit def asJavaConcurrentMapConverter[A, B](m: concurrent.Map[A, B]): AsJava[juc.ConcurrentMap[A, B]] =
+ new AsJava(asJavaConcurrentMap(m))
}
diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala
index bb14228e67..722f0b9af9 100644
--- a/src/library/scala/collection/convert/DecorateAsScala.scala
+++ b/src/library/scala/collection/convert/DecorateAsScala.scala
@@ -156,10 +156,29 @@ trait DecorateAsScala {
* @return An object with an `asScala` method that returns a Scala mutable
* `ConcurrentMap` view of the argument.
*/
- implicit def asScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[mutable.ConcurrentMap[A, B]] =
+ @deprecated("Use `mapAsScalaConcurrentMapConverter` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
+ def asScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[mutable.ConcurrentMap[A, B]] =
new AsScala(asScalaConcurrentMap(m))
/**
+ * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap`
+ * to a Scala mutable `concurrent.Map`. The returned Scala `concurrent.Map` is
+ * backed by the provided Java `ConcurrentMap` and any side-effects of using
+ * it via the Scala interface will be visible via the Java interface and
+ * vice versa.
+ *
+ * If the Java `ConcurrentMap` was previously obtained from an implicit or
+ * explicit call of `mapAsScalaConcurrentMap(scala.collection.mutable.ConcurrentMap)`
+ * then the original Scala `concurrent.Map` will be returned.
+ *
+ * @param m The `ConcurrentMap` to be converted.
+ * @return An object with an `asScala` method that returns a Scala mutable
+ * `concurrent.Map` view of the argument.
+ */
+ implicit def mapAsScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[concurrent.Map[A, B]] =
+ new AsScala(mapAsScalaConcurrentMap(m))
+
+ /**
* Adds an `asScala` method that implicitly converts a Java `Dictionary`
* to a Scala mutable `Map[String, String]`. The returned Scala
* `Map[String, String]` is backed by the provided Java `Dictionary` and
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
index 6274518d1a..cdec72b9fe 100644
--- a/src/library/scala/collection/convert/WrapAsJava.scala
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -241,16 +241,45 @@ trait WrapAsJava {
* will be visible via the Scala interface and vice versa.
*
* If the Scala `ConcurrentMap` was previously obtained from an implicit or
- * explicit call of `asConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * explicit call of `asScalaConcurrentMap(java.util.concurrect.ConcurrentMap)`
* then the original Java ConcurrentMap will be returned.
*
* @param m The `ConcurrentMap` to be converted.
* @return A Java `ConcurrentMap` view of the argument.
*/
+ @deprecated("Use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
implicit def asJavaConcurrentMap[A, B](m: mutable.ConcurrentMap[A, B]): juc.ConcurrentMap[A, B] = m match {
+ case JConcurrentMapDeprecatedWrapper(wrapped) => wrapped
+ case _ => new ConcurrentMapDeprecatedWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Scala mutable `concurrent.Map` to a Java
+ * `ConcurrentMap`.
+ *
+ * The returned Java `ConcurrentMap` is backed by the provided Scala
+ * `concurrent.Map` and any side-effects of using it via the Java interface
+ * will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `concurrent.Map` was previously obtained from an implicit or
+ * explicit call of `mapAsScalaConcurrentMap(java.util.concurrect.ConcurrentMap)`
+ * then the original Java ConcurrentMap will be returned.
+ *
+ * @param m The Scala `concurrent.Map` to be converted.
+ * @return A Java `ConcurrentMap` view of the argument.
+ */
+ implicit def asJavaConcurrentMap[A, B](m: concurrent.Map[A, B]): juc.ConcurrentMap[A, B] = m match {
case JConcurrentMapWrapper(wrapped) => wrapped
case _ => new ConcurrentMapWrapper(m)
}
}
object WrapAsJava extends WrapAsJava { }
+
+
+
+
+
+
+
+
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
index 02b58f55a4..56e13b2105 100644
--- a/src/library/scala/collection/convert/WrapAsScala.scala
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -154,9 +154,28 @@ trait WrapAsScala {
* @param m The ConcurrentMap to be converted.
* @return A Scala mutable ConcurrentMap view of the argument.
*/
- implicit def asScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = m match {
- case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying
- case _ => new JConcurrentMapWrapper(m)
+ @deprecated("Use `mapAsScalaConcurrentMap` instead, and use `concurrent.Map` instead of `ConcurrentMap`.", "2.10.0")
+ def asScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): mutable.ConcurrentMap[A, B] = m match {
+ case cmw: ConcurrentMapDeprecatedWrapper[a, b] => cmw.underlying
+ case _ => new JConcurrentMapDeprecatedWrapper(m)
+ }
+
+ /**
+ * Implicitly converts a Java ConcurrentMap to a Scala mutable ConcurrentMap.
+ * The returned Scala ConcurrentMap is backed by the provided Java
+ * ConcurrentMap and any side-effects of using it via the Scala interface will
+ * be visible via the Java interface and vice versa.
+ *
+ * If the Java ConcurrentMap was previously obtained from an implicit or
+ * explicit call of `asConcurrentMap(scala.collection.mutable.ConcurrentMap)`
+ * then the original Scala ConcurrentMap will be returned.
+ *
+ * @param m The ConcurrentMap to be converted.
+ * @return A Scala mutable ConcurrentMap view of the argument.
+ */
+ implicit def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = m match {
+ case cmw: ConcurrentMapWrapper[a, b] => cmw.underlying
+ case _ => new JConcurrentMapWrapper(m)
}
/**
diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala
index 8136e462cb..b1b48b760f 100644
--- a/src/library/scala/collection/convert/Wrappers.scala
+++ b/src/library/scala/collection/convert/Wrappers.scala
@@ -268,7 +268,7 @@ private[collection] trait Wrappers {
override def empty = JMapWrapper(new ju.HashMap[A, B])
}
- class ConcurrentMapWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
+ class ConcurrentMapDeprecatedWrapper[A, B](override val underlying: mutable.ConcurrentMap[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
case Some(v) => v
@@ -290,7 +290,54 @@ private[collection] trait Wrappers {
def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
}
- case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with mutable.ConcurrentMap[A, B] {
+ class ConcurrentMapWrapper[A, B](override val underlying: concurrent.Map[A, B]) extends MutableMapWrapper[A, B](underlying) with juc.ConcurrentMap[A, B] {
+
+ def putIfAbsent(k: A, v: B) = underlying.putIfAbsent(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def remove(k: AnyRef, v: AnyRef) = try {
+ underlying.remove(k.asInstanceOf[A], v.asInstanceOf[B])
+ } catch {
+ case ex: ClassCastException =>
+ false
+ }
+
+ def replace(k: A, v: B): B = underlying.replace(k, v) match {
+ case Some(v) => v
+ case None => null.asInstanceOf[B]
+ }
+
+ def replace(k: A, oldval: B, newval: B) = underlying.replace(k, oldval, newval)
+ }
+
+ case class JConcurrentMapDeprecatedWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapDeprecatedWrapper[A, B]] with mutable.ConcurrentMap[A, B] {
+ override def get(k: A) = {
+ val v = underlying get k
+ if (v != null) Some(v)
+ else None
+ }
+
+ override def empty = new JConcurrentMapDeprecatedWrapper(new juc.ConcurrentHashMap[A, B])
+
+ def putIfAbsent(k: A, v: B): Option[B] = {
+ val r = underlying.putIfAbsent(k, v)
+ if (r != null) Some(r) else None
+ }
+
+ def remove(k: A, v: B): Boolean = underlying.remove(k, v)
+
+ def replace(k: A, v: B): Option[B] = {
+ val prev = underlying.replace(k, v)
+ if (prev != null) Some(prev) else None
+ }
+
+ def replace(k: A, oldvalue: B, newvalue: B): Boolean =
+ underlying.replace(k, oldvalue, newvalue)
+ }
+
+ case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) extends mutable.AbstractMap[A, B] with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with concurrent.Map[A, B] {
override def get(k: A) = {
val v = underlying get k
if (v != null) Some(v)
diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala
index cc0aed6963..06b7d40bfc 100644
--- a/src/library/scala/collection/mutable/HashTable.scala
+++ b/src/library/scala/collection/mutable/HashTable.scala
@@ -366,7 +366,7 @@ private[collection] object HashTable {
private[collection] final def newThreshold(_loadFactor: Int, size: Int) = ((size.toLong * _loadFactor) / loadFactorDenum).toInt
- private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = thr * loadFactorDenum / _loadFactor
+ private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = ((thr.toLong * loadFactorDenum) / _loadFactor).toInt
private[collection] final def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize)
diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala
index ba98757906..f4744a8757 100644
--- a/src/library/scala/concurrent/ConcurrentPackageObject.scala
+++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala
@@ -10,8 +10,8 @@ package scala.concurrent
-import java.util.concurrent.{ Executors, ExecutorService }
-import scala.concurrent.forkjoin.ForkJoinPool
+import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory }
+import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread }
import scala.util.{ Try, Success, Failure }
import scala.concurrent.util.Duration
import ConcurrentPackageObject._
@@ -24,14 +24,9 @@ abstract class ConcurrentPackageObject {
/** A global execution environment for executing lightweight tasks.
*/
lazy val executionContext =
- new impl.ExecutionContextImpl(getExecutorService)
-
- private[concurrent] def getExecutorService: AnyRef =
- if (scala.util.Properties.isJavaAtLeast("1.6")) {
- val vendor = scala.util.Properties.javaVmVendor
- if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple")) new ForkJoinPool
- else Executors.newCachedThreadPool()
- } else Executors.newCachedThreadPool()
+ new impl.ExecutionContextImpl()
+
+ private val currentExecutionContext = new ThreadLocal[ExecutionContext]
val handledFutureException: PartialFunction[Throwable, Throwable] = {
case t: Throwable if isFutureThrowable(t) => t
@@ -58,10 +53,10 @@ abstract class ConcurrentPackageObject {
/* concurrency constructs */
- def future[T](body: =>T)(implicit execCtx: ExecutionContext = executionContext): Future[T] =
+ def future[T](body: =>T)(implicit execctx: ExecutionContext = executionContext): Future[T] =
Future[T](body)
- def promise[T]()(implicit execCtx: ExecutionContext = executionContext): Promise[T] =
+ def promise[T]()(implicit execctx: ExecutionContext = executionContext): Promise[T] =
Promise[T]()
/** Wraps a block of code into an awaitable object. */
@@ -82,8 +77,8 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](body: =>T)(implicit execCtx: ExecutionContext): T =
- executionContext.blocking(body)
+ def blocking[T](body: =>T): T =
+ blocking(body2awaitable(body), Duration.fromNanos(0))
/** Blocks on an awaitable object.
*
@@ -94,8 +89,11 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](awaitable: Awaitable[T], atMost: Duration)(implicit execCtx: ExecutionContext = executionContext): T =
- executionContext.blocking(awaitable, atMost)
+ def blocking[T](awaitable: Awaitable[T], atMost: Duration): T =
+ currentExecutionContext.get match {
+ case null => Await.result(awaitable, atMost)
+ case ec => ec.internalBlockingCall(awaitable, atMost)
+ }
@inline implicit final def int2durationops(x: Int): DurationOps = new DurationOps(x)
}
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index a206a2d4ea..f639f76dc9 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -26,10 +26,8 @@ trait ExecutionContext {
def execute[U](body: () => U): Unit
- def blocking[T](body: =>T): T
-
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T
-
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T
+
def reportFailure(t: Throwable): Unit
/* implementations follow */
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index d73801aa90..8cecadc605 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -274,6 +274,18 @@ self =>
p.future
}
+ /** Used by for-comprehensions.
+ */
+ final def withFilter(p: T => Boolean): Future[T] = filter(p)
+ // final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
+
+ // final class FutureWithFilter[+S](self: Future[S], p: S => Boolean) {
+ // def foreach(f: S => Unit): Unit = self filter p foreach f
+ // def map[R](f: S => R) = self filter p map f
+ // def flatMap[R](f: S => Future[R]) = self filter p flatMap f
+ // def withFilter(q: S => Boolean): FutureWithFilter[S] = new FutureWithFilter[S](self, x => p(x) && q(x))
+ // }
+
/** Creates a new future by mapping the value of the current future if the given partial function is defined at that value.
*
* If the current future contains a value for which the partial function is defined, the new future will also hold that value.
@@ -417,7 +429,26 @@ self =>
p.future
}
-
+
+ /** Creates a new `Future[S]` which is completed with this `Future`'s result if
+ * that conforms to `S`'s erased type or a `ClassCastException` otherwise.
+ */
+ def mapTo[S](implicit m: Manifest[S]): Future[S] = {
+ val p = newPromise[S]
+
+ onComplete {
+ case l: Failure[_] => p complete l.asInstanceOf[Try[S]]
+ case Success(t) =>
+ p complete (try {
+ Success(impl.Future.boxedType(m.erasure).cast(t).asInstanceOf[S])
+ } catch {
+ case e: ClassCastException => Failure(e)
+ })
+ }
+
+ p.future
+ }
+
/** Applies the side-effecting function to the result of this future, and returns
* a new future with the result of this future.
*
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 5dc440f42b..2cfd6f22cd 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -10,7 +10,7 @@ package scala.concurrent.impl
-import java.util.concurrent.{Callable, ExecutorService}
+import java.util.concurrent.{Callable, ExecutorService, Executors, ThreadFactory}
import scala.concurrent.forkjoin._
import scala.concurrent.{ExecutionContext, resolver, Awaitable, body2awaitable}
import scala.util.{ Try, Success, Failure }
@@ -18,8 +18,42 @@ import scala.concurrent.util.{ Duration }
-private[scala] class ExecutionContextImpl(val executorService: AnyRef) extends ExecutionContext {
+private[scala] class ExecutionContextImpl() extends ExecutionContext {
import ExecutionContextImpl._
+
+ val executorService: AnyRef = getExecutorService
+
+ // to ensure that the current execution context thread local is properly set
+ private def executorsThreadFactory = new ThreadFactory {
+ def newThread(r: Runnable) = new Thread(new Runnable {
+ override def run() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
+ r.run()
+ }
+ })
+ }
+
+ // to ensure that the current execution context thread local is properly set
+ private def forkJoinPoolThreadFactory = new ForkJoinPool.ForkJoinWorkerThreadFactory {
+ def newThread(fjp: ForkJoinPool) = new ForkJoinWorkerThread(fjp) {
+ override def onStart() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
+ }
+ }
+ }
+
+ private def getExecutorService: AnyRef =
+ if (scala.util.Properties.isJavaAtLeast("1.6")) {
+ val vendor = scala.util.Properties.javaVmVendor
+ if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple"))
+ new ForkJoinPool(
+ Runtime.getRuntime.availableProcessors(),
+ forkJoinPoolThreadFactory,
+ null,
+ false)
+ else
+ Executors.newCachedThreadPool(executorsThreadFactory)
+ } else Executors.newCachedThreadPool(executorsThreadFactory)
def execute(runnable: Runnable): Unit = executorService match {
case fj: ForkJoinPool =>
@@ -37,9 +71,7 @@ private[scala] class ExecutionContextImpl(val executorService: AnyRef) extends E
def run() = body()
})
- def blocking[T](body: =>T): T = blocking(body2awaitable(body), Duration.fromNanos(0))
-
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T = {
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T = {
Future.releaseStack(this)
awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence)
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
index 6833b2467f..1111aa4753 100644
--- a/src/library/scala/concurrent/impl/Future.scala
+++ b/src/library/scala/concurrent/impl/Future.scala
@@ -40,36 +40,6 @@ private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awa
def onComplete[U](func: Try[T] => U): this.type
- /** Creates a new Future[A] which is completed with this Future's result if
- * that conforms to A's erased type or a ClassCastException otherwise.
- */
- final def mapTo[T](implicit m: Manifest[T]) = {
- val p = new Promise.DefaultPromise[T]
-
- onComplete {
- case f @ Failure(t) => p complete f.asInstanceOf[Try[T]]
- case Success(v) =>
- p complete (try {
- Success(Future.boxedType(m.erasure).cast(v).asInstanceOf[T])
- } catch {
- case e: ClassCastException => Failure(e)
- })
- }
-
- p.future
- }
-
- /** Used by for-comprehensions.
- */
- final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
-
- final class FutureWithFilter[+A](self: Future[A], p: A => Boolean) {
- def foreach(f: A => Unit): Unit = self filter p foreach f
- def map[B](f: A => B) = self filter p map f
- def flatMap[B](f: A => Future[B]) = self filter p flatMap f
- def withFilter(q: A => Boolean): FutureWithFilter[A] = new FutureWithFilter[A](self, x ⇒ p(x) && q(x))
- }
-
}
object Future {
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index c79b0d02cc..f05e306088 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -127,7 +127,7 @@ object Promise {
value.isDefined
}
- executor.blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost)
+ blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost)
}
def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index c1f45eccfb..cb42b76b51 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -183,7 +183,8 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def equals (that: Any): Boolean = that match {
case that: BigDecimal => this equals that
case that: BigInt => this.toBigIntExact exists (that equals _)
- case _: Float | _: Double => unifiedPrimitiveEquals(that)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case _ => isValidLong && unifiedPrimitiveEquals(that)
}
override def isValidByte = noArithmeticException(toByteExact)
@@ -191,6 +192,18 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def isValidChar = isValidInt && toIntExact >= Char.MinValue && toIntExact <= Char.MaxValue
override def isValidInt = noArithmeticException(toIntExact)
def isValidLong = noArithmeticException(toLongExact)
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val f = toFloat
+ !f.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(f)) == 0
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val d = toDouble
+ !d.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(d)) == 0
+ }
private def noArithmeticException(body: => Unit): Boolean = {
try { body ; true }
diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala
index 8a53afaa62..dbec30b2fe 100644
--- a/src/library/scala/math/BigInt.scala
+++ b/src/library/scala/math/BigInt.scala
@@ -20,6 +20,7 @@ object BigInt {
private val minCached = -1024
private val maxCached = 1024
private val cache = new Array[BigInt](maxCached - minCached + 1)
+ private val minusOne = BigInteger.valueOf(-1)
@deprecated("Use Long.MinValue", "2.9.0")
val MinLong = BigInt(Long.MinValue)
@@ -122,6 +123,8 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def equals(that: Any): Boolean = that match {
case that: BigInt => this equals that
case that: BigDecimal => that.toBigIntExact exists (this equals _)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case x => isValidLong && unifiedPrimitiveEquals(x)
}
override def isValidByte = this >= Byte.MinValue && this <= Byte.MaxValue
@@ -129,6 +132,41 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def isValidChar = this >= Char.MinValue && this <= Char.MaxValue
override def isValidInt = this >= Int.MinValue && this <= Int.MaxValue
def isValidLong = this >= Long.MinValue && this <= Long.MaxValue
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val bitLen = bitLength
+ (bitLen <= 24 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Float.MAX_EXPONENT + 1 && // exclude this < -2^128 && this >= 2^128
+ lowest >= bitLen - 24 &&
+ lowest < java.lang.Float.MAX_EXPONENT + 1 // exclude this == -2^128
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val bitLen = bitLength
+ (bitLen <= 53 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Double.MAX_EXPONENT + 1 && // exclude this < -2^1024 && this >= 2^1024
+ lowest >= bitLen - 53 &&
+ lowest < java.lang.Double.MAX_EXPONENT + 1 // exclude this == -2^1024
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Some implementations of java.math.BigInteger allow huge values with bit length greater than Int.MaxValue .
+ * The BigInteger.bitLength method returns truncated bit length in this case .
+ * This method tests if result of bitLength is valid.
+ * This method will become unnecessary if BigInt constructors reject huge BigIntegers.
+ */
+ private def bitLengthOverflow = {
+ val shifted = bigInteger.shiftRight(Int.MaxValue)
+ (shifted.signum != 0) && !(shifted equals BigInt.minusOne)
+ }
protected[math] def isWhole = true
def underlying = bigInteger
diff --git a/test/files/neg/override-object-flag.check b/test/files/neg/override-object-flag.check
index 152d31ff8a..344165138d 100644
--- a/test/files/neg/override-object-flag.check
+++ b/test/files/neg/override-object-flag.check
@@ -1,4 +1,4 @@
-override-object-flag.scala:3: error: overriding object Foo in trait A of type object B.this.Foo;
+override-object-flag.scala:3: error: overriding object Foo in trait A;
object Foo cannot override final member
trait B extends A { override object Foo }
^
diff --git a/test/files/neg/override-object-no.check b/test/files/neg/override-object-no.check
index f9fb37381b..52bad2b937 100644
--- a/test/files/neg/override-object-no.check
+++ b/test/files/neg/override-object-no.check
@@ -10,7 +10,7 @@ an overriding object must conform to the overridden object's class bound;
required: Object{def g: Int}
trait Quux2 extends Quux1 { override object Bar { def g = "abc" } } // err
^
-override-object-no.scala:25: error: overriding object Bar in trait Quux3 of type object Quux4.this.Bar;
+override-object-no.scala:25: error: overriding object Bar in trait Quux3;
object Bar cannot override final member
trait Quux4 extends Quux3 { override object Bar } // err
^
diff --git a/test/files/neg/t961.check b/test/files/neg/t961.check
index 48273f764d..14d39b0f42 100644
--- a/test/files/neg/t961.check
+++ b/test/files/neg/t961.check
@@ -1,4 +1,4 @@
-t961.scala:11: error: object Temp.B does not take parameters
+t961.scala:11: error: Temp.B.type does not take parameters
B() match {
^
one error found
diff --git a/test/files/presentation/callcc-interpreter.check b/test/files/presentation/callcc-interpreter.check
index 3385ef12b7..c50e171b4e 100644
--- a/test/files/presentation/callcc-interpreter.check
+++ b/test/files/presentation/callcc-interpreter.check
@@ -52,7 +52,7 @@ retrieved 64 members
`method wait(x$1: Long, x$2: Int)Unit`
`method x=> callccInterpreter.type`
`method →[B](y: B)(callccInterpreter.type, B)`
-`object Wrongobject callccInterpreter.Wrong`
+`object WrongcallccInterpreter.Wrong.type`
`trait TermcallccInterpreter.Term`
`trait ValuecallccInterpreter.Value`
`type AnswercallccInterpreter.Answer`
diff --git a/test/files/run/concurrent-map-conversions.scala b/test/files/run/concurrent-map-conversions.scala
new file mode 100644
index 0000000000..0350b69642
--- /dev/null
+++ b/test/files/run/concurrent-map-conversions.scala
@@ -0,0 +1,36 @@
+
+
+
+
+
+object Test {
+
+ def main(args: Array[String]) {
+ testConversions()
+ testConverters()
+ }
+
+ def needPackageConcurrentMap(map: collection.concurrent.Map[Int, Int]) {
+ }
+ def needJavaConcurrent(map: java.util.concurrent.ConcurrentMap[Int, Int]) {
+ }
+
+ def testConversions() {
+ import collection.JavaConversions._
+ val skiplist = new java.util.concurrent.ConcurrentSkipListMap[Int, Int]
+ val ctrie = new collection.concurrent.TrieMap[Int, Int]
+
+ needPackageConcurrentMap(skiplist)
+ needJavaConcurrent(ctrie)
+ }
+
+ def testConverters() {
+ import collection.JavaConverters._
+ val skiplist = new java.util.concurrent.ConcurrentSkipListMap[Int, Int]
+ val ctrie = new collection.concurrent.TrieMap[Int, Int]
+
+ needPackageConcurrentMap(skiplist.asScala)
+ needJavaConcurrent(ctrie.asJava)
+ }
+
+}
diff --git a/test/files/run/is-valid-num.scala b/test/files/run/is-valid-num.scala
index f919a21dee..9c43e98911 100644
--- a/test/files/run/is-valid-num.scala
+++ b/test/files/run/is-valid-num.scala
@@ -1,11 +1,15 @@
object Test {
def x = BigInt("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
def y = BigDecimal("" + (Short.MaxValue + 1) + ".0")
+ def y1 = BigDecimal("0.1")
+ def y2 = BigDecimal("0.5")
def l1 = Int.MaxValue.toLong + 1
def l2 = Int.MinValue.toLong - 1
def main(args: Array[String]): Unit = {
+ assert(!x.isValidDouble, x)
+ assert(!x.isValidFloat, x)
assert(!x.isValidLong, x)
assert(!x.isValidInt, x)
assert(!x.isValidChar, x)
@@ -13,8 +17,81 @@ object Test {
assert(!y.isValidShort, y)
assert(y.isValidChar, y)
assert(y.isValidInt, y)
+ assert(y.isValidFloat, y)
+ assert(y.isValidDouble, y)
+ assert(!y1.isValidLong, y1)
+ assert(!y1.isValidFloat, y1)
+ assert(!y1.isValidDouble, y1)
+ assert(!y2.isValidLong, y2)
+ assert(y2.isValidFloat, y2)
+ assert(y2.isValidDouble, y2)
+
+ testBigIntIsFloat()
+ testBigIntIsDouble()
assert(!l1.isValidInt && (l1 - 1).isValidInt, l1)
assert(!l2.isValidInt && (l2 + 1).isValidInt, l2)
}
+
+ def biExp2(e: Int) = BigInt(1) << e
+
+ def testBigIntIsFloat() {
+ val prec = 24
+ def checkFloatT(x: BigInt) = {
+ assert(x.isValidFloat, x)
+ assert((-x).isValidFloat, -x)
+ }
+ def checkFloatF(x: BigInt) = {
+ assert(!x.isValidFloat, x)
+ assert(!(-x).isValidFloat, -x)
+ }
+ checkFloatT(biExp2(prec) - 1)
+ checkFloatT(biExp2(prec))
+ checkFloatF(biExp2(prec) + 1)
+ checkFloatT(biExp2(prec) + 2)
+ checkFloatT(biExp2(prec) - 2)
+ checkFloatF(biExp2(prec + 1) - 1)
+ checkFloatT(biExp2(prec + 1))
+ checkFloatF(biExp2(prec + 1) + 1)
+ checkFloatF(biExp2(prec + 1) + 2)
+ checkFloatF(biExp2(prec + 1) + 3)
+ checkFloatT(biExp2(prec + 1) + 4)
+ checkFloatT(biExp2(64))
+ checkFloatF(biExp2(64) + biExp2(64 - prec))
+ checkFloatT(biExp2(64) + biExp2(64 - prec + 1))
+ checkFloatT(biExp2(127))
+ checkFloatT(biExp2(128) - biExp2(128 - prec))
+ checkFloatF(biExp2(128) - biExp2(128 - prec - 1))
+ checkFloatF(biExp2(128))
+ }
+
+ def testBigIntIsDouble() {
+ val prec = 53
+ def checkDoubleT(x: BigInt) = {
+ assert(x.isValidDouble, x)
+ assert((-x).isValidDouble, -x)
+ }
+ def checkDoubleF(x: BigInt) = {
+ assert(!x.isValidDouble, x)
+ assert(!(-x).isValidDouble, -x)
+ }
+ checkDoubleT(biExp2(prec) - 1)
+ checkDoubleT(biExp2(prec))
+ checkDoubleF(biExp2(prec) + 1)
+ checkDoubleT(biExp2(prec) + 2)
+ checkDoubleT(biExp2(prec + 1) - 2)
+ checkDoubleF(biExp2(prec + 1) - 1)
+ checkDoubleT(biExp2(prec + 1))
+ checkDoubleF(biExp2(prec + 1) + 1)
+ checkDoubleF(biExp2(prec + 1) + 2)
+ checkDoubleF(biExp2(prec + 1) + 3)
+ checkDoubleT(biExp2(prec + 1) + 4)
+ checkDoubleT(biExp2(64))
+ checkDoubleF(biExp2(64) + biExp2(64 - prec))
+ checkDoubleT(biExp2(64) + biExp2(64 - prec + 1))
+ checkDoubleT(biExp2(1023))
+ checkDoubleT(biExp2(1024) - biExp2(1024 - prec))
+ checkDoubleF(biExp2(1024) - biExp2(1024 - prec - 1))
+ checkDoubleF(biExp2(1024))
+ }
}
diff --git a/test/files/run/numbereq.scala b/test/files/run/numbereq.scala
index 77a217df36..a1f11da205 100644
--- a/test/files/run/numbereq.scala
+++ b/test/files/run/numbereq.scala
@@ -16,7 +16,20 @@ object Test {
base ::: extras
}
-
+
+ def mkNumbers(x: BigInt): List[AnyRef] = {
+ List(
+ List(BigDecimal(x, java.math.MathContext.UNLIMITED)),
+ List(x),
+ if (x.isValidDouble) List(new java.lang.Double(x.toDouble)) else Nil,
+ if (x.isValidFloat) List(new java.lang.Float(x.toFloat)) else Nil,
+ if (x.isValidLong) List(new java.lang.Long(x.toLong)) else Nil,
+ if (x.isValidInt) List(new java.lang.Integer(x.toInt)) else Nil,
+ if (x.isValidShort) List(new java.lang.Short(x.toShort)) else Nil,
+ if (x.isValidByte) List(new java.lang.Byte(x.toByte)) else Nil,
+ if (x.isValidChar) List(new java.lang.Character(x.toChar)) else Nil
+ ).flatten
+ }
def main(args: Array[String]): Unit = {
val ints = (0 to 15).toList map (Short.MinValue >> _)
@@ -37,5 +50,23 @@ object Test {
assert(x == y, "%s/%s != %s/%s".format(x, x.getClass, y, y.getClass))
assert(x.## == y.##, "%s != %s".format(x.getClass, y.getClass))
}
+
+ val bigInts = (0 to 1024).toList map (BigInt(-1) << _)
+ val bigInts2 = bigInts map (x => -x)
+ val bigInts3 = bigInts map (_ + 1)
+ val bigInts4 = bigInts2 map (_ - 1)
+
+ val setneg1b = bigInts map mkNumbers
+ val setneg2b = bigInts3 map mkNumbers
+ val setpos1b = bigInts2 map mkNumbers
+ val setpos2b = bigInts4 map mkNumbers
+
+ val sets2 = setneg1 ++ setneg1b ++ setneg2 ++ setneg2b ++ List(zero) ++ setpos1 ++ setpos1b ++ setpos2 ++ setpos2b
+
+ for (set <- sets2 ; x <- set ; y <- set) {
+// println("'%s' == '%s' (%s == %s) (%s == %s)".format(x, y, x.hashCode, y.hashCode, x.##, y.##))
+ assert(x == y, "%s/%s != %s/%s".format(x, x.getClass, y, y.getClass))
+// assert(x.## == y.##, "%s != %s".format(x.getClass, y.getClass)) Disable until Double.## is fixed (SI-5640)
+ }
}
-} \ No newline at end of file
+}