diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/cmd/Property.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/reflect/WrappedProperties.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/util/PathResolver.scala | 2 | ||||
-rw-r--r-- | src/library/scala/collection/concurrent/Map.scala | 11 | ||||
-rw-r--r-- | src/library/scala/collection/convert/WrapAsJava.scala | 56 | ||||
-rw-r--r-- | src/library/scala/collection/convert/WrapAsScala.scala | 35 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/Stream.scala | 79 | ||||
-rw-r--r-- | src/library/scala/concurrent/duration/Duration.scala | 2 | ||||
-rw-r--r-- | src/library/scala/math/package.scala | 2 | ||||
-rw-r--r-- | src/library/scala/sys/SystemProperties.scala | 11 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeInfo.scala | 1 |
12 files changed, 113 insertions, 115 deletions
diff --git a/src/compiler/scala/tools/cmd/Property.scala b/src/compiler/scala/tools/cmd/Property.scala index b1d951a5c4..e6262a7e40 100644 --- a/src/compiler/scala/tools/cmd/Property.scala +++ b/src/compiler/scala/tools/cmd/Property.scala @@ -9,6 +9,7 @@ package cmd import nsc.io._ import java.util.Properties import java.io.FileInputStream +import scala.sys.SystemProperties /** Contains logic for translating a property key/value pair into * equivalent command line arguments. The default settings will @@ -58,7 +59,7 @@ trait Property extends Reference { returning(new Properties)(_ load new FileInputStream(file.path)) def systemPropertiesToOptions: List[String] = - propertiesToOptions(System.getProperties) + propertiesToOptions(new SystemProperties().toList) def propertiesToOptions(file: File): List[String] = propertiesToOptions(loadProperties(file)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2dd79075ee..7f86a59164 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -918,24 +918,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper def insertApply(): Tree = { assert(!context.inTypeConstructorAllowed, mode) //@M val adapted = adaptToName(tree, nme.apply) - def stabilize0(pre: Type): Tree = stabilize(adapted, pre, MonoQualifierModes, WildcardType) - - // TODO reconcile the overlap between Typers#stablize and TreeGen.stabilize - val qual = adapted match { - case This(_) => - gen.stabilize(adapted) - case Ident(_) => - val owner = adapted.symbol.owner - val pre = - if (owner.isPackageClass) owner.thisType - else if (owner.isClass) context.enclosingSubClassContext(owner).prefix - else NoPrefix - stabilize0(pre) - case Select(qualqual, _) => - stabilize0(qualqual.tpe) - case other => - other - } + val qual = gen.stabilize(adapted) typedPos(tree.pos, mode, pt) { Select(qual setPos tree.pos.makeTransparent, nme.apply) } @@ -5210,7 +5193,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (refTyped.isErrorTyped) { setError(tree) } else { - tree setType refTyped.tpe.resultType + tree setType refTyped.tpe.resultType.deconst if (refTyped.isErrorTyped || treeInfo.admitsTypeSelection(refTyped)) tree else UnstableTreeError(tree) } diff --git a/src/compiler/scala/tools/reflect/WrappedProperties.scala b/src/compiler/scala/tools/reflect/WrappedProperties.scala index 523287fc66..348d000d15 100644 --- a/src/compiler/scala/tools/reflect/WrappedProperties.scala +++ b/src/compiler/scala/tools/reflect/WrappedProperties.scala @@ -30,9 +30,10 @@ trait WrappedProperties extends PropertiesTrait { def systemProperties: List[(String, String)] = { import scala.collection.JavaConverters._ wrap { + // SI-7269,7775 Avoid `ConcurrentModificationException` and nulls if another thread modifies properties val props = System.getProperties - // SI-7269 Be careful to avoid `ConcurrentModificationException` if another thread modifies the properties map - props.stringPropertyNames().asScala.toList.map(k => (k, props.get(k).asInstanceOf[String])) + val it = props.stringPropertyNames().asScala.iterator map (k => (k, props getProperty k)) filter (_._2 ne null) + it.toList } getOrElse Nil } } diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala index 8e5b1e0a5c..f122437b63 100644 --- a/src/compiler/scala/tools/util/PathResolver.scala +++ b/src/compiler/scala/tools/util/PathResolver.scala @@ -52,7 +52,7 @@ object PathResolver { */ object Environment { private def searchForBootClasspath = - systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse "" + systemProperties collectFirst { case (k, v) if k endsWith ".boot.class.path" => v } getOrElse "" /** Environment variables which java pays attention to so it * seems we do as well. diff --git a/src/library/scala/collection/concurrent/Map.scala b/src/library/scala/collection/concurrent/Map.scala index 2eea15b8dc..f0a5f57225 100644 --- a/src/library/scala/collection/concurrent/Map.scala +++ b/src/library/scala/collection/concurrent/Map.scala @@ -86,4 +86,15 @@ trait Map[A, B] extends scala.collection.mutable.Map[A, B] { * @return `Some(v)` if the given key was previously mapped to some value `v`, or `None` otherwise */ def replace(k: A, v: B): Option[B] + + override def getOrElseUpdate(key: A, op: =>B): B = get(key) match { + case Some(v) => v + case None => + val v = op + putIfAbsent(key, v) match { + case Some(nv) => nv + case None => v + } + } + } diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala index 9916fe9843..e97a2ff1fc 100644 --- a/src/library/scala/collection/convert/WrapAsJava.scala +++ b/src/library/scala/collection/convert/WrapAsJava.scala @@ -30,8 +30,9 @@ trait WrapAsJava { * @return A Java Iterator view of the argument. */ implicit def asJavaIterator[A](it: Iterator[A]): ju.Iterator[A] = it match { - case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]] - case _ => IteratorWrapper(it) + case null => null + case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]] + case _ => IteratorWrapper(it) } /** @@ -48,8 +49,9 @@ trait WrapAsJava { * @return A Java Enumeration view of the argument. */ implicit def asJavaEnumeration[A](it: Iterator[A]): ju.Enumeration[A] = it match { + case null => null case JEnumerationWrapper(wrapped) => wrapped.asInstanceOf[ju.Enumeration[A]] - case _ => IteratorWrapper(it) + case _ => IteratorWrapper(it) } /** @@ -66,8 +68,9 @@ trait WrapAsJava { * @return A Java Iterable view of the argument. */ implicit def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = i match { - case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]] - case _ => IterableWrapper(i) + case null => null + case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]] + case _ => IterableWrapper(i) } /** @@ -82,8 +85,9 @@ trait WrapAsJava { * @return A Java Collection view of the argument. */ implicit def asJavaCollection[A](it: Iterable[A]): ju.Collection[A] = it match { - case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]] - case _ => new IterableWrapper(it) + case null => null + case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]] + case _ => new IterableWrapper(it) } /** @@ -100,8 +104,9 @@ trait WrapAsJava { * @return A Java List view of the argument. */ implicit def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match { - case JListWrapper(wrapped) => wrapped - case _ => new MutableBufferWrapper(b) + case null => null + case JListWrapper(wrapped) => wrapped + case _ => new MutableBufferWrapper(b) } /** @@ -118,8 +123,9 @@ trait WrapAsJava { * @return A Java List view of the argument. */ implicit def mutableSeqAsJavaList[A](seq: mutable.Seq[A]): ju.List[A] = seq match { - case JListWrapper(wrapped) => wrapped - case _ => new MutableSeqWrapper(seq) + case null => null + case JListWrapper(wrapped) => wrapped + case _ => new MutableSeqWrapper(seq) } /** @@ -136,8 +142,9 @@ trait WrapAsJava { * @return A Java List view of the argument. */ implicit def seqAsJavaList[A](seq: Seq[A]): ju.List[A] = seq match { - case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]] - case _ => new SeqWrapper(seq) + case null => null + case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]] + case _ => new SeqWrapper(seq) } /** @@ -154,8 +161,9 @@ trait WrapAsJava { * @return A Java Set view of the argument. */ implicit def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = s match { + case null => null case JSetWrapper(wrapped) => wrapped - case _ => new MutableSetWrapper(s) + case _ => new MutableSetWrapper(s) } /** @@ -172,8 +180,9 @@ trait WrapAsJava { * @return A Java Set view of the argument. */ implicit def setAsJavaSet[A](s: Set[A]): ju.Set[A] = s match { + case null => null case JSetWrapper(wrapped) => wrapped - case _ => new SetWrapper(s) + case _ => new SetWrapper(s) } /** @@ -190,9 +199,9 @@ trait WrapAsJava { * @return A Java Map view of the argument. */ implicit def mutableMapAsJavaMap[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = m match { - //case JConcurrentMapWrapper(wrapped) => wrapped + case null => null case JMapWrapper(wrapped) => wrapped - case _ => new MutableMapWrapper(m) + case _ => new MutableMapWrapper(m) } /** @@ -210,9 +219,9 @@ trait WrapAsJava { * @return A Java `Dictionary` view of the argument. */ implicit def asJavaDictionary[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = m match { - //case JConcurrentMapWrapper(wrapped) => wrapped - case JDictionaryWrapper(wrapped) => wrapped - case _ => new DictionaryWrapper(m) + case null => null + case JDictionaryWrapper(wrapped) => wrapped + case _ => new DictionaryWrapper(m) } /** @@ -230,9 +239,9 @@ trait WrapAsJava { * @return A Java `Map` view of the argument. */ implicit def mapAsJavaMap[A, B](m: Map[A, B]): ju.Map[A, B] = m match { - //case JConcurrentMapWrapper(wrapped) => wrapped + case null => null case JMapWrapper(wrapped) => wrapped.asInstanceOf[ju.Map[A, B]] - case _ => new MapWrapper(m) + case _ => new MapWrapper(m) } /** @@ -251,8 +260,9 @@ trait WrapAsJava { * @return A Java `ConcurrentMap` view of the argument. */ implicit def mapAsJavaConcurrentMap[A, B](m: concurrent.Map[A, B]): juc.ConcurrentMap[A, B] = m match { + case null => null case JConcurrentMapWrapper(wrapped) => wrapped - case _ => new ConcurrentMapWrapper(m) + case _ => new ConcurrentMapWrapper(m) } } diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala index ab151a6778..7332b71af1 100644 --- a/src/library/scala/collection/convert/WrapAsScala.scala +++ b/src/library/scala/collection/convert/WrapAsScala.scala @@ -30,8 +30,9 @@ trait WrapAsScala { * @return A Scala `Iterator` view of the argument. */ implicit def asScalaIterator[A](it: ju.Iterator[A]): Iterator[A] = it match { + case null => null case IteratorWrapper(wrapped) => wrapped - case _ => JIteratorWrapper(it) + case _ => JIteratorWrapper(it) } /** @@ -48,8 +49,9 @@ trait WrapAsScala { * @return A Scala Iterator view of the argument. */ implicit def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = i match { + case null => null case IteratorWrapper(wrapped) => wrapped - case _ => JEnumerationWrapper(i) + case _ => JEnumerationWrapper(i) } /** @@ -67,8 +69,9 @@ trait WrapAsScala { * @return A Scala Iterable view of the argument. */ implicit def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = i match { + case null => null case IterableWrapper(wrapped) => wrapped - case _ => JIterableWrapper(i) + case _ => JIterableWrapper(i) } /** @@ -82,8 +85,9 @@ trait WrapAsScala { * @return A Scala Iterable view of the argument. */ implicit def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = i match { + case null => null case IterableWrapper(wrapped) => wrapped - case _ => JCollectionWrapper(i) + case _ => JCollectionWrapper(i) } /** @@ -101,8 +105,9 @@ trait WrapAsScala { * @return A Scala mutable `Buffer` view of the argument. */ implicit def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match { - case MutableBufferWrapper(wrapped) => wrapped - case _ =>new JListWrapper(l) + case null => null + case MutableBufferWrapper(wrapped) => wrapped + case _ => new JListWrapper(l) } /** @@ -119,8 +124,9 @@ trait WrapAsScala { * @return A Scala mutable Set view of the argument. */ implicit def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = s match { + case null => null case MutableSetWrapper(wrapped) => wrapped - case _ =>new JSetWrapper(s) + case _ => new JSetWrapper(s) } /** @@ -144,9 +150,9 @@ trait WrapAsScala { * @return A Scala mutable Map view of the argument. */ implicit def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = m match { - //case ConcurrentMapWrapper(wrapped) => wrapped + case null => null case MutableMapWrapper(wrapped) => wrapped - case _ => new JMapWrapper(m) + case _ => new JMapWrapper(m) } /** @@ -163,8 +169,9 @@ trait WrapAsScala { * @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) + case null => null + case cmw: ConcurrentMapWrapper[A, B] => cmw.underlying + case _ => new JConcurrentMapWrapper(m) } /** @@ -179,8 +186,9 @@ trait WrapAsScala { * @return A Scala mutable Map[String, String] view of the argument. */ implicit def dictionaryAsScalaMap[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = p match { + case null => null case DictionaryWrapper(wrapped) => wrapped - case _ => new JDictionaryWrapper(p) + case _ => new JDictionaryWrapper(p) } /** @@ -194,7 +202,8 @@ trait WrapAsScala { * @return A Scala mutable Map[String, String] view of the argument. */ implicit def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = p match { - case _ => new JPropertiesWrapper(p) + case null => null + case _ => new JPropertiesWrapper(p) } } diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index b819302460..8be0b2fee2 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -524,57 +524,9 @@ self => */ override def filter(p: A => Boolean): Stream[A] = filterImpl(p, isFlipped = false) // This override is only left in 2.11 because of binary compatibility, see PR #3925 - override final def withFilter(p: A => Boolean): StreamWithFilter = new StreamWithFilter(p) - - /** A lazier implementation of WithFilter than TraversableLike's. - */ - final class StreamWithFilter(p: A => Boolean) extends WithFilter(p) { - - override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { - def tailMap(coll: Stream[A]): Stream[B] = { - var head: A = null.asInstanceOf[A] - var tail: Stream[A] = coll - while (true) { - if (tail.isEmpty) - return Stream.Empty - head = tail.head - tail = tail.tail - if (p(head)) - return cons(f(head), tailMap(tail)) - } - throw new RuntimeException() - } - - if (isStreamBuilder(bf)) asThat(tailMap(Stream.this)) - else super.map(f)(bf) - } - - override def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { - def tailFlatMap(coll: Stream[A]): Stream[B] = { - var head: A = null.asInstanceOf[A] - var tail: Stream[A] = coll - while (true) { - if (tail.isEmpty) - return Stream.Empty - head = tail.head - tail = tail.tail - if (p(head)) - return f(head).toStream append tailFlatMap(tail) - } - throw new RuntimeException() - } - - if (isStreamBuilder(bf)) asThat(tailFlatMap(Stream.this)) - else super.flatMap(f)(bf) - } - - override def foreach[B](f: A => B) = - for (x <- self) - if (p(x)) f(x) - - override def withFilter(q: A => Boolean): StreamWithFilter = - new StreamWithFilter(x => p(x) && q(x)) - } + /** A FilterMonadic which allows GC of the head of stream during processing */ + @noinline // Workaround SI-9137, see https://github.com/scala/scala/pull/4284#issuecomment-73180791 + override final def withFilter(p: A => Boolean): FilterMonadic[A, Stream[A]] = new Stream.StreamWithFilter(this, p) /** A lazier Iterator than LinearSeqLike's. */ override def iterator: Iterator[A] = new StreamIterator(self) @@ -1293,6 +1245,29 @@ object Stream extends SeqFactory[Stream] { private[immutable] def collectedTail[A, B, That](head: B, stream: Stream[A], pf: PartialFunction[A, B], bf: CanBuildFrom[Stream[A], B, That]) = { cons(head, stream.tail.collect(pf)(bf).asInstanceOf[Stream[B]]) } -} + /** An implementation of `FilterMonadic` allowing GC of the filtered-out elements of + * the `Stream` as it is processed. + * + * Because this is not an inner class of `Stream` with a reference to the original + * head, it is now possible for GC to collect any leading and filtered-out elements + * which do not satisfy the filter, while the tail is still processing (see SI-8990). + */ + private[immutable] final class StreamWithFilter[A](sl: => Stream[A], p: A => Boolean) extends FilterMonadic[A, Stream[A]] { + private var s = sl // set to null to allow GC after filtered + private lazy val filtered = { val f = s filter p; s = null; f } // don't set to null if throw during filter + + def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Stream[A], B, That]): That = + filtered map f + def flatMap[B, That](f: A => scala.collection.GenTraversableOnce[B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = + filtered flatMap f + + def foreach[U](f: A => U): Unit = + filtered foreach f + + def withFilter(q: A => Boolean): FilterMonadic[A, Stream[A]] = + new StreamWithFilter[A](filtered, q) + } + +} diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala index 2eded9f060..3697950e2e 100644 --- a/src/library/scala/concurrent/duration/Duration.scala +++ b/src/library/scala/concurrent/duration/Duration.scala @@ -705,7 +705,7 @@ final class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duratio final def isFinite() = true - final def toCoarsest: Duration = { + final override def toCoarsest: FiniteDuration = { def loop(length: Long, unit: TimeUnit): FiniteDuration = { def coarserOrThis(coarser: TimeUnit, divider: Int) = if (length % divider == 0) loop(length / divider, coarser) diff --git a/src/library/scala/math/package.scala b/src/library/scala/math/package.scala index 58ece8a05b..b6593d6661 100644 --- a/src/library/scala/math/package.scala +++ b/src/library/scala/math/package.scala @@ -26,7 +26,7 @@ package object math { /** Returns a `double` value with a positive sign, greater than or equal * to `0.0` and less than `1.0`. */ - def random: Double = java.lang.Math.random() + def random(): Double = java.lang.Math.random() def sin(x: Double): Double = java.lang.Math.sin(x) def cos(x: Double): Double = java.lang.Math.cos(x) diff --git a/src/library/scala/sys/SystemProperties.scala b/src/library/scala/sys/SystemProperties.scala index d2ebf8c044..6f8b13a89b 100644 --- a/src/library/scala/sys/SystemProperties.scala +++ b/src/library/scala/sys/SystemProperties.scala @@ -35,8 +35,15 @@ extends mutable.AbstractMap[String, String] override def empty = new SystemProperties override def default(key: String): String = null - def iterator: Iterator[(String, String)] = - wrapAccess(System.getProperties().asScala.iterator) getOrElse Iterator.empty + def iterator: Iterator[(String, String)] = wrapAccess { + val ps = System.getProperties() + names map (k => (k, ps getProperty k)) filter (_._2 ne null) + } getOrElse Iterator.empty + + def names: Iterator[String] = wrapAccess ( + System.getProperties().stringPropertyNames().asScala.iterator + ) getOrElse Iterator.empty + def get(key: String) = wrapAccess(Option(System.getProperty(key))) flatMap (x => x) override def contains(key: String) = diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala index 4657fa0000..7ad5fdf096 100644 --- a/src/reflect/scala/reflect/internal/TreeInfo.scala +++ b/src/reflect/scala/reflect/internal/TreeInfo.scala @@ -128,6 +128,7 @@ abstract class TreeInfo { symOk(tree.symbol) && tree.symbol.isStable && !definitions.isByNameParamType(tree.tpe) + && !definitions.isByName(tree.symbol) && (allowVolatile || !tree.symbol.hasVolatileType) // TODO SPEC: not required by spec ) |