summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
Diffstat (limited to 'src/library')
-rw-r--r--src/library/rootdoc.txt6
-rw-r--r--src/library/scala/Array.scala31
-rw-r--r--src/library/scala/Boolean.scala11
-rw-r--r--src/library/scala/Byte.scala11
-rw-r--r--src/library/scala/Char.scala11
-rw-r--r--src/library/scala/Double.scala11
-rw-r--r--src/library/scala/Enumeration.scala14
-rw-r--r--src/library/scala/Float.scala11
-rw-r--r--src/library/scala/Int.scala11
-rw-r--r--src/library/scala/Long.scala11
-rw-r--r--src/library/scala/PartialFunction.scala15
-rw-r--r--src/library/scala/Predef.scala244
-rw-r--r--src/library/scala/Short.scala11
-rw-r--r--src/library/scala/Symbol.scala4
-rw-r--r--src/library/scala/Unit.scala9
-rw-r--r--src/library/scala/annotation/elidable.scala4
-rw-r--r--src/library/scala/annotation/implicitAmbiguous.scala32
-rw-r--r--src/library/scala/beans/BeanInfo.scala1
-rw-r--r--src/library/scala/collection/BitSetLike.scala21
-rw-r--r--src/library/scala/collection/GenSeqLike.scala1
-rw-r--r--src/library/scala/collection/IndexedSeqLike.scala3
-rw-r--r--src/library/scala/collection/IndexedSeqOptimized.scala1
-rw-r--r--src/library/scala/collection/IterableLike.scala11
-rw-r--r--src/library/scala/collection/IterableProxyLike.scala1
-rw-r--r--src/library/scala/collection/IterableViewLike.scala5
-rw-r--r--src/library/scala/collection/Iterator.scala217
-rw-r--r--src/library/scala/collection/JavaConversions.scala30
-rw-r--r--src/library/scala/collection/JavaConverters.scala82
-rw-r--r--src/library/scala/collection/LinearSeqOptimized.scala6
-rw-r--r--src/library/scala/collection/MapLike.scala23
-rw-r--r--src/library/scala/collection/SeqLike.scala5
-rw-r--r--src/library/scala/collection/SeqViewLike.scala22
-rw-r--r--src/library/scala/collection/SetLike.scala17
-rw-r--r--src/library/scala/collection/TraversableLike.scala4
-rw-r--r--src/library/scala/collection/TraversableOnce.scala2
-rw-r--r--src/library/scala/collection/TraversableViewLike.scala22
-rw-r--r--src/library/scala/collection/concurrent/Map.scala11
-rw-r--r--src/library/scala/collection/concurrent/TrieMap.scala23
-rw-r--r--src/library/scala/collection/convert/AsJavaConverters.scala262
-rw-r--r--src/library/scala/collection/convert/AsScalaConverters.scala207
-rw-r--r--src/library/scala/collection/convert/DecorateAsJava.scala250
-rw-r--r--src/library/scala/collection/convert/DecorateAsScala.scala155
-rw-r--r--src/library/scala/collection/convert/Decorators.scala10
-rw-r--r--src/library/scala/collection/convert/ImplicitConversions.scala125
-rw-r--r--src/library/scala/collection/convert/WrapAsJava.scala81
-rw-r--r--src/library/scala/collection/convert/WrapAsScala.scala70
-rw-r--r--src/library/scala/collection/convert/Wrappers.scala14
-rw-r--r--src/library/scala/collection/convert/package.scala9
-rw-r--r--src/library/scala/collection/generic/BitOperations.scala23
-rw-r--r--src/library/scala/collection/generic/GenericParTemplate.scala1
-rw-r--r--src/library/scala/collection/generic/MapFactory.scala2
-rw-r--r--src/library/scala/collection/generic/MutableSortedMapFactory.scala24
-rw-r--r--src/library/scala/collection/generic/ParFactory.scala1
-rw-r--r--src/library/scala/collection/generic/ParSetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/SetFactory.scala1
-rw-r--r--src/library/scala/collection/generic/package.scala1
-rw-r--r--src/library/scala/collection/immutable/BitSet.scala31
-rw-r--r--src/library/scala/collection/immutable/HashMap.scala10
-rw-r--r--src/library/scala/collection/immutable/HashSet.scala40
-rw-r--r--src/library/scala/collection/immutable/List.scala17
-rw-r--r--src/library/scala/collection/immutable/ListMap.scala31
-rw-r--r--src/library/scala/collection/immutable/ListSet.scala13
-rw-r--r--src/library/scala/collection/immutable/Map.scala22
-rw-r--r--src/library/scala/collection/immutable/NumericRange.scala4
-rw-r--r--src/library/scala/collection/immutable/PagedSeq.scala3
-rw-r--r--src/library/scala/collection/immutable/Queue.scala4
-rw-r--r--src/library/scala/collection/immutable/Range.scala22
-rw-r--r--src/library/scala/collection/immutable/Set.scala9
-rw-r--r--src/library/scala/collection/immutable/SortedMap.scala1
-rw-r--r--src/library/scala/collection/immutable/SortedSet.scala1
-rw-r--r--src/library/scala/collection/immutable/Stream.scala119
-rw-r--r--src/library/scala/collection/immutable/StreamViewLike.scala2
-rw-r--r--src/library/scala/collection/immutable/StringLike.scala89
-rw-r--r--src/library/scala/collection/immutable/TreeMap.scala3
-rw-r--r--src/library/scala/collection/immutable/TreeSet.scala3
-rw-r--r--src/library/scala/collection/immutable/Vector.scala6
-rw-r--r--src/library/scala/collection/immutable/WrappedString.scala3
-rw-r--r--src/library/scala/collection/mutable/AVLTree.scala250
-rw-r--r--src/library/scala/collection/mutable/AnyRefMap.scala32
-rw-r--r--src/library/scala/collection/mutable/ArrayBuffer.scala13
-rw-r--r--src/library/scala/collection/mutable/ArrayBuilder.scala181
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala28
-rw-r--r--src/library/scala/collection/mutable/ArraySeq.scala2
-rw-r--r--src/library/scala/collection/mutable/ArrayStack.scala7
-rw-r--r--src/library/scala/collection/mutable/BitSet.scala6
-rw-r--r--src/library/scala/collection/mutable/BufferLike.scala16
-rw-r--r--src/library/scala/collection/mutable/BufferProxy.scala2
-rw-r--r--src/library/scala/collection/mutable/Builder.scala16
-rw-r--r--src/library/scala/collection/mutable/GrowingBuilder.scala4
-rw-r--r--src/library/scala/collection/mutable/IndexedSeqView.scala1
-rw-r--r--src/library/scala/collection/mutable/LazyBuilder.scala4
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala25
-rw-r--r--src/library/scala/collection/mutable/LongMap.scala26
-rw-r--r--src/library/scala/collection/mutable/MapBuilder.scala2
-rw-r--r--src/library/scala/collection/mutable/MapLike.scala12
-rw-r--r--src/library/scala/collection/mutable/MutableList.scala2
-rw-r--r--src/library/scala/collection/mutable/PriorityQueue.scala182
-rw-r--r--src/library/scala/collection/mutable/PriorityQueueProxy.scala96
-rw-r--r--src/library/scala/collection/mutable/RedBlackTree.scala580
-rw-r--r--src/library/scala/collection/mutable/ResizableArray.scala2
-rw-r--r--src/library/scala/collection/mutable/ReusableBuilder.scala49
-rw-r--r--src/library/scala/collection/mutable/SetBuilder.scala4
-rw-r--r--src/library/scala/collection/mutable/SetLike.scala11
-rw-r--r--src/library/scala/collection/mutable/SortedMap.scala57
-rw-r--r--src/library/scala/collection/mutable/SortedSet.scala7
-rw-r--r--src/library/scala/collection/mutable/StringBuilder.scala8
-rw-r--r--src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala101
-rw-r--r--src/library/scala/collection/mutable/SynchronizedStack.scala1
-rw-r--r--src/library/scala/collection/mutable/TreeMap.scala185
-rw-r--r--src/library/scala/collection/mutable/TreeSet.scala181
-rw-r--r--src/library/scala/collection/mutable/UnrolledBuffer.scala11
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala9
-rw-r--r--src/library/scala/collection/mutable/WrappedArrayBuilder.scala16
-rw-r--r--src/library/scala/collection/package.scala8
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala20
-rw-r--r--src/library/scala/collection/parallel/ParMap.scala1
-rw-r--r--src/library/scala/collection/parallel/ParMapLike.scala4
-rw-r--r--src/library/scala/collection/parallel/ParSeqLike.scala15
-rw-r--r--src/library/scala/collection/parallel/RemainsIterator.scala12
-rw-r--r--src/library/scala/collection/parallel/TaskSupport.scala4
-rw-r--r--src/library/scala/collection/parallel/Tasks.scala13
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashSet.scala2
-rw-r--r--src/library/scala/collection/parallel/immutable/ParMap.scala1
-rw-r--r--src/library/scala/collection/parallel/immutable/ParRange.scala1
-rw-r--r--src/library/scala/collection/parallel/mutable/LazyCombiner.scala1
-rw-r--r--src/library/scala/collection/parallel/mutable/ParArray.scala1
-rw-r--r--src/library/scala/collection/parallel/mutable/ParTrieMap.scala15
-rw-r--r--src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala8
-rw-r--r--src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala16
-rw-r--r--src/library/scala/collection/parallel/package.scala12
-rw-r--r--src/library/scala/compat/Platform.scala3
-rw-r--r--src/library/scala/concurrent/BlockContext.scala15
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala37
-rw-r--r--src/library/scala/concurrent/Future.scala488
-rw-r--r--src/library/scala/concurrent/FutureTaskRunner.scala39
-rw-r--r--src/library/scala/concurrent/ManagedBlocker.scala34
-rw-r--r--src/library/scala/concurrent/Promise.scala12
-rw-r--r--src/library/scala/concurrent/SyncChannel.scala8
-rw-r--r--src/library/scala/concurrent/SyncVar.scala43
-rw-r--r--src/library/scala/concurrent/TaskRunner.scala27
-rw-r--r--src/library/scala/concurrent/ThreadPoolRunner.scala51
-rw-r--r--src/library/scala/concurrent/duration/Duration.scala10
-rw-r--r--src/library/scala/concurrent/forkjoin/package.scala60
-rw-r--r--src/library/scala/concurrent/impl/AbstractPromise.java17
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala230
-rw-r--r--src/library/scala/concurrent/impl/Future.scala34
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala181
-rw-r--r--src/library/scala/deprecatedInheritance.scala1
-rw-r--r--src/library/scala/deprecatedName.scala4
-rw-r--r--src/library/scala/deprecatedOverriding.scala1
-rw-r--r--src/library/scala/inline.scala26
-rw-r--r--src/library/scala/io/BufferedSource.scala2
-rw-r--r--src/library/scala/io/Source.scala32
-rw-r--r--src/library/scala/math/BigDecimal.scala121
-rw-r--r--src/library/scala/math/BigInt.scala23
-rw-r--r--src/library/scala/math/Integral.scala2
-rw-r--r--src/library/scala/math/Ordering.scala22
-rw-r--r--src/library/scala/math/package.scala2
-rw-r--r--src/library/scala/noinline.scala26
-rw-r--r--src/library/scala/ref/SoftReference.scala13
-rw-r--r--src/library/scala/reflect/ClassTag.scala5
-rw-r--r--src/library/scala/runtime/AbstractPartialFunction.scala2
-rw-r--r--src/library/scala/runtime/ArrayRuntime.java26
-rw-r--r--src/library/scala/runtime/Boxed.scala12
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java66
-rw-r--r--src/library/scala/runtime/LambdaDeserialize.java29
-rw-r--r--src/library/scala/runtime/LambdaDeserializer.scala132
-rw-r--r--src/library/scala/runtime/ScalaNumberProxy.scala4
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala133
-rw-r--r--src/library/scala/runtime/SeqCharSequence.scala2
-rw-r--r--src/library/scala/runtime/Statics.java54
-rw-r--r--src/library/scala/runtime/StructuralCallSite.java43
-rw-r--r--src/library/scala/runtime/SymbolLiteral.java20
-rw-r--r--src/library/scala/runtime/Tuple2Zipped.scala2
-rw-r--r--src/library/scala/runtime/Tuple3Zipped.scala2
-rw-r--r--src/library/scala/runtime/java8/JFunction.java146
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcB$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcC$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcF$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcS$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcV$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0$mcZ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction0.java39
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcDD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcDF$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcDI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcDJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcFD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcFF$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcFI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcFJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcID$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcIF$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcII$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcIJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcJD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcJF$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcJI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcJJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcVD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcVF$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcVI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcVJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcZD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcZF$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcZI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1$mcZJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction1.java228
-rw-r--r--src/library/scala/runtime/java8/JFunction10.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction11.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction12.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction13.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction14.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction15.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction16.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction17.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction18.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction19.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDDD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDDI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDID$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDII$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDJD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDJI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFDD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFDI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFID$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFII$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFJD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFJI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIDD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIDI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIID$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIII$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIJD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIJI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJDD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJDI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJID$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJII$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJJD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJJI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVDD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVDI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVID$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVII$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVJD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVJI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZDD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZDI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZID$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZII$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZJD$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZJI$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.java13
-rw-r--r--src/library/scala/runtime/java8/JFunction2.java498
-rw-r--r--src/library/scala/runtime/java8/JFunction20.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction21.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction22.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction3.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction4.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction5.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction6.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction7.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction8.java10
-rw-r--r--src/library/scala/runtime/java8/JFunction9.java10
-rw-r--r--src/library/scala/runtime/java8/JProcedure0.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure1.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure10.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure11.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure12.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure13.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure14.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure15.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure16.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure17.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure18.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure19.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure2.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure20.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure21.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure22.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure3.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure4.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure5.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure6.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure7.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure8.java21
-rw-r--r--src/library/scala/runtime/java8/JProcedure9.java21
-rw-r--r--src/library/scala/sys/SystemProperties.scala49
-rw-r--r--src/library/scala/sys/process/BasicIO.scala4
-rw-r--r--src/library/scala/sys/process/Process.scala4
-rw-r--r--src/library/scala/sys/process/ProcessBuilderImpl.scala2
-rw-r--r--src/library/scala/sys/process/ProcessImpl.scala161
-rw-r--r--src/library/scala/sys/process/package.scala34
-rw-r--r--src/library/scala/util/Either.scala4
-rw-r--r--src/library/scala/util/Properties.scala4
-rw-r--r--src/library/scala/util/Sorting.scala18
-rw-r--r--src/library/scala/util/Try.scala148
-rw-r--r--src/library/scala/util/control/Exception.scala212
-rw-r--r--src/library/scala/util/control/NoStackTrace.scala6
-rw-r--r--src/library/scala/util/control/TailCalls.scala2
322 files changed, 7500 insertions, 2857 deletions
diff --git a/src/library/rootdoc.txt b/src/library/rootdoc.txt
index e84942b8c4..d78df01046 100644
--- a/src/library/rootdoc.txt
+++ b/src/library/rootdoc.txt
@@ -37,19 +37,15 @@ Notable packages include:
- [[scala.sys `scala.sys`]] - Interaction with other processes and the operating system
- [[scala.util.matching `scala.util.matching`]] - [[scala.util.matching.Regex Regular expressions]]
-Other packages exist. See the complete list on the left.
+Other packages exist. See the complete list on the right.
Additional parts of the standard library are shipped as separate libraries. These include:
- [[scala.reflect `scala.reflect`]] - Scala's reflection API (scala-reflect.jar)
- [[scala.xml `scala.xml`]] - XML parsing, manipulation, and serialization (scala-xml.jar)
- [[scala.swing `scala.swing`]] - A convenient wrapper around Java's GUI framework called Swing (scala-swing.jar)
- - [[scala.util.continuations `scala.util.continuations`]] - Delimited continuations using continuation-passing-style
- (scala-continuations-library.jar, scala-continuations-plugin.jar)
- [[scala.util.parsing `scala.util.parsing`]] - [[scala.util.parsing.combinator Parser combinators]], including an
example implementation of a [[scala.util.parsing.json JSON parser]] (scala-parser-combinators.jar)
- - [[scala.actors `scala.actors`]] - Actor-based concurrency (deprecated and replaced by Akka actors,
- scala-actors.jar)
== Automatic imports ==
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala
index d89e9d291d..7f3200b90a 100644
--- a/src/library/scala/Array.scala
+++ b/src/library/scala/Array.scala
@@ -486,6 +486,37 @@ object Array extends FallbackArrayBuilding {
* @see [[http://www.scala-lang.org/files/archive/spec/2.11/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.)
* @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8.
* @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information.
+ * @hideImplicitConversion scala.Predef.booleanArrayOps
+ * @hideImplicitConversion scala.Predef.byteArrayOps
+ * @hideImplicitConversion scala.Predef.charArrayOps
+ * @hideImplicitConversion scala.Predef.doubleArrayOps
+ * @hideImplicitConversion scala.Predef.floatArrayOps
+ * @hideImplicitConversion scala.Predef.intArrayOps
+ * @hideImplicitConversion scala.Predef.longArrayOps
+ * @hideImplicitConversion scala.Predef.refArrayOps
+ * @hideImplicitConversion scala.Predef.shortArrayOps
+ * @hideImplicitConversion scala.Predef.unitArrayOps
+ * @hideImplicitConversion scala.Predef._booleanArrayOps
+ * @hideImplicitConversion scala.Predef._byteArrayOps
+ * @hideImplicitConversion scala.Predef._charArrayOps
+ * @hideImplicitConversion scala.Predef._doubleArrayOps
+ * @hideImplicitConversion scala.Predef._floatArrayOps
+ * @hideImplicitConversion scala.Predef._intArrayOps
+ * @hideImplicitConversion scala.Predef._longArrayOps
+ * @hideImplicitConversion scala.Predef._refArrayOps
+ * @hideImplicitConversion scala.Predef._shortArrayOps
+ * @hideImplicitConversion scala.Predef._unitArrayOps
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapRefArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapIntArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapDoubleArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapLongArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapFloatArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapCharArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapByteArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapShortArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapBooleanArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.wrapUnitArray
+ * @hideImplicitConversion scala.LowPriorityImplicits.genericWrapArray
* @define coll array
* @define Coll `Array`
* @define orderDependent
diff --git a/src/library/scala/Boolean.scala b/src/library/scala/Boolean.scala
index 53b4fb2af2..017f10a283 100644
--- a/src/library/scala/Boolean.scala
+++ b/src/library/scala/Boolean.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -102,7 +102,8 @@ final abstract class Boolean private extends AnyVal {
*/
def ^(x: Boolean): Boolean
- override def getClass(): Class[Boolean] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Boolean] = ???
}
object Boolean extends AnyValCompanion {
@@ -114,7 +115,7 @@ object Boolean extends AnyValCompanion {
* @param x the Boolean to be boxed
* @return a java.lang.Boolean offering `x` as its underlying value.
*/
- def box(x: Boolean): java.lang.Boolean = java.lang.Boolean.valueOf(x)
+ def box(x: Boolean): java.lang.Boolean = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -126,7 +127,7 @@ object Boolean extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Boolean
* @return the Boolean resulting from calling booleanValue() on `x`
*/
- def unbox(x: java.lang.Object): Boolean = x.asInstanceOf[java.lang.Boolean].booleanValue()
+ def unbox(x: java.lang.Object): Boolean = ???
/** The String representation of the scala.Boolean companion object. */
override def toString = "object scala.Boolean"
diff --git a/src/library/scala/Byte.scala b/src/library/scala/Byte.scala
index fb662911b3..3709586f2e 100644
--- a/src/library/scala/Byte.scala
+++ b/src/library/scala/Byte.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -434,7 +434,8 @@ final abstract class Byte private extends AnyVal {
/** Returns the remainder of the division of this value by `x`. */
def %(x: Double): Double
- override def getClass(): Class[Byte] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Byte] = ???
}
object Byte extends AnyValCompanion {
@@ -451,7 +452,7 @@ object Byte extends AnyValCompanion {
* @param x the Byte to be boxed
* @return a java.lang.Byte offering `x` as its underlying value.
*/
- def box(x: Byte): java.lang.Byte = java.lang.Byte.valueOf(x)
+ def box(x: Byte): java.lang.Byte = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -463,7 +464,7 @@ object Byte extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Byte
* @return the Byte resulting from calling byteValue() on `x`
*/
- def unbox(x: java.lang.Object): Byte = x.asInstanceOf[java.lang.Byte].byteValue()
+ def unbox(x: java.lang.Object): Byte = ???
/** The String representation of the scala.Byte companion object. */
override def toString = "object scala.Byte"
diff --git a/src/library/scala/Char.scala b/src/library/scala/Char.scala
index 9f06503569..7dbb0209c3 100644
--- a/src/library/scala/Char.scala
+++ b/src/library/scala/Char.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -434,7 +434,8 @@ final abstract class Char private extends AnyVal {
/** Returns the remainder of the division of this value by `x`. */
def %(x: Double): Double
- override def getClass(): Class[Char] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Char] = ???
}
object Char extends AnyValCompanion {
@@ -451,7 +452,7 @@ object Char extends AnyValCompanion {
* @param x the Char to be boxed
* @return a java.lang.Character offering `x` as its underlying value.
*/
- def box(x: Char): java.lang.Character = java.lang.Character.valueOf(x)
+ def box(x: Char): java.lang.Character = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -463,7 +464,7 @@ object Char extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Character
* @return the Char resulting from calling charValue() on `x`
*/
- def unbox(x: java.lang.Object): Char = x.asInstanceOf[java.lang.Character].charValue()
+ def unbox(x: java.lang.Object): Char = ???
/** The String representation of the scala.Char companion object. */
override def toString = "object scala.Char"
diff --git a/src/library/scala/Double.scala b/src/library/scala/Double.scala
index a58fa3ed25..08bcb9fefc 100644
--- a/src/library/scala/Double.scala
+++ b/src/library/scala/Double.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -200,7 +200,8 @@ final abstract class Double private extends AnyVal {
/** Returns the remainder of the division of this value by `x`. */
def %(x: Double): Double
- override def getClass(): Class[Double] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Double] = ???
}
object Double extends AnyValCompanion {
@@ -229,7 +230,7 @@ object Double extends AnyValCompanion {
* @param x the Double to be boxed
* @return a java.lang.Double offering `x` as its underlying value.
*/
- def box(x: Double): java.lang.Double = java.lang.Double.valueOf(x)
+ def box(x: Double): java.lang.Double = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -241,7 +242,7 @@ object Double extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Double
* @return the Double resulting from calling doubleValue() on `x`
*/
- def unbox(x: java.lang.Object): Double = x.asInstanceOf[java.lang.Double].doubleValue()
+ def unbox(x: java.lang.Object): Double = ???
/** The String representation of the scala.Double companion object. */
override def toString = "object scala.Double"
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index c4aa511cd7..9d9a3f849b 100644
--- a/src/library/scala/Enumeration.scala
+++ b/src/library/scala/Enumeration.scala
@@ -9,7 +9,7 @@
package scala
import scala.collection.{ mutable, immutable, generic, SortedSetLike, AbstractSet }
-import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField }
+import java.lang.reflect.{ Method => JMethod, Field => JField }
import scala.reflect.NameTransformer._
import scala.util.matching.Regex
@@ -154,14 +154,14 @@ abstract class Enumeration (initial: Int) extends Serializable {
protected final def Value(i: Int, name: String): Value = new Val(i, name)
private def populateNameMap() {
- val fields = getClass.getDeclaredFields
- def isValDef(m: JMethod) = fields exists (fd => fd.getName == m.getName && fd.getType == m.getReturnType)
+ val fields: Array[JField] = getClass.getDeclaredFields
+ def isValDef(m: JMethod): Boolean = fields exists (fd => fd.getName == m.getName && fd.getType == m.getReturnType)
// The list of possible Value methods: 0-args which return a conforming type
- val methods = getClass.getMethods filter (m => m.getParameterTypes.isEmpty &&
- classOf[Value].isAssignableFrom(m.getReturnType) &&
- m.getDeclaringClass != classOf[Enumeration] &&
- isValDef(m))
+ val methods: Array[JMethod] = getClass.getMethods filter (m => m.getParameterTypes.isEmpty &&
+ classOf[Value].isAssignableFrom(m.getReturnType) &&
+ m.getDeclaringClass != classOf[Enumeration] &&
+ isValDef(m))
methods foreach { m =>
val name = m.getName
// invoke method to obtain actual `Value` instance
diff --git a/src/library/scala/Float.scala b/src/library/scala/Float.scala
index 3c59057a8d..01fdbc00e4 100644
--- a/src/library/scala/Float.scala
+++ b/src/library/scala/Float.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -200,7 +200,8 @@ final abstract class Float private extends AnyVal {
/** Returns the remainder of the division of this value by `x`. */
def %(x: Double): Double
- override def getClass(): Class[Float] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Float] = ???
}
object Float extends AnyValCompanion {
@@ -229,7 +230,7 @@ object Float extends AnyValCompanion {
* @param x the Float to be boxed
* @return a java.lang.Float offering `x` as its underlying value.
*/
- def box(x: Float): java.lang.Float = java.lang.Float.valueOf(x)
+ def box(x: Float): java.lang.Float = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -241,7 +242,7 @@ object Float extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Float
* @return the Float resulting from calling floatValue() on `x`
*/
- def unbox(x: java.lang.Object): Float = x.asInstanceOf[java.lang.Float].floatValue()
+ def unbox(x: java.lang.Object): Float = ???
/** The String representation of the scala.Float companion object. */
override def toString = "object scala.Float"
diff --git a/src/library/scala/Int.scala b/src/library/scala/Int.scala
index 3bd3775eba..b605af5e37 100644
--- a/src/library/scala/Int.scala
+++ b/src/library/scala/Int.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -434,7 +434,8 @@ final abstract class Int private extends AnyVal {
/** Returns the remainder of the division of this value by `x`. */
def %(x: Double): Double
- override def getClass(): Class[Int] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Int] = ???
}
object Int extends AnyValCompanion {
@@ -451,7 +452,7 @@ object Int extends AnyValCompanion {
* @param x the Int to be boxed
* @return a java.lang.Integer offering `x` as its underlying value.
*/
- def box(x: Int): java.lang.Integer = java.lang.Integer.valueOf(x)
+ def box(x: Int): java.lang.Integer = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -463,7 +464,7 @@ object Int extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Integer
* @return the Int resulting from calling intValue() on `x`
*/
- def unbox(x: java.lang.Object): Int = x.asInstanceOf[java.lang.Integer].intValue()
+ def unbox(x: java.lang.Object): Int = ???
/** The String representation of the scala.Int companion object. */
override def toString = "object scala.Int"
diff --git a/src/library/scala/Long.scala b/src/library/scala/Long.scala
index b27a66647f..84e6f09da3 100644
--- a/src/library/scala/Long.scala
+++ b/src/library/scala/Long.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -434,7 +434,8 @@ final abstract class Long private extends AnyVal {
/** Returns the remainder of the division of this value by `x`. */
def %(x: Double): Double
- override def getClass(): Class[Long] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Long] = ???
}
object Long extends AnyValCompanion {
@@ -451,7 +452,7 @@ object Long extends AnyValCompanion {
* @param x the Long to be boxed
* @return a java.lang.Long offering `x` as its underlying value.
*/
- def box(x: Long): java.lang.Long = java.lang.Long.valueOf(x)
+ def box(x: Long): java.lang.Long = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -463,7 +464,7 @@ object Long extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Long
* @return the Long resulting from calling longValue() on `x`
*/
- def unbox(x: java.lang.Object): Long = x.asInstanceOf[java.lang.Long].longValue()
+ def unbox(x: java.lang.Object): Long = ???
/** The String representation of the scala.Long companion object. */
override def toString = "object scala.Long"
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index fba759eb32..c1a413d516 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -20,7 +20,7 @@ package scala
* {{{
* val f: PartialFunction[Int, Any] = { case _ => 1/0 }
* }}}
- *
+ *
* It is the responsibility of the caller to call `isDefinedAt` before
* calling `apply`, because if `isDefinedAt` is false, it is not guaranteed
* `apply` will throw an exception to indicate an error condition. If an
@@ -161,10 +161,11 @@ trait PartialFunction[-A, +B] extends (A => B) { self =>
object PartialFunction {
/** Composite function produced by `PartialFunction#orElse` method
*/
- private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B]) extends PartialFunction[A, B] {
+ private class OrElse[-A, +B] (f1: PartialFunction[A, B], f2: PartialFunction[A, B])
+ extends scala.runtime.AbstractPartialFunction[A, B] with Serializable {
def isDefinedAt(x: A) = f1.isDefinedAt(x) || f2.isDefinedAt(x)
- def apply(x: A): B = f1.applyOrElse(x, f2)
+ override def apply(x: A): B = f1.applyOrElse(x, f2)
override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = {
val z = f1.applyOrElse(x, checkFallback[B])
@@ -180,7 +181,7 @@ object PartialFunction {
/** Composite function produced by `PartialFunction#andThen` method
*/
- private class AndThen[-A, B, +C] (pf: PartialFunction[A, B], k: B => C) extends PartialFunction[A, C] {
+ private class AndThen[-A, B, +C] (pf: PartialFunction[A, B], k: B => C) extends PartialFunction[A, C] with Serializable {
def isDefinedAt(x: A) = pf.isDefinedAt(x)
def apply(x: A): C = k(pf(x))
@@ -217,7 +218,7 @@ object PartialFunction {
private def fallbackOccurred[B](x: B) = (fallback_pf eq x.asInstanceOf[AnyRef])
private class Lifted[-A, +B] (val pf: PartialFunction[A, B])
- extends scala.runtime.AbstractFunction1[A, Option[B]] {
+ extends scala.runtime.AbstractFunction1[A, Option[B]] with Serializable {
def apply(x: A): Option[B] = {
val z = pf.applyOrElse(x, checkFallback[B])
@@ -225,7 +226,7 @@ object PartialFunction {
}
}
- private class Unlifted[A, B] (f: A => Option[B]) extends scala.runtime.AbstractPartialFunction[A, B] {
+ private class Unlifted[A, B] (f: A => Option[B]) extends scala.runtime.AbstractPartialFunction[A, B] with Serializable {
def isDefinedAt(x: A): Boolean = f(x).isDefined
override def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 = {
@@ -248,7 +249,7 @@ object PartialFunction {
private[this] val constFalse: Any => Boolean = { _ => false}
- private[this] val empty_pf: PartialFunction[Any, Nothing] = new PartialFunction[Any, Nothing] {
+ private[this] val empty_pf: PartialFunction[Any, Nothing] = new PartialFunction[Any, Nothing] with Serializable {
def isDefinedAt(x: Any) = false
def apply(x: Any) = throw new MatchError(x)
override def orElse[A1, B1](that: PartialFunction[A1, B1]) = that
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 94cb331ce1..58d43f8666 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -8,13 +8,14 @@
package scala
+import scala.language.implicitConversions
+
import scala.collection.{ mutable, immutable, generic }
import immutable.StringOps
import mutable.ArrayOps
import generic.CanBuildFrom
import scala.annotation.{ elidable, implicitNotFound }
import scala.annotation.elidable.ASSERTION
-import scala.language.{implicitConversions, existentials}
import scala.io.StdIn
/** The `Predef` object provides definitions that are accessible in all Scala
@@ -27,13 +28,11 @@ import scala.io.StdIn
* constructors ([[scala.collection.immutable.::]] and
* [[scala.collection.immutable.Nil]]).
*
- * === Console I/O ===
- * Predef provides a number of simple functions for console I/O, such as
- * `print`, `println`, `readLine`, `readInt`, etc. These functions are all
- * aliases of the functions provided by [[scala.Console]].
+ * === Console Output ===
+ * For basic console output, `Predef` provides convenience methods [[print(x:Any* print]] and [[println(x:Any* println]],
+ * which are aliases of the methods in the object [[scala.Console]].
*
* === Assertions ===
- *
* A set of `assert` functions are provided for use as a way to document
* and dynamically check invariants in code. Invocations of `assert` can be elided
* at compile time by providing the command line option `-Xdisable-assertions`,
@@ -66,6 +65,49 @@ import scala.io.StdIn
* are provided for the "widening" of numeric values, for instance, converting a
* Short value to a Long value as required, and to add additional higher-order
* functions to Array values. These are described in more detail in the documentation of [[scala.Array]].
+ *
+ * @groupname utilities Utility Methods
+ * @groupprio utilities 10
+ *
+ * @groupname assertions Assertions
+ * @groupprio assertions 20
+ * @groupdesc assertions These methods support program verfication and runtime correctness.
+ *
+ * @groupname console-output Console Output
+ * @groupprio console-output 30
+ * @groupdesc console-output These methods provide output via the console.
+ *
+ * @groupname type-constraints Type Constraints
+ * @groupprio type-constraints 40
+ * @groupdesc type-constraints These entities allows constraints between types to be stipulated.
+ *
+ * @groupname aliases Aliases
+ * @groupprio aliases 50
+ * @groupdesc aliases These aliases bring selected immutable types into scope without any imports.
+ *
+ * @groupname conversions-string String Conversions
+ * @groupprio conversions-string 60
+ * @groupdesc conversions-string Conversions to and from String and StringOps.
+ *
+ * @groupname implicit-classes-any Implicit Classes
+ * @groupprio implicit-classes-any 70
+ * @groupdesc implicit-classes-any These implicit classes add useful extension methods to every type.
+ *
+ * @groupname implicit-classes-char CharSequence Conversions
+ * @groupprio implicit-classes-char 80
+ * @groupdesc implicit-classes-char These implicit classes add CharSequence methods to Array[Char] and IndexedSeq[Char] instances.
+ *
+ * @groupname conversions-java-to-anyval Java to Scala
+ * @groupprio conversions-java-to-anyval 90
+ * @groupdesc conversions-java-to-anyval Implicit conversion from Java primitive wrapper types to Scala equivalents.
+ *
+ * @groupname conversions-anyval-to-java Scala to Java
+ * @groupprio conversions-anyval-to-java 100
+ * @groupdesc conversions-anyval-to-java Implicit conversion from Scala AnyVals to Java primitive wrapper types equivalents.
+ *
+ * @groupname conversions-array-to-wrapped-array Array to WrappedArray
+ * @groupprio conversions-array-to-wrapped-array 110
+ * @groupdesc conversions-array-to-wrapped-array Conversions from Arrays to WrappedArrays.
*/
object Predef extends LowPriorityImplicits with DeprecatedPredef {
/**
@@ -79,6 +121,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
* val mapIntString = classOf[Map[Int,String]]
* // mapIntString is java.lang.Class[Map[Int,String]] = interface scala.collection.immutable.Map
* }}}
+ * @group utilities
*/
def classOf[T]: Class[T] = null // This is a stub method. The actual implementation is filled in by the compiler.
@@ -86,19 +129,26 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
* Java String (see the documentation corresponding to your Java version, for
* example [[http://docs.oracle.com/javase/8/docs/api/java/lang/String.html]]) or
* are added implicitly through [[scala.collection.immutable.StringOps]].
+ * @group aliases
*/
type String = java.lang.String
+ /** @group aliases */
type Class[T] = java.lang.Class[T]
// miscellaneous -----------------------------------------------------
scala.`package` // to force scala package object to be seen.
scala.collection.immutable.List // to force Nil, :: to be seen.
+ /** @group aliases */
type Function[-A, +B] = Function1[A, B]
+ /** @group aliases */
type Map[A, +B] = immutable.Map[A, B]
+ /** @group aliases */
type Set[A] = immutable.Set[A]
+ /** @group aliases */
val Map = immutable.Map
+ /** @group aliases */
val Set = immutable.Set
// Manifest types, companions, and incantations for summoning
@@ -131,24 +181,22 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
def optManifest[T](implicit m: OptManifest[T]) = m
// Minor variations on identity functions
- def identity[A](x: A): A = x // @see `conforms` for the implicit version
+ /** @group utilities */
+ @inline def identity[A](x: A): A = x // @see `conforms` for the implicit version
+ /** @group utilities */
@inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero`
+ /** @group utilities */
@inline def locally[T](x: T): T = x // to communicate intent and avoid unmoored statements
- // errors and asserts -------------------------------------------------
-
- // !!! Remove this when possible - ideally for 2.11.
- // We are stuck with it a while longer because sbt's compiler interface
- // still calls it as of 0.12.2.
- @deprecated("Use `sys.error(message)` instead", "2.9.0")
- def error(message: String): Nothing = sys.error(message)
+ // assertions ---------------------------------------------------------
/** Tests an expression, throwing an `AssertionError` if false.
* Calls to this method will not be generated if `-Xelide-below`
- * is at least `ASSERTION`.
+ * is greater than `ASSERTION`.
*
- * @see elidable
+ * @see [[scala.annotation.elidable elidable]]
* @param assertion the expression to test
+ * @group assertions
*/
@elidable(ASSERTION)
def assert(assertion: Boolean) {
@@ -158,11 +206,12 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
/** Tests an expression, throwing an `AssertionError` if false.
* Calls to this method will not be generated if `-Xelide-below`
- * is at least `ASSERTION`.
+ * is greater than `ASSERTION`.
*
- * @see elidable
+ * @see [[scala.annotation.elidable elidable]]
* @param assertion the expression to test
* @param message a String to include in the failure message
+ * @group assertions
*/
@elidable(ASSERTION) @inline
final def assert(assertion: Boolean, message: => Any) {
@@ -174,10 +223,11 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
* This method differs from assert only in the intent expressed:
* assert contains a predicate which needs to be proven, while
* assume contains an axiom for a static checker. Calls to this method
- * will not be generated if `-Xelide-below` is at least `ASSERTION`.
+ * will not be generated if `-Xelide-below` is greater than `ASSERTION`.
*
- * @see elidable
+ * @see [[scala.annotation.elidable elidable]]
* @param assumption the expression to test
+ * @group assertions
*/
@elidable(ASSERTION)
def assume(assumption: Boolean) {
@@ -189,11 +239,12 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
* This method differs from assert only in the intent expressed:
* assert contains a predicate which needs to be proven, while
* assume contains an axiom for a static checker. Calls to this method
- * will not be generated if `-Xelide-below` is at least `ASSERTION`.
+ * will not be generated if `-Xelide-below` is greater than `ASSERTION`.
*
- * @see elidable
+ * @see [[scala.annotation.elidable elidable]]
* @param assumption the expression to test
* @param message a String to include in the failure message
+ * @group assertions
*/
@elidable(ASSERTION) @inline
final def assume(assumption: Boolean, message: => Any) {
@@ -206,6 +257,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
* for violating the condition.
*
* @param requirement the expression to test
+ * @group assertions
*/
def require(requirement: Boolean) {
if (!requirement)
@@ -218,6 +270,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
*
* @param requirement the expression to test
* @param message a String to include in the failure message
+ * @group assertions
*/
@inline final def require(requirement: Boolean, message: => Any) {
if (!requirement)
@@ -226,6 +279,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
/** `???` can be used for marking methods that remain to be implemented.
* @throws NotImplementedError
+ * @group utilities
*/
def ??? : Nothing = throw new NotImplementedError
@@ -249,11 +303,13 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
// implicit classes -----------------------------------------------------
+ /** @group implicit-classes-any */
implicit final class ArrowAssoc[A](private val self: A) extends AnyVal {
@inline def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y)
def →[B](y: B): Tuple2[A, B] = ->(y)
}
+ /** @group implicit-classes-any */
implicit final class Ensuring[A](private val self: A) extends AnyVal {
def ensuring(cond: Boolean): A = { assert(cond); self }
def ensuring(cond: Boolean, msg: => Any): A = { assert(cond, msg); self }
@@ -261,6 +317,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
def ensuring(cond: A => Boolean, msg: => Any): A = { assert(cond(self), msg); self }
}
+ /** @group implicit-classes-any */
implicit final class StringFormat[A](private val self: A) extends AnyVal {
/** Returns string formatted according to given `format` string.
* Format strings are as for `String.format`
@@ -269,14 +326,8 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
@inline def formatted(fmtstr: String): String = fmtstr format self
}
- // TODO: remove, only needed for binary compatibility of 2.11.0-RC1 with 2.11.0-M8
- // note that `private[scala]` becomes `public` in bytecode
- private[scala] final class StringAdd[A](private val self: A) extends AnyVal {
- def +(other: String): String = String.valueOf(self) + other
- }
- private[scala] def StringAdd(x: Any): Any = new StringAdd(x)
-
// SI-8229 retaining the pre 2.11 name for source compatibility in shadowing this implicit
+ /** @group implicit-classes-any */
implicit final class any2stringadd[A](private val self: A) extends AnyVal {
def +(other: String): String = String.valueOf(self) + other
}
@@ -286,6 +337,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
@deprecated("Use Throwable#getStackTrace", "2.11.0") def getStackTraceString = self.getStackTrace().mkString("", EOL, EOL)
}
+ /** @group implicit-classes-char */
implicit final class SeqCharSequence(val __sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence {
def length: Int = __sequenceOfChars.length
def charAt(index: Int): Char = __sequenceOfChars(index)
@@ -293,6 +345,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
override def toString = __sequenceOfChars mkString ""
}
+ /** @group implicit-classes-char */
implicit final class ArrayCharSequence(val __arrayOfChars: Array[Char]) extends CharSequence {
def length: Int = __arrayOfChars.length
def charAt(index: Int): Char = __arrayOfChars(index)
@@ -305,14 +358,48 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
def apply() = mutable.StringBuilder.newBuilder
}
+ /** @group conversions-string */
@inline implicit def augmentString(x: String): StringOps = new StringOps(x)
+ /** @group conversions-string */
@inline implicit def unaugmentString(x: StringOps): String = x.repr
// printing -----------------------------------------------------------
+ /** Prints an object to `out` using its `toString` method.
+ *
+ * @param x the object to print; may be null.
+ * @group console-output
+ */
def print(x: Any) = Console.print(x)
+
+ /** Prints a newline character on the default output.
+ * @group console-output
+ */
def println() = Console.println()
+
+ /** Prints out an object to the default output, followed by a newline character.
+ *
+ * @param x the object to print.
+ * @group console-output
+ */
def println(x: Any) = Console.println(x)
+
+ /** Prints its arguments as a formatted string to the default output,
+ * based on a string pattern (in a fashion similar to printf in C).
+ *
+ * The interpretation of the formatting patterns is described in
+ * <a href="" target="contentFrame" class="java/util/Formatter">
+ * `java.util.Formatter`</a>.
+ *
+ * Consider using the [[scala.StringContext.f f interpolator]] as more type safe and idiomatic.
+ *
+ * @param text the pattern for formatting the arguments.
+ * @param args the arguments used to instantiating the pattern.
+ * @throws java.lang.IllegalArgumentException if there was a problem with the format string or arguments
+ *
+ * @see [[scala.StringContext.f StringContext.f]]
+ * @group console-output
+ */
def printf(text: String, xs: Any*) = Console.print(text.format(xs: _*))
// views --------------------------------------------------------------
@@ -334,36 +421,64 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
case null => null
}).asInstanceOf[ArrayOps[T]]
- implicit def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs)
- implicit def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps.ofByte(xs)
- implicit def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps.ofChar(xs)
- implicit def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs)
- implicit def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps.ofFloat(xs)
- implicit def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs)
- implicit def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs)
- implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs)
- implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs)
- implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs)
+ // TODO: when we remove, these should we drop the underscores from the new generation below? (For source compatibility in case someone was shadowing these.)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps.ofBoolean(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps.ofByte(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps.ofChar(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps.ofFloat(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps.ofShort(xs)
+ @deprecated("For binary compatibility only. Release new partest and remove in M3.", "2.12.0-M2") def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps.ofUnit(xs)
+
+ implicit def _booleanArrayOps(xs: Array[Boolean]): ArrayOps.ofBoolean = new ArrayOps.ofBoolean(xs)
+ implicit def _byteArrayOps(xs: Array[Byte]): ArrayOps.ofByte = new ArrayOps.ofByte(xs)
+ implicit def _charArrayOps(xs: Array[Char]): ArrayOps.ofChar = new ArrayOps.ofChar(xs)
+ implicit def _doubleArrayOps(xs: Array[Double]): ArrayOps.ofDouble = new ArrayOps.ofDouble(xs)
+ implicit def _floatArrayOps(xs: Array[Float]): ArrayOps.ofFloat = new ArrayOps.ofFloat(xs)
+ implicit def _intArrayOps(xs: Array[Int]): ArrayOps.ofInt = new ArrayOps.ofInt(xs)
+ implicit def _longArrayOps(xs: Array[Long]): ArrayOps.ofLong = new ArrayOps.ofLong(xs)
+ implicit def _refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps.ofRef[T] = new ArrayOps.ofRef[T](xs)
+ implicit def _shortArrayOps(xs: Array[Short]): ArrayOps.ofShort = new ArrayOps.ofShort(xs)
+ implicit def _unitArrayOps(xs: Array[Unit]): ArrayOps.ofUnit = new ArrayOps.ofUnit(xs)
// "Autoboxing" and "Autounboxing" ---------------------------------------------------
- implicit def byte2Byte(x: Byte) = java.lang.Byte.valueOf(x)
- implicit def short2Short(x: Short) = java.lang.Short.valueOf(x)
- implicit def char2Character(x: Char) = java.lang.Character.valueOf(x)
- implicit def int2Integer(x: Int) = java.lang.Integer.valueOf(x)
- implicit def long2Long(x: Long) = java.lang.Long.valueOf(x)
- implicit def float2Float(x: Float) = java.lang.Float.valueOf(x)
- implicit def double2Double(x: Double) = java.lang.Double.valueOf(x)
- implicit def boolean2Boolean(x: Boolean) = java.lang.Boolean.valueOf(x)
-
- implicit def Byte2byte(x: java.lang.Byte): Byte = x.byteValue
- implicit def Short2short(x: java.lang.Short): Short = x.shortValue
- implicit def Character2char(x: java.lang.Character): Char = x.charValue
- implicit def Integer2int(x: java.lang.Integer): Int = x.intValue
- implicit def Long2long(x: java.lang.Long): Long = x.longValue
- implicit def Float2float(x: java.lang.Float): Float = x.floatValue
- implicit def Double2double(x: java.lang.Double): Double = x.doubleValue
- implicit def Boolean2boolean(x: java.lang.Boolean): Boolean = x.booleanValue
+ /** @group conversions-anyval-to-java */
+ implicit def byte2Byte(x: Byte): java.lang.Byte = x.asInstanceOf[java.lang.Byte]
+ /** @group conversions-anyval-to-java */
+ implicit def short2Short(x: Short): java.lang.Short = x.asInstanceOf[java.lang.Short]
+ /** @group conversions-anyval-to-java */
+ implicit def char2Character(x: Char): java.lang.Character = x.asInstanceOf[java.lang.Character]
+ /** @group conversions-anyval-to-java */
+ implicit def int2Integer(x: Int): java.lang.Integer = x.asInstanceOf[java.lang.Integer]
+ /** @group conversions-anyval-to-java */
+ implicit def long2Long(x: Long): java.lang.Long = x.asInstanceOf[java.lang.Long]
+ /** @group conversions-anyval-to-java */
+ implicit def float2Float(x: Float): java.lang.Float = x.asInstanceOf[java.lang.Float]
+ /** @group conversions-anyval-to-java */
+ implicit def double2Double(x: Double): java.lang.Double = x.asInstanceOf[java.lang.Double]
+ /** @group conversions-anyval-to-java */
+ implicit def boolean2Boolean(x: Boolean): java.lang.Boolean = x.asInstanceOf[java.lang.Boolean]
+
+ /** @group conversions-java-to-anyval */
+ implicit def Byte2byte(x: java.lang.Byte): Byte = x.asInstanceOf[Byte]
+ /** @group conversions-java-to-anyval */
+ implicit def Short2short(x: java.lang.Short): Short = x.asInstanceOf[Short]
+ /** @group conversions-java-to-anyval */
+ implicit def Character2char(x: java.lang.Character): Char = x.asInstanceOf[Char]
+ /** @group conversions-java-to-anyval */
+ implicit def Integer2int(x: java.lang.Integer): Int = x.asInstanceOf[Int]
+ /** @group conversions-java-to-anyval */
+ implicit def Long2long(x: java.lang.Long): Long = x.asInstanceOf[Long]
+ /** @group conversions-java-to-anyval */
+ implicit def Float2float(x: java.lang.Float): Float = x.asInstanceOf[Float]
+ /** @group conversions-java-to-anyval */
+ implicit def Double2double(x: java.lang.Double): Double = x.asInstanceOf[Double]
+ /** @group conversions-java-to-anyval */
+ implicit def Boolean2boolean(x: java.lang.Boolean): Boolean = x.asInstanceOf[Boolean]
// Type Constraints --------------------------------------------------------------
@@ -383,6 +498,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
* required lower bound.
*
* In part contributed by Jason Zaugg.
+ * @group type-constraints
*/
@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
@@ -390,6 +506,7 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
// The dollar prefix is to dodge accidental shadowing of this method
// by a user-defined method of the same name (SI-7788).
// The collections rely on this method.
+ /** @group type-constraints */
implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
@deprecated("Use `implicitly[T <:< U]` or `identity` instead.", "2.11.0")
@@ -398,10 +515,12 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
/** An instance of `A =:= B` witnesses that the types `A` and `B` are equal.
*
* @see `<:<` for expressing subtyping constraints
+ * @group type-constraints
*/
@implicitNotFound(msg = "Cannot prove that ${From} =:= ${To}.")
sealed abstract class =:=[From, To] extends (From => To) with Serializable
private[this] final val singleton_=:= = new =:=[Any,Any] { def apply(x: Any): Any = x }
+ /** @group type-constraints */
object =:= {
implicit def tpEquals[A]: A =:= A = singleton_=:=.asInstanceOf[A =:= A]
}
@@ -481,6 +600,7 @@ private[scala] abstract class LowPriorityImplicits {
@inline implicit def doubleWrapper(x: Double) = new runtime.RichDouble(x)
@inline implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x)
+ /** @group conversions-array-to-wrapped-array */
implicit def genericWrapArray[T](xs: Array[T]): WrappedArray[T] =
if (xs eq null) null
else WrappedArray.make(xs)
@@ -488,23 +608,35 @@ private[scala] abstract class LowPriorityImplicits {
// Since the JVM thinks arrays are covariant, one 0-length Array[AnyRef]
// is as good as another for all T <: AnyRef. Instead of creating 100,000,000
// unique ones by way of this implicit, let's share one.
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapRefArray[T <: AnyRef](xs: Array[T]): WrappedArray[T] = {
if (xs eq null) null
else if (xs.length == 0) WrappedArray.empty[T]
else new WrappedArray.ofRef[T](xs)
}
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapIntArray(xs: Array[Int]): WrappedArray[Int] = if (xs ne null) new WrappedArray.ofInt(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapDoubleArray(xs: Array[Double]): WrappedArray[Double] = if (xs ne null) new WrappedArray.ofDouble(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapLongArray(xs: Array[Long]): WrappedArray[Long] = if (xs ne null) new WrappedArray.ofLong(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapFloatArray(xs: Array[Float]): WrappedArray[Float] = if (xs ne null) new WrappedArray.ofFloat(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapCharArray(xs: Array[Char]): WrappedArray[Char] = if (xs ne null) new WrappedArray.ofChar(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapByteArray(xs: Array[Byte]): WrappedArray[Byte] = if (xs ne null) new WrappedArray.ofByte(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapShortArray(xs: Array[Short]): WrappedArray[Short] = if (xs ne null) new WrappedArray.ofShort(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapBooleanArray(xs: Array[Boolean]): WrappedArray[Boolean] = if (xs ne null) new WrappedArray.ofBoolean(xs) else null
+ /** @group conversions-array-to-wrapped-array */
implicit def wrapUnitArray(xs: Array[Unit]): WrappedArray[Unit] = if (xs ne null) new WrappedArray.ofUnit(xs) else null
+ /** @group conversions-string */
implicit def wrapString(s: String): WrappedString = if (s ne null) new WrappedString(s) else null
+ /** @group conversions-string */
implicit def unwrapString(ws: WrappedString): String = if (ws ne null) ws.self else null
implicit def fallbackStringCanBuildFrom[T]: CanBuildFrom[String, T, immutable.IndexedSeq[T]] =
diff --git a/src/library/scala/Short.scala b/src/library/scala/Short.scala
index 2cbbf3cc59..136d745f16 100644
--- a/src/library/scala/Short.scala
+++ b/src/library/scala/Short.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -434,7 +434,8 @@ final abstract class Short private extends AnyVal {
/** Returns the remainder of the division of this value by `x`. */
def %(x: Double): Double
- override def getClass(): Class[Short] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Short] = ???
}
object Short extends AnyValCompanion {
@@ -451,7 +452,7 @@ object Short extends AnyValCompanion {
* @param x the Short to be boxed
* @return a java.lang.Short offering `x` as its underlying value.
*/
- def box(x: Short): java.lang.Short = java.lang.Short.valueOf(x)
+ def box(x: Short): java.lang.Short = ???
/** Transform a boxed type into a value type. Note that this
* method is not typesafe: it accepts any Object, but will throw
@@ -463,7 +464,7 @@ object Short extends AnyValCompanion {
* @throws ClassCastException if the argument is not a java.lang.Short
* @return the Short resulting from calling shortValue() on `x`
*/
- def unbox(x: java.lang.Object): Short = x.asInstanceOf[java.lang.Short].shortValue()
+ def unbox(x: java.lang.Object): Short = ???
/** The String representation of the scala.Short companion object. */
override def toString = "object scala.Short"
diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala
index 4fead7a50c..4dcfdd4cba 100644
--- a/src/library/scala/Symbol.scala
+++ b/src/library/scala/Symbol.scala
@@ -71,8 +71,8 @@ private[scala] abstract class UniquenessCache[K, V >: Null]
else {
// If we don't remove the old String key from the map, we can
// wind up with one String as the key and a different String as
- // as the name field in the Symbol, which can lead to surprising
- // GC behavior and duplicate Symbols. See SI-6706.
+ // the name field in the Symbol, which can lead to surprising GC
+ // behavior and duplicate Symbols. See SI-6706.
map remove name
val sym = valueFromKey(name)
map.put(name, new WeakReference(sym))
diff --git a/src/library/scala/Unit.scala b/src/library/scala/Unit.scala
index 018ad24a99..eb6d1d0ddf 100644
--- a/src/library/scala/Unit.scala
+++ b/src/library/scala/Unit.scala
@@ -7,8 +7,8 @@
\* */
// DO NOT EDIT, CHANGES WILL BE LOST
-// This auto-generated code can be modified in scala.tools.cmd.gen.
-// Afterwards, running tools/codegen-anyvals regenerates this source file.
+// This auto-generated code can be modified in "project/GenerateAnyVals.scala".
+// Afterwards, running "sbt generateSources" regenerates this source file.
package scala
@@ -19,7 +19,8 @@ package scala
* method which is declared `void`.
*/
final abstract class Unit private extends AnyVal {
- override def getClass(): Class[Unit] = null
+ // Provide a more specific return type for Scaladoc
+ override def getClass(): Class[Unit] = ???
}
object Unit extends AnyValCompanion {
@@ -39,7 +40,7 @@ object Unit extends AnyValCompanion {
* @throws ClassCastException if the argument is not a scala.runtime.BoxedUnit
* @return the Unit value ()
*/
- def unbox(x: java.lang.Object): Unit = ()
+ def unbox(x: java.lang.Object): Unit = x.asInstanceOf[scala.runtime.BoxedUnit]
/** The String representation of the scala.Unit companion object. */
override def toString = "object scala.Unit"
diff --git a/src/library/scala/annotation/elidable.scala b/src/library/scala/annotation/elidable.scala
index f9c5e8a744..dd0d9b511c 100644
--- a/src/library/scala/annotation/elidable.scala
+++ b/src/library/scala/annotation/elidable.scala
@@ -8,8 +8,6 @@
package scala.annotation
-import java.util.logging.Level
-
/** An annotation for methods whose bodies may be excluded
* from compiler-generated bytecode.
*
@@ -62,7 +60,7 @@ import java.util.logging.Level
* @author Paul Phillips
* @since 2.8
*/
-final class elidable(final val level: Int) extends scala.annotation.StaticAnnotation {}
+final class elidable(final val level: Int) extends scala.annotation.StaticAnnotation
/** This useless appearing code was necessary to allow people to use
* named constants for the elidable annotation. This is what it takes
diff --git a/src/library/scala/annotation/implicitAmbiguous.scala b/src/library/scala/annotation/implicitAmbiguous.scala
new file mode 100644
index 0000000000..44e8d23085
--- /dev/null
+++ b/src/library/scala/annotation/implicitAmbiguous.scala
@@ -0,0 +1,32 @@
+package scala.annotation
+
+/**
+ * To customize the error message that's emitted when an implicit search finds
+ * multiple ambiguous values, annotate at least one of the implicit values
+ * `@implicitAmbiguous`. Assuming the implicit value is a method with type
+ * parameters `X1,..., XN`, the error message will be the result of replacing
+ * all occurrences of `${Xi}` in the string `msg` with the string representation
+ * of the corresponding type argument `Ti`.
+ *
+ * If more than one `@implicitAmbiguous` annotation is collected, the compiler is
+ * free to pick any of them to display.
+ *
+ * Nice errors can direct users to fix imports or even tell them why code
+ * intentionally doesn't compile.
+ *
+ * {{{
+ * trait =!=[C, D]
+ *
+ * implicit def neq[E, F] : E =!= F = null
+ *
+ * @annotation.implicitAmbiguous("Could not prove ${J} =!= ${J}")
+ * implicit def neqAmbig1[G, H, J] : J =!= J = null
+ * implicit def neqAmbig2[I] : I =!= I = null
+ *
+ * implicitly[Int =!= Int]
+ * }}}
+ *
+ * @author Brian McKenna
+ * @since 2.12.0
+ */
+final class implicitAmbiguous(msg: String) extends scala.annotation.StaticAnnotation
diff --git a/src/library/scala/beans/BeanInfo.scala b/src/library/scala/beans/BeanInfo.scala
index 799e93e71a..d7f0a1618b 100644
--- a/src/library/scala/beans/BeanInfo.scala
+++ b/src/library/scala/beans/BeanInfo.scala
@@ -17,4 +17,5 @@ package scala.beans
*
* @author Ross Judson (rjudson@managedobjects.com)
*/
+@deprecated(message = "the generation of BeanInfo classes is no longer supported", since = "2.12.0")
class BeanInfo extends scala.annotation.Annotation
diff --git a/src/library/scala/collection/BitSetLike.scala b/src/library/scala/collection/BitSetLike.scala
index 29369447d1..209b00ebf9 100644
--- a/src/library/scala/collection/BitSetLike.scala
+++ b/src/library/scala/collection/BitSetLike.scala
@@ -204,6 +204,27 @@ trait BitSetLike[+This <: BitSetLike[This] with SortedSet[Int]] extends SortedSe
def subsetOf(other: BitSet): Boolean =
(0 until nwords) forall (idx => (this.word(idx) & ~ other.word(idx)) == 0L)
+ override def head: Int = {
+ val n = nwords
+ var i = 0
+ while (i < n) {
+ val wi = word(i)
+ if (wi != 0L) return WordLength*i + java.lang.Long.numberOfTrailingZeros(wi)
+ i += 1
+ }
+ throw new NoSuchElementException("Empty BitSet")
+ }
+
+ override def last: Int = {
+ var i = nwords - 1
+ while (i >= 0) {
+ val wi = word(i)
+ if (wi != 0L) return WordLength*i + 63 - java.lang.Long.numberOfLeadingZeros(wi)
+ i += 1
+ }
+ throw new NoSuchElementException("Empty BitSet")
+ }
+
override def addString(sb: StringBuilder, start: String, sep: String, end: String) = {
sb append start
var pre = ""
diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala
index be1da1660a..405d8d7e57 100644
--- a/src/library/scala/collection/GenSeqLike.scala
+++ b/src/library/scala/collection/GenSeqLike.scala
@@ -58,6 +58,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal
* Note: `xs.length` and `xs.size` yield the same result.
*
* @return the number of elements in this $coll.
+ * @throws IllegalArgumentException if the length of the sequence cannot be represented in an `Int`, for example, `(-1 to Int.MaxValue).length`.
*/
def length: Int
diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala
index 18c9175ee1..f4bf58ffe3 100644
--- a/src/library/scala/collection/IndexedSeqLike.scala
+++ b/src/library/scala/collection/IndexedSeqLike.scala
@@ -9,9 +9,6 @@
package scala
package collection
-import mutable.ArrayBuffer
-import scala.annotation.tailrec
-
/** A template trait for indexed sequences of type `IndexedSeq[A]`.
*
* $indexedSeqInfo
diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala
index a7e06b4d1a..3765b2fff0 100644
--- a/src/library/scala/collection/IndexedSeqOptimized.scala
+++ b/src/library/scala/collection/IndexedSeqOptimized.scala
@@ -10,7 +10,6 @@ package scala
package collection
import generic._
-import mutable.ArrayBuffer
import scala.annotation.tailrec
/** A template trait for indexed sequences of type `IndexedSeq[A]` which optimizes
diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala
index ecf64624e8..b89720da78 100644
--- a/src/library/scala/collection/IterableLike.scala
+++ b/src/library/scala/collection/IterableLike.scala
@@ -10,8 +10,7 @@ package scala
package collection
import generic._
-import immutable.{ List, Stream }
-import scala.annotation.unchecked.uncheckedVariance
+import immutable.Stream
/** A template trait for iterable collections of type `Iterable[A]`.
* $iterableInfo
@@ -83,8 +82,8 @@ self =>
iterator.foldRight(z)(op)
override /*TraversableLike*/ def reduceRight[B >: A](op: (A, B) => B): B =
iterator.reduceRight(op)
-
-
+
+
/** Returns this $coll as an iterable collection.
*
* A new collection will not be built; lazy collections will stay lazy.
@@ -94,7 +93,7 @@ self =>
*/
override /*TraversableLike*/ def toIterable: Iterable[A] =
thisCollection
-
+
/** Returns an Iterator over the elements in this $coll. Produces the same
* result as `iterator`.
* $willNotTerminateInf
@@ -102,7 +101,7 @@ self =>
*/
@deprecatedOverriding("toIterator should stay consistent with iterator for all Iterables: override iterator instead.", "2.11.0")
override def toIterator: Iterator[A] = iterator
-
+
override /*TraversableLike*/ def head: A =
iterator.next()
diff --git a/src/library/scala/collection/IterableProxyLike.scala b/src/library/scala/collection/IterableProxyLike.scala
index 90e630ee28..334b511fb9 100644
--- a/src/library/scala/collection/IterableProxyLike.scala
+++ b/src/library/scala/collection/IterableProxyLike.scala
@@ -12,7 +12,6 @@ package scala
package collection
import generic._
-import mutable.Buffer
// Methods could be printed by cat IterableLike.scala | egrep '^ (override )?def'
diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala
index b84d90c51b..c254ed7480 100644
--- a/src/library/scala/collection/IterableViewLike.scala
+++ b/src/library/scala/collection/IterableViewLike.scala
@@ -69,6 +69,10 @@ trait IterableViewLike[+A,
trait Appended[B >: A] extends super.Appended[B] with Transformed[B] {
def iterator = self.iterator ++ rest
}
+
+ trait Prepended[B >: A] extends super.Prepended[B] with Transformed[B] {
+ def iterator = fst.toIterator ++ self
+ }
trait Filtered extends super.Filtered with Transformed[A] {
def iterator = self.iterator filter pred
@@ -110,6 +114,7 @@ trait IterableViewLike[+A,
} with AbstractTransformed[(A1, B)] with ZippedAll[A1, B]
protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected override def newPrepended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val fst = that } with AbstractTransformed[B] with Prepended[B]
protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 8d88b1c6b1..1426278954 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -11,9 +11,8 @@ package collection
import mutable.ArrayBuffer
import scala.annotation.{tailrec, migration}
+import scala.annotation.unchecked.{uncheckedVariance => uV}
import immutable.Stream
-import scala.collection.generic.CanBuildFrom
-import scala.annotation.unchecked.{ uncheckedVariance => uV }
/** The `Iterator` object provides various functions for creating specialized iterators.
*
@@ -162,30 +161,49 @@ object Iterator {
def next = elem
}
- /** Avoid stack overflows when applying ++ to lots of iterators by
- * flattening the unevaluated iterators out into a vector of closures.
+ /** Creates an iterator to which other iterators can be appended efficiently.
+ * Nested ConcatIterators are merged to avoid blowing the stack.
*/
- private[scala] final class ConcatIterator[+A](private[this] var current: Iterator[A], initial: Vector[() => Iterator[A]]) extends Iterator[A] {
- @deprecated def this(initial: Vector[() => Iterator[A]]) = this(Iterator.empty, initial) // for binary compatibility
- private[this] var queue: Vector[() => Iterator[A]] = initial
- private[this] var currentHasNextChecked = false
+ private final class ConcatIterator[+A](private var current: Iterator[A @uV]) extends Iterator[A] {
+ private var tail: ConcatIteratorCell[A @uV] = null
+ private var last: ConcatIteratorCell[A @uV] = null
+ private var currentHasNextChecked = false
+
// Advance current to the next non-empty iterator
// current is set to null when all iterators are exhausted
@tailrec
private[this] def advance(): Boolean = {
- if (queue.isEmpty) {
+ if (tail eq null) {
current = null
+ last = null
false
}
else {
- current = queue.head()
- queue = queue.tail
- if (current.hasNext) {
+ current = tail.headIterator
+ tail = tail.tail
+ merge()
+ if (currentHasNextChecked) true
+ else if (current.hasNext) {
currentHasNextChecked = true
true
} else advance()
}
}
+
+ // If the current iterator is a ConcatIterator, merge it into this one
+ @tailrec
+ private[this] def merge(): Unit =
+ if (current.isInstanceOf[ConcatIterator[_]]) {
+ val c = current.asInstanceOf[ConcatIterator[A]]
+ current = c.current
+ currentHasNextChecked = c.currentHasNextChecked
+ if (c.tail ne null) {
+ c.last.tail = tail
+ tail = c.tail
+ }
+ merge()
+ }
+
def hasNext =
if (currentHasNextChecked) true
else if (current eq null) false
@@ -193,47 +211,73 @@ object Iterator {
currentHasNextChecked = true
true
} else advance()
+
def next() =
if (hasNext) {
currentHasNextChecked = false
current.next()
} else Iterator.empty.next()
- override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] =
- new ConcatIterator(current, queue :+ (() => that.toIterator))
+ override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = {
+ val c = new ConcatIteratorCell[B](that, null).asInstanceOf[ConcatIteratorCell[A]]
+ if(tail eq null) {
+ tail = c
+ last = c
+ } else {
+ last.tail = c
+ last = c
+ }
+ if(current eq null) current = Iterator.empty
+ this
+ }
}
- private[scala] final class JoinIterator[+A](lhs: Iterator[A], that: => GenTraversableOnce[A]) extends Iterator[A] {
- private[this] var state = 0 // 0: lhs not checked, 1: lhs has next, 2: switched to rhs
- private[this] lazy val rhs: Iterator[A] = that.toIterator
- def hasNext = state match {
- case 0 =>
- if (lhs.hasNext) {
- state = 1
- true
- } else {
- state = 2
- rhs.hasNext
- }
- case 1 => true
- case _ => rhs.hasNext
+ private[this] final class ConcatIteratorCell[A](head: => GenTraversableOnce[A], var tail: ConcatIteratorCell[A]) {
+ def headIterator: Iterator[A] = head.toIterator
+ }
+
+ /** Creates a delegating iterator capped by a limit count. Negative limit means unbounded.
+ * Lazily skip to start on first evaluation. Avoids daisy-chained iterators due to slicing.
+ */
+ private[scala] final class SliceIterator[A](val underlying: Iterator[A], start: Int, limit: Int) extends AbstractIterator[A] {
+ private var remaining = limit
+ private var dropping = start
+ @inline private def unbounded = remaining < 0
+ private def skip(): Unit =
+ while (dropping > 0) {
+ if (underlying.hasNext) {
+ underlying.next()
+ dropping -= 1
+ } else
+ dropping = 0
+ }
+ def hasNext = { skip(); remaining != 0 && underlying.hasNext }
+ def next() = {
+ skip()
+ if (remaining > 0) {
+ remaining -= 1
+ underlying.next()
+ }
+ else if (unbounded) underlying.next()
+ else empty.next()
}
- def next() = state match {
- case 0 =>
- if (lhs.hasNext) lhs.next()
- else {
- state = 2
- rhs.next()
- }
- case 1 =>
- state = 0
- lhs.next()
- case _ =>
- rhs.next()
+ override protected def sliceIterator(from: Int, until: Int): Iterator[A] = {
+ val lo = from max 0
+ def adjustedBound =
+ if (unbounded) -1
+ else 0 max (remaining - lo)
+ val rest =
+ if (until < 0) adjustedBound // respect current bound, if any
+ else if (until <= lo) 0 // empty
+ else if (unbounded) until - lo // now finite
+ else adjustedBound min (until - lo) // keep lesser bound
+ if (rest == 0) empty
+ else {
+ dropping += lo
+ remaining = rest
+ this
+ }
}
-
- override def ++[B >: A](that: => GenTraversableOnce[B]) =
- new ConcatIterator(this, Vector(() => that.toIterator))
}
}
@@ -346,11 +390,11 @@ trait Iterator[+A] extends TraversableOnce[A] {
/** Selects first ''n'' values of this iterator.
*
* @param n the number of values to take
- * @return an iterator producing only of the first `n` values of this iterator, or else the
+ * @return an iterator producing only the first `n` values of this iterator, or else the
* whole iterator, if it produces fewer than `n` values.
* @note Reuse: $consumesAndProducesIterator
*/
- def take(n: Int): Iterator[A] = slice(0, n)
+ def take(n: Int): Iterator[A] = sliceIterator(0, n max 0)
/** Advances this iterator past the first ''n'' elements, or the length of the iterator, whichever is smaller.
*
@@ -371,29 +415,24 @@ trait Iterator[+A] extends TraversableOnce[A] {
/** Creates an iterator returning an interval of the values produced by this iterator.
*
* @param from the index of the first element in this iterator which forms part of the slice.
- * @param until the index of the first element following the slice.
+ * If negative, the slice starts at zero.
+ * @param until the index of the first element following the slice. If negative, the slice is empty.
* @return an iterator which advances this iterator past the first `from` elements using `drop`,
* and then takes `until - from` elements, using `take`.
* @note Reuse: $consumesAndProducesIterator
*/
- def slice(from: Int, until: Int): Iterator[A] = {
+ def slice(from: Int, until: Int): Iterator[A] = sliceIterator(from, until max 0)
+
+ /** Creates an optionally bounded slice, unbounded if `until` is negative. */
+ protected def sliceIterator(from: Int, until: Int): Iterator[A] = {
val lo = from max 0
- var toDrop = lo
- while (toDrop > 0 && self.hasNext) {
- self.next()
- toDrop -= 1
- }
+ val rest =
+ if (until < 0) -1 // unbounded
+ else if (until <= lo) 0 // empty
+ else until - lo // finite
- new AbstractIterator[A] {
- private var remaining = until - lo
- def hasNext = remaining > 0 && self.hasNext
- def next(): A =
- if (remaining > 0) {
- remaining -= 1
- self.next()
- }
- else empty.next()
- }
+ if (rest == 0) empty
+ else new Iterator.SliceIterator(this, lo, rest)
}
/** Creates a new iterator that maps all produced values of this iterator
@@ -419,7 +458,7 @@ trait Iterator[+A] extends TraversableOnce[A] {
* @usecase def ++(that: => Iterator[A]): Iterator[A]
* @inheritdoc
*/
- def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new Iterator.JoinIterator(self, that)
+ def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new Iterator.ConcatIterator(self) ++ that
/** Creates a new iterator by applying a function to all values produced by this iterator
* and concatenating the results.
@@ -521,13 +560,13 @@ trait Iterator[+A] extends TraversableOnce[A] {
def collect[B](pf: PartialFunction[A, B]): Iterator[B] = new AbstractIterator[B] {
// Manually buffer to avoid extra layer of wrapping with buffered
private[this] var hd: A = _
-
+
// Little state machine to keep track of where we are
// Seek = 0; Found = 1; Empty = -1
// Not in vals because scalac won't make them static (@inline def only works with -optimize)
// BE REALLY CAREFUL TO KEEP COMMENTS AND NUMBERS IN SYNC!
private[this] var status = 0/*Seek*/
-
+
def hasNext = {
while (status == 0/*Seek*/) {
if (self.hasNext) {
@@ -700,9 +739,9 @@ trait Iterator[+A] extends TraversableOnce[A] {
}
}
}
-
+
val leading = new Leading
-
+
val trailing = new AbstractIterator[A] {
private[this] var myLeading = leading
/* Status flags meanings:
@@ -738,7 +777,7 @@ trait Iterator[+A] extends TraversableOnce[A] {
}
else Iterator.empty.next()
}
-
+
override def toString = "unknown-if-empty iterator"
}
@@ -772,7 +811,7 @@ trait Iterator[+A] extends TraversableOnce[A] {
status = 1
false
}
- def next() =
+ def next() =
if (hasNext) {
if (status == 1) self.next()
else {
@@ -955,8 +994,25 @@ trait Iterator[+A] extends TraversableOnce[A] {
* or -1 if such an element does not exist until the end of the iterator is reached.
* @note Reuse: $consumesIterator
*/
- def indexWhere(p: A => Boolean): Int = {
+ def indexWhere(p: A => Boolean): Int = indexWhere(p, 0)
+
+ /** Returns the index of the first produced value satisfying a predicate, or -1, after or at
+ * some start index.
+ * $mayNotTerminateInf
+ *
+ * @param p the predicate to test values
+ * @param from the start index
+ * @return the index `>= from` of the first produced value satisfying `p`,
+ * or -1 if such an element does not exist until the end of the iterator is reached.
+ * @note Reuse: $consumesIterator
+ */
+ def indexWhere(p: A => Boolean, from: Int): Int = {
var i = 0
+ while (i < from && hasNext) {
+ next()
+ i += 1
+ }
+
while (hasNext) {
if (p(next())) return i
i += 1
@@ -973,8 +1029,26 @@ trait Iterator[+A] extends TraversableOnce[A] {
* or -1 if such an element does not exist until the end of the iterator is reached.
* @note Reuse: $consumesIterator
*/
- def indexOf[B >: A](elem: B): Int = {
+ def indexOf[B >: A](elem: B): Int = indexOf(elem, 0)
+
+ /** Returns the index of the first occurrence of the specified object in this iterable object
+ * after or at some start index.
+ * $mayNotTerminateInf
+ *
+ * @param elem element to search for.
+ * @param from the start index
+ * @return the index `>= from` of the first occurrence of `elem` in the values produced by this
+ * iterator, or -1 if such an element does not exist until the end of the iterator is
+ * reached.
+ * @note Reuse: $consumesIterator
+ */
+ def indexOf[B >: A](elem: B, from: Int): Int = {
var i = 0
+ while (i < from && hasNext) {
+ next()
+ i += 1
+ }
+
while (hasNext) {
if (next() == elem) return i
i += 1
@@ -1289,7 +1363,6 @@ trait Iterator[+A] extends TraversableOnce[A] {
* $willNotTerminateInf
*/
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Unit = {
- require(start >= 0 && (start < xs.length || xs.length == 0), s"start $start out of range ${xs.length}")
var i = start
val end = start + math.min(len, xs.length - start)
while (i < end && hasNext) {
diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala
index 7bfa60771f..960e452cdf 100644
--- a/src/library/scala/collection/JavaConversions.scala
+++ b/src/library/scala/collection/JavaConversions.scala
@@ -1,6 +1,6 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2006-2016, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
@@ -11,21 +11,21 @@ package collection
import convert._
-/** A collection of implicit conversions supporting interoperability between
- * Scala and Java collections.
+/** A variety of implicit conversions supporting interoperability between
+ * Scala and Java collections.
*
- * The following conversions are supported:
+ * The following conversions are supported:
*{{{
- * scala.collection.Iterable <=> java.lang.Iterable
- * scala.collection.Iterable <=> java.util.Collection
- * scala.collection.Iterator <=> java.util.{ Iterator, Enumeration }
+ * scala.collection.Iterable <=> java.lang.Iterable
+ * scala.collection.Iterable <=> java.util.Collection
+ * scala.collection.Iterator <=> java.util.{ Iterator, Enumeration }
* scala.collection.mutable.Buffer <=> java.util.List
- * scala.collection.mutable.Set <=> java.util.Set
- * scala.collection.mutable.Map <=> java.util.{ Map, Dictionary }
+ * scala.collection.mutable.Set <=> java.util.Set
+ * scala.collection.mutable.Map <=> java.util.{ Map, Dictionary }
* scala.collection.concurrent.Map <=> java.util.concurrent.ConcurrentMap
*}}}
- * In all cases, converting from a source type to a target type and back
- * again will return the original source object, eg.
+ * In all cases, converting from a source type to a target type and back
+ * again will return the original source object:
*
*{{{
* import scala.collection.JavaConversions._
@@ -45,8 +45,16 @@ import convert._
* java.util.Properties => scala.collection.mutable.Map[String, String]
*}}}
*
+ * The transparent conversions provided here are considered
+ * fragile because they can result in unexpected behavior and performance.
+ *
+ * Therefore, this API has been deprecated and `JavaConverters` should be
+ * used instead. `JavaConverters` provides the same conversions, but through
+ * extension methods.
+ *
* @author Miles Sabin
* @author Martin Odersky
* @since 2.8
*/
+@deprecated("Use JavaConverters", since="2.12")
object JavaConversions extends WrapAsScala with WrapAsJava
diff --git a/src/library/scala/collection/JavaConverters.scala b/src/library/scala/collection/JavaConverters.scala
index 86e86d4584..d48a1764e9 100644
--- a/src/library/scala/collection/JavaConverters.scala
+++ b/src/library/scala/collection/JavaConverters.scala
@@ -1,6 +1,6 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2006-2016, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
@@ -11,50 +11,62 @@ package collection
import convert._
-// TODO: I cleaned all this documentation up in JavaConversions, but the
-// documentation in here is basically the pre-cleaned-up version with minor
-// additions. Would be nice to have in one place.
-
-/** A collection of decorators that allow converting between
- * Scala and Java collections using `asScala` and `asJava` methods.
- *
- * The following conversions are supported via `asJava`, `asScala`
+/** A variety of decorators that enable converting between
+ * Scala and Java collections using extension methods, `asScala` and `asJava`.
*
- * - `scala.collection.Iterable` <=> `java.lang.Iterable`
- * - `scala.collection.Iterator` <=> `java.util.Iterator`
- * - `scala.collection.mutable.Buffer` <=> `java.util.List`
- * - `scala.collection.mutable.Set` <=> `java.util.Set`
- * - `scala.collection.mutable.Map` <=> `java.util.Map`
- * - `scala.collection.mutable.concurrent.Map` <=> `java.util.concurrent.ConcurrentMap`
+ * The extension methods return adapters for the corresponding API.
*
+ * The following conversions are supported via `asScala` and `asJava`:
+ *{{{
+ * scala.collection.Iterable <=> java.lang.Iterable
+ * scala.collection.Iterator <=> java.util.Iterator
+ * scala.collection.mutable.Buffer <=> java.util.List
+ * scala.collection.mutable.Set <=> java.util.Set
+ * scala.collection.mutable.Map <=> java.util.Map
+ * scala.collection.mutable.concurrent.Map <=> java.util.concurrent.ConcurrentMap
+ *}}}
+ * The following conversions are supported via `asScala` and through
+ * specially-named extension methods to convert to Java collections, as shown:
+ *{{{
+ * scala.collection.Iterable <=> java.util.Collection (via asJavaCollection)
+ * scala.collection.Iterator <=> java.util.Enumeration (via asJavaEnumeration)
+ * scala.collection.mutable.Map <=> java.util.Dictionary (via asJavaDictionary)
+ *}}}
+ * In addition, the following one-way conversions are provided via `asJava`:
+ *{{{
+ * scala.collection.Seq => java.util.List
+ * scala.collection.mutable.Seq => java.util.List
+ * scala.collection.Set => java.util.Set
+ * scala.collection.Map => java.util.Map
+ *}}}
+ * The following one way conversion is provided via `asScala`:
+ *{{{
+ * java.util.Properties => scala.collection.mutable.Map
+ *}}}
* In all cases, converting from a source type to a target type and back
- * again will return the original source object, e.g.
+ * again will return the original source object. For example:
* {{{
* import scala.collection.JavaConverters._
*
- * val sl = new scala.collection.mutable.ListBuffer[Int]
- * val jl : java.util.List[Int] = sl.asJava
- * val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
- * assert(sl eq sl2)
+ * val source = new scala.collection.mutable.ListBuffer[Int]
+ * val target: java.util.List[Int] = source.asJava
+ * val other: scala.collection.mutable.Buffer[Int] = target.asScala
+ * assert(source eq other)
* }}}
- * The following conversions are also supported, but the
- * direction from Scala to Java is done by the more specifically named methods:
- * `asJavaCollection`, `asJavaEnumeration`, `asJavaDictionary`.
- *
- * - `scala.collection.Iterable` <=> `java.util.Collection`
- * - `scala.collection.Iterator` <=> `java.util.Enumeration`
- * - `scala.collection.mutable.Map` <=> `java.util.Dictionary`
- *
- * In addition, the following one way conversions are provided via `asJava`:
+ * Alternatively, the conversion methods have descriptive names and can be invoked explicitly.
+ * {{{
+ * scala> val vs = java.util.Arrays.asList("hi", "bye")
+ * vs: java.util.List[String] = [hi, bye]
*
- * - `scala.collection.Seq` => `java.util.List`
- * - `scala.collection.mutable.Seq` => `java.util.List`
- * - `scala.collection.Set` => `java.util.Set`
- * - `scala.collection.Map` => `java.util.Map`
+ * scala> val ss = asScalaIterator(vs.iterator)
+ * ss: Iterator[String] = non-empty iterator
*
- * The following one way conversion is provided via `asScala`:
+ * scala> .toList
+ * res0: List[String] = List(hi, bye)
*
- * - `java.util.Properties` => `scala.collection.mutable.Map`
+ * scala> val ss = asScalaBuffer(vs)
+ * ss: scala.collection.mutable.Buffer[String] = Buffer(hi, bye)
+ * }}}
*
* @since 2.8.1
*/
diff --git a/src/library/scala/collection/LinearSeqOptimized.scala b/src/library/scala/collection/LinearSeqOptimized.scala
index b7af8840a9..a3860f10a4 100644
--- a/src/library/scala/collection/LinearSeqOptimized.scala
+++ b/src/library/scala/collection/LinearSeqOptimized.scala
@@ -9,8 +9,6 @@
package scala
package collection
-import mutable.ListBuffer
-import immutable.List
import scala.annotation.tailrec
/** A template trait for linear sequences of type `LinearSeq[A]` which optimizes
@@ -133,9 +131,9 @@ trait LinearSeqOptimized[+A, +Repr <: LinearSeqOptimized[A, Repr]] extends Linea
else op(head, tail.foldRight(z)(op))
override /*TraversableLike*/
- def reduceLeft[B >: A](f: (B, A) => B): B =
+ def reduceLeft[B >: A](@deprecatedName('f) op: (B, A) => B): B =
if (isEmpty) throw new UnsupportedOperationException("empty.reduceLeft")
- else tail.foldLeft[B](head)(f)
+ else tail.foldLeft[B](head)(op)
override /*IterableLike*/
def reduceRight[B >: A](op: (A, B) => B): B =
diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala
index 99ed67325c..4ac87b29a9 100644
--- a/src/library/scala/collection/MapLike.scala
+++ b/src/library/scala/collection/MapLike.scala
@@ -11,7 +11,7 @@ package collection
import generic._
import mutable.{ Builder, MapBuilder }
-import scala.annotation.{migration, bridge}
+import scala.annotation.migration
import parallel.ParMap
/** A template trait for maps, which associate keys with values.
@@ -230,11 +230,15 @@ self =>
protected class FilteredKeys(p: A => Boolean) extends AbstractMap[A, B] with DefaultMap[A, B] {
override def foreach[U](f: ((A, B)) => U): Unit = for (kv <- self) if (p(kv._1)) f(kv)
def iterator = self.iterator.filter(kv => p(kv._1))
- override def contains(key: A) = self.contains(key) && p(key)
+ override def contains(key: A) = p(key) && self.contains(key)
def get(key: A) = if (!p(key)) None else self.get(key)
}
/** Filters this map by retaining only keys satisfying a predicate.
+ *
+ * '''Note''': the predicate must accept any key of type `A`, not just those already
+ * present in the map, as the predicate is tested before the underlying map is queried.
+ *
* @param p the predicate used to test keys
* @return an immutable map consisting only of those key value pairs of this map where the key satisfies
* the predicate `p`. The resulting map wraps the original map without copying any elements.
@@ -319,11 +323,20 @@ self =>
res
}
- /* Overridden for efficiency. */
- override def toSeq: Seq[(A, B)] = toBuffer[(A, B)]
+ override def toSeq: Seq[(A, B)] = {
+ if (isEmpty) Vector.empty[(A, B)]
+ else {
+ // Default appropriate for immutable collections; mutable collections override this
+ val vb = Vector.newBuilder[(A, B)]
+ foreach(vb += _)
+ vb.result
+ }
+ }
+
override def toBuffer[C >: (A, B)]: mutable.Buffer[C] = {
val result = new mutable.ArrayBuffer[C](size)
- copyToBuffer(result)
+ // Faster to let the map iterate itself than to defer through copyToBuffer
+ foreach(result += _)
result
}
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index b775480532..a26765027c 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -9,11 +9,10 @@
package scala
package collection
-import mutable.{ ListBuffer, ArraySeq }
import immutable.{ List, Range }
import generic._
import parallel.ParSeq
-import scala.math.{ min, max, Ordering }
+import scala.math.Ordering
/** A template trait for sequences of type `Seq[A]`
* $seqInfo
@@ -146,7 +145,7 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[
* more than one way to generate the same subsequence, only one will be returned.
*
* For example, `"xyyy"` has three different ways to generate `"xy"` depending on
- * whether the first, second, or third `"y"` is selected. However, since all are
+ * whether the first, second, or third `"y"` is selected. However, since all are
* identical, only one will be chosen. Which of the three will be taken is an
* implementation detail that is not defined.
*
diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala
index 3473c8aff1..1fbcb6531e 100644
--- a/src/library/scala/collection/SeqViewLike.scala
+++ b/src/library/scala/collection/SeqViewLike.scala
@@ -96,6 +96,14 @@ trait SeqViewLike[+A,
if (idx < self.length) self(idx) else restSeq(idx - self.length)
}
+ trait Prepended[B >: A] extends super.Prepended[B] with Transformed[B] {
+ protected[this] lazy val fstSeq = fst.toSeq
+ def length: Int = fstSeq.length + self.length
+ def apply(idx: Int): B =
+ if (idx < fstSeq.length) fstSeq(idx)
+ else self.apply(idx - fstSeq.length)
+ }
+
trait Filtered extends super.Filtered with Transformed[A] {
protected[this] lazy val index = {
var len = 0
@@ -179,21 +187,12 @@ trait SeqViewLike[+A,
final override protected[this] def viewIdentifier = "P"
}
- trait Prepended[B >: A] extends Transformed[B] {
- protected[this] val fst: B
- override def iterator: Iterator[B] = Iterator.single(fst) ++ self.iterator
- def length: Int = 1 + self.length
- def apply(idx: Int): B =
- if (idx == 0) fst
- else self.apply(idx - 1)
- final override protected[this] def viewIdentifier = "A"
- }
-
/** Boilerplate method, to override in each subclass
* This method could be eliminated if Scala had virtual classes
*/
protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected override def newPrepended[B >: A](that: GenTraversable[B]): Transformed[B] = new { protected[this] val fst = that } with AbstractTransformed[B] with Prepended[B]
protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
@@ -212,7 +211,6 @@ trait SeqViewLike[+A,
val patch = _patch
val replaced = _replaced
} with AbstractTransformed[B] with Patched[B]
- protected def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with AbstractTransformed[B] with Prepended[B]
// see comment in IterableViewLike.
protected override def newTaken(n: Int): Transformed[A] = newSliced(SliceInterval(0, n))
@@ -242,7 +240,7 @@ trait SeqViewLike[+A,
}
override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[This, B, That]): That =
- newPrepended(elem).asInstanceOf[That]
+ newPrepended(elem :: Nil).asInstanceOf[That]
override def :+[B >: A, That](elem: B)(implicit bf: CanBuildFrom[This, B, That]): That =
++(Iterator.single(elem))(bf)
diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala
index f8ac1d754d..9143c40870 100644
--- a/src/library/scala/collection/SetLike.scala
+++ b/src/library/scala/collection/SetLike.scala
@@ -11,7 +11,7 @@ package collection
import generic._
import mutable.{ Builder, SetBuilder }
-import scala.annotation.{migration, bridge}
+import scala.annotation.migration
import parallel.ParSet
/** A template trait for sets.
@@ -77,11 +77,20 @@ self =>
protected[this] override def parCombiner = ParSet.newCombiner[A]
- /* Overridden for efficiency. */
- override def toSeq: Seq[A] = toBuffer[A]
+ // Default collection type appropriate for immutable collections; mutable collections override this
+ override def toSeq: Seq[A] = {
+ if (isEmpty) Vector.empty[A]
+ else {
+ val vb = Vector.newBuilder[A]
+ foreach(vb += _)
+ vb.result
+ }
+ }
+
override def toBuffer[A1 >: A]: mutable.Buffer[A1] = {
val result = new mutable.ArrayBuffer[A1](size)
- copyToBuffer(result)
+ // Faster to let the map iterate itself than to defer through copyToBuffer
+ foreach(result += _)
result
}
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index bbbc33b3f5..d914f2e0ff 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -11,7 +11,7 @@ package collection
import generic._
import mutable.{ Builder }
-import scala.annotation.{tailrec, migration, bridge}
+import scala.annotation.migration
import scala.annotation.unchecked.{ uncheckedVariance => uV }
import parallel.ParIterable
import scala.language.higherKinds
@@ -242,7 +242,7 @@ trait TraversableLike[+A, +Repr] extends Any
b.result
}
- private def filterImpl(p: A => Boolean, isFlipped: Boolean): Repr = {
+ private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Repr = {
val b = newBuilder
for (x <- this)
if (p(x) != isFlipped) b += x
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index 75c0d82922..b87fcd166e 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -9,7 +9,7 @@
package scala
package collection
-import mutable.{ Buffer, Builder, ListBuffer, ArrayBuffer }
+import mutable.{ Buffer, Builder, ArrayBuffer }
import generic.CanBuildFrom
import scala.annotation.unchecked.{ uncheckedVariance => uV }
import scala.language.{implicitConversions, higherKinds}
diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala
index 5926c69ebf..0901d749c3 100644
--- a/src/library/scala/collection/TraversableViewLike.scala
+++ b/src/library/scala/collection/TraversableViewLike.scala
@@ -189,6 +189,15 @@ trait TraversableViewLike[+A,
}
final override protected[this] def viewIdentifier = "A"
}
+
+ trait Prepended[B >: A] extends Transformed[B] {
+ protected[this] val fst: GenTraversable[B]
+ def foreach[U](f: B => U) {
+ fst foreach f
+ self foreach f
+ }
+ final override protected[this] def viewIdentifier = "A"
+ }
trait Filtered extends Transformed[A] {
protected[this] val pred: A => Boolean
@@ -222,11 +231,15 @@ trait TraversableViewLike[+A,
final override protected[this] def viewIdentifier = "D"
}
- override def ++[B >: A, That](xs: GenTraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That = {
+ override def ++[B >: A, That](xs: GenTraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That =
newAppended(xs.seq.toTraversable).asInstanceOf[That]
-// was: if (bf.isInstanceOf[ByPassCanBuildFrom]) newAppended(that).asInstanceOf[That]
-// else super.++[B, That](that)(bf)
- }
+
+ override def ++:[B >: A, That](xs: TraversableOnce[B])(implicit bf: CanBuildFrom[This, B, That]): That =
+ newPrepended(xs.seq.toTraversable).asInstanceOf[That]
+
+ // Need second one because of optimization in TraversableLike
+ override def ++:[B >: A, That](xs: Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That =
+ newPrepended(xs).asInstanceOf[That]
override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[This, B, That]): That = {
newMapped(f).asInstanceOf[That]
@@ -253,6 +266,7 @@ trait TraversableViewLike[+A,
*/
protected def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected def newPrepended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val fst = that } with AbstractTransformed[B] with Prepended[B]
protected def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
diff --git a/src/library/scala/collection/concurrent/Map.scala b/src/library/scala/collection/concurrent/Map.scala
index cfb567abe9..f27dfd57fc 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/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala
index bcfea7a463..5dc01547e6 100644
--- a/src/library/scala/collection/concurrent/TrieMap.scala
+++ b/src/library/scala/collection/concurrent/TrieMap.scala
@@ -11,13 +11,11 @@ package collection
package concurrent
import java.util.concurrent.atomic._
-import scala.collection.immutable.{ ListMap => ImmutableListMap }
import scala.collection.parallel.mutable.ParTrieMap
import scala.util.hashing.Hashing
import scala.util.control.ControlThrowable
import generic._
import scala.annotation.tailrec
-import scala.annotation.switch
private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends INodeBase[K, V](g) {
import INodeBase._
@@ -471,7 +469,7 @@ private[collection] final class CNode[K, V](val bitmap: Int, val array: Array[Ba
val offset =
if (array.length > 0)
//util.Random.nextInt(array.length) /* <-- benchmarks show that this causes observable contention */
- scala.concurrent.forkjoin.ThreadLocalRandom.current.nextInt(0, array.length)
+ java.util.concurrent.ThreadLocalRandom.current.nextInt(0, array.length)
else 0
while (i < array.length) {
val pos = (i + offset) % array.length
@@ -641,7 +639,8 @@ extends scala.collection.concurrent.Map[K, V]
private var rootupdater = rtupd
def hashing = hashingobj
def equality = equalityobj
- @volatile var root = r
+ @deprecated("This field will be made private", "2.12.0")
+ @volatile /*private*/ var root = r
def this(hashf: Hashing[K], ef: Equiv[K]) = this(
INode.newRootNode,
@@ -685,11 +684,14 @@ extends scala.collection.concurrent.Map[K, V]
} while (obj != TrieMapSerializationEnd)
}
- def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv)
+ @deprecated("This method will be made private", "2.12.0")
+ /*private*/ def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv)
- def readRoot(abort: Boolean = false): INode[K, V] = RDCSS_READ_ROOT(abort)
+ @deprecated("This method will be made private", "2.12.0")
+ /*private[collection]*/ def readRoot(abort: Boolean = false): INode[K, V] = RDCSS_READ_ROOT(abort)
- def RDCSS_READ_ROOT(abort: Boolean = false): INode[K, V] = {
+ @deprecated("This method will be made private", "2.12.0")
+ /*private[concurrent]*/ def RDCSS_READ_ROOT(abort: Boolean = false): INode[K, V] = {
val r = /*READ*/root
r match {
case in: INode[K, V] => in
@@ -884,7 +886,7 @@ extends scala.collection.concurrent.Map[K, V]
*
* If the specified mapping function throws an exception,
* that exception is rethrown.
- *
+ *
* Note: This method will invoke op at most once.
* However, `op` may be invoked without the result being added to the map if
* a concurrent process is also trying to add a value corresponding to the
@@ -1083,6 +1085,7 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct:
Seq(this)
}
+ @deprecated("This method will be removed", "2.12.0")
def printDebug() {
println("ctrie iterator")
println(stackpos.mkString(","))
@@ -1103,14 +1106,14 @@ private[concurrent] case object TrieMapSerializationEnd
private[concurrent] object Debug {
- import scala.collection._
+ import JavaConverters._
lazy val logbuffer = new java.util.concurrent.ConcurrentLinkedQueue[AnyRef]
def log(s: AnyRef) = logbuffer.add(s)
def flush() {
- for (s <- JavaConversions.asScalaIterator(logbuffer.iterator())) Console.out.println(s.toString)
+ for (s <- logbuffer.iterator().asScala) Console.out.println(s.toString)
logbuffer.clear()
}
diff --git a/src/library/scala/collection/convert/AsJavaConverters.scala b/src/library/scala/collection/convert/AsJavaConverters.scala
new file mode 100644
index 0000000000..c7c1fb9c74
--- /dev/null
+++ b/src/library/scala/collection/convert/AsJavaConverters.scala
@@ -0,0 +1,262 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2016, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+package collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+
+/** Defines converter methods from Scala to Java collections. */
+trait AsJavaConverters {
+ import Wrappers._
+
+ /**
+ * Converts a Scala `Iterator` to a Java `Iterator`.
+ *
+ * The returned Java `Iterator` is backed by the provided Scala `Iterator` and any side-effects of
+ * using it via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Iterator` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asScalaIterator]](java.util.Iterator)` then the original Java `Iterator` will
+ * be returned.
+ *
+ * @param i The Scala `Iterator` to be converted.
+ * @return A Java `Iterator` view of the argument.
+ */
+ def asJavaIterator[A](i: Iterator[A]): ju.Iterator[A] = i match {
+ case null => null
+ case JIteratorWrapper(wrapped) => wrapped.asInstanceOf[ju.Iterator[A]]
+ case _ => IteratorWrapper(i)
+ }
+
+ /**
+ * Converts a Scala `Iterator` to a Java `Enumeration`.
+ *
+ * The returned Java `Enumeration` is backed by the provided Scala `Iterator` and any side-effects
+ * of using it via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Iterator` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.enumerationAsScalaIterator]](java.util.Enumeration)` then the original Java
+ * `Enumeration` will be returned.
+ *
+ * @param i The Scala `Iterator` to be converted.
+ * @return A Java `Enumeration` view of the argument.
+ */
+ def asJavaEnumeration[A](i: Iterator[A]): ju.Enumeration[A] = i match {
+ case null => null
+ case JEnumerationWrapper(wrapped) => wrapped.asInstanceOf[ju.Enumeration[A]]
+ case _ => IteratorWrapper(i)
+ }
+
+ /**
+ * Converts a Scala `Iterable` to a Java `Iterable`.
+ *
+ * The returned Java `Iterable` is backed by the provided Scala `Iterable` and any side-effects of
+ * using it via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Iterable` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.iterableAsScalaIterable]](java.lang.Iterable)` then the original Java
+ * `Iterable` will be returned.
+ *
+ * @param i The Scala `Iterable` to be converted.
+ * @return A Java `Iterable` view of the argument.
+ */
+ def asJavaIterable[A](i: Iterable[A]): jl.Iterable[A] = i match {
+ case null => null
+ case JIterableWrapper(wrapped) => wrapped.asInstanceOf[jl.Iterable[A]]
+ case _ => IterableWrapper(i)
+ }
+
+ /**
+ * Converts a Scala `Iterable` to an immutable Java `Collection`.
+ *
+ * If the Scala `Iterable` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.collectionAsScalaIterable]](java.util.Collection)` then the original Java
+ * `Collection` will be returned.
+ *
+ * @param i The Scala `Iterable` to be converted.
+ * @return A Java `Collection` view of the argument.
+ */
+ def asJavaCollection[A](i: Iterable[A]): ju.Collection[A] = i match {
+ case null => null
+ case JCollectionWrapper(wrapped) => wrapped.asInstanceOf[ju.Collection[A]]
+ case _ => new IterableWrapper(i)
+ }
+
+ /**
+ * Converts a Scala mutable `Buffer` to a Java List.
+ *
+ * The returned Java List is backed by the provided Scala `Buffer` and any side-effects of using
+ * it via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Buffer` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asScalaBuffer]](java.util.List)` then the original Java `List` will be
+ * returned.
+ *
+ * @param b The Scala `Buffer` to be converted.
+ * @return A Java `List` view of the argument.
+ */
+ def bufferAsJavaList[A](b: mutable.Buffer[A]): ju.List[A] = b match {
+ case null => null
+ case JListWrapper(wrapped) => wrapped
+ case _ => new MutableBufferWrapper(b)
+ }
+
+ /**
+ * Converts a Scala mutable `Seq` to a Java `List`.
+ *
+ * The returned Java `List` is backed by the provided Scala `Seq` and any side-effects of using it
+ * via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Seq` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asScalaBuffer]](java.util.List)` then the original Java `List` will be
+ * returned.
+ *
+ * @param s The Scala `Seq` to be converted.
+ * @return A Java `List` view of the argument.
+ */
+ def mutableSeqAsJavaList[A](s: mutable.Seq[A]): ju.List[A] = s match {
+ case null => null
+ case JListWrapper(wrapped) => wrapped
+ case _ => new MutableSeqWrapper(s)
+ }
+
+ /**
+ * Converts a Scala `Seq` to a Java `List`.
+ *
+ * The returned Java `List` is backed by the provided Scala `Seq` and any side-effects of using it
+ * via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Seq` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asScalaBuffer]](java.util.List)` then the original Java `List` will be
+ * returned.
+ *
+ * @param s The Scala `Seq` to be converted.
+ * @return A Java `List` view of the argument.
+ */
+ def seqAsJavaList[A](s: Seq[A]): ju.List[A] = s match {
+ case null => null
+ case JListWrapper(wrapped) => wrapped.asInstanceOf[ju.List[A]]
+ case _ => new SeqWrapper(s)
+ }
+
+ /**
+ * Converts a Scala mutable `Set` to a Java `Set`.
+ *
+ * The returned Java `Set` is backed by the provided Scala `Set` and any side-effects of using it
+ * via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Set` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asScalaSet]](java.util.Set)` then the original Java `Set` will be returned.
+ *
+ * @param s The Scala mutable `Set` to be converted.
+ * @return A Java `Set` view of the argument.
+ */
+ def mutableSetAsJavaSet[A](s: mutable.Set[A]): ju.Set[A] = s match {
+ case null => null
+ case JSetWrapper(wrapped) => wrapped
+ case _ => new MutableSetWrapper(s)
+ }
+
+ /**
+ * Converts a Scala `Set` to a Java `Set`.
+ *
+ * The returned Java `Set` is backed by the provided Scala `Set` and any side-effects of using it
+ * via the Java interface will be visible via the Scala interface and vice versa.
+ *
+ * If the Scala `Set` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asScalaSet]](java.util.Set)` then the original Java `Set` will be returned.
+ *
+ * @param s The Scala `Set` to be converted.
+ * @return A Java `Set` view of the argument.
+ */
+ def setAsJavaSet[A](s: Set[A]): ju.Set[A] = s match {
+ case null => null
+ case JSetWrapper(wrapped) => wrapped
+ case _ => new SetWrapper(s)
+ }
+
+ /**
+ * Converts a Scala mutable `Map` to a Java `Map`.
+ *
+ * The returned Java `Map` is backed by the provided Scala `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 `Map` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.mapAsScalaMap]](java.util.Map)` then the original Java `Map` will be
+ * returned.
+ *
+ * @param m The Scala mutable `Map` to be converted.
+ * @return A Java `Map` view of the argument.
+ */
+ def mutableMapAsJavaMap[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = m match {
+ case null => null
+ case JMapWrapper(wrapped) => wrapped
+ case _ => new MutableMapWrapper(m)
+ }
+
+ /**
+ * Converts a Scala mutable `Map` to a Java `Dictionary`.
+ *
+ * The returned Java `Dictionary` is backed by the provided Scala `Dictionary` and any
+ * side-effects of using it via the Java interface will be visible via the Scala interface and
+ * vice versa.
+ *
+ * If the Scala `Dictionary` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.dictionaryAsScalaMap]](java.util.Dictionary)` then the original Java
+ * `Dictionary` will be returned.
+ *
+ * @param m The Scala `Map` to be converted.
+ * @return A Java `Dictionary` view of the argument.
+ */
+ def asJavaDictionary[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = m match {
+ case null => null
+ case JDictionaryWrapper(wrapped) => wrapped
+ case _ => new DictionaryWrapper(m)
+ }
+
+ /**
+ * Converts a Scala `Map` to a Java `Map`.
+ *
+ * The returned Java `Map` is backed by the provided Scala `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 `Map` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.mapAsScalaMap]](java.util.Map)` then the original Java `Map` will be
+ * returned.
+ *
+ * @param m The Scala `Map` to be converted.
+ * @return A Java `Map` view of the argument.
+ */
+ def mapAsJavaMap[A, B](m: Map[A, B]): ju.Map[A, B] = m match {
+ case null => null
+ case JMapWrapper(wrapped) => wrapped.asInstanceOf[ju.Map[A, B]]
+ case _ => new MapWrapper(m)
+ }
+
+ /**
+ * 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
+ * `[[JavaConverters.mapAsScalaConcurrentMap]](java.util.concurrent.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.
+ */
+ 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)
+ }
+}
diff --git a/src/library/scala/collection/convert/AsScalaConverters.scala b/src/library/scala/collection/convert/AsScalaConverters.scala
new file mode 100644
index 0000000000..f9e38797e1
--- /dev/null
+++ b/src/library/scala/collection/convert/AsScalaConverters.scala
@@ -0,0 +1,207 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2016, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+package collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+
+/** Defines converter methods from Java to Scala collections. */
+trait AsScalaConverters {
+ import Wrappers._
+
+ /**
+ * Converts a Java `Iterator` to a Scala `Iterator`.
+ *
+ * The returned Scala `Iterator` is backed by the provided Java `Iterator` and any side-effects of
+ * using it via the Scala interface will be visible via the Java interface and vice versa.
+ *
+ * If the Java `Iterator` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asJavaIterator]](scala.collection.Iterator)` then the original Scala
+ * `Iterator` will be returned.
+ *
+ * @param i The Java `Iterator` to be converted.
+ * @return A Scala `Iterator` view of the argument.
+ */
+ def asScalaIterator[A](i: ju.Iterator[A]): Iterator[A] = i match {
+ case null => null
+ case IteratorWrapper(wrapped) => wrapped
+ case _ => JIteratorWrapper(i)
+ }
+
+ /**
+ * Converts a Java `Enumeration` to a Scala `Iterator`.
+ *
+ * The returned Scala `Iterator` is backed by the provided Java `Enumeration` and any side-effects
+ * of using it via the Scala interface will be visible via the Java interface and vice versa.
+ *
+ * If the Java `Enumeration` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asJavaEnumeration]](scala.collection.Iterator)` then the original Scala
+ * `Iterator` will be returned.
+ *
+ * @param i The Java `Enumeration` to be converted.
+ * @return A Scala `Iterator` view of the argument.
+ */
+ def enumerationAsScalaIterator[A](i: ju.Enumeration[A]): Iterator[A] = i match {
+ case null => null
+ case IteratorWrapper(wrapped) => wrapped
+ case _ => JEnumerationWrapper(i)
+ }
+
+ /**
+ * Converts a Java `Iterable` to a Scala `Iterable`.
+ *
+ * The returned Scala `Iterable` is backed by the provided Java `Iterable` and any side-effects of
+ * using it via the Scala interface will be visible via the Java interface and vice versa.
+ *
+ * If the Java `Iterable` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asJavaIterable]](scala.collection.Iterable) then the original Scala
+ * `Iterable` will be returned.
+ *
+ * @param i The Java `Iterable` to be converted.
+ * @return A Scala `Iterable` view of the argument.
+ */
+ def iterableAsScalaIterable[A](i: jl.Iterable[A]): Iterable[A] = i match {
+ case null => null
+ case IterableWrapper(wrapped) => wrapped
+ case _ => JIterableWrapper(i)
+ }
+
+ /**
+ * Converts a Java `Collection` to an Scala `Iterable`.
+ *
+ * If the Java `Collection` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asJavaCollection]](scala.collection.Iterable)` then the original Scala
+ * `Iterable` will be returned.
+ *
+ * @param i The Java `Collection` to be converted.
+ * @return A Scala `Iterable` view of the argument.
+ */
+ def collectionAsScalaIterable[A](i: ju.Collection[A]): Iterable[A] = i match {
+ case null => null
+ case IterableWrapper(wrapped) => wrapped
+ case _ => JCollectionWrapper(i)
+ }
+
+ /**
+ * Converts a Java `List` to a Scala mutable `Buffer`.
+ *
+ * The returned Scala `Buffer` is backed by the provided Java `List` and any side-effects of using
+ * it via the Scala interface will be visible via the Java interface and vice versa.
+ *
+ * If the Java `List` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.bufferAsJavaList]](scala.collection.mutable.Buffer)` then the original Scala
+ * `Buffer` will be returned.
+ *
+ * @param l The Java `List` to be converted.
+ * @return A Scala mutable `Buffer` view of the argument.
+ */
+ def asScalaBuffer[A](l: ju.List[A]): mutable.Buffer[A] = l match {
+ case null => null
+ case MutableBufferWrapper(wrapped) => wrapped
+ case _ => new JListWrapper(l)
+ }
+
+ /**
+ * Converts a Java `Set` to a Scala mutable `Set`.
+ *
+ * The returned Scala `Set` is backed by the provided Java `Set` and any side-effects of using it
+ * via the Scala interface will be visible via the Java interface and vice versa.
+ *
+ * If the Java `Set` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.mutableSetAsJavaSet]](scala.collection.mutable.Set)` then the original Scala
+ * `Set` will be returned.
+ *
+ * @param s The Java `Set` to be converted.
+ * @return A Scala mutable `Set` view of the argument.
+ */
+ def asScalaSet[A](s: ju.Set[A]): mutable.Set[A] = s match {
+ case null => null
+ case MutableSetWrapper(wrapped) => wrapped
+ case _ => new JSetWrapper(s)
+ }
+
+ /**
+ * Converts a Java `Map` to a Scala mutable `Map`.
+ *
+ * The returned Scala `Map` is backed by the provided Java `Map` and any side-effects of using it
+ * via the Scala interface will be visible via the Java interface and vice versa.
+ *
+ * If the Java `Map` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.mutableMapAsJavaMap]](scala.collection.mutable.Map)` then the original Scala
+ * `Map` will be returned.
+ *
+ * If the wrapped map is synchronized (e.g. from `java.util.Collections.synchronizedMap`), it is
+ * your responsibility to wrap all non-atomic operations with `underlying.synchronized`.
+ * This includes `get`, as `java.util.Map`'s API does not allow for an atomic `get` when `null`
+ * values may be present.
+ *
+ * @param m The Java `Map` to be converted.
+ * @return A Scala mutable `Map` view of the argument.
+ */
+ def mapAsScalaMap[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = m match {
+ case null => null
+ case MutableMapWrapper(wrapped) => wrapped
+ case _ => new JMapWrapper(m)
+ }
+
+ /**
+ * 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
+ * `[[JavaConverters.mapAsJavaConcurrentMap]](scala.collection.mutable.ConcurrentMap)`
+ * then the original Scala `ConcurrentMap` will be returned.
+ *
+ * @param m The Java `ConcurrentMap` to be converted.
+ * @return A Scala mutable `ConcurrentMap` view of the argument.
+ */
+ def mapAsScalaConcurrentMap[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = m match {
+ case null => null
+ case cmw: ConcurrentMapWrapper[_, _] => cmw.underlying
+ case _ => new JConcurrentMapWrapper(m)
+ }
+
+ /**
+ * Converts a Java `Dictionary` to a Scala mutable `Map`.
+ *
+ * The returned Scala `Map` is backed by the provided Java `Dictionary` and any side-effects of
+ * using it via the Scala interface will be visible via the Java interface and vice versa.
+ *
+ * If the Java `Dictionary` was previously obtained from an implicit or explicit call of
+ * `[[JavaConverters.asJavaDictionary]](scala.collection.mutable.Map)` then the original
+ * Scala `Map` will be returned.
+ *
+ * @param p The Java `Dictionary` to be converted.
+ * @return A Scala mutable `Map` view of the argument.
+ */
+ 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)
+ }
+
+ /**
+ * Converts a Java `Properties` to a Scala mutable `Map[String, String]`.
+ *
+ * The returned Scala `Map[String, String]` is backed by the provided Java `Properties` and any
+ * side-effects of using it via the Scala interface will be visible via the Java interface and
+ * vice versa.
+ *
+ * @param p The Java `Properties` to be converted.
+ * @return A Scala mutable `Map[String, String]` view of the argument.
+ */
+ def propertiesAsScalaMap(p: ju.Properties): mutable.Map[String, String] = p match {
+ case null => null
+ case _ => new JPropertiesWrapper(p)
+ }
+}
diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala
index e6aa5da067..8371804b91 100644
--- a/src/library/scala/collection/convert/DecorateAsJava.scala
+++ b/src/library/scala/collection/convert/DecorateAsJava.scala
@@ -1,6 +1,6 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2006-2016, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
@@ -12,289 +12,97 @@ package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import Decorators._
-import WrapAsJava._
import scala.language.implicitConversions
-
-/** A collection of decorators that allow converting between
- * Scala and Java collections using `asScala` and `asJava` methods.
- *
- * The following conversions are supported via `asJava`, `asScala`
- *
- * - `scala.collection.Iterable` <=> `java.lang.Iterable`
- * - `scala.collection.Iterator` <=> `java.util.Iterator`
- * - `scala.collection.mutable.Buffer` <=> `java.util.List`
- * - `scala.collection.mutable.Set` <=> `java.util.Set`
- * - `scala.collection.mutable.Map` <=> `java.util.Map`
- * - `scala.collection.mutable.concurrent.Map` <=> `java.util.concurrent.ConcurrentMap`
- *
- * In all cases, converting from a source type to a target type and back
- * again will return the original source object, e.g.
- * {{{
- * import scala.collection.JavaConverters._
- *
- * val sl = new scala.collection.mutable.ListBuffer[Int]
- * val jl : java.util.List[Int] = sl.asJava
- * val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
- * assert(sl eq sl2)
- * }}}
- * The following conversions are also supported, but the
- * direction from Scala to Java is done by the more specifically named methods:
- * `asJavaCollection`, `asJavaEnumeration`, `asJavaDictionary`.
- *
- * - `scala.collection.Iterable` <=> `java.util.Collection`
- * - `scala.collection.Iterator` <=> `java.util.Enumeration`
- * - `scala.collection.mutable.Map` <=> `java.util.Dictionary`
- *
- * In addition, the following one way conversions are provided via `asJava`:
- *
- * - `scala.collection.Seq` => `java.util.List`
- * - `scala.collection.mutable.Seq` => `java.util.List`
- * - `scala.collection.Set` => `java.util.Set`
- * - `scala.collection.Map` => `java.util.Map`
- *
- * The following one way conversion is provided via `asScala`:
- *
- * - `java.util.Properties` => `scala.collection.mutable.Map`
- *
- * @since 2.8.1
- */
-trait DecorateAsJava {
+/** Defines `asJava` extension methods for [[JavaConverters]]. */
+trait DecorateAsJava extends AsJavaConverters {
/**
- * Adds an `asJava` method that implicitly converts a Scala `Iterator` to a
- * Java `Iterator`. The returned Java `Iterator` is backed by the provided Scala
- * `Iterator` and any side-effects of using it via the Java interface will
- * be visible via the Scala interface and vice versa.
- *
- * If the Scala `Iterator` was previously obtained from an implicit or explicit
- * call of `asIterator(java.util.Iterator)` then the original Java `Iterator`
- * will be returned by the `asJava` method.
- *
- * @param i The `Iterator` to be converted.
- * @return An object with an `asJava` method that returns a Java `Iterator` view of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala `Iterator` to a Java `Iterator`.
+ * See [[asJavaIterator]].
*/
implicit def asJavaIteratorConverter[A](i : Iterator[A]): AsJava[ju.Iterator[A]] =
new AsJava(asJavaIterator(i))
/**
- * Adds an `asJavaEnumeration` method that implicitly converts a Scala
- * `Iterator` to a Java `Enumeration`. The returned Java `Enumeration` is
- * backed by the provided Scala `Iterator` and any side-effects of using
- * it via the Java interface will be visible via the Scala interface and
- * vice versa.
- *
- * If the Scala `Iterator` was previously obtained from an implicit or
- * explicit call of `asIterator(java.util.Enumeration)` then the
- * original Java `Enumeration` will be returned.
- *
- * @param i The `Iterator` to be converted.
- * @return An object with an `asJavaEnumeration` method that returns a Java
- * `Enumeration` view of the argument.
+ * Adds an `asJavaEnumeration` method that implicitly converts a Scala `Iterator` to a Java
+ * `Enumeration`. See [[asJavaEnumeration]].
*/
implicit def asJavaEnumerationConverter[A](i : Iterator[A]): AsJavaEnumeration[A] =
new AsJavaEnumeration(i)
/**
- * Adds an `asJava` method that implicitly converts a Scala `Iterable` to
- * a Java `Iterable`.
- *
- * The returned Java `Iterable` is backed by the provided Scala `Iterable`
- * and any side-effects of using it via the Java interface will be visible
- * via the Scala interface and vice versa.
- *
- * If the Scala `Iterable` was previously obtained from an implicit or
- * explicit call of `asIterable(java.lang.Iterable)` then the original
- * Java `Iterable` will be returned.
- *
- * @param i The `Iterable` to be converted.
- * @return An object with an `asJavaCollection` method that returns a Java
- * `Iterable` view of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala `Iterable` to a Java `Iterable`.
+ * See [[asJavaIterable]].
*/
implicit def asJavaIterableConverter[A](i : Iterable[A]): AsJava[jl.Iterable[A]] =
new AsJava(asJavaIterable(i))
/**
- * Adds an `asJavaCollection` method that implicitly converts a Scala
- * `Iterable` to an immutable Java `Collection`.
- *
- * If the Scala `Iterable` was previously obtained from an implicit or
- * explicit call of `asSizedIterable(java.util.Collection)` then the
- * original Java `Collection` will be returned.
- *
- * @param i The `SizedIterable` to be converted.
- * @return An object with an `asJava` method that returns a Java
- * `Collection` view of the argument.
+ * Adds an `asJavaCollection` method that implicitly converts a Scala `Iterable` to an immutable
+ * Java `Collection`. See [[asJavaCollection]].
*/
implicit def asJavaCollectionConverter[A](i : Iterable[A]): AsJavaCollection[A] =
new AsJavaCollection(i)
/**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Buffer`
- * to a Java `List`.
- *
- * The returned Java `List` is backed by the provided Scala `Buffer` and any
- * side-effects of using it via the Java interface will be visible via the
- * Scala interface and vice versa.
- *
- * If the Scala `Buffer` was previously obtained from an implicit or explicit
- * call of `asBuffer(java.util.List)` then the original Java `List` will be
- * returned.
- *
- * @param b The `Buffer` to be converted.
- * @return An object with an `asJava` method that returns a Java `List` view
- * of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Buffer` to a Java `List`.
+ * See [[bufferAsJavaList]].
*/
implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] =
new AsJava(bufferAsJavaList(b))
/**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Seq`
- * to a Java `List`.
- *
- * The returned Java `List` is backed by the provided Scala `Seq` and any
- * side-effects of using it via the Java interface will be visible via the
- * Scala interface and vice versa.
- *
- * If the Scala `Seq` was previously obtained from an implicit or explicit
- * call of `asSeq(java.util.List)` then the original Java `List` will be
- * returned.
- *
- * @param b The `Seq` to be converted.
- * @return An object with an `asJava` method that returns a Java `List`
- * view of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Seq` to a Java `List`.
+ * See [[mutableSeqAsJavaList]].
*/
implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] =
new AsJava(mutableSeqAsJavaList(b))
/**
- * Adds an `asJava` method that implicitly converts a Scala `Seq` to a
- * Java `List`.
- *
- * The returned Java `List` is backed by the provided Scala `Seq` and any
- * side-effects of using it via the Java interface will be visible via the
- * Scala interface and vice versa.
- *
- * If the Scala `Seq` was previously obtained from an implicit or explicit
- * call of `asSeq(java.util.List)` then the original Java `List` will be
- * returned.
- *
- * @param b The `Seq` to be converted.
- * @return An object with an `asJava` method that returns a Java `List`
- * view of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala `Seq` to a Java `List`.
+ * See [[seqAsJavaList]].
*/
implicit def seqAsJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] =
new AsJava(seqAsJavaList(b))
/**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Set`>
- * to a Java `Set`.
- *
- * The returned Java `Set` is backed by the provided Scala `Set` and any
- * side-effects of using it via the Java interface will be visible via
- * the Scala interface and vice versa.
- *
- * If the Scala `Set` was previously obtained from an implicit or explicit
- * call of `asSet(java.util.Set)` then the original Java `Set` will be
- * returned.
- *
- * @param s The `Set` to be converted.
- * @return An object with an `asJava` method that returns a Java `Set` view
- * of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Set` to a Java `Set`.
+ * See [[mutableSetAsJavaSet]].
*/
implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] =
new AsJava(mutableSetAsJavaSet(s))
/**
- * Adds an `asJava` method that implicitly converts a Scala `Set` to a
- * Java `Set`.
- *
- * The returned Java `Set` is backed by the provided Scala `Set` and any
- * side-effects of using it via the Java interface will be visible via
- * the Scala interface and vice versa.
- *
- * If the Scala `Set` was previously obtained from an implicit or explicit
- * call of `asSet(java.util.Set)` then the original Java `Set` will be
- * returned.
- *
- * @param s The `Set` to be converted.
- * @return An object with an `asJava` method that returns a Java `Set` view
- * of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala `Set` to a Java `Set`.
+ * See [[setAsJavaSet]].
*/
implicit def setAsJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] =
new AsJava(setAsJavaSet(s))
/**
- * Adds an `asJava` method that implicitly converts a Scala mutable `Map`
- * to a Java `Map`.
- *
- * The returned Java `Map` is backed by the provided Scala `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 `Map` was previously obtained from an implicit or explicit
- * call of `asMap(java.util.Map)` then the original Java `Map` will be
- * returned.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asJava` method that returns a Java `Map` view
- * of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala mutable `Map` to a Java `Map`.
+ * See [[mutableMapAsJavaMap]].
*/
implicit def mutableMapAsJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] =
new AsJava(mutableMapAsJavaMap(m))
/**
- * Adds an `asJavaDictionary` method that implicitly converts a Scala
- * mutable `Map` to a Java `Dictionary`.
- *
- * The returned Java `Dictionary` is backed by the provided Scala
- * `Dictionary` and any side-effects of using it via the Java interface
- * will be visible via the Scala interface and vice versa.
- *
- * If the Scala `Dictionary` was previously obtained from an implicit or
- * explicit call of `asMap(java.util.Dictionary)` then the original
- * Java `Dictionary` will be returned.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asJavaDictionary` method that returns a
- * Java `Dictionary` view of the argument.
+ * Adds an `asJavaDictionary` method that implicitly converts a Scala mutable `Map` to a Java
+ * `Dictionary`. See [[asJavaDictionary]].
*/
implicit def asJavaDictionaryConverter[A, B](m : mutable.Map[A, B]): AsJavaDictionary[A, B] =
new AsJavaDictionary(m)
/**
- * Adds an `asJava` method that implicitly converts a Scala `Map` to
- * a Java `Map`.
- *
- * The returned Java `Map` is backed by the provided Scala `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 `Map` was previously obtained from an implicit or explicit
- * call of `asMap(java.util.Map)` then the original Java `Map` will be
- * returned.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asJava` method that returns a Java `Map` view
- * of the argument.
+ * Adds an `asJava` method that implicitly converts a Scala `Map` to a Java `Map`.
+ * See [[mapAsJavaMap]].
*/
implicit def mapAsJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] =
new AsJava(mapAsJavaMap(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.concurrent.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.
+ * Adds an `asJava` method that implicitly converts a Scala mutable `concurrent.Map` to a Java
+ * `ConcurrentMap`. See [[mapAsJavaConcurrentMap]].
*/
implicit def mapAsJavaConcurrentMapConverter[A, B](m: concurrent.Map[A, B]): AsJava[juc.ConcurrentMap[A, B]] =
new AsJava(mapAsJavaConcurrentMap(m))
diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala
index 5448f5f91c..b74a06ece5 100644
--- a/src/library/scala/collection/convert/DecorateAsScala.scala
+++ b/src/library/scala/collection/convert/DecorateAsScala.scala
@@ -1,6 +1,6 @@
/* __ *\
** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
+** / __/ __// _ | / / / _ | (c) 2006-2016, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
@@ -12,185 +12,76 @@ package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import Decorators._
-import WrapAsScala._
import scala.language.implicitConversions
-trait DecorateAsScala {
+/** Defines `asScala` extension methods for [[JavaConverters]]. */
+trait DecorateAsScala extends AsScalaConverters {
/**
- * Adds an `asScala` method that implicitly converts a Java `Iterator` to
- * a Scala `Iterator`.
- *
- * The returned Scala `Iterator` is backed by the provided Java `Iterator`
- * and any side-effects of using it via the Scala interface will be visible
- * via the Java interface and vice versa.
- *
- * If the Java `Iterator` was previously obtained from an implicit or
- * explicit call of `asIterator(scala.collection.Iterator)` then the
- * original Scala `Iterator` will be returned.
- *
- * @param i The `Iterator` to be converted.
- * @return An object with an `asScala` method that returns a Scala
- * `Iterator` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Iterator` to a Scala `Iterator`.
+ * See [[asScalaIterator]].
*/
implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): AsScala[Iterator[A]] =
new AsScala(asScalaIterator(i))
/**
- * Adds an `asScala` method that implicitly converts a Java `Enumeration`
- * to a Scala `Iterator`.
- *
- * The returned Scala `Iterator` is backed by the provided Java
- * `Enumeration` and any side-effects of using it via the Scala interface
- * will be visible via the Java interface and vice versa.
- *
- * If the Java `Enumeration` was previously obtained from an implicit or
- * explicit call of `asEnumeration(scala.collection.Iterator)` then the
- * original Scala `Iterator` will be returned.
- *
- * @param i The `Enumeration` to be converted.
- * @return An object with an `asScala` method that returns a Scala
- * `Iterator` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Enumeration` to a Scala `Iterator`.
+ * See [[enumerationAsScalaIterator]].
*/
implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): AsScala[Iterator[A]] =
new AsScala(enumerationAsScalaIterator(i))
/**
- * Adds an `asScala` method that implicitly converts a Java `Iterable` to
- * a Scala `Iterable`.
- *
- * The returned Scala `Iterable` is backed by the provided Java `Iterable`
- * and any side-effects of using it via the Scala interface will be visible
- * via the Java interface and vice versa.
- *
- * If the Java `Iterable` was previously obtained from an implicit or
- * explicit call of `asIterable(scala.collection.Iterable)` then the original
- * Scala `Iterable` will be returned.
- *
- * @param i The `Iterable` to be converted.
- * @return An object with an `asScala` method that returns a Scala `Iterable`
- * view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Iterable` to a Scala `Iterable`.
+ * See [[iterableAsScalaIterable]].
*/
implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] =
new AsScala(iterableAsScalaIterable(i))
/**
- * Adds an `asScala` method that implicitly converts a Java `Collection` to
- * an Scala `Iterable`.
- *
- * If the Java `Collection` was previously obtained from an implicit or
- * explicit call of `asCollection(scala.collection.SizedIterable)` then
- * the original Scala `SizedIterable` will be returned.
- *
- * @param i The `Collection` to be converted.
- * @return An object with an `asScala` method that returns a Scala
- * `SizedIterable` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Collection` to an Scala `Iterable`.
+ * See [[collectionAsScalaIterable]].
*/
implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] =
new AsScala(collectionAsScalaIterable(i))
/**
- * Adds an `asScala` method that implicitly converts a Java `List` to a
- * Scala mutable `Buffer`.
- *
- * The returned Scala `Buffer` is backed by the provided Java `List` and
- * any side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * If the Java `List` was previously obtained from an implicit or explicit
- * call of `asList(scala.collection.mutable.Buffer)` then the original
- * Scala `Buffer` will be returned.
- *
- * @param l The `List` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Buffer` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `List` to a Scala mutable `Buffer`.
+ * See [[asScalaBuffer]].
*/
implicit def asScalaBufferConverter[A](l : ju.List[A]): AsScala[mutable.Buffer[A]] =
new AsScala(asScalaBuffer(l))
/**
- * Adds an `asScala` method that implicitly converts a Java `Set` to a
- * Scala mutable `Set`.
- *
- * The returned Scala `Set` is backed by the provided Java `Set` and any
- * side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * If the Java `Set` was previously obtained from an implicit or explicit
- * call of `asSet(scala.collection.mutable.Set)` then the original
- * Scala `Set` will be returned.
- *
- * @param s The `Set` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Set` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Set` to a Scala mutable `Set`.
+ * See [[asScalaSet]].
*/
implicit def asScalaSetConverter[A](s : ju.Set[A]): AsScala[mutable.Set[A]] =
new AsScala(asScalaSet(s))
/**
- * Adds an `asScala` method that implicitly converts a Java `Map` to a Scala
- * mutable `Map`. The returned Scala `Map` is backed by the provided Java
- * `Map` and any side-effects of using it via the Scala interface will
- * be visible via the Java interface and vice versa.
- *
- * If the Java `Map` was previously obtained from an implicit or explicit
- * call of `asMap(scala.collection.mutable.Map)` then the original
- * Scala `Map` will be returned.
- *
- * If the wrapped map is synchronized (e.g. from `java.util.Collections.synchronizedMap`),
- * it is your responsibility to wrap all
- * non-atomic operations with `underlying.synchronized`.
- * This includes `get`, as `java.util.Map`'s API does not allow for an
- * atomic `get` when `null` values may be present.
- *
- * @param m The `Map` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Map` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Map` to a Scala mutable `Map`.
+ * See [[mapAsScalaMap]].
*/
implicit def mapAsScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] =
new AsScala(mapAsScalaMap(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.
+ * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` to a Scala mutable
+ * `concurrent.Map`. See [[mapAsScalaConcurrentMap]].
*/
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
- * any side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * @param p The `Dictionary` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Map[String, String]` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Dictionary` to a Scala mutable `Map`.
+ * See [[dictionaryAsScalaMap]].
*/
implicit def dictionaryAsScalaMapConverter[A, B](p: ju.Dictionary[A, B]): AsScala[mutable.Map[A, B]] =
new AsScala(dictionaryAsScalaMap(p))
/**
- * Adds an `asScala` method that implicitly converts a Java `Properties`
- * to a Scala mutable `Map[String, String]`. The returned Scala
- * `Map[String, String]` is backed by the provided Java `Properties` and
- * any side-effects of using it via the Scala interface will be visible via
- * the Java interface and vice versa.
- *
- * @param p The `Properties` to be converted.
- * @return An object with an `asScala` method that returns a Scala mutable
- * `Map[String, String]` view of the argument.
+ * Adds an `asScala` method that implicitly converts a Java `Properties` to a Scala mutable
+ * `Map[String, String]`. See [[propertiesAsScalaMap]].
*/
implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] =
new AsScala(propertiesAsScalaMap(p))
diff --git a/src/library/scala/collection/convert/Decorators.scala b/src/library/scala/collection/convert/Decorators.scala
index d232fa04e1..3e45a02254 100644
--- a/src/library/scala/collection/convert/Decorators.scala
+++ b/src/library/scala/collection/convert/Decorators.scala
@@ -12,7 +12,7 @@ package convert
import java.{ util => ju }
-private[collection] trait Decorators {
+private[collection] object Decorators {
/** Generic class containing the `asJava` converter method */
class AsJava[A](op: => A) {
/** Converts a Scala collection to the corresponding Java collection */
@@ -28,20 +28,18 @@ private[collection] trait Decorators {
/** Generic class containing the `asJavaCollection` converter method */
class AsJavaCollection[A](i: Iterable[A]) {
/** Converts a Scala `Iterable` to a Java `Collection` */
- def asJavaCollection: ju.Collection[A] = JavaConversions.asJavaCollection(i)
+ def asJavaCollection: ju.Collection[A] = JavaConverters.asJavaCollection(i)
}
/** Generic class containing the `asJavaEnumeration` converter method */
class AsJavaEnumeration[A](i: Iterator[A]) {
/** Converts a Scala `Iterator` to a Java `Enumeration` */
- def asJavaEnumeration: ju.Enumeration[A] = JavaConversions.asJavaEnumeration(i)
+ def asJavaEnumeration: ju.Enumeration[A] = JavaConverters.asJavaEnumeration(i)
}
/** Generic class containing the `asJavaDictionary` converter method */
class AsJavaDictionary[A, B](m : mutable.Map[A, B]) {
/** Converts a Scala `Map` to a Java `Dictionary` */
- def asJavaDictionary: ju.Dictionary[A, B] = JavaConversions.asJavaDictionary(m)
+ def asJavaDictionary: ju.Dictionary[A, B] = JavaConverters.asJavaDictionary(m)
}
}
-
-private[collection] object Decorators extends Decorators
diff --git a/src/library/scala/collection/convert/ImplicitConversions.scala b/src/library/scala/collection/convert/ImplicitConversions.scala
new file mode 100644
index 0000000000..747e0606c8
--- /dev/null
+++ b/src/library/scala/collection/convert/ImplicitConversions.scala
@@ -0,0 +1,125 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2016, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+package collection
+package convert
+
+import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
+import scala.language.implicitConversions
+
+import JavaConverters._
+
+/** Defines implicit converter methods from Java to Scala collections. */
+trait ToScalaImplicits {
+ /** Implicitly converts a Java `Iterator` to a Scala `Iterator`. See [[asScalaIterator]]. */
+ implicit def `iterator asScala`[A](it: ju.Iterator[A]): Iterator[A] = asScalaIterator(it)
+
+ /** Implicitly converts a Java `Enumeration` to a Scala `Iterator`. See [[enumerationAsScalaIterator]]. */
+ implicit def `enumeration AsScalaIterator`[A](i: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(i)
+
+ /** Implicitly converts a Java `Iterable` to a Scala `Iterable`. See [[iterableAsScalaIterable]]. */
+ implicit def `iterable AsScalaIterable`[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)
+
+ /** Implicitly converts a Java `Collection` to an Scala `Iterable`. See [[collectionAsScalaIterable]]. */
+ implicit def `collection AsScalaIterable`[A](i: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(i)
+
+ /** Implicitly converts a Java `List` to a Scala mutable `Buffer`. See [[asScalaBuffer]]. */
+ implicit def `list asScalaBuffer`[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)
+
+ /** Implicitly converts a Java `Set` to a Scala mutable `Set`. See [[asScalaSet]]. */
+ implicit def `set asScala`[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)
+
+ /** Implicitly converts a Java `Map` to a Scala mutable `Map`. See [[mapAsScalaMap]]. */
+ implicit def `map AsScala`[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)
+
+ /** Implicitly converts a Java `ConcurrentMap` to a Scala mutable `ConcurrentMap`. See [[mapAsScalaConcurrentMap]]. */
+ implicit def `map AsScalaConcurrentMap`[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)
+
+ /** Implicitly converts a Java `Dictionary` to a Scala mutable `Map`. See [[dictionaryAsScalaMap]]. */
+ implicit def `dictionary AsScalaMap`[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(p)
+
+ /** Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`. See [[propertiesAsScalaMap]]. */
+ implicit def `properties AsScalaMap`(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
+}
+
+/** Defines implicit conversions from Scala to Java collections. */
+trait ToJavaImplicits {
+ /** Implicitly converts a Scala `Iterator` to a Java `Iterator`. See [[asJavaIterator]]. */
+ implicit def `iterator asJava`[A](it: Iterator[A]): ju.Iterator[A] = asJavaIterator(it)
+
+ /** Implicitly converts a Scala `Iterator` to a Java `Enumeration`. See [[asJavaEnumeration]]. */
+ implicit def `enumeration asJava`[A](it: Iterator[A]): ju.Enumeration[A] = asJavaEnumeration(it)
+
+ /** Implicitly converts a Scala `Iterable` to a Java `Iterable`. See [[asJavaIterable]]. */
+ implicit def `iterable asJava`[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)
+
+ /** Implicitly converts a Scala `Iterable` to an immutable Java `Collection`. See [[asJavaCollection]]. */
+ implicit def `collection asJava`[A](it: Iterable[A]): ju.Collection[A] = asJavaCollection(it)
+
+ /** Implicitly converts a Scala mutable `Buffer` to a Java `List`. See [[bufferAsJavaList]]. */
+ implicit def `buffer AsJavaList`[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)
+
+ /** Implicitly converts a Scala mutable `Seq` to a Java `List`. See [[mutableSeqAsJavaList]]. */
+ implicit def `mutableSeq AsJavaList`[A](seq: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(seq)
+
+ /** Implicitly converts a Scala `Seq` to a Java `List`. See [[seqAsJavaList]]. */
+ implicit def `seq AsJavaList`[A](seq: Seq[A]): ju.List[A] = seqAsJavaList(seq)
+
+ /** Implicitly converts a Scala mutable `Set` to a Java `Set`. See [[mutableSetAsJavaSet]]. */
+ implicit def `mutableSet AsJavaSet`[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)
+
+ /** Implicitly converts a Scala `Set` to a Java `Set`. See [[setAsJavaSet]]. */
+ implicit def `set AsJavaSet`[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)
+
+ /** Implicitly converts a Scala mutable `Map` to a Java `Map`. See [[mutableMapAsJavaMap]]. */
+ implicit def `mutableMap AsJavaMap`[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = mutableMapAsJavaMap(m)
+
+ /** Implicitly converts a Scala mutable `Map` to a Java `Dictionary`. See [[asJavaDictionary]]. */
+ implicit def `dictionary asJava`[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = asJavaDictionary(m)
+
+ /** Implicitly converts a Scala `Map` to a Java `Map`. See [[mapAsJavaMap]]. */
+ implicit def `map AsJavaMap`[A, B](m: Map[A, B]): ju.Map[A, B] = mapAsJavaMap(m)
+
+ /** Implicitly converts a Scala mutable `concurrent.Map` to a Java `ConcurrentMap`. See [[mapAsJavaConcurrentMap]]. */
+ implicit def `map AsJavaConcurrentMap`[A, B](m: concurrent.Map[A, B]): juc.ConcurrentMap[A, B] = mapAsJavaConcurrentMap(m)
+}
+
+/**
+ * Convenience for miscellaneous implicit conversions from Scala to Java collections API.
+ *
+ * It is recommended to use explicit conversions provided by [[collection.JavaConverters]] instead.
+ * Implicit conversions may cause unexpected issues, see [[ImplicitConversions]].
+ */
+object ImplicitConversionsToJava extends ToJavaImplicits
+
+/**
+ * Convenience for miscellaneous implicit conversions from Java to Scala collections API.
+ *
+ * It is recommended to use explicit conversions provided by [[collection.JavaConverters]] instead.
+ * Implicit conversions may cause unexpected issues, see [[ImplicitConversions]].
+ */
+object ImplicitConversionsToScala extends ToScalaImplicits
+
+/**
+ * Convenience for miscellaneous implicit conversions between Java and Scala collections API.
+ *
+ * It is recommended to use explicit conversions provided by [[collection.JavaConverters]] instead.
+ * Implicit conversions may cause unexpected issues. Example:
+ *
+ * {{{
+ * import collection.convert.ImplicitConversions._
+ * case class StringBox(s: String)
+ * val m = Map(StringBox("one") -> "uno")
+ * m.get("one")
+ * }}}
+ *
+ * The above example returns `null` instead of producing a type error at compile-time. The map is
+ * implicitly converted to a `java.util.Map` which provides a method `get(x: AnyRef)`.
+ */
+object ImplicitConversions extends ToScalaImplicits with ToJavaImplicits
diff --git a/src/library/scala/collection/convert/WrapAsJava.scala b/src/library/scala/collection/convert/WrapAsJava.scala
index 9916fe9843..e45c1666a5 100644
--- a/src/library/scala/collection/convert/WrapAsJava.scala
+++ b/src/library/scala/collection/convert/WrapAsJava.scala
@@ -13,7 +13,27 @@ package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import scala.language.implicitConversions
-trait WrapAsJava {
+@deprecated("Use JavaConverters or consider ToJavaImplicits", since="2.12")
+trait WrapAsJava extends LowPriorityWrapAsJava {
+ // provide higher-priority implicits with names that don't exist in JavaConverters for the case
+ // when importing both JavaConverters._ and JavaConversions._. otherwise implicit conversions
+ // would not apply, see https://github.com/scala/scala/pull/5109#issuecomment-212417789
+ implicit def `deprecated asJavaIterator`[A](it: Iterator[A]): ju.Iterator[A] = asJavaIterator(it)
+ implicit def `deprecated asJavaEnumeration`[A](it: Iterator[A]): ju.Enumeration[A] = asJavaEnumeration(it)
+ implicit def `deprecated asJavaIterable`[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)
+ implicit def `deprecated asJavaCollection`[A](it: Iterable[A]): ju.Collection[A] = asJavaCollection(it)
+ implicit def `deprecated bufferAsJavaList`[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)
+ implicit def `deprecated mutableSeqAsJavaList`[A](seq: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(seq)
+ implicit def `deprecated seqAsJavaList`[A](seq: Seq[A]): ju.List[A] = seqAsJavaList(seq)
+ implicit def `deprecated mutableSetAsJavaSet`[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)
+ implicit def `deprecated setAsJavaSet`[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)
+ implicit def `deprecated mutableMapAsJavaMap`[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = mutableMapAsJavaMap(m)
+ implicit def `deprecated asJavaDictionary`[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = asJavaDictionary(m)
+ implicit def `deprecated mapAsJavaMap`[A, B](m: Map[A, B]): ju.Map[A, B] = mapAsJavaMap(m)
+ implicit def `deprecated mapAsJavaConcurrentMap`[A, B](m: concurrent.Map[A, B]): juc.ConcurrentMap[A, B] = mapAsJavaConcurrentMap(m)
+}
+
+private[convert] trait LowPriorityWrapAsJava {
import Wrappers._
/**
@@ -30,8 +50,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 +69,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 +88,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 +105,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 +124,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 +143,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 +162,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 +181,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 +200,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 +219,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 +239,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 +259,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,9 +280,11 @@ 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)
}
}
-object WrapAsJava extends WrapAsJava { }
+@deprecated("Use JavaConverters or consider ImplicitConversionsToJava", since="2.12")
+object WrapAsJava extends WrapAsJava
diff --git a/src/library/scala/collection/convert/WrapAsScala.scala b/src/library/scala/collection/convert/WrapAsScala.scala
index ab151a6778..514490e348 100644
--- a/src/library/scala/collection/convert/WrapAsScala.scala
+++ b/src/library/scala/collection/convert/WrapAsScala.scala
@@ -13,8 +13,26 @@ package convert
import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import scala.language.implicitConversions
-trait WrapAsScala {
+@deprecated("Use JavaConverters or consider ToScalaImplicits", since="2.12")
+trait WrapAsScala extends LowPriorityWrapAsScala {
+ // provide higher-priority implicits with names that don't exist in JavaConverters for the case
+ // when importing both JavaConverters._ and JavaConversions._. otherwise implicit conversions
+ // would not apply, see https://github.com/scala/scala/pull/5109#issuecomment-212417789
+ implicit def `deprecated asScalaIterator`[A](it: ju.Iterator[A]): Iterator[A] = asScalaIterator(it)
+ implicit def `deprecated enumerationAsScalaIterator`[A](i: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(i)
+ implicit def `deprecated iterableAsScalaIterable`[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)
+ implicit def `deprecated collectionAsScalaIterable`[A](i: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(i)
+ implicit def `deprecated asScalaBuffer`[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)
+ implicit def `deprecated asScalaSet`[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)
+ implicit def `deprecated mapAsScalaMap`[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)
+ implicit def `deprecated mapAsScalaConcurrentMap`[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)
+ implicit def `deprecated dictionaryAsScalaMap`[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(p)
+ implicit def `deprecated propertiesAsScalaMap`(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
+}
+
+private[convert] trait LowPriorityWrapAsScala {
import Wrappers._
+
/**
* Implicitly converts a Java `Iterator` to a Scala `Iterator`.
*
@@ -30,8 +48,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 +67,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 +87,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 +103,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 +123,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 +142,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)
}
/**
@@ -133,20 +157,20 @@ trait WrapAsScala {
* If the Java `Map` was previously obtained from an implicit or
* explicit call of `mapAsScalaMap(scala.collection.mutable.Map)` then
* the original Scala Map will be returned.
- *
+ *
* If the wrapped map is synchronized (e.g. from `java.util.Collections.synchronizedMap`),
- * it is your responsibility to wrap all
+ * it is your responsibility to wrap all
* non-atomic operations with `underlying.synchronized`.
* This includes `get`, as `java.util.Map`'s API does not allow for an
* atomic `get` when `null` values may be present.
- *
+ *
* @param m The Map to be converted.
* @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,24 +187,26 @@ 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[_, _] => cmw.underlying
+ case _ => new JConcurrentMapWrapper(m)
}
/**
* Implicitly converts a Java `Dictionary` to a Scala mutable
- * `Map[String, String]`.
+ * `Map`.
*
- * The returned Scala `Map[String, String]` is backed by the provided Java
+ * The returned Scala `Map` is backed by the provided Java
* `Dictionary` and any side-effects of using it via the Scala interface
* will be visible via the Java interface and vice versa.
*
* @param p The Dictionary to be converted.
- * @return A Scala mutable Map[String, String] view of the argument.
+ * @return A Scala mutable Map 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,8 +220,10 @@ 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)
}
}
-object WrapAsScala extends WrapAsScala { }
+@deprecated("Use JavaConverters or consider ImplicitConversionsToScala", since="2.12")
+object WrapAsScala extends WrapAsScala
diff --git a/src/library/scala/collection/convert/Wrappers.scala b/src/library/scala/collection/convert/Wrappers.scala
index e829a0215b..6d745bc6b0 100644
--- a/src/library/scala/collection/convert/Wrappers.scala
+++ b/src/library/scala/collection/convert/Wrappers.scala
@@ -14,10 +14,7 @@ import java.{ lang => jl, util => ju }, java.util.{ concurrent => juc }
import WrapAsScala._
import WrapAsJava._
-/** Don't put the implementations in the same scope as the implicits
- * which utilize them, or they will stow away into every scope which
- * extends one of those implementations. See SI-5580.
- */
+/** Adapters for Java/Scala collections API. */
private[collection] trait Wrappers {
trait IterableWrapperTrait[A] extends ju.AbstractCollection[A] {
val underlying: Iterable[A]
@@ -102,9 +99,9 @@ private[collection] trait Wrappers {
override def clone(): JListWrapper[A] = JListWrapper(new ju.ArrayList[A](underlying))
}
- // Note various overrides to avoid performance gotchas.
- class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] {
- self =>
+ @SerialVersionUID(1L)
+ class SetWrapper[A](underlying: Set[A]) extends ju.AbstractSet[A] with Serializable { self =>
+ // Note various overrides to avoid performance gotchas.
override def contains(o: Object): Boolean = {
try { underlying.contains(o.asInstanceOf[A]) }
catch { case cce: ClassCastException => false }
@@ -165,7 +162,8 @@ private[collection] trait Wrappers {
new JSetWrapper[A](new ju.LinkedHashSet[A](underlying))
}
- class MapWrapper[A, B](underlying: Map[A, B]) extends ju.AbstractMap[A, B] { self =>
+ @SerialVersionUID(1L)
+ class MapWrapper[A, B](underlying: Map[A, B]) extends ju.AbstractMap[A, B] with Serializable { self =>
override def size = underlying.size
override def get(key: AnyRef): B = try {
diff --git a/src/library/scala/collection/convert/package.scala b/src/library/scala/collection/convert/package.scala
index 13970f9a3e..7f48023b58 100644
--- a/src/library/scala/collection/convert/package.scala
+++ b/src/library/scala/collection/convert/package.scala
@@ -10,10 +10,17 @@ package scala
package collection
package object convert {
+ @deprecated("Use JavaConverters", since="2.12")
val decorateAsJava = new DecorateAsJava { }
+ @deprecated("Use JavaConverters", since="2.12")
val decorateAsScala = new DecorateAsScala { }
- val decorateAll = new DecorateAsJava with DecorateAsScala { }
+ @deprecated("Use JavaConverters", since="2.12")
+ val decorateAll = JavaConverters
+
+ @deprecated("Use JavaConverters or consider ImplicitConversionsToJava", since="2.12")
val wrapAsJava = new WrapAsJava { }
+ @deprecated("Use JavaConverters or consider ImplicitConversionsToScala", since="2.12")
val wrapAsScala = new WrapAsScala { }
+ @deprecated("Use JavaConverters or consider ImplicitConversions", since="2.12")
val wrapAll = new WrapAsJava with WrapAsScala { }
}
diff --git a/src/library/scala/collection/generic/BitOperations.scala b/src/library/scala/collection/generic/BitOperations.scala
index d430ece2f5..2f460eee1f 100644
--- a/src/library/scala/collection/generic/BitOperations.scala
+++ b/src/library/scala/collection/generic/BitOperations.scala
@@ -26,16 +26,7 @@ private[collection] object BitOperations {
def complement(i: Int) = (-1) ^ i
def bits(num: Int) = 31 to 0 by -1 map (i => (num >>> i & 1) != 0)
def bitString(num: Int, sep: String = "") = bits(num) map (b => if (b) "1" else "0") mkString sep
-
- def highestOneBit(j: Int) = {
- var i = j
- i |= (i >> 1)
- i |= (i >> 2)
- i |= (i >> 4)
- i |= (i >> 8)
- i |= (i >> 16)
- i - (i >>> 1)
- }
+ def highestOneBit(j: Int) = java.lang.Integer.highestOneBit(j)
}
object Int extends Int
@@ -49,17 +40,7 @@ private[collection] object BitOperations {
def complement(i: Long) = (-1L) ^ i
def bits(num: Long) = 63L to 0L by -1L map (i => (num >>> i & 1L) != 0L)
def bitString(num: Long, sep: String = "") = bits(num) map (b => if (b) "1" else "0") mkString sep
-
- def highestOneBit(j: Long) = {
- var i = j
- i |= (i >> 1)
- i |= (i >> 2)
- i |= (i >> 4)
- i |= (i >> 8)
- i |= (i >> 16)
- i |= (i >> 32)
- i - (i >>> 1)
- }
+ def highestOneBit(j: Long) = java.lang.Long.highestOneBit(j)
}
object Long extends Long
}
diff --git a/src/library/scala/collection/generic/GenericParTemplate.scala b/src/library/scala/collection/generic/GenericParTemplate.scala
index b9b7043270..44a778a953 100644
--- a/src/library/scala/collection/generic/GenericParTemplate.scala
+++ b/src/library/scala/collection/generic/GenericParTemplate.scala
@@ -13,7 +13,6 @@ package generic
import scala.collection.parallel.Combiner
import scala.collection.parallel.ParIterable
import scala.collection.parallel.ParMap
-import scala.collection.parallel.TaskSupport
import scala.annotation.unchecked.uncheckedVariance
import scala.language.higherKinds
diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala
index b9f3d4b010..255d695303 100644
--- a/src/library/scala/collection/generic/MapFactory.scala
+++ b/src/library/scala/collection/generic/MapFactory.scala
@@ -10,8 +10,6 @@ package scala
package collection
package generic
-
-import mutable.{Builder, MapBuilder}
import scala.language.higherKinds
/** A template for companion objects of `Map` and subclasses thereof.
diff --git a/src/library/scala/collection/generic/MutableSortedMapFactory.scala b/src/library/scala/collection/generic/MutableSortedMapFactory.scala
new file mode 100644
index 0000000000..b6fa933ca8
--- /dev/null
+++ b/src/library/scala/collection/generic/MutableSortedMapFactory.scala
@@ -0,0 +1,24 @@
+package scala
+package collection
+package generic
+
+import scala.language.higherKinds
+
+/**
+ * A template for companion objects of `SortedMap` and subclasses thereof.
+ *
+ * @tparam CC the type of the collection.
+ *
+ * @author Rui Gonçalves
+ * @since 2.12
+ * @version 2.12
+ *
+ * @define Coll `mutable.SortedMap`
+ * @define coll mutable sorted map
+ * @define factoryInfo
+ * This object provides a set of operations needed to create sorted maps of type `$Coll`.
+ * @define sortedMapCanBuildFromInfo
+ * The standard `CanBuildFrom` instance for sorted maps
+ */
+abstract class MutableSortedMapFactory[CC[A, B] <: mutable.SortedMap[A, B] with SortedMapLike[A, B, CC[A, B]]]
+ extends SortedMapFactory[CC]
diff --git a/src/library/scala/collection/generic/ParFactory.scala b/src/library/scala/collection/generic/ParFactory.scala
index 4486cea419..901e9fc239 100644
--- a/src/library/scala/collection/generic/ParFactory.scala
+++ b/src/library/scala/collection/generic/ParFactory.scala
@@ -11,7 +11,6 @@ package collection
package generic
import scala.collection.parallel.ParIterable
-import scala.collection.parallel.Combiner
import scala.language.higherKinds
/** A template class for companion objects of `ParIterable` and subclasses
diff --git a/src/library/scala/collection/generic/ParSetFactory.scala b/src/library/scala/collection/generic/ParSetFactory.scala
index 4320635ae6..1341ddcb38 100644
--- a/src/library/scala/collection/generic/ParSetFactory.scala
+++ b/src/library/scala/collection/generic/ParSetFactory.scala
@@ -10,7 +10,6 @@ package scala
package collection
package generic
-import scala.collection.mutable.Builder
import scala.collection.parallel.Combiner
import scala.collection.parallel.ParSet
import scala.collection.parallel.ParSetLike
diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala
index fcd8d00c18..5e50844cc9 100644
--- a/src/library/scala/collection/generic/SetFactory.scala
+++ b/src/library/scala/collection/generic/SetFactory.scala
@@ -12,7 +12,6 @@ package scala
package collection
package generic
-import mutable.Builder
import scala.language.higherKinds
abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]]
diff --git a/src/library/scala/collection/generic/package.scala b/src/library/scala/collection/generic/package.scala
index 1beb4a8599..015c3455db 100644
--- a/src/library/scala/collection/generic/package.scala
+++ b/src/library/scala/collection/generic/package.scala
@@ -1,6 +1,5 @@
package scala
package collection
-import generic.CanBuildFrom
import scala.language.higherKinds
diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala
index 70543aa3a6..6bb1f116fe 100644
--- a/src/library/scala/collection/immutable/BitSet.scala
+++ b/src/library/scala/collection/immutable/BitSet.scala
@@ -14,7 +14,7 @@ package immutable
import generic._
import BitSetLike.{LogWL, updateArray}
-import mutable.{ Builder, SetBuilder }
+import mutable.Builder
/** A class for immutable bitsets.
* $bitsetinfo
@@ -103,6 +103,7 @@ object BitSet extends BitSetFactory[BitSet] {
else new BitSetN(elems)
}
+ @SerialVersionUID(2260107458435649300L)
class BitSet1(val elems: Long) extends BitSet {
protected def nwords = 1
protected def word(idx: Int) = if (idx == 0) elems else 0L
@@ -110,6 +111,12 @@ object BitSet extends BitSetFactory[BitSet] {
if (idx == 0) new BitSet1(w)
else if (idx == 1) new BitSet2(elems, w)
else fromBitMaskNoCopy(updateArray(Array(elems), idx, w))
+ override def head: Int =
+ if (elems == 0L) throw new NoSuchElementException("Empty BitSet")
+ else java.lang.Long.numberOfTrailingZeros(elems)
+ override def tail: BitSet =
+ if (elems == 0L) throw new NoSuchElementException("Empty BitSet")
+ else new BitSet1(elems - java.lang.Long.lowestOneBit(elems))
}
class BitSet2(val elems0: Long, elems1: Long) extends BitSet {
@@ -119,6 +126,18 @@ object BitSet extends BitSetFactory[BitSet] {
if (idx == 0) new BitSet2(w, elems1)
else if (idx == 1) new BitSet2(elems0, w)
else fromBitMaskNoCopy(updateArray(Array(elems0, elems1), idx, w))
+ override def head: Int =
+ if (elems0 == 0L) {
+ if (elems1 == 0) throw new NoSuchElementException("Empty BitSet")
+ 64 + java.lang.Long.numberOfTrailingZeros(elems1)
+ }
+ else java.lang.Long.numberOfTrailingZeros(elems0)
+ override def tail: BitSet =
+ if (elems0 == 0L) {
+ if (elems1 == 0L) throw new NoSuchElementException("Empty BitSet")
+ new BitSet2(elems0, elems1 - java.lang.Long.lowestOneBit(elems1))
+ }
+ else new BitSet2(elems0 - java.lang.Long.lowestOneBit(elems0), elems1)
}
/** The implementing class for bit sets with elements >= 128 (exceeding
@@ -131,5 +150,15 @@ object BitSet extends BitSetFactory[BitSet] {
protected def nwords = elems.length
protected def word(idx: Int) = if (idx < nwords) elems(idx) else 0L
protected def updateWord(idx: Int, w: Long): BitSet = fromBitMaskNoCopy(updateArray(elems, idx, w))
+ override def tail: BitSet = {
+ val n = nwords
+ var i = 0
+ while (i < n) {
+ val wi = word(i)
+ if (wi != 0L) return fromBitMaskNoCopy(updateArray(elems, i, wi - java.lang.Long.lowestOneBit(wi)))
+ i += 1
+ }
+ throw new NoSuchElementException("Empty BitSet")
+ }
}
}
diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala
index 92d915fe8b..eac9c14f3f 100644
--- a/src/library/scala/collection/immutable/HashMap.scala
+++ b/src/library/scala/collection/immutable/HashMap.scala
@@ -33,8 +33,7 @@ import parallel.immutable.ParHashMap
* @define willNotTerminateInf
*/
@SerialVersionUID(2L)
-@deprecatedInheritance("The implementation details of immutable hash maps make inheriting from them unwise.", "2.11.0")
-class HashMap[A, +B] extends AbstractMap[A, B]
+sealed class HashMap[A, +B] extends AbstractMap[A, B]
with Map[A, B]
with MapLike[A, B, HashMap[A, B]]
with Serializable
@@ -65,6 +64,8 @@ class HashMap[A, +B] extends AbstractMap[A, B]
def - (key: A): HashMap[A, B] =
removed0(key, computeHash(key), 0)
+ override def tail: HashMap[A, B] = this - head._1
+
override def filter(p: ((A, B)) => Boolean) = {
val buffer = new Array[HashMap[A, B]](bufferSize(size))
nullToEmpty(filter0(p, false, 0, buffer, 0))
@@ -156,7 +157,10 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), HashMap[A, B]] = new MapCanBuildFrom[A, B]
def empty[A, B]: HashMap[A, B] = EmptyHashMap.asInstanceOf[HashMap[A, B]]
- private object EmptyHashMap extends HashMap[Any, Nothing] { }
+ private object EmptyHashMap extends HashMap[Any, Nothing] {
+ override def head: (Any, Nothing) = throw new NoSuchElementException("Empty Map")
+ override def tail: HashMap[Any, Nothing] = throw new NoSuchElementException("Empty Map")
+ }
// utility method to create a HashTrieMap from two leaf HashMaps (HashMap1 or HashMapCollision1) with non-colliding hash code)
private def makeHashTrieMap[A, B](hash0:Int, elem0:HashMap[A, B], hash1:Int, elem1:HashMap[A, B], level:Int, size:Int) : HashTrieMap[A, B] = {
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala
index 050e90b49b..fc937e3a22 100644
--- a/src/library/scala/collection/immutable/HashSet.scala
+++ b/src/library/scala/collection/immutable/HashSet.scala
@@ -31,8 +31,7 @@ import scala.annotation.tailrec
* @define coll immutable hash set
*/
@SerialVersionUID(2L)
-@deprecatedInheritance("The implementation details of immutable hash sets make inheriting from them unwise.", "2.11.0")
-class HashSet[A] extends AbstractSet[A]
+sealed class HashSet[A] extends AbstractSet[A]
with Set[A]
with GenericSetTemplate[A, HashSet]
with SetLike[A, HashSet[A]]
@@ -162,6 +161,8 @@ class HashSet[A] extends AbstractSet[A]
def - (e: A): HashSet[A] =
nullToEmpty(removed0(e, computeHash(e), 0))
+ override def tail: HashSet[A] = this - head
+
override def filter(p: A => Boolean) = {
val buffer = new Array[HashSet[A]](bufferSize(size))
nullToEmpty(filter0(p, false, 0, buffer, 0))
@@ -187,7 +188,7 @@ class HashSet[A] extends AbstractSet[A]
protected def get0(key: A, hash: Int, level: Int): Boolean = false
- def updated0(key: A, hash: Int, level: Int): HashSet[A] =
+ private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
new HashSet.HashSet1(key, hash)
protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = this
@@ -213,7 +214,10 @@ object HashSet extends ImmutableSetFactory[HashSet] {
/** $setCanBuildFromInfo */
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, HashSet[A]] = setCanBuildFrom[A]
- private object EmptyHashSet extends HashSet[Any] { }
+ private object EmptyHashSet extends HashSet[Any] {
+ override def head: Any = throw new NoSuchElementException("Empty Set")
+ override def tail: HashSet[Any] = throw new NoSuchElementException("Empty Set")
+ }
private[collection] def emptyInstance: HashSet[Any] = EmptyHashSet
// utility method to create a HashTrieSet from two leaf HashSets (HashSet1 or HashSetCollision1) with non-colliding hash code)
@@ -250,10 +254,10 @@ object HashSet extends ImmutableSetFactory[HashSet] {
class HashSet1[A](private[HashSet] val key: A, private[HashSet] val hash: Int) extends LeafHashSet[A] {
override def size = 1
- override def get0(key: A, hash: Int, level: Int): Boolean =
+ override protected def get0(key: A, hash: Int, level: Int): Boolean =
(hash == this.hash && key == this.key)
- override def subsetOf0(that: HashSet[A], level: Int) = {
+ override protected def subsetOf0(that: HashSet[A], level: Int) = {
// check if that contains this.key
// we use get0 with our key and hash at the correct level instead of calling contains,
// which would not work since that might not be a top-level HashSet
@@ -261,7 +265,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
that.get0(key, hash, level)
}
- override def updated0(key: A, hash: Int, level: Int): HashSet[A] =
+ override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash && key == this.key) this
else {
if (hash != this.hash) {
@@ -306,7 +310,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
override private[immutable] def diff0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] =
if (that.get0(key, hash, level)) null else this
- override def removed0(key: A, hash: Int, level: Int): HashSet[A] =
+ override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash && key == this.key) null else this
override protected def filter0(p: A => Boolean, negate: Boolean, level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] =
@@ -320,10 +324,10 @@ object HashSet extends ImmutableSetFactory[HashSet] {
override def size = ks.size
- override def get0(key: A, hash: Int, level: Int): Boolean =
+ override protected def get0(key: A, hash: Int, level: Int): Boolean =
if (hash == this.hash) ks.contains(key) else false
- override def subsetOf0(that: HashSet[A], level: Int) = {
+ override protected def subsetOf0(that: HashSet[A], level: Int) = {
// we have to check each element
// we use get0 with our hash at the correct level instead of calling contains,
// which would not work since that might not be a top-level HashSet
@@ -331,11 +335,11 @@ object HashSet extends ImmutableSetFactory[HashSet] {
ks.forall(key => that.get0(key, hash, level))
}
- override def updated0(key: A, hash: Int, level: Int): HashSet[A] =
+ override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash) new HashSetCollision1(hash, ks + key)
else makeHashTrieSet(this.hash, this, hash, new HashSet1(key, hash), level)
- override def union0(that: LeafHashSet[A], level: Int): HashSet[A] = that match {
+ override private[immutable] def union0(that: LeafHashSet[A], level: Int): HashSet[A] = that match {
case that if that.hash != this.hash =>
// different hash code, so there is no need to investigate further.
// Just create a branch node containing the two.
@@ -368,7 +372,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
}
}
- override def union0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = that match {
+ override private[immutable] def union0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = that match {
case that: LeafHashSet[A] =>
// switch to the simpler Tree/Leaf implementation
this.union0(that, level)
@@ -425,7 +429,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
}
}
- override def removed0(key: A, hash: Int, level: Int): HashSet[A] =
+ override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] =
if (hash == this.hash) {
val ks1 = ks - key
ks1.size match {
@@ -522,7 +526,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
override def size = size0
- override def get0(key: A, hash: Int, level: Int): Boolean = {
+ override protected def get0(key: A, hash: Int, level: Int): Boolean = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
if (bitmap == - 1) {
@@ -534,7 +538,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
false
}
- override def updated0(key: A, hash: Int, level: Int): HashSet[A] = {
+ override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
val offset = Integer.bitCount(bitmap & (mask-1))
@@ -836,7 +840,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
case _ => this
}
- override def removed0(key: A, hash: Int, level: Int): HashSet[A] = {
+ override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
val offset = Integer.bitCount(bitmap & (mask-1))
@@ -873,7 +877,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
}
}
- override def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match {
+ override protected def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match {
case that: HashTrieSet[A] if this.size0 <= that.size0 =>
// create local mutable copies of members
var abm = this.bitmap
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index 75ddded6d2..c09328cae6 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -13,7 +13,7 @@ package immutable
import generic._
import mutable.{Builder, ListBuffer}
import scala.annotation.tailrec
-import java.io._
+import java.io.{ObjectOutputStream, ObjectInputStream}
/** A class for immutable linked lists representing ordered collections
* of elements of type `A`.
@@ -86,11 +86,9 @@ sealed abstract class List[+A] extends AbstractSeq[A]
with Product
with GenericTraversableTemplate[A, List]
with LinearSeqOptimized[A, List[A]]
- with Serializable {
+ with scala.Serializable {
override def companion: GenericCompanion[List] = List
- import scala.collection.{Iterable, Traversable, Seq, IndexedSeq}
-
def isEmpty: Boolean
def head: A
def tail: List[A]
@@ -265,8 +263,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
}
(b.toList, these)
}
-
- @noinline // TODO - fix optimizer bug that requires noinline (see SI-8334)
+
final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = {
if (bf eq List.ReusableCBF) {
if (this eq Nil) Nil.asInstanceOf[That] else {
@@ -284,8 +281,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
}
else super.map(f)
}
-
- @noinline // TODO - fix optimizer bug that requires noinline for map; applied here to be safe (see SI-8334)
+
final override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That]): That = {
if (bf eq List.ReusableCBF) {
if (this eq Nil) Nil.asInstanceOf[That] else {
@@ -314,8 +310,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
}
else super.collect(pf)
}
-
- @noinline // TODO - fix optimizer bug that requires noinline for map; applied here to be safe (see SI-8334)
+
final override def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]): That = {
if (bf eq List.ReusableCBF) {
if (this eq Nil) Nil.asInstanceOf[That] else {
@@ -455,7 +450,7 @@ object List extends SeqFactory[List] {
override def empty[A]: List[A] = Nil
override def apply[A](xs: A*): List[A] = xs.toList
-
+
private[collection] val partialNotApplied = new Function1[Any, Any] { def apply(x: Any): Any = this }
@SerialVersionUID(1L)
diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala
index 1eedf93269..e1bcc0711c 100644
--- a/src/library/scala/collection/immutable/ListMap.scala
+++ b/src/library/scala/collection/immutable/ListMap.scala
@@ -13,13 +13,16 @@ package collection
package immutable
import generic._
-import scala.annotation.{tailrec, bridge}
+import scala.annotation.tailrec
/** $factoryInfo
* @since 1
* @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#list_maps "Scala's Collection Library overview"]]
* section on `List Maps` for more information.
*
+ * Note that `ListMap` is built in reverse order to canonical traversal order (traversal order is oldest first).
+ * Thus, `head` and `tail` are O(n). To rapidly partition a `ListMap` into elements, use `last` and `init` instead. These are O(1).
+ *
* @define Coll immutable.ListMap
* @define coll immutable list map
*/
@@ -29,7 +32,13 @@ object ListMap extends ImmutableMapFactory[ListMap] {
new MapCanBuildFrom[A, B]
def empty[A, B]: ListMap[A, B] = EmptyListMap.asInstanceOf[ListMap[A, B]]
- private object EmptyListMap extends ListMap[Any, Nothing] { }
+ @SerialVersionUID(-8256686706655863282L)
+ private object EmptyListMap extends ListMap[Any, Nothing] {
+ override def apply(key: Any) = throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: Any) = false
+ override def last: (Any, Nothing) = throw new NoSuchElementException("Empty ListMap")
+ override def init: ListMap[Any, Nothing] = throw new NoSuchElementException("Empty ListMap")
+ }
}
/** This class implements immutable maps using a list-based data structure, which preserves insertion order.
@@ -49,8 +58,7 @@ object ListMap extends ImmutableMapFactory[ListMap] {
* @define willNotTerminateInf
*/
@SerialVersionUID(301002838095710379L)
-@deprecatedInheritance("The semantics of immutable collections makes inheriting from ListMap error-prone.", "2.11.0")
-class ListMap[A, +B]
+sealed class ListMap[A, +B]
extends AbstractMap[A, B]
with Map[A, B]
with MapLike[A, B, ListMap[A, B]]
@@ -159,7 +167,6 @@ extends AbstractMap[A, B]
*/
override def apply(k: A): B1 = apply0(this, k)
-
@tailrec private def apply0(cur: ListMap[A, B1], k: A): B1 =
if (cur.isEmpty) throw new NoSuchElementException("key not found: "+k)
else if (k == cur.key) cur.value
@@ -177,6 +184,15 @@ extends AbstractMap[A, B]
if (k == cur.key) Some(cur.value)
else if (cur.next.nonEmpty) get0(cur.next, k) else None
+
+ override def contains(key: A): Boolean = contains0(this, key)
+
+ @tailrec private def contains0(cur: ListMap[A, B1], k: A): Boolean =
+ if (k == cur.key) true
+ else if (cur.next.nonEmpty) contains0(cur.next, k)
+ else false
+
+
/** This method allows one to create a new map with an additional mapping
* from `key` to `value`. If the map contains already a mapping for `key`,
* it will be overridden by this function.
@@ -186,6 +202,7 @@ extends AbstractMap[A, B]
new m.Node[B2](k, v)
}
+
/** Creates a new mapping without the given `key`.
* If the map does not contain a mapping for the given key, the
* method returns the same map.
@@ -203,5 +220,9 @@ extends AbstractMap[A, B]
remove0(k, cur.next, cur::acc)
override protected def next: ListMap[A, B1] = ListMap.this
+
+ override def last: (A, B1) = (key, value)
+
+ override def init: ListMap[A, B1] = next
}
}
diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala
index adc975479a..d20e7bc6d2 100644
--- a/src/library/scala/collection/immutable/ListSet.scala
+++ b/src/library/scala/collection/immutable/ListSet.scala
@@ -11,8 +11,8 @@ package collection
package immutable
import generic._
-import scala.annotation.{tailrec, bridge}
-import mutable.{ ListBuffer, Builder }
+import scala.annotation.tailrec
+import mutable.{Builder, ReusableBuilder}
/** $factoryInfo
* @define Coll immutable.ListSet
@@ -32,8 +32,10 @@ object ListSet extends ImmutableSetFactory[ListSet] {
* a time to a list backed set puts the "squared" in N^2. There is a
* temporary space cost, but it's improbable a list backed set could
* become large enough for this to matter given its pricy element lookup.
+ *
+ * This builder is reusable.
*/
- class ListSetBuilder[Elem](initial: ListSet[Elem]) extends Builder[Elem, ListSet[Elem]] {
+ class ListSetBuilder[Elem](initial: ListSet[Elem]) extends ReusableBuilder[Elem, ListSet[Elem]] {
def this() = this(empty[Elem])
protected val elems = (new mutable.ListBuffer[Elem] ++= initial).reverse
protected val seen = new mutable.HashSet[Elem] ++= initial
@@ -65,8 +67,7 @@ object ListSet extends ImmutableSetFactory[ListSet] {
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@deprecatedInheritance("The semantics of immutable collections makes inheriting from ListSet error-prone.", "2.11.0")
-class ListSet[A] extends AbstractSet[A]
+sealed class ListSet[A] extends AbstractSet[A]
with Set[A]
with GenericSetTemplate[A, ListSet]
with SetLike[A, ListSet[A]]
@@ -179,6 +180,6 @@ class ListSet[A] extends AbstractSet[A]
override def tail: ListSet[A] = self
}
-
+
override def toSet[B >: A]: Set[B] = this.asInstanceOf[ListSet[B]]
}
diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala
index 2c5b444c70..6f135cd35f 100644
--- a/src/library/scala/collection/immutable/Map.scala
+++ b/src/library/scala/collection/immutable/Map.scala
@@ -94,6 +94,8 @@ object Map extends ImmutableMapFactory[Map] {
private object EmptyMap extends AbstractMap[Any, Nothing] with Map[Any, Nothing] with Serializable {
override def size: Int = 0
+ override def apply(key: Any) = throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: Any) = false
def get(key: Any): Option[Nothing] = None
def iterator: Iterator[(Any, Nothing)] = Iterator.empty
override def updated [B1] (key: Any, value: B1): Map[Any, B1] = new Map1(key, value)
@@ -103,6 +105,8 @@ object Map extends ImmutableMapFactory[Map] {
class Map1[A, +B](key1: A, value1: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 1
+ override def apply(key: A) = if (key == key1) value1 else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = key == key1
def get(key: A): Option[B] =
if (key == key1) Some(value1) else None
def iterator = Iterator((key1, value1))
@@ -119,6 +123,11 @@ object Map extends ImmutableMapFactory[Map] {
class Map2[A, +B](key1: A, value1: B, key2: A, value2: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 2
+ override def apply(key: A) =
+ if (key == key1) value1
+ else if (key == key2) value2
+ else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = (key == key1) || (key == key2)
def get(key: A): Option[B] =
if (key == key1) Some(value1)
else if (key == key2) Some(value2)
@@ -140,6 +149,12 @@ object Map extends ImmutableMapFactory[Map] {
class Map3[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 3
+ override def apply(key: A) =
+ if (key == key1) value1
+ else if (key == key2) value2
+ else if (key == key3) value3
+ else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = (key == key1) || (key == key2) || (key == key3)
def get(key: A): Option[B] =
if (key == key1) Some(value1)
else if (key == key2) Some(value2)
@@ -164,6 +179,13 @@ object Map extends ImmutableMapFactory[Map] {
class Map4[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B, key4: A, value4: B) extends AbstractMap[A, B] with Map[A, B] with Serializable {
override def size = 4
+ override def apply(key: A) =
+ if (key == key1) value1
+ else if (key == key2) value2
+ else if (key == key3) value3
+ else if (key == key4) value4
+ else throw new NoSuchElementException("key not found: " + key)
+ override def contains(key: A) = (key == key1) || (key == key2) || (key == key3) || (key == key4)
def get(key: A): Option[B] =
if (key == key1) Some(value1)
else if (key == key2) Some(value2)
diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala
index 11603a118b..c8d7519254 100644
--- a/src/library/scala/collection/immutable/NumericRange.scala
+++ b/src/library/scala/collection/immutable/NumericRange.scala
@@ -10,8 +10,6 @@ package scala
package collection
package immutable
-import mutable.{ Builder, ListBuffer }
-
// TODO: Now the specialization exists there is no clear reason to have
// separate classes for Range/NumericRange. Investigate and consolidate.
@@ -193,7 +191,7 @@ extends AbstractSeq[T] with IndexedSeq[T] with Serializable {
// Either numRangeElements or (head + last) must be even, so divide the even one before multiplying
val a = head.toLong
val b = last.toLong
- val ans =
+ val ans =
if ((numRangeElements & 1) == 0) (numRangeElements / 2) * (a + b)
else numRangeElements * {
// Sum is even, but we might overflow it, so divide in pieces and add back remainder
diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala
index 982c10687c..fab5ad47eb 100644
--- a/src/library/scala/collection/immutable/PagedSeq.scala
+++ b/src/library/scala/collection/immutable/PagedSeq.scala
@@ -12,8 +12,7 @@ package scala
package collection
package immutable
-import java.io._
-import scala.util.matching.Regex
+import java.io.{File, FileReader, Reader}
import scala.reflect.ClassTag
/** The `PagedSeq` object defines a lazy implementations of
diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala
index 53af3ce158..3ad6656636 100644
--- a/src/library/scala/collection/immutable/Queue.scala
+++ b/src/library/scala/collection/immutable/Queue.scala
@@ -12,7 +12,6 @@ package immutable
import generic._
import mutable.{ Builder, ListBuffer }
-import scala.annotation.tailrec
/** `Queue` objects implement data structures that allow to
* insert and retrieve elements in a first-in-first-out (FIFO) manner.
@@ -38,8 +37,7 @@ import scala.annotation.tailrec
*/
@SerialVersionUID(-7622936493364270175L)
-@deprecatedInheritance("The implementation details of immutable queues make inheriting from them unwise.", "2.11.0")
-class Queue[+A] protected(protected val in: List[A], protected val out: List[A])
+sealed class Queue[+A] protected(protected val in: List[A], protected val out: List[A])
extends AbstractSeq[A]
with LinearSeq[A]
with GenericTraversableTemplate[A, Queue]
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index ca6720da19..d3fe367e50 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -57,8 +57,7 @@ import scala.collection.parallel.immutable.ParRange
* and its complexity is O(1).
*/
@SerialVersionUID(7618862778670199309L)
-@deprecatedInheritance("The implementation details of Range makes inheriting from it unwise.", "2.11.0")
-class Range(val start: Int, val end: Int, val step: Int)
+sealed class Range(val start: Int, val end: Int, val step: Int)
extends scala.collection.AbstractSeq[Int]
with IndexedSeq[Int]
with scala.collection.CustomParallelizable[Int, ParRange]
@@ -198,7 +197,24 @@ extends scala.collection.AbstractSeq[Int]
copy(locationAfterN(n), end, step)
}
)
-
+
+ /** Creates a new range containing the elements starting at `from` up to but not including `until`.
+ *
+ * $doesNotUseBuilders
+ *
+ * @param from the element at which to start
+ * @param until the element at which to end (not included in the range)
+ * @return a new range consisting of a contiguous interval of values in the old range
+ */
+ override def slice(from: Int, until: Int): Range =
+ if (from <= 0) take(until)
+ else if (until >= numRangeElements && numRangeElements >= 0) drop(from)
+ else {
+ val fromValue = locationAfterN(from)
+ if (from >= until) newEmptyRange(fromValue)
+ else new Range.Inclusive(fromValue, locationAfterN(until-1), step)
+ }
+
/** Creates a new range containing all the elements of this range except the last one.
*
* $doesNotUseBuilders
diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala
index 031e5248c1..3a8ee8b0be 100644
--- a/src/library/scala/collection/immutable/Set.scala
+++ b/src/library/scala/collection/immutable/Set.scala
@@ -103,10 +103,11 @@ object Set extends ImmutableSetFactory[Set] {
if (p(elem1)) Some(elem1)
else None
}
+ override def head: A = elem1
+ override def tail: Set[A] = Set.empty
// Why is Set1 non-final? Need to fix that!
@deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set1[B]]
-
}
/** An optimized representation for immutable sets of size 2 */
@@ -138,6 +139,8 @@ object Set extends ImmutableSetFactory[Set] {
else if (p(elem2)) Some(elem2)
else None
}
+ override def head: A = elem1
+ override def tail: Set[A] = new Set1(elem2)
// Why is Set2 non-final? Need to fix that!
@deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set2[B]]
@@ -174,6 +177,8 @@ object Set extends ImmutableSetFactory[Set] {
else if (p(elem3)) Some(elem3)
else None
}
+ override def head: A = elem1
+ override def tail: Set[A] = new Set2(elem2, elem3)
// Why is Set3 non-final? Need to fix that!
@deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set3[B]]
@@ -212,6 +217,8 @@ object Set extends ImmutableSetFactory[Set] {
else if (p(elem4)) Some(elem4)
else None
}
+ override def head: A = elem1
+ override def tail: Set[A] = new Set3(elem2, elem3, elem4)
// Why is Set4 non-final? Need to fix that!
@deprecatedOverriding("This immutable set should do nothing on toSet but cast itself to a Set with a wider element type.", "2.11.8")
override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set4[B]]
diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala
index 682788e18e..0f3bd2e195 100644
--- a/src/library/scala/collection/immutable/SortedMap.scala
+++ b/src/library/scala/collection/immutable/SortedMap.scala
@@ -14,7 +14,6 @@ package immutable
import generic._
import mutable.Builder
-import scala.annotation.unchecked.uncheckedVariance
/** A map whose keys are sorted.
*
diff --git a/src/library/scala/collection/immutable/SortedSet.scala b/src/library/scala/collection/immutable/SortedSet.scala
index 4a8859a7ab..107f77f287 100644
--- a/src/library/scala/collection/immutable/SortedSet.scala
+++ b/src/library/scala/collection/immutable/SortedSet.scala
@@ -13,7 +13,6 @@ package collection
package immutable
import generic._
-import mutable.Builder
/** A subtrait of `collection.SortedSet` which represents sorted sets
* which cannot be mutated.
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index d3be809255..d135bb29a8 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -11,7 +11,7 @@ package collection
package immutable
import generic._
-import mutable.{Builder, StringBuilder, LazyBuilder, ListBuffer}
+import mutable.{Builder, StringBuilder, LazyBuilder}
import scala.annotation.tailrec
import Stream.cons
import scala.language.implicitConversions
@@ -198,16 +198,13 @@ import scala.language.implicitConversions
* @define orderDependentFold
* @define willTerminateInf Note: lazily evaluated; will terminate for infinite-sized collections.
*/
-@deprecatedInheritance("This class will be sealed.", "2.11.0")
-abstract class Stream[+A] extends AbstractSeq[A]
+sealed abstract class Stream[+A] extends AbstractSeq[A]
with LinearSeq[A]
with GenericTraversableTemplate[A, Stream]
with LinearSeqOptimized[A, Stream[A]]
- with Serializable {
-self =>
- override def companion: GenericCompanion[Stream] = Stream
+ with Serializable { self =>
- import scala.collection.{Traversable, Iterable, Seq, IndexedSeq}
+ override def companion: GenericCompanion[Stream] = Stream
/** Indicates whether or not the `Stream` is empty.
*
@@ -360,7 +357,7 @@ self =>
* `List(BigInt(12)) ++ fibs`.
*
* @tparam B The element type of the returned collection.'''That'''
- * @param that The [[scala.collection.GenTraversableOnce]] the be concatenated
+ * @param that The [[scala.collection.GenTraversableOnce]] to be concatenated
* to this `Stream`.
* @return A new collection containing the result of concatenating `this` with
* `that`.
@@ -499,80 +496,19 @@ self =>
)
else super.flatMap(f)(bf)
- /** Returns all the elements of this `Stream` that satisfy the predicate `p`
- * in a new `Stream` - i.e., it is still a lazy data structure. The order of
- * the elements is preserved
- *
- * @param p the predicate used to filter the stream.
- * @return the elements of this stream satisfying `p`.
- *
- * @example {{{
- * $naturalsEx
- * naturalsFrom(1) filter { _ % 5 == 0 } take 10 mkString(", ")
- * // produces "5, 10, 15, 20, 25, 30, 35, 40, 45, 50"
- * }}}
- */
- override def filter(p: A => Boolean): Stream[A] = {
+ override private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Stream[A] = {
// optimization: drop leading prefix of elems for which f returns false
// var rest = this dropWhile (!p(_)) - forget DRY principle - GC can't collect otherwise
var rest = this
- while (!rest.isEmpty && !p(rest.head)) rest = rest.tail
+ while (!rest.isEmpty && p(rest.head) == isFlipped) rest = rest.tail
// private utility func to avoid `this` on stack (would be needed for the lazy arg)
- if (rest.nonEmpty) Stream.filteredTail(rest, p)
+ if (rest.nonEmpty) Stream.filteredTail(rest, p, isFlipped)
else Stream.Empty
}
- 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[U](f: A => U) =
- 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)
@@ -1152,14 +1088,12 @@ object Stream extends SeqFactory[Stream] {
/** Creates a new builder for a stream */
def newBuilder[A]: Builder[A, Stream[A]] = new StreamBuilder[A]
- import scala.collection.{Iterable, Seq, IndexedSeq}
-
/** A builder for streams
* @note This builder is lazy only in the sense that it does not go downs the spine
* of traversables that are added as a whole. If more laziness can be achieved,
* this builder should be bypassed.
*/
- class StreamBuilder[A] extends scala.collection.mutable.LazyBuilder[A, Stream[A]] {
+ class StreamBuilder[A] extends LazyBuilder[A, Stream[A]] {
def result: Stream[A] = parts.toStream flatMap (_.toStream)
}
@@ -1295,13 +1229,36 @@ object Stream extends SeqFactory[Stream] {
else cons(start, range(start + step, end, step))
}
- private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean) = {
- cons(stream.head, stream.tail filter p)
+ private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean, isFlipped: Boolean) = {
+ cons(stream.head, stream.tail.filterImpl(p, isFlipped))
}
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/collection/immutable/StreamViewLike.scala b/src/library/scala/collection/immutable/StreamViewLike.scala
index c2eb85815d..4d7eaeff2a 100644
--- a/src/library/scala/collection/immutable/StreamViewLike.scala
+++ b/src/library/scala/collection/immutable/StreamViewLike.scala
@@ -53,6 +53,7 @@ extends SeqView[A, Coll]
/** boilerplate */
protected override def newForced[B](xs: => scala.collection.GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B]
protected override def newAppended[B >: A](that: scala.collection.GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B]
+ protected override def newPrepended[B >: A](that: scala.collection.GenTraversable[B]): Transformed[B] = new { protected[this] val fst = that } with AbstractTransformed[B] with Prepended[B]
protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B]
protected override def newFlatMapped[B](f: A => scala.collection.GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B]
protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered
@@ -67,7 +68,6 @@ extends SeqView[A, Coll]
protected override def newPatched[B >: A](_from: Int, _patch: scala.collection.GenSeq[B], _replaced: Int): Transformed[B] = {
new { val from = _from; val patch = _patch; val replaced = _replaced } with AbstractTransformed[B] with Patched[B]
}
- protected override def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with AbstractTransformed[B] with Prepended[B]
override def stringPrefix = "StreamView"
}
diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala
index 1b52e40b72..d92db68912 100644
--- a/src/library/scala/collection/immutable/StringLike.scala
+++ b/src/library/scala/collection/immutable/StringLike.scala
@@ -10,7 +10,7 @@ package scala
package collection
package immutable
-import mutable.{ ArrayBuilder, Builder }
+import mutable.Builder
import scala.util.matching.Regex
import scala.math.ScalaNumber
import scala.reflect.ClassTag
@@ -201,35 +201,64 @@ self =>
*/
def stripMargin: String = stripMargin('|')
- private def escape(ch: Char): String = "\\Q" + ch + "\\E"
-
- def split(separator: Char): Array[String] = {
- val thisString = toString
- var pos = thisString.indexOf(separator)
-
- if (pos != -1) {
- val res = new ArrayBuilder.ofRef[String]
-
- var prev = 0
- do {
- res += thisString.substring(prev, pos)
- prev = pos + 1
- pos = thisString.indexOf(separator, prev)
- } while (pos != -1)
-
- if (prev != thisString.length)
- res += thisString.substring(prev, thisString.length)
-
- val initialResult = res.result()
- pos = initialResult.length
- while (pos > 0 && initialResult(pos - 1).isEmpty) pos = pos - 1
- if (pos != initialResult.length) {
- val trimmed = new Array[String](pos)
- Array.copy(initialResult, 0, trimmed, 0, pos)
- trimmed
- } else initialResult
- } else Array[String](thisString)
- }
+ private def escape(ch: Char): String = if (
+ (ch >= 'a') && (ch <= 'z') ||
+ (ch >= 'A') && (ch <= 'Z') ||
+ (ch >= '0' && ch <= '9')) ch.toString
+ else "\\" + ch
+
+ /** Split this string around the separator character
+ *
+ * If this string is the empty string, returns an array of strings
+ * that contains a single empty string.
+ *
+ * If this string is not the empty string, returns an array containing
+ * the substrings terminated by the start of the string, the end of the
+ * string or the separator character, excluding empty trailing substrings
+ *
+ * If the separator character is a surrogate character, only split on
+ * matching surrogate characters if they are not part of a surrogate pair
+ *
+ * The behaviour follows, and is implemented in terms of <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String%29">String.split(re: String)</a>
+ *
+ *
+ * @example {{{
+ * "a.b".split('.') //returns Array("a", "b")
+ *
+ * //splitting the empty string always returns the array with a single
+ * //empty string
+ * "".split('.') //returns Array("")
+ *
+ * //only trailing empty substrings are removed
+ * "a.".split('.') //returns Array("a")
+ * ".a.".split('.') //returns Array("", "a")
+ * "..a..".split('.') //returns Array("", "", "a")
+ *
+ * //all parts are empty and trailing
+ * ".".split('.') //returns Array()
+ * "..".split('.') //returns Array()
+ *
+ * //surrogate pairs
+ * val high = 0xD852.toChar
+ * val low = 0xDF62.toChar
+ * val highstring = high.toString
+ * val lowstring = low.toString
+ *
+ * //well-formed surrogate pairs are not split
+ * val highlow = highstring + lowstring
+ * highlow.split(high) //returns Array(highlow)
+ *
+ * //bare surrogate characters are split
+ * val bare = "_" + highstring + "_"
+ * bare.split(high) //returns Array("_", "_")
+ *
+ * }}}
+ *
+ * @param separator the character used as a delimiter
+ */
+ def split(separator: Char): Array[String] =
+ toString.split(escape(separator))
+
@throws(classOf[java.util.regex.PatternSyntaxException])
def split(separators: Array[Char]): Array[String] = {
diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala
index b845b76026..2d1bf0f6b1 100644
--- a/src/library/scala/collection/immutable/TreeMap.scala
+++ b/src/library/scala/collection/immutable/TreeMap.scala
@@ -44,8 +44,7 @@ object TreeMap extends ImmutableSortedMapFactory[TreeMap] {
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@deprecatedInheritance("The implementation details of immutable tree maps make inheriting from them unwise.", "2.11.0")
-class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Ordering[A])
+final class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Ordering[A])
extends SortedMap[A, B]
with SortedMapLike[A, B, TreeMap[A, B]]
with MapLike[A, B, TreeMap[A, B]]
diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala
index 2800030d67..2cdf3b3521 100644
--- a/src/library/scala/collection/immutable/TreeSet.scala
+++ b/src/library/scala/collection/immutable/TreeSet.scala
@@ -49,8 +49,7 @@ object TreeSet extends ImmutableSortedSetFactory[TreeSet] {
* @define willNotTerminateInf
*/
@SerialVersionUID(-5685982407650748405L)
-@deprecatedInheritance("The implementation details of immutable tree sets make inheriting from them unwise.", "2.11.0")
-class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Ordering[A])
+final class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Ordering[A])
extends SortedSet[A] with SortedSetLike[A, TreeSet[A]] with Serializable {
if (ordering eq null)
diff --git a/src/library/scala/collection/immutable/Vector.scala b/src/library/scala/collection/immutable/Vector.scala
index 5a9734a99e..539ae9c387 100644
--- a/src/library/scala/collection/immutable/Vector.scala
+++ b/src/library/scala/collection/immutable/Vector.scala
@@ -13,7 +13,7 @@ package immutable
import scala.annotation.unchecked.uncheckedVariance
import scala.compat.Platform
import scala.collection.generic._
-import scala.collection.mutable.Builder
+import scala.collection.mutable.{Builder, ReusableBuilder}
import scala.collection.parallel.immutable.ParVector
/** Companion object to the Vector class
@@ -704,8 +704,8 @@ extends AbstractIterator[A]
}
}
-
-final class VectorBuilder[A]() extends Builder[A,Vector[A]] with VectorPointer[A @uncheckedVariance] {
+/** A class to build instances of `Vector`. This builder is reusable. */
+final class VectorBuilder[A]() extends ReusableBuilder[A,Vector[A]] with VectorPointer[A @uncheckedVariance] {
// possible alternative: start with display0 = null, blockIndex = -32, lo = 32
// to avoid allocating initial array if the result will be empty anyways
diff --git a/src/library/scala/collection/immutable/WrappedString.scala b/src/library/scala/collection/immutable/WrappedString.scala
index 7592316650..8726bd2ed9 100644
--- a/src/library/scala/collection/immutable/WrappedString.scala
+++ b/src/library/scala/collection/immutable/WrappedString.scala
@@ -29,8 +29,7 @@ import mutable.{Builder, StringBuilder}
* @define Coll `WrappedString`
* @define coll wrapped string
*/
-@deprecatedInheritance("Inherit from StringLike instead of WrappedString.", "2.11.0")
-class WrappedString(val self: String) extends AbstractSeq[Char] with IndexedSeq[Char] with StringLike[WrappedString] {
+final class WrappedString(val self: String) extends AbstractSeq[Char] with IndexedSeq[Char] with StringLike[WrappedString] {
override protected[this] def thisCollection: WrappedString = this
override protected[this] def toCollection(repr: WrappedString): WrappedString = repr
diff --git a/src/library/scala/collection/mutable/AVLTree.scala b/src/library/scala/collection/mutable/AVLTree.scala
deleted file mode 100644
index b63d0aae33..0000000000
--- a/src/library/scala/collection/mutable/AVLTree.scala
+++ /dev/null
@@ -1,250 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala
-package collection
-package mutable
-
-/**
- * An immutable AVL Tree implementation formerly used by mutable.TreeSet
- *
- * @author Lucien Pereira
- */
-@deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11.2")
-private[mutable] sealed trait AVLTree[+A] extends Serializable {
- def balance: Int
-
- def depth: Int
-
- def iterator[B >: A]: Iterator[B] = Iterator.empty
-
- def contains[B >: A](value: B, ordering: Ordering[B]): Boolean = false
-
- /**
- * Returns a new tree containing the given element.
- * Throws an IllegalArgumentException if element is already present.
- *
- */
- def insert[B >: A](value: B, ordering: Ordering[B]): AVLTree[B] = Node(value, Leaf, Leaf)
-
- /**
- * Return a new tree which not contains given element.
- *
- */
- def remove[B >: A](value: B, ordering: Ordering[B]): AVLTree[A] =
- throw new NoSuchElementException(String.valueOf(value))
-
- /**
- * Return a tuple containing the smallest element of the provided tree
- * and a new tree from which this element has been extracted.
- *
- */
- def removeMin[B >: A]: (B, AVLTree[B]) = sys.error("Should not happen.")
-
- /**
- * Return a tuple containing the biggest element of the provided tree
- * and a new tree from which this element has been extracted.
- *
- */
- def removeMax[B >: A]: (B, AVLTree[B]) = sys.error("Should not happen.")
-
- def rebalance[B >: A]: AVLTree[B] = this
-
- def leftRotation[B >: A]: Node[B] = sys.error("Should not happen.")
-
- def rightRotation[B >: A]: Node[B] = sys.error("Should not happen.")
-
- def doubleLeftRotation[B >: A]: Node[B] = sys.error("Should not happen.")
-
- def doubleRightRotation[B >: A]: Node[B] = sys.error("Should not happen.")
-}
-
-/**
- * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11.0")
- */
-private case object Leaf extends AVLTree[Nothing] {
- override val balance: Int = 0
-
- override val depth: Int = -1
-}
-
-/**
- * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11.0")
- */
-private case class Node[A](data: A, left: AVLTree[A], right: AVLTree[A]) extends AVLTree[A] {
- override val balance: Int = right.depth - left.depth
-
- override val depth: Int = math.max(left.depth, right.depth) + 1
-
- override def iterator[B >: A]: Iterator[B] = new AVLIterator(this)
-
- override def contains[B >: A](value: B, ordering: Ordering[B]) = {
- val ord = ordering.compare(value, data)
- if (0 == ord)
- true
- else if (ord < 0)
- left.contains(value, ordering)
- else
- right.contains(value, ordering)
- }
-
- /**
- * Returns a new tree containing the given element.
- * Throws an IllegalArgumentException if element is already present.
- *
- */
- override def insert[B >: A](value: B, ordering: Ordering[B]) = {
- val ord = ordering.compare(value, data)
- if (0 == ord)
- throw new IllegalArgumentException()
- else if (ord < 0)
- Node(data, left.insert(value, ordering), right).rebalance
- else
- Node(data, left, right.insert(value, ordering)).rebalance
- }
-
- /**
- * Return a new tree which not contains given element.
- *
- */
- override def remove[B >: A](value: B, ordering: Ordering[B]): AVLTree[A] = {
- val ord = ordering.compare(value, data)
- if(ord == 0) {
- if (Leaf == left) {
- if (Leaf == right) {
- Leaf
- } else {
- val (min, newRight) = right.removeMin
- Node(min, left, newRight).rebalance
- }
- } else {
- val (max, newLeft) = left.removeMax
- Node(max, newLeft, right).rebalance
- }
- } else if (ord < 0) {
- Node(data, left.remove(value, ordering), right).rebalance
- } else {
- Node(data, left, right.remove(value, ordering)).rebalance
- }
- }
-
- /**
- * Return a tuple containing the smallest element of the provided tree
- * and a new tree from which this element has been extracted.
- *
- */
- override def removeMin[B >: A]: (B, AVLTree[B]) = {
- if (Leaf == left)
- (data, right)
- else {
- val (min, newLeft) = left.removeMin
- (min, Node(data, newLeft, right).rebalance)
- }
- }
-
- /**
- * Return a tuple containing the biggest element of the provided tree
- * and a new tree from which this element has been extracted.
- *
- */
- override def removeMax[B >: A]: (B, AVLTree[B]) = {
- if (Leaf == right)
- (data, left)
- else {
- val (max, newRight) = right.removeMax
- (max, Node(data, left, newRight).rebalance)
- }
- }
-
- override def rebalance[B >: A] = {
- if (-2 == balance) {
- if (1 == left.balance)
- doubleRightRotation
- else
- rightRotation
- } else if (2 == balance) {
- if (-1 == right.balance)
- doubleLeftRotation
- else
- leftRotation
- } else {
- this
- }
- }
-
- override def leftRotation[B >: A] = {
- if (Leaf != right) {
- val r: Node[A] = right.asInstanceOf[Node[A]]
- Node(r.data, Node(data, left, r.left), r.right)
- } else sys.error("Should not happen.")
- }
-
- override def rightRotation[B >: A] = {
- if (Leaf != left) {
- val l: Node[A] = left.asInstanceOf[Node[A]]
- Node(l.data, l.left, Node(data, l.right, right))
- } else sys.error("Should not happen.")
- }
-
- override def doubleLeftRotation[B >: A] = {
- if (Leaf != right) {
- val r: Node[A] = right.asInstanceOf[Node[A]]
- // Let's save an instanceOf by 'inlining' the left rotation
- val rightRotated = r.rightRotation
- Node(rightRotated.data, Node(data, left, rightRotated.left), rightRotated.right)
- } else sys.error("Should not happen.")
- }
-
- override def doubleRightRotation[B >: A] = {
- if (Leaf != left) {
- val l: Node[A] = left.asInstanceOf[Node[A]]
- // Let's save an instanceOf by 'inlining' the right rotation
- val leftRotated = l.leftRotation
- Node(leftRotated.data, leftRotated.left, Node(data, leftRotated.right, right))
- } else sys.error("Should not happen.")
- }
-}
-
-/**
- * @deprecated("AVLTree and its related classes are being removed from the standard library since they're not different enough from RedBlackTree to justify keeping them.", "2.11.0")
- */
-private class AVLIterator[A](root: Node[A]) extends Iterator[A] {
- val stack = mutable.ArrayStack[Node[A]](root)
- diveLeft()
-
- private def diveLeft(): Unit = {
- if (Leaf != stack.head.left) {
- val left: Node[A] = stack.head.left.asInstanceOf[Node[A]]
- stack.push(left)
- diveLeft()
- }
- }
-
- private def engageRight(): Unit = {
- if (Leaf != stack.head.right) {
- val right: Node[A] = stack.head.right.asInstanceOf[Node[A]]
- stack.pop()
- stack.push(right)
- diveLeft()
- } else
- stack.pop()
- }
-
- override def hasNext: Boolean = !stack.isEmpty
-
- override def next(): A = {
- if (stack.isEmpty)
- throw new NoSuchElementException()
- else {
- val result = stack.head.data
- // Let's maintain stack for the next invocation
- engageRight()
- result
- }
- }
-}
diff --git a/src/library/scala/collection/mutable/AnyRefMap.scala b/src/library/scala/collection/mutable/AnyRefMap.scala
index 369d596ec3..6ff79dd1b8 100644
--- a/src/library/scala/collection/mutable/AnyRefMap.scala
+++ b/src/library/scala/collection/mutable/AnyRefMap.scala
@@ -27,10 +27,12 @@ import generic.CanBuildFrom
* rapidly as 2^30^ is approached.
*
*/
+@SerialVersionUID(1L)
final class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initialBufferSize: Int, initBlank: Boolean)
extends AbstractMap[K, V]
with Map[K, V]
with MapLike[K, V, AnyRefMap[K, V]]
+ with Serializable
{
import AnyRefMap._
def this() = this(AnyRefMap.exceptionDefault, 16, true)
@@ -335,6 +337,24 @@ extends AbstractMap[K, V]
arm
}
+ override def +[V1 >: V](kv: (K, V1)): AnyRefMap[K, V1] = {
+ val arm = clone().asInstanceOf[AnyRefMap[K, V1]]
+ arm += kv
+ arm
+ }
+
+ override def ++[V1 >: V](xs: GenTraversableOnce[(K, V1)]): AnyRefMap[K, V1] = {
+ val arm = clone().asInstanceOf[AnyRefMap[K, V1]]
+ xs.foreach(kv => arm += kv)
+ arm
+ }
+
+ override def updated[V1 >: V](key: K, value: V1): AnyRefMap[K, V1] = {
+ val arm = clone().asInstanceOf[AnyRefMap[K, V1]]
+ arm += (key, value)
+ arm
+ }
+
private[this] def foreachElement[A,B](elems: Array[AnyRef], f: A => B) {
var i,j = 0
while (i < _hashes.length & j < _size) {
@@ -399,7 +419,11 @@ object AnyRefMap {
private final val VacantBit = 0x40000000
private final val MissVacant = 0xC0000000
- private val exceptionDefault = (k: Any) => throw new NoSuchElementException(if (k == null) "(null)" else k.toString)
+ @SerialVersionUID(1L)
+ private class ExceptionDefault extends (Any => Nothing) with Serializable {
+ def apply(k: Any): Nothing = throw new NoSuchElementException(if (k == null) "(null)" else k.toString)
+ }
+ private val exceptionDefault = new ExceptionDefault
implicit def canBuildFrom[K <: AnyRef, V, J <: AnyRef, U]: CanBuildFrom[AnyRefMap[K,V], (J, U), AnyRefMap[J,U]] =
new CanBuildFrom[AnyRefMap[K,V], (J, U), AnyRefMap[J,U]] {
@@ -407,7 +431,11 @@ object AnyRefMap {
def apply(): AnyRefMapBuilder[J, U] = new AnyRefMapBuilder[J, U]
}
- final class AnyRefMapBuilder[K <: AnyRef, V] extends Builder[(K, V), AnyRefMap[K, V]] {
+ /** A builder for instances of `AnyRefMap`.
+ *
+ * This builder can be reused to create multiple instances.
+ */
+ final class AnyRefMapBuilder[K <: AnyRef, V] extends ReusableBuilder[(K, V), AnyRefMap[K, V]] {
private[collection] var elems: AnyRefMap[K, V] = new AnyRefMap[K, V]
def +=(entry: (K, V)): this.type = {
elems += entry
diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala
index 011fd415ee..167e04ccbd 100644
--- a/src/library/scala/collection/mutable/ArrayBuffer.scala
+++ b/src/library/scala/collection/mutable/ArrayBuffer.scala
@@ -149,13 +149,16 @@ class ArrayBuffer[A](override protected val initialSize: Int)
/** Removes the element on a given index position. It takes time linear in
* the buffer size.
*
- * @param n the index which refers to the first element to delete.
- * @param count the number of elements to delete
- * @throws IndexOutOfBoundsException if `n` is out of bounds.
+ * @param n the index which refers to the first element to remove.
+ * @param count the number of elements to remove.
+ * @throws IndexOutOfBoundsException if the index `n` is not in the valid range
+ * `0 <= n <= length - count` (with `count > 0`).
+ * @throws IllegalArgumentException if `count < 0`.
*/
override def remove(n: Int, count: Int) {
- require(count >= 0, "removing negative number of elements")
- if (n < 0 || n > size0 - count) throw new IndexOutOfBoundsException(n.toString)
+ if (count < 0) throw new IllegalArgumentException("removing negative number of elements: " + count.toString)
+ else if (count == 0) return // Did nothing
+ if (n < 0 || n > size0 - count) throw new IndexOutOfBoundsException("at " + n.toString + " deleting " + count.toString)
copy(n + count, n, size0 - (n + count))
reduceToSize(size0 - count)
}
diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala
index 6e53824cbe..d023110c1b 100644
--- a/src/library/scala/collection/mutable/ArrayBuilder.scala
+++ b/src/library/scala/collection/mutable/ArrayBuilder.scala
@@ -11,7 +11,6 @@ package collection
package mutable
import scala.reflect.ClassTag
-import scala.runtime.ScalaRunTime
/** A builder class for arrays.
*
@@ -19,7 +18,7 @@ import scala.runtime.ScalaRunTime
*
* @tparam T the type of the elements for the builder.
*/
-abstract class ArrayBuilder[T] extends Builder[T, Array[T]] with Serializable
+abstract class ArrayBuilder[T] extends ReusableBuilder[T, Array[T]] with Serializable
/** A companion object for array builders.
*
@@ -50,10 +49,11 @@ object ArrayBuilder {
/** A class for array builders for arrays of reference types.
*
+ * This builder can be reused.
+ *
* @tparam T type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound.
*/
- @deprecatedInheritance("ArrayBuilder.ofRef is an internal implementation not intended for subclassing.", "2.11.0")
- class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] {
+ final class ofRef[T <: AnyRef : ClassTag] extends ArrayBuilder[T] {
private var elems: Array[T] = _
private var capacity: Int = 0
@@ -99,12 +99,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -116,9 +117,8 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofRef"
}
- /** A class for array builders for arrays of `byte`s. */
- @deprecatedInheritance("ArrayBuilder.ofByte is an internal implementation not intended for subclassing.", "2.11.0")
- class ofByte extends ArrayBuilder[Byte] {
+ /** A class for array builders for arrays of `byte`s. It can be reused. */
+ final class ofByte extends ArrayBuilder[Byte] {
private var elems: Array[Byte] = _
private var capacity: Int = 0
@@ -164,12 +164,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -181,9 +182,8 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofByte"
}
- /** A class for array builders for arrays of `short`s. */
- @deprecatedInheritance("ArrayBuilder.ofShort is an internal implementation not intended for subclassing.", "2.11.0")
- class ofShort extends ArrayBuilder[Short] {
+ /** A class for array builders for arrays of `short`s. It can be reused. */
+ final class ofShort extends ArrayBuilder[Short] {
private var elems: Array[Short] = _
private var capacity: Int = 0
@@ -229,12 +229,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -246,9 +247,8 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofShort"
}
- /** A class for array builders for arrays of `char`s. */
- @deprecatedInheritance("ArrayBuilder.ofChar is an internal implementation not intended for subclassing.", "2.11.0")
- class ofChar extends ArrayBuilder[Char] {
+ /** A class for array builders for arrays of `char`s. It can be reused. */
+ final class ofChar extends ArrayBuilder[Char] {
private var elems: Array[Char] = _
private var capacity: Int = 0
@@ -294,12 +294,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -311,9 +312,8 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofChar"
}
- /** A class for array builders for arrays of `int`s. */
- @deprecatedInheritance("ArrayBuilder.ofInt is an internal implementation not intended for subclassing.", "2.11.0")
- class ofInt extends ArrayBuilder[Int] {
+ /** A class for array builders for arrays of `int`s. It can be reused. */
+ final class ofInt extends ArrayBuilder[Int] {
private var elems: Array[Int] = _
private var capacity: Int = 0
@@ -359,12 +359,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -376,9 +377,8 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofInt"
}
- /** A class for array builders for arrays of `long`s. */
- @deprecatedInheritance("ArrayBuilder.ofLong is an internal implementation not intended for subclassing.", "2.11.0")
- class ofLong extends ArrayBuilder[Long] {
+ /** A class for array builders for arrays of `long`s. It can be reused. */
+ final class ofLong extends ArrayBuilder[Long] {
private var elems: Array[Long] = _
private var capacity: Int = 0
@@ -424,12 +424,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -441,9 +442,8 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofLong"
}
- /** A class for array builders for arrays of `float`s. */
- @deprecatedInheritance("ArrayBuilder.ofFloat is an internal implementation not intended for subclassing.", "2.11.0")
- class ofFloat extends ArrayBuilder[Float] {
+ /** A class for array builders for arrays of `float`s. It can be reused. */
+ final class ofFloat extends ArrayBuilder[Float] {
private var elems: Array[Float] = _
private var capacity: Int = 0
@@ -489,12 +489,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -506,9 +507,8 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofFloat"
}
- /** A class for array builders for arrays of `double`s. */
- @deprecatedInheritance("ArrayBuilder.ofDouble is an internal implementation not intended for subclassing.", "2.11.0")
- class ofDouble extends ArrayBuilder[Double] {
+ /** A class for array builders for arrays of `double`s. It can be reused. */
+ final class ofDouble extends ArrayBuilder[Double] {
private var elems: Array[Double] = _
private var capacity: Int = 0
@@ -554,12 +554,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -571,7 +572,7 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofDouble"
}
- /** A class for array builders for arrays of `boolean`s. */
+ /** A class for array builders for arrays of `boolean`s. It can be reused. */
class ofBoolean extends ArrayBuilder[Boolean] {
private var elems: Array[Boolean] = _
@@ -618,12 +619,13 @@ object ArrayBuilder {
super.++=(xs)
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
@@ -635,65 +637,32 @@ object ArrayBuilder {
override def toString = "ArrayBuilder.ofBoolean"
}
- /** A class for array builders for arrays of `Unit` type. */
- @deprecatedInheritance("ArrayBuilder.ofUnit is an internal implementation not intended for subclassing.", "2.11.0")
- class ofUnit extends ArrayBuilder[Unit] {
+ /** A class for array builders for arrays of `Unit` type. It can be reused. */
+ final class ofUnit extends ArrayBuilder[Unit] {
- private var elems: Array[Unit] = _
- private var capacity: Int = 0
private var size: Int = 0
- private def mkArray(size: Int): Array[Unit] = {
- val newelems = new Array[Unit](size)
- if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
- newelems
- }
-
- private def resize(size: Int) {
- elems = mkArray(size)
- capacity = size
- }
-
- override def sizeHint(size: Int) {
- if (capacity < size) resize(size)
- }
-
- private def ensureSize(size: Int) {
- if (capacity < size || capacity == 0) {
- var newsize = if (capacity == 0) 16 else capacity * 2
- while (newsize < size) newsize *= 2
- resize(newsize)
- }
- }
-
def +=(elem: Unit): this.type = {
- ensureSize(size + 1)
- elems(size) = elem
size += 1
this
}
- override def ++=(xs: TraversableOnce[Unit]): this.type = xs match {
- case xs: WrappedArray.ofUnit =>
- ensureSize(this.size + xs.length)
- Array.copy(xs.array, 0, elems, this.size, xs.length)
- size += xs.length
- this
- case _ =>
- super.++=(xs)
+ override def ++=(xs: TraversableOnce[Unit]): this.type = {
+ size += xs.size
+ this
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
- else mkArray(size)
+ val ans = new Array[Unit](size)
+ var i = 0
+ while (i < size) { ans(i) = (); i += 1 }
+ ans
}
override def equals(other: Any): Boolean = other match {
- case x: ofUnit => (size == x.size) && (elems == x.elems)
+ case x: ofUnit => (size == x.size)
case _ => false
}
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 00491ef20e..507585b9cf 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -10,9 +10,7 @@ package scala
package collection
package mutable
-import scala.compat.Platform.arraycopy
import scala.reflect.ClassTag
-import scala.runtime.ScalaRunTime._
import parallel.mutable.ParArray
/** This class serves as a wrapper for `Array`s with all the operations found in
@@ -33,20 +31,18 @@ import parallel.mutable.ParArray
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@deprecatedInheritance("ArrayOps will be sealed to facilitate greater flexibility with array/collections integration in future releases.", "2.11.0")
-trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] {
+sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] {
private def elementClass: Class[_] =
- arrayElementClass(repr.getClass)
+ repr.getClass.getComponentType
override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) {
- var l = math.min(len, repr.length)
- if (xs.length - start < l) l = xs.length - start max 0
- Array.copy(repr, 0, xs, start, l)
+ val l = len min repr.length min (xs.length - start)
+ if (l > 0) Array.copy(repr, 0, xs, start, l)
}
override def toArray[U >: T : ClassTag]: Array[U] = {
- val thatElementClass = arrayElementClass(implicitly[ClassTag[U]])
+ val thatElementClass = implicitly[ClassTag[U]].runtimeClass
if (elementClass eq thatElementClass)
repr.asInstanceOf[Array[U]]
else
@@ -94,7 +90,7 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass))
if (isEmpty) bb.result()
else {
- def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass)))
+ def mkRowBuilder() = Array.newBuilder(ClassTag[U](elementClass.getComponentType))
val bs = asArray(head) map (_ => mkRowBuilder())
for (xs <- this) {
var i = 0
@@ -107,9 +103,9 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
bb.result()
}
}
-
+
/** Converts an array of pairs into an array of first elements and an array of second elements.
- *
+ *
* @tparam T1 the type of the first half of the element pairs
* @tparam T2 the type of the second half of the element pairs
* @param asPair an implicit conversion which asserts that the element type
@@ -135,9 +131,9 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
}
(a1, a2)
}
-
+
/** Converts an array of triples into three arrays, one containing the elements from each position of the triple.
- *
+ *
* @tparam T1 the type of the first of three elements in the triple
* @tparam T2 the type of the second of three elements in the triple
* @tparam T3 the type of the third of three elements in the triple
@@ -169,7 +165,7 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
}
(a1, a2, a3)
}
-
+
def seq = thisCollection
@@ -187,7 +183,7 @@ object ArrayOps {
override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr)
override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr)
- override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](arrayElementClass(repr.getClass)))
+ override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](repr.getClass.getComponentType))
def length: Int = repr.length
def apply(index: Int): T = repr(index)
diff --git a/src/library/scala/collection/mutable/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala
index ddb48627af..1e82096baf 100644
--- a/src/library/scala/collection/mutable/ArraySeq.scala
+++ b/src/library/scala/collection/mutable/ArraySeq.scala
@@ -87,7 +87,7 @@ extends AbstractSeq[A]
*/
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
val len1 = len min (xs.length - start) min length
- Array.copy(array, 0, xs, start, len1)
+ if (len1 > 0) Array.copy(array, 0, xs, start, len1)
}
override def clone(): ArraySeq[A] = {
diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala
index 8ff128c026..951a90b084 100644
--- a/src/library/scala/collection/mutable/ArrayStack.scala
+++ b/src/library/scala/collection/mutable/ArrayStack.scala
@@ -64,9 +64,10 @@ object ArrayStack extends SeqFactory[ArrayStack] {
class ArrayStack[T] private(private var table : Array[AnyRef],
private var index : Int)
extends AbstractSeq[T]
- with Seq[T]
- with SeqLike[T, ArrayStack[T]]
+ with IndexedSeq[T]
+ with IndexedSeqLike[T, ArrayStack[T]]
with GenericTraversableTemplate[T, ArrayStack]
+ with IndexedSeqOptimized[T, ArrayStack[T]]
with Cloneable[ArrayStack[T]]
with Builder[T, ArrayStack[T]]
with Serializable
@@ -224,7 +225,7 @@ extends AbstractSeq[T]
/** Creates and iterator over the stack in LIFO order.
* @return an iterator over the elements of the stack.
*/
- def iterator: Iterator[T] = new AbstractIterator[T] {
+ override def iterator: Iterator[T] = new AbstractIterator[T] {
var currentIndex = index
def hasNext = currentIndex > 0
def next() = {
diff --git a/src/library/scala/collection/mutable/BitSet.scala b/src/library/scala/collection/mutable/BitSet.scala
index e92d48cfeb..feef694e01 100644
--- a/src/library/scala/collection/mutable/BitSet.scala
+++ b/src/library/scala/collection/mutable/BitSet.scala
@@ -13,7 +13,7 @@ package collection
package mutable
import generic._
-import BitSetLike.{LogWL, MaxSize, updateArray}
+import BitSetLike.{LogWL, MaxSize}
/** A class for mutable bitsets.
*
@@ -56,7 +56,7 @@ class BitSet(protected final var elems: Array[Long]) extends AbstractSet[Int]
@deprecatedOverriding("Internal implementation does not admit sensible overriding of this method.", "2.11.0")
protected def nwords = elems.length
-
+
@deprecatedOverriding("Internal implementation does not admit sensible overriding of this method.", "2.11.0")
protected def word(idx: Int): Long =
if (idx < nwords) elems(idx) else 0L
@@ -100,7 +100,7 @@ class BitSet(protected final var elems: Array[Long]) extends AbstractSet[Int]
@deprecatedOverriding("Override add to prevent += and add from exhibiting different behavior.", "2.11.0")
def += (elem: Int): this.type = { add(elem); this }
-
+
@deprecatedOverriding("Override add to prevent += and add from exhibiting different behavior.", "2.11.0")
def -= (elem: Int): this.type = { remove(elem); this }
diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala
index 3c57387c03..98c9771a05 100644
--- a/src/library/scala/collection/mutable/BufferLike.scala
+++ b/src/library/scala/collection/mutable/BufferLike.scala
@@ -14,7 +14,7 @@ package mutable
import generic._
import script._
-import scala.annotation.{migration, bridge}
+import scala.annotation.migration
/** A template trait for buffers of type `Buffer[A]`.
*
@@ -105,15 +105,18 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
*/
def remove(n: Int): A
- /** Removes a number of elements from a given index position.
+ /** Removes a number of elements from a given index position. Subclasses of `BufferLike`
+ * will typically override this method to provide better performance than `count`
+ * successive calls to single-element `remove`.
*
* @param n the index which refers to the first element to remove.
* @param count the number of elements to remove.
* @throws IndexOutOfBoundsException if the index `n` is not in the valid range
- * `0 <= n <= length - count`.
+ * `0 <= n <= length - count` (with `count > 0`).
* @throws IllegalArgumentException if `count < 0`.
*/
def remove(n: Int, count: Int) {
+ if (count < 0) throw new IllegalArgumentException("removing negative number of elements: " + count.toString)
for (i <- 0 until count) remove(n)
}
@@ -211,13 +214,6 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
*/
override def stringPrefix: String = "Buffer"
- /** Returns the current evolving(!) state of this buffer as a read-only sequence.
- *
- * @return A sequence that forwards to this buffer for all its operations.
- */
- @deprecated("The returned sequence changes as this buffer is mutated. For an immutable copy, use, e.g., toList.", "2.11.0")
- def readOnly: scala.collection.Seq[A] = toSeq
-
/** Creates a new collection containing both the elements of this collection and the provided
* traversable object.
*
diff --git a/src/library/scala/collection/mutable/BufferProxy.scala b/src/library/scala/collection/mutable/BufferProxy.scala
index d9632cce91..2d52831d37 100644
--- a/src/library/scala/collection/mutable/BufferProxy.scala
+++ b/src/library/scala/collection/mutable/BufferProxy.scala
@@ -43,8 +43,6 @@ trait BufferProxy[A] extends Buffer[A] with Proxy {
*/
def +=(elem: A): this.type = { self.+=(elem); this }
- override def readOnly = self.readOnly
-
/** Appends a number of elements provided by a traversable object.
*
* @param xs the traversable object.
diff --git a/src/library/scala/collection/mutable/Builder.scala b/src/library/scala/collection/mutable/Builder.scala
index 75560580cc..8d6a0ec69d 100644
--- a/src/library/scala/collection/mutable/Builder.scala
+++ b/src/library/scala/collection/mutable/Builder.scala
@@ -18,6 +18,14 @@ import generic._
* elements to the builder with `+=` and then converting to the required
* collection type with `result`.
*
+ * One cannot assume that a single `Builder` can build more than one
+ * instance of the desired collection. Particular subclasses may allow
+ * such behavior. Otherwise, `result` should be treated as a terminal
+ * operation: after it is called, no further methods should be called on
+ * the builder. Extend the [[collection.mutable.ReusableBuilder]] trait
+ * instead of `Builder` for builders that may be reused to build multiple
+ * instances.
+ *
* @tparam Elem the type of elements that get added to the builder.
* @tparam To the type of collection that it produced.
*
@@ -36,8 +44,10 @@ trait Builder[-Elem, +To] extends Growable[Elem] {
*/
def clear()
- /** Produces a collection from the added elements.
- * The builder's contents are undefined after this operation.
+ /** Produces a collection from the added elements. This is a terminal operation:
+ * the builder's contents are undefined after this operation, and no further
+ * methods should be called.
+ *
* @return a collection containing the elements added to this builder.
*/
def result(): To
@@ -112,6 +122,8 @@ trait Builder[-Elem, +To] extends Growable[Elem] {
* @tparam NewTo the type of collection returned by `f`.
* @return a new builder which is the same as the current builder except
* that a transformation function is applied to this builder's result.
+ *
+ * @note The original builder should no longer be used after `mapResult` is called.
*/
def mapResult[NewTo](f: To => NewTo): Builder[Elem, NewTo] =
new Builder[Elem, NewTo] with Proxy {
diff --git a/src/library/scala/collection/mutable/GrowingBuilder.scala b/src/library/scala/collection/mutable/GrowingBuilder.scala
index c4b5e546aa..27d554d98e 100644
--- a/src/library/scala/collection/mutable/GrowingBuilder.scala
+++ b/src/library/scala/collection/mutable/GrowingBuilder.scala
@@ -15,6 +15,8 @@ import generic._
/** The canonical builder for collections that are growable, i.e. that support an
* efficient `+=` method which adds an element to the collection.
*
+ * GrowableBuilders can produce only a single instance of the collection they are growing.
+ *
* @author Paul Phillips
* @version 2.8
* @since 2.8
@@ -25,6 +27,6 @@ import generic._
class GrowingBuilder[Elem, To <: Growable[Elem]](empty: To) extends Builder[Elem, To] {
protected var elems: To = empty
def +=(x: Elem): this.type = { elems += x; this }
- def clear() { elems = empty }
+ def clear() { empty.clear }
def result: To = elems
}
diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala
index 7acdeeff18..b525baaf5f 100644
--- a/src/library/scala/collection/mutable/IndexedSeqView.scala
+++ b/src/library/scala/collection/mutable/IndexedSeqView.scala
@@ -15,7 +15,6 @@ package mutable
import generic._
import TraversableView.NoBuilder
-import scala.language.implicitConversions
/** A non-strict view of a mutable `IndexedSeq`.
* $viewInfo
diff --git a/src/library/scala/collection/mutable/LazyBuilder.scala b/src/library/scala/collection/mutable/LazyBuilder.scala
index ebee38b77f..f0a5e6971a 100644
--- a/src/library/scala/collection/mutable/LazyBuilder.scala
+++ b/src/library/scala/collection/mutable/LazyBuilder.scala
@@ -13,12 +13,14 @@ package mutable
/** A builder that constructs its result lazily. Iterators or iterables to
* be added to this builder with `++=` are not evaluated until `result` is called.
*
+ * This builder can be reused.
+ *
* @since 2.8
*
* @tparam Elem type of the elements for this builder.
* @tparam To type of the collection this builder builds.
*/
-abstract class LazyBuilder[Elem, +To] extends Builder[Elem, To] {
+abstract class LazyBuilder[Elem, +To] extends ReusableBuilder[Elem, To] {
/** The different segments of elements to be added to the builder, represented as iterators */
protected var parts = new ListBuffer[TraversableOnce[Elem]]
def +=(x: Elem): this.type = { parts += List(x); this }
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index f9bab40a1e..02fcced3ac 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -12,8 +12,7 @@ package mutable
import generic._
import immutable.{List, Nil, ::}
-import java.io._
-import scala.annotation.migration
+import java.io.{ObjectOutputStream, ObjectInputStream}
/** A `Buffer` implementation backed by a list. It provides constant time
* prepend and append. Most other operations are linear.
@@ -47,7 +46,7 @@ final class ListBuffer[A]
with Buffer[A]
with GenericTraversableTemplate[A, ListBuffer]
with BufferLike[A, ListBuffer[A]]
- with Builder[A, List[A]]
+ with ReusableBuilder[A, List[A]]
with SeqForwarder[A]
with Serializable
{
@@ -262,13 +261,14 @@ final class ListBuffer[A]
*
* @param n the index which refers to the first element to remove.
* @param count the number of elements to remove.
+ * @throws IndexOutOfBoundsException if the index `n` is not in the valid range
+ * `0 <= n <= length - count` (with `count > 0`).
+ * @throws IllegalArgumentException if `count < 0`.
*/
- @migration("Invalid input values will be rejected in future releases.", "2.11")
override def remove(n: Int, count: Int) {
- if (n >= len)
- return
- if (count < 0)
- throw new IllegalArgumentException(s"removing negative number ($count) of elements")
+ if (count < 0) throw new IllegalArgumentException("removing negative number of elements: " + count.toString)
+ else if (count == 0) return // Nothing to do
+ if (n < 0 || n > len - count) throw new IndexOutOfBoundsException("at " + n.toString + " deleting " + count.toString)
if (exported) copy()
val n1 = n max 0
val count1 = count min (len - n1)
@@ -297,6 +297,10 @@ final class ListBuffer[A]
// Implementation of abstract method in Builder
+ /** Returns the accumulated `List`.
+ *
+ * This method may be called multiple times to obtain snapshots of the list in different stages of construction.
+ */
def result: List[A] = toList
/** Converts this buffer to a list. Takes constant time. The buffer is
@@ -408,9 +412,6 @@ final class ListBuffer[A]
}
}
- @deprecated("The result of this method will change along with this buffer, which is often not what's expected.", "2.11.0")
- override def readOnly: List[A] = start
-
// Private methods
/** Copy contents of this buffer */
@@ -426,7 +427,7 @@ final class ListBuffer[A]
}
override def equals(that: Any): Boolean = that match {
- case that: ListBuffer[_] => this.readOnly equals that.readOnly
+ case that: ListBuffer[_] => this.start equals that.start
case _ => super.equals(that)
}
diff --git a/src/library/scala/collection/mutable/LongMap.scala b/src/library/scala/collection/mutable/LongMap.scala
index 198e34bd29..ecbb1952af 100644
--- a/src/library/scala/collection/mutable/LongMap.scala
+++ b/src/library/scala/collection/mutable/LongMap.scala
@@ -415,6 +415,24 @@ extends AbstractMap[Long, V]
lm
}
+ override def +[V1 >: V](kv: (Long, V1)): LongMap[V1] = {
+ val lm = clone().asInstanceOf[LongMap[V1]]
+ lm += kv
+ lm
+ }
+
+ override def ++[V1 >: V](xs: GenTraversableOnce[(Long, V1)]): LongMap[V1] = {
+ val lm = clone().asInstanceOf[LongMap[V1]]
+ xs.foreach(kv => lm += kv)
+ lm
+ }
+
+ override def updated[V1 >: V](key: Long, value: V1): LongMap[V1] = {
+ val lm = clone().asInstanceOf[LongMap[V1]]
+ lm += (key, value)
+ lm
+ }
+
/** Applies a function to all keys of this map. */
def foreachKey[A](f: Long => A) {
if ((extraKeys & 1) == 1) f(0L)
@@ -501,7 +519,11 @@ object LongMap {
def apply(): LongMapBuilder[U] = new LongMapBuilder[U]
}
- final class LongMapBuilder[V] extends Builder[(Long, V), LongMap[V]] {
+ /** A builder for instances of `LongMap`.
+ *
+ * This builder can be reused to create multiple instances.
+ */
+ final class LongMapBuilder[V] extends ReusableBuilder[(Long, V), LongMap[V]] {
private[collection] var elems: LongMap[V] = new LongMap[V]
def +=(entry: (Long, V)): this.type = {
elems += entry
@@ -541,7 +563,7 @@ object LongMap {
/** Creates a new `LongMap` from keys and values.
* Equivalent to but more efficient than `LongMap((keys zip values): _*)`.
*/
- def fromZip[V](keys: Iterable[Long], values: Iterable[V]): LongMap[V] = {
+ def fromZip[V](keys: collection.Iterable[Long], values: collection.Iterable[V]): LongMap[V] = {
val sz = math.min(keys.size, values.size)
val lm = new LongMap[V](sz * 2)
val ki = keys.iterator
diff --git a/src/library/scala/collection/mutable/MapBuilder.scala b/src/library/scala/collection/mutable/MapBuilder.scala
index a5a6b12ea9..cfc3079f41 100644
--- a/src/library/scala/collection/mutable/MapBuilder.scala
+++ b/src/library/scala/collection/mutable/MapBuilder.scala
@@ -23,7 +23,7 @@ package mutable
* @since 2.8
*/
class MapBuilder[A, B, Coll <: scala.collection.GenMap[A, B] with scala.collection.GenMapLike[A, B, Coll]](empty: Coll)
-extends Builder[(A, B), Coll] {
+extends ReusableBuilder[(A, B), Coll] {
protected var elems: Coll = empty
def +=(x: (A, B)): this.type = {
elems = (elems + x).asInstanceOf[Coll]
diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala
index 44af886cf5..949e5e3536 100644
--- a/src/library/scala/collection/mutable/MapLike.scala
+++ b/src/library/scala/collection/mutable/MapLike.scala
@@ -61,6 +61,18 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
override protected[this] def newBuilder: Builder[(A, B), This] = empty
protected[this] override def parCombiner = ParMap.newCombiner[A, B]
+
+ /** Converts this $coll to a sequence.
+ *
+ * ```Note```: assumes a fast `size` method. Subclasses should override if this is not true.
+ */
+ override def toSeq: collection.Seq[(A, B)] = {
+ // ArrayBuffer for efficiency, preallocated to the right size.
+ val result = new ArrayBuffer[(A, B)](size)
+ foreach(result += _)
+ result
+ }
+
/** Adds a new key/value pair to this map and optionally returns previously bound value.
* If the map already contains a
diff --git a/src/library/scala/collection/mutable/MutableList.scala b/src/library/scala/collection/mutable/MutableList.scala
index 646023f469..a333eedb1a 100644
--- a/src/library/scala/collection/mutable/MutableList.scala
+++ b/src/library/scala/collection/mutable/MutableList.scala
@@ -11,7 +11,7 @@ package collection
package mutable
import generic._
-import immutable.{List, Nil}
+import immutable.List
/**
* This class is used internally to represent mutable lists. It is the
diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala
index 2562f60355..d5b7673c37 100644
--- a/src/library/scala/collection/mutable/PriorityQueue.scala
+++ b/src/library/scala/collection/mutable/PriorityQueue.scala
@@ -16,7 +16,7 @@ import generic._
* To prioritize elements of type A there must be an implicit
* Ordering[A] available at creation.
*
- * Only the `dequeue` and `dequeueAll` methods will return methods in priority
+ * Only the `dequeue` and `dequeueAll` methods will return elements in priority
* order (while removing elements from the heap). Standard collection methods
* including `drop`, `iterator`, and `toString` will remove or traverse the heap
* in whichever order seems most convenient.
@@ -46,8 +46,7 @@ import generic._
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@deprecatedInheritance("PriorityQueue is not intended to be subclassed due to extensive private implementation details.", "2.11.0")
-class PriorityQueue[A](implicit val ord: Ordering[A])
+sealed class PriorityQueue[A](implicit val ord: Ordering[A])
extends AbstractIterable[A]
with Iterable[A]
with GenericOrderedTraversableTemplate[A, PriorityQueue]
@@ -201,9 +200,7 @@ class PriorityQueue[A](implicit val ord: Ordering[A])
* @return A reversed priority queue.
*/
def reverse = {
- val revq = new PriorityQueue[A]()(new scala.math.Ordering[A] {
- def compare(x: A, y: A) = ord.compare(y, x)
- })
+ val revq = new PriorityQueue[A]()(ord.reverse)
for (i <- 1 until resarr.length) revq += resarr(i)
revq
}
@@ -266,3 +263,176 @@ object PriorityQueue extends OrderedTraversableFactory[PriorityQueue] {
implicit def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, PriorityQueue[A]] = new GenericCanBuildFrom[A]
}
+
+/** This class servers as a proxy for priority queues. The
+ * elements of the queue have to be ordered in terms of the
+ * `Ordered[T]` class.
+ *
+ * @author Matthias Zenger
+ * @version 1.0, 03/05/2004
+ * @since 1
+ */
+@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
+sealed abstract class PriorityQueueProxy[A](implicit ord: Ordering[A]) extends PriorityQueue[A]
+ with Proxy
+{
+ def self: PriorityQueue[A]
+
+ /** Creates a new iterator over all elements contained in this
+ * object.
+ *
+ * @return the new iterator
+ */
+ override def iterator: Iterator[A] = self.iterator
+
+ /** Returns the length of this priority queue.
+ */
+ override def length: Int = self.length
+
+ /** Checks if the queue is empty.
+ *
+ * @return true, iff there is no element in the queue.
+ */
+ override def isEmpty: Boolean = self.isEmpty
+
+ /** Inserts a single element into the priority queue.
+ *
+ * @param elem the element to insert
+ */
+ override def +=(elem: A): this.type = { self += elem; this }
+
+ /** Adds all elements provided by an iterator into the priority queue.
+ *
+ * @param it an iterator
+ */
+ override def ++=(it: TraversableOnce[A]): this.type = {
+ self ++= it
+ this
+ }
+
+ /** Adds all elements to the queue.
+ *
+ * @param elems the elements to add.
+ */
+ override def enqueue(elems: A*): Unit = self ++= elems
+
+ /** Returns the element with the highest priority in the queue,
+ * and removes this element from the queue.
+ *
+ * @return the element with the highest priority.
+ */
+ override def dequeue(): A = self.dequeue()
+
+ /** Returns the element with the highest priority in the queue,
+ * or throws an error if there is no element contained in the queue.
+ *
+ * @return the element with the highest priority.
+ */
+ override def head: A = self.head
+
+ /** Removes all elements from the queue. After this operation is completed,
+ * the queue will be empty.
+ */
+ override def clear(): Unit = self.clear()
+
+ /** Returns a regular queue containing the same elements.
+ */
+ override def toQueue: Queue[A] = self.toQueue
+
+ /** This method clones the priority queue.
+ *
+ * @return a priority queue with the same elements.
+ */
+ override def clone(): PriorityQueue[A] = new PriorityQueueProxy[A] {
+ def self = PriorityQueueProxy.this.self.clone()
+ }
+}
+
+
+/** This class implements synchronized priority queues using a binary heap.
+ * The elements of the queue have to be ordered in terms of the `Ordered[T]` class.
+ *
+ * @tparam A type of the elements contained in this synchronized priority queue
+ * @param ord implicit ordering used to compared elements of type `A`
+ *
+ * @author Matthias Zenger
+ * @version 1.0, 03/05/2004
+ * @since 1
+ * @define Coll `SynchronizedPriorityQueue`
+ * @define coll synchronized priority queue
+ */
+@deprecated("Comprehensive synchronization via selective overriding of methods is inherently unreliable. Consider java.util.concurrent.ConcurrentSkipListSet as an alternative.", "2.11.0")
+sealed class SynchronizedPriorityQueue[A](implicit ord: Ordering[A]) extends PriorityQueue[A] {
+
+ /** Checks if the queue is empty.
+ *
+ * @return true, iff there is no element in the queue.
+ */
+ override def isEmpty: Boolean = synchronized { super.isEmpty }
+
+ /** Inserts a single element into the priority queue.
+ *
+ * @param elem the element to insert
+ */
+ override def +=(elem: A): this.type = {
+ synchronized {
+ super.+=(elem)
+ }
+ this
+ }
+
+ /** Adds all elements of a traversable object into the priority queue.
+ *
+ * @param xs a traversable object
+ */
+ override def ++=(xs: TraversableOnce[A]): this.type = {
+ synchronized {
+ super.++=(xs)
+ }
+ this
+ }
+
+ /** Adds all elements to the queue.
+ *
+ * @param elems the elements to add.
+ */
+ override def enqueue(elems: A*): Unit = synchronized { super.++=(elems) }
+
+ /** Returns the element with the highest priority in the queue,
+ * and removes this element from the queue.
+ *
+ * @return the element with the highest priority.
+ */
+ override def dequeue(): A = synchronized { super.dequeue() }
+
+ /** Returns the element with the highest priority in the queue,
+ * or throws an error if there is no element contained in the queue.
+ *
+ * @return the element with the highest priority.
+ */
+ override def head: A = synchronized { super.head }
+
+ /** Removes all elements from the queue. After this operation is completed,
+ * the queue will be empty.
+ */
+ override def clear(): Unit = synchronized { super.clear() }
+
+ /** Returns an iterator which yield all the elements of the priority
+ * queue in descending priority order.
+ *
+ * @return an iterator over all elements sorted in descending order.
+ */
+ override def iterator: Iterator[A] = synchronized { super.iterator }
+
+ /** Checks if two queues are structurally identical.
+ *
+ * @return true, iff both queues contain the same sequence of elements.
+ */
+ override def equals(that: Any): Boolean = synchronized { super.equals(that) }
+
+ /** Returns a textual representation of a queue as a string.
+ *
+ * @return the string representation of this queue.
+ */
+ override def toString(): String = synchronized { super.toString() }
+}
diff --git a/src/library/scala/collection/mutable/PriorityQueueProxy.scala b/src/library/scala/collection/mutable/PriorityQueueProxy.scala
deleted file mode 100644
index b24551a6b7..0000000000
--- a/src/library/scala/collection/mutable/PriorityQueueProxy.scala
+++ /dev/null
@@ -1,96 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-package scala
-package collection
-package mutable
-
-/** This class servers as a proxy for priority queues. The
- * elements of the queue have to be ordered in terms of the
- * `Ordered[T]` class.
- *
- * @author Matthias Zenger
- * @version 1.0, 03/05/2004
- * @since 1
- */
-@deprecated("Proxying is deprecated due to lack of use and compiler-level support.", "2.11.0")
-abstract class PriorityQueueProxy[A](implicit ord: Ordering[A]) extends PriorityQueue[A]
- with Proxy
-{
- def self: PriorityQueue[A]
-
- /** Creates a new iterator over all elements contained in this
- * object.
- *
- * @return the new iterator
- */
- override def iterator: Iterator[A] = self.iterator
-
- /** Returns the length of this priority queue.
- */
- override def length: Int = self.length
-
- /** Checks if the queue is empty.
- *
- * @return true, iff there is no element in the queue.
- */
- override def isEmpty: Boolean = self.isEmpty
-
- /** Inserts a single element into the priority queue.
- *
- * @param elem the element to insert
- */
- override def +=(elem: A): this.type = { self += elem; this }
-
- /** Adds all elements provided by an iterator into the priority queue.
- *
- * @param it an iterator
- */
- override def ++=(it: TraversableOnce[A]): this.type = {
- self ++= it
- this
- }
-
- /** Adds all elements to the queue.
- *
- * @param elems the elements to add.
- */
- override def enqueue(elems: A*): Unit = self ++= elems
-
- /** Returns the element with the highest priority in the queue,
- * and removes this element from the queue.
- *
- * @return the element with the highest priority.
- */
- override def dequeue(): A = self.dequeue()
-
- /** Returns the element with the highest priority in the queue,
- * or throws an error if there is no element contained in the queue.
- *
- * @return the element with the highest priority.
- */
- override def head: A = self.head
-
- /** Removes all elements from the queue. After this operation is completed,
- * the queue will be empty.
- */
- override def clear(): Unit = self.clear()
-
- /** Returns a regular queue containing the same elements.
- */
- override def toQueue: Queue[A] = self.toQueue
-
- /** This method clones the priority queue.
- *
- * @return a priority queue with the same elements.
- */
- override def clone(): PriorityQueue[A] = new PriorityQueueProxy[A] {
- def self = PriorityQueueProxy.this.self.clone()
- }
-}
diff --git a/src/library/scala/collection/mutable/RedBlackTree.scala b/src/library/scala/collection/mutable/RedBlackTree.scala
new file mode 100644
index 0000000000..e4793242bf
--- /dev/null
+++ b/src/library/scala/collection/mutable/RedBlackTree.scala
@@ -0,0 +1,580 @@
+package scala.collection.mutable
+
+import scala.annotation.tailrec
+import scala.collection.Iterator
+
+/**
+ * An object containing the red-black tree implementation used by mutable `TreeMaps`.
+ *
+ * The trees implemented in this object are *not* thread safe.
+ *
+ * @author Rui Gonçalves
+ * @version 2.12
+ * @since 2.12
+ */
+private[collection] object RedBlackTree {
+
+ // ---- class structure ----
+
+ // For performance reasons, this implementation uses `null` references to represent leaves instead of a sentinel node.
+ // Currently, the internal nodes do not store their subtree size - only the tree object keeps track of their size.
+ // Therefore, while obtaining the size of the whole tree is O(1), knowing the number of entries inside a range is O(n)
+ // on the size of the range.
+
+ @SerialVersionUID(21575944040195605L)
+ final class Tree[A, B](var root: Node[A, B], var size: Int) extends Serializable
+
+ @SerialVersionUID(1950599696441054720L)
+ final class Node[A, B](var key: A, var value: B, var red: Boolean,
+ var left: Node[A, B], var right: Node[A, B], var parent: Node[A, B]) extends Serializable {
+
+ override def toString: String = "Node(" + key + ", " + value + ", " + red + ", " + left + ", " + right + ")"
+ }
+
+ object Tree {
+ def empty[A, B]: Tree[A, B] = new Tree(null, 0)
+ }
+
+ object Node {
+
+ @inline def apply[A, B](key: A, value: B, red: Boolean,
+ left: Node[A, B], right: Node[A, B], parent: Node[A, B]): Node[A, B] =
+ new Node(key, value, red, left, right, parent)
+
+ @inline def leaf[A, B](key: A, value: B, red: Boolean, parent: Node[A, B]): Node[A, B] =
+ new Node(key, value, red, null, null, parent)
+
+ def unapply[A, B](t: Node[A, B]) = Some((t.key, t.value, t.left, t.right, t.parent))
+ }
+
+ // ---- getters ----
+
+ def isRed(node: Node[_, _]) = (node ne null) && node.red
+ def isBlack(node: Node[_, _]) = (node eq null) || !node.red
+
+ // ---- size ----
+
+ def size(node: Node[_, _]): Int = if (node eq null) 0 else 1 + size(node.left) + size(node.right)
+ def size(tree: Tree[_, _]): Int = tree.size
+ def isEmpty(tree: Tree[_, _]) = tree.root eq null
+ def clear(tree: Tree[_, _]): Unit = { tree.root = null; tree.size = 0 }
+
+ // ---- search ----
+
+ def get[A: Ordering, B](tree: Tree[A, B], key: A): Option[B] = getNode(tree.root, key) match {
+ case null => None
+ case node => Some(node.value)
+ }
+
+ @tailrec private[this] def getNode[A, B](node: Node[A, B], key: A)(implicit ord: Ordering[A]): Node[A, B] =
+ if (node eq null) null
+ else {
+ val cmp = ord.compare(key, node.key)
+ if (cmp < 0) getNode(node.left, key)
+ else if (cmp > 0) getNode(node.right, key)
+ else node
+ }
+
+ def contains[A: Ordering](tree: Tree[A, _], key: A) = getNode(tree.root, key) ne null
+
+ def min[A, B](tree: Tree[A, B]): Option[(A, B)] = minNode(tree.root) match {
+ case null => None
+ case node => Some((node.key, node.value))
+ }
+
+ def minKey[A](tree: Tree[A, _]): Option[A] = minNode(tree.root) match {
+ case null => None
+ case node => Some(node.key)
+ }
+
+ private def minNode[A, B](node: Node[A, B]): Node[A, B] =
+ if (node eq null) null else minNodeNonNull(node)
+
+ @tailrec def minNodeNonNull[A, B](node: Node[A, B]): Node[A, B] =
+ if (node.left eq null) node else minNodeNonNull(node.left)
+
+ def max[A, B](tree: Tree[A, B]): Option[(A, B)] = maxNode(tree.root) match {
+ case null => None
+ case node => Some((node.key, node.value))
+ }
+
+ def maxKey[A](tree: Tree[A, _]): Option[A] = maxNode(tree.root) match {
+ case null => None
+ case node => Some(node.key)
+ }
+
+ private def maxNode[A, B](node: Node[A, B]): Node[A, B] =
+ if (node eq null) null else maxNodeNonNull(node)
+
+ @tailrec def maxNodeNonNull[A, B](node: Node[A, B]): Node[A, B] =
+ if (node.right eq null) node else maxNodeNonNull(node.right)
+
+ /**
+ * Returns the first (lowest) map entry with a key equal or greater than `key`. Returns `None` if there is no such
+ * node.
+ */
+ def minAfter[A, B](tree: Tree[A, B], key: A)(implicit ord: Ordering[A]): Option[(A, B)] =
+ minNodeAfter(tree.root, key) match {
+ case null => None
+ case node => Some((node.key, node.value))
+ }
+
+ def minKeyAfter[A](tree: Tree[A, _], key: A)(implicit ord: Ordering[A]): Option[A] =
+ minNodeAfter(tree.root, key) match {
+ case null => None
+ case node => Some(node.key)
+ }
+
+ private[this] def minNodeAfter[A, B](node: Node[A, B], key: A)(implicit ord: Ordering[A]): Node[A, B] = {
+ if (node eq null) null
+ else {
+ var y: Node[A, B] = null
+ var x = node
+ var cmp = 1
+ while ((x ne null) && cmp != 0) {
+ y = x
+ cmp = ord.compare(key, x.key)
+ x = if (cmp < 0) x.left else x.right
+ }
+ if (cmp <= 0) y else successor(y)
+ }
+ }
+
+ /**
+ * Returns the last (highest) map entry with a key smaller than `key`. Returns `None` if there is no such node.
+ */
+ def maxBefore[A, B](tree: Tree[A, B], key: A)(implicit ord: Ordering[A]): Option[(A, B)] =
+ maxNodeBefore(tree.root, key) match {
+ case null => None
+ case node => Some((node.key, node.value))
+ }
+
+ def maxKeyBefore[A](tree: Tree[A, _], key: A)(implicit ord: Ordering[A]): Option[A] =
+ maxNodeBefore(tree.root, key) match {
+ case null => None
+ case node => Some(node.key)
+ }
+
+ private[this] def maxNodeBefore[A, B](node: Node[A, B], key: A)(implicit ord: Ordering[A]): Node[A, B] = {
+ if (node eq null) null
+ else {
+ var y: Node[A, B] = null
+ var x = node
+ var cmp = 1
+ while ((x ne null) && cmp != 0) {
+ y = x
+ cmp = ord.compare(key, x.key)
+ x = if (cmp < 0) x.left else x.right
+ }
+ if (cmp > 0) y else predecessor(y)
+ }
+ }
+
+ // ---- insertion ----
+
+ def insert[A, B](tree: Tree[A, B], key: A, value: B)(implicit ord: Ordering[A]): Unit = {
+ var y: Node[A, B] = null
+ var x = tree.root
+ var cmp = 1
+ while ((x ne null) && cmp != 0) {
+ y = x
+ cmp = ord.compare(key, x.key)
+ x = if (cmp < 0) x.left else x.right
+ }
+
+ if (cmp == 0) y.value = value
+ else {
+ val z = Node.leaf(key, value, red = true, y)
+
+ if (y eq null) tree.root = z
+ else if (cmp < 0) y.left = z
+ else y.right = z
+
+ fixAfterInsert(tree, z)
+ tree.size += 1
+ }
+ }
+
+ private[this] def fixAfterInsert[A, B](tree: Tree[A, B], node: Node[A, B]): Unit = {
+ var z = node
+ while (isRed(z.parent)) {
+ if (z.parent eq z.parent.parent.left) {
+ val y = z.parent.parent.right
+ if (isRed(y)) {
+ z.parent.red = false
+ y.red = false
+ z.parent.parent.red = true
+ z = z.parent.parent
+ } else {
+ if (z eq z.parent.right) {
+ z = z.parent
+ rotateLeft(tree, z)
+ }
+ z.parent.red = false
+ z.parent.parent.red = true
+ rotateRight(tree, z.parent.parent)
+ }
+ } else { // symmetric cases
+ val y = z.parent.parent.left
+ if (isRed(y)) {
+ z.parent.red = false
+ y.red = false
+ z.parent.parent.red = true
+ z = z.parent.parent
+ } else {
+ if (z eq z.parent.left) {
+ z = z.parent
+ rotateRight(tree, z)
+ }
+ z.parent.red = false
+ z.parent.parent.red = true
+ rotateLeft(tree, z.parent.parent)
+ }
+ }
+ }
+ tree.root.red = false
+ }
+
+ // ---- deletion ----
+
+ def delete[A, B](tree: Tree[A, B], key: A)(implicit ord: Ordering[A]): Unit = {
+ val z = getNode(tree.root, key)
+ if (z ne null) {
+ var y = z
+ var yIsRed = y.red
+ var x: Node[A, B] = null
+ var xParent: Node[A, B] = null
+
+ if (z.left eq null) {
+ x = z.right
+ transplant(tree, z, z.right)
+ xParent = z.parent
+ }
+ else if (z.right eq null) {
+ x = z.left
+ transplant(tree, z, z.left)
+ xParent = z.parent
+ }
+ else {
+ y = minNodeNonNull(z.right)
+ yIsRed = y.red
+ x = y.right
+
+ if (y.parent eq z) xParent = y
+ else {
+ xParent = y.parent
+ transplant(tree, y, y.right)
+ y.right = z.right
+ y.right.parent = y
+ }
+ transplant(tree, z, y)
+ y.left = z.left
+ y.left.parent = y
+ y.red = z.red
+ }
+
+ if (!yIsRed) fixAfterDelete(tree, x, xParent)
+ tree.size -= 1
+ }
+ }
+
+ private[this] def fixAfterDelete[A, B](tree: Tree[A, B], node: Node[A, B], parent: Node[A, B]): Unit = {
+ var x = node
+ var xParent = parent
+ while ((x ne tree.root) && isBlack(x)) {
+ if (x eq xParent.left) {
+ var w = xParent.right
+ // assert(w ne null)
+
+ if (w.red) {
+ w.red = false
+ xParent.red = true
+ rotateLeft(tree, xParent)
+ w = xParent.right
+ }
+ if (isBlack(w.left) && isBlack(w.right)) {
+ w.red = true
+ x = xParent
+ } else {
+ if (isBlack(w.right)) {
+ w.left.red = false
+ w.red = true
+ rotateRight(tree, w)
+ w = xParent.right
+ }
+ w.red = xParent.red
+ xParent.red = false
+ w.right.red = false
+ rotateLeft(tree, xParent)
+ x = tree.root
+ }
+ } else { // symmetric cases
+ var w = xParent.left
+ // assert(w ne null)
+
+ if (w.red) {
+ w.red = false
+ xParent.red = true
+ rotateRight(tree, xParent)
+ w = xParent.left
+ }
+ if (isBlack(w.right) && isBlack(w.left)) {
+ w.red = true
+ x = xParent
+ } else {
+ if (isBlack(w.left)) {
+ w.right.red = false
+ w.red = true
+ rotateLeft(tree, w)
+ w = xParent.left
+ }
+ w.red = xParent.red
+ xParent.red = false
+ w.left.red = false
+ rotateRight(tree, xParent)
+ x = tree.root
+ }
+ }
+ xParent = x.parent
+ }
+ if (x ne null) x.red = false
+ }
+
+ // ---- helpers ----
+
+ /**
+ * Returns the node that follows `node` in an in-order tree traversal. If `node` has the maximum key (and is,
+ * therefore, the last node), this method returns `null`.
+ */
+ private[this] def successor[A, B](node: Node[A, B]): Node[A, B] = {
+ if (node.right ne null) minNodeNonNull(node.right)
+ else {
+ var x = node
+ var y = x.parent
+ while ((y ne null) && (x eq y.right)) {
+ x = y
+ y = y.parent
+ }
+ y
+ }
+ }
+
+ /**
+ * Returns the node that precedes `node` in an in-order tree traversal. If `node` has the minimum key (and is,
+ * therefore, the first node), this method returns `null`.
+ */
+ private[this] def predecessor[A, B](node: Node[A, B]): Node[A, B] = {
+ if (node.left ne null) maxNodeNonNull(node.left)
+ else {
+ var x = node
+ var y = x.parent
+ while ((y ne null) && (x eq y.left)) {
+ x = y
+ y = y.parent
+ }
+ y
+ }
+ }
+
+ private[this] def rotateLeft[A, B](tree: Tree[A, B], x: Node[A, B]): Unit = if (x ne null) {
+ // assert(x.right ne null)
+ val y = x.right
+ x.right = y.left
+
+ if (y.left ne null) y.left.parent = x
+ y.parent = x.parent
+
+ if (x.parent eq null) tree.root = y
+ else if (x eq x.parent.left) x.parent.left = y
+ else x.parent.right = y
+
+ y.left = x
+ x.parent = y
+ }
+
+ private[this] def rotateRight[A, B](tree: Tree[A, B], x: Node[A, B]): Unit = if (x ne null) {
+ // assert(x.left ne null)
+ val y = x.left
+ x.left = y.right
+
+ if (y.right ne null) y.right.parent = x
+ y.parent = x.parent
+
+ if (x.parent eq null) tree.root = y
+ else if (x eq x.parent.right) x.parent.right = y
+ else x.parent.left = y
+
+ y.right = x
+ x.parent = y
+ }
+
+ /**
+ * Transplant the node `from` to the place of node `to`. This is done by setting `from` as a child of `to`'s previous
+ * parent and setting `from`'s parent to the `to`'s previous parent. The children of `from` are left unchanged.
+ */
+ private[this] def transplant[A, B](tree: Tree[A, B], to: Node[A, B], from: Node[A, B]): Unit = {
+ if (to.parent eq null) tree.root = from
+ else if (to eq to.parent.left) to.parent.left = from
+ else to.parent.right = from
+
+ if (from ne null) from.parent = to.parent
+ }
+
+ // ---- tree traversal ----
+
+ def foreach[A, B, U](tree: Tree[A, B], f: ((A, B)) => U): Unit = foreachNode(tree.root, f)
+
+ private[this] def foreachNode[A, B, U](node: Node[A, B], f: ((A, B)) => U): Unit =
+ if (node ne null) foreachNodeNonNull(node, f)
+
+ private[this] def foreachNodeNonNull[A, B, U](node: Node[A, B], f: ((A, B)) => U): Unit = {
+ if (node.left ne null) foreachNodeNonNull(node.left, f)
+ f((node.key, node.value))
+ if (node.right ne null) foreachNodeNonNull(node.right, f)
+ }
+
+ def foreachKey[A, U](tree: Tree[A, _], f: A => U): Unit = foreachNodeKey(tree.root, f)
+
+ private[this] def foreachNodeKey[A, U](node: Node[A, _], f: A => U): Unit =
+ if (node ne null) foreachNodeKeyNonNull(node, f)
+
+ private[this] def foreachNodeKeyNonNull[A, U](node: Node[A, _], f: A => U): Unit = {
+ if (node.left ne null) foreachNodeKeyNonNull(node.left, f)
+ f(node.key)
+ if (node.right ne null) foreachNodeKeyNonNull(node.right, f)
+ }
+
+ def transform[A, B](tree: Tree[A, B], f: (A, B) => B): Unit = transformNode(tree.root, f)
+
+ private[this] def transformNode[A, B, U](node: Node[A, B], f: (A, B) => B): Unit =
+ if (node ne null) transformNodeNonNull(node, f)
+
+ private[this] def transformNodeNonNull[A, B, U](node: Node[A, B], f: (A, B) => B): Unit = {
+ if (node.left ne null) transformNodeNonNull(node.left, f)
+ node.value = f(node.key, node.value)
+ if (node.right ne null) transformNodeNonNull(node.right, f)
+ }
+
+ def iterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[(A, B)] =
+ new EntriesIterator(tree, start, end)
+
+ def keysIterator[A: Ordering](tree: Tree[A, _], start: Option[A] = None, end: Option[A] = None): Iterator[A] =
+ new KeysIterator(tree, start, end)
+
+ def valuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A] = None, end: Option[A] = None): Iterator[B] =
+ new ValuesIterator(tree, start, end)
+
+ private[this] abstract class TreeIterator[A, B, R](tree: Tree[A, B], start: Option[A], end: Option[A])
+ (implicit ord: Ordering[A]) extends Iterator[R] {
+
+ protected[this] def nextResult(node: Node[A, B]): R
+
+ def hasNext: Boolean = nextNode ne null
+
+ def next(): R = nextNode match {
+ case null => throw new NoSuchElementException("next on empty iterator")
+ case node =>
+ nextNode = successor(node)
+ setNullIfAfterEnd()
+ nextResult(node)
+ }
+
+ private[this] var nextNode: Node[A, B] = start match {
+ case None => minNode(tree.root)
+ case Some(from) => minNodeAfter(tree.root, from)
+ }
+
+ private[this] def setNullIfAfterEnd(): Unit =
+ if (end.isDefined && (nextNode ne null) && ord.compare(nextNode.key, end.get) >= 0)
+ nextNode = null
+
+ setNullIfAfterEnd()
+ }
+
+ private[this] final class EntriesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A])
+ extends TreeIterator[A, B, (A, B)](tree, start, end) {
+
+ def nextResult(node: Node[A, B]) = (node.key, node.value)
+ }
+
+ private[this] final class KeysIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A])
+ extends TreeIterator[A, B, A](tree, start, end) {
+
+ def nextResult(node: Node[A, B]) = node.key
+ }
+
+ private[this] final class ValuesIterator[A: Ordering, B](tree: Tree[A, B], start: Option[A], end: Option[A])
+ extends TreeIterator[A, B, B](tree, start, end) {
+
+ def nextResult(node: Node[A, B]) = node.value
+ }
+
+ // ---- debugging ----
+
+ /**
+ * Checks if the tree is in a valid state. That happens if:
+ * - It is a valid binary search tree;
+ * - All red-black properties are satisfied;
+ * - All non-null nodes have their `parent` reference correct;
+ * - The size variable in `tree` corresponds to the actual size of the tree.
+ */
+ def isValid[A: Ordering, B](tree: Tree[A, B]): Boolean =
+ isValidBST(tree.root) && hasProperParentRefs(tree) && isValidRedBlackTree(tree) && size(tree.root) == tree.size
+
+ /**
+ * Returns true if all non-null nodes have their `parent` reference correct.
+ */
+ private[this] def hasProperParentRefs[A, B](tree: Tree[A, B]): Boolean = {
+
+ def hasProperParentRefs(node: Node[A, B]): Boolean = {
+ if (node eq null) true
+ else {
+ if ((node.left ne null) && (node.left.parent ne node) ||
+ (node.right ne null) && (node.right.parent ne node)) false
+ else hasProperParentRefs(node.left) && hasProperParentRefs(node.right)
+ }
+ }
+
+ if(tree.root eq null) true
+ else (tree.root.parent eq null) && hasProperParentRefs(tree.root)
+ }
+
+ /**
+ * Returns true if this node follows the properties of a binary search tree.
+ */
+ private[this] def isValidBST[A, B](node: Node[A, B])(implicit ord: Ordering[A]): Boolean = {
+ if (node eq null) true
+ else {
+ if ((node.left ne null) && (ord.compare(node.key, node.left.key) <= 0) ||
+ (node.right ne null) && (ord.compare(node.key, node.right.key) >= 0)) false
+ else isValidBST(node.left) && isValidBST(node.right)
+ }
+ }
+
+ /**
+ * Returns true if the tree has all the red-black tree properties: if the root node is black, if all children of red
+ * nodes are black and if the path from any node to any of its null children has the same number of black nodes.
+ */
+ private[this] def isValidRedBlackTree[A, B](tree: Tree[A, B]): Boolean = {
+
+ def noRedAfterRed(node: Node[A, B]): Boolean = {
+ if (node eq null) true
+ else if (node.red && (isRed(node.left) || isRed(node.right))) false
+ else noRedAfterRed(node.left) && noRedAfterRed(node.right)
+ }
+
+ def blackHeight(node: Node[A, B]): Int = {
+ if (node eq null) 1
+ else {
+ val lh = blackHeight(node.left)
+ val rh = blackHeight(node.right)
+
+ if (lh == -1 || lh != rh) -1
+ else if (isRed(node)) lh
+ else lh + 1
+ }
+ }
+
+ isBlack(tree.root) && noRedAfterRed(tree.root) && blackHeight(tree.root) >= 0
+ }
+}
diff --git a/src/library/scala/collection/mutable/ResizableArray.scala b/src/library/scala/collection/mutable/ResizableArray.scala
index c3047522e2..85a299216e 100644
--- a/src/library/scala/collection/mutable/ResizableArray.scala
+++ b/src/library/scala/collection/mutable/ResizableArray.scala
@@ -74,7 +74,7 @@ trait ResizableArray[A] extends IndexedSeq[A]
*/
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
val len1 = len min (xs.length - start) min length
- Array.copy(array, 0, xs, start, len1)
+ if (len1 > 0) Array.copy(array, 0, xs, start, len1)
}
//##########################################################################
diff --git a/src/library/scala/collection/mutable/ReusableBuilder.scala b/src/library/scala/collection/mutable/ReusableBuilder.scala
new file mode 100644
index 0000000000..83a4fcfc29
--- /dev/null
+++ b/src/library/scala/collection/mutable/ReusableBuilder.scala
@@ -0,0 +1,49 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2016, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+package scala
+package collection
+package mutable
+
+/** `ReusableBuilder` is a marker trait that indicates that a `Builder`
+ * can be reused to build more than one instance of a collection. In
+ * particular, calling `result` followed by `clear` will produce a
+ * collection and reset the builder to begin building a new collection
+ * of the same type.
+ *
+ * It is up to subclasses to implement this behavior, and to document any
+ * other behavior that varies from standard `ReusableBuilder` usage
+ * (e.g. operations being well-defined after a call to `result`, or allowing
+ * multiple calls to result to obtain different snapshots of a collection under
+ * construction).
+ *
+ * @tparam Elem the type of elements that get added to the builder.
+ * @tparam To the type of collection that it produced.
+ *
+ * @since 2.12
+ */
+trait ReusableBuilder[-Elem, +To] extends Builder[Elem, To] {
+ /** Clears the contents of this builder.
+ * After execution of this method, the builder will contain no elements.
+ *
+ * If executed immediately after a call to `result`, this allows a new
+ * instance of the same type of collection to be built.
+ */
+ override def clear(): Unit // Note: overriding for scaladoc only!
+
+ /** Produces a collection from the added elements.
+ *
+ * After a call to `result`, the behavior of all other methods is undefined
+ * save for `clear`. If `clear` is called, then the builder is reset and
+ * may be used to build another instance.
+ *
+ * @return a collection containing the elements added to this builder.
+ */
+ override def result(): To // Note: overriding for scaladoc only!
+}
diff --git a/src/library/scala/collection/mutable/SetBuilder.scala b/src/library/scala/collection/mutable/SetBuilder.scala
index 01bfdc96ed..5d1e9ffc3a 100644
--- a/src/library/scala/collection/mutable/SetBuilder.scala
+++ b/src/library/scala/collection/mutable/SetBuilder.scala
@@ -17,7 +17,9 @@ package mutable
* @param empty The empty element of the collection.
* @since 2.8
*/
-class SetBuilder[A, Coll <: scala.collection.Set[A] with scala.collection.SetLike[A, Coll]](empty: Coll) extends Builder[A, Coll] {
+class SetBuilder[A, Coll <: scala.collection.Set[A]
+with scala.collection.SetLike[A, Coll]](empty: Coll)
+extends ReusableBuilder[A, Coll] {
protected var elems: Coll = empty
def +=(x: A): this.type = { elems = elems + x; this }
def clear() { elems = empty }
diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala
index 01075a2633..a19130e742 100644
--- a/src/library/scala/collection/mutable/SetLike.scala
+++ b/src/library/scala/collection/mutable/SetLike.scala
@@ -72,6 +72,17 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
protected[this] override def parCombiner = ParSet.newCombiner[A]
+ /** Converts this $coll to a sequence.
+ *
+ * ```Note```: assumes a fast `size` method. Subclasses should override if this is not true.
+ */
+ override def toSeq: collection.Seq[A] = {
+ // ArrayBuffer for efficiency, preallocated to the right size.
+ val result = new ArrayBuffer[A](size)
+ foreach(result += _)
+ result
+ }
+
/** Adds an element to this $coll.
*
* @param elem the element to be added
diff --git a/src/library/scala/collection/mutable/SortedMap.scala b/src/library/scala/collection/mutable/SortedMap.scala
new file mode 100644
index 0000000000..806b30e79a
--- /dev/null
+++ b/src/library/scala/collection/mutable/SortedMap.scala
@@ -0,0 +1,57 @@
+package scala
+package collection
+package mutable
+
+import generic._
+
+/**
+ * A mutable map whose keys are sorted.
+ *
+ * @tparam A the type of the keys contained in this sorted map.
+ * @tparam B the type of the values associated with the keys.
+ *
+ * @author Rui Gonçalves
+ * @version 2.12
+ * @since 2.12
+ *
+ * @define Coll mutable.SortedMap
+ * @define coll mutable sorted map
+ */
+trait SortedMap[A, B]
+ extends Map[A, B]
+ with collection.SortedMap[A, B]
+ with MapLike[A, B, SortedMap[A, B]]
+ with SortedMapLike[A, B, SortedMap[A, B]] {
+
+ override protected[this] def newBuilder: Builder[(A, B), SortedMap[A, B]] = SortedMap.newBuilder[A, B]
+
+ override def empty: SortedMap[A, B] = SortedMap.empty
+
+ override def updated[B1 >: B](key: A, value: B1): SortedMap[A, B1] = this + ((key, value))
+
+ override def +[B1 >: B](kv: (A, B1)): SortedMap[A, B1] = clone().asInstanceOf[SortedMap[A, B1]] += kv
+
+ override def +[B1 >: B](elem1: (A, B1), elem2: (A, B1), elems: (A, B1)*): SortedMap[A, B1] =
+ clone().asInstanceOf[SortedMap[A, B1]] += elem1 += elem2 ++= elems
+
+ override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): SortedMap[A, B1] =
+ clone().asInstanceOf[SortedMap[A, B1]] ++= xs.seq
+}
+
+/**
+ * $factoryInfo
+ *
+ * @define Coll mutable.SortedMap
+ * @define coll mutable sorted map
+ */
+object SortedMap extends MutableSortedMapFactory[SortedMap] {
+
+ def empty[A, B](implicit ord: Ordering[A]): SortedMap[A, B] = TreeMap.empty[A, B]
+
+ /** $sortedMapCanBuildFromInfo */
+ implicit def canBuildFrom[A, B](implicit ord: Ordering[A]): CanBuildFrom[Coll, (A, B), SortedMap[A, B]] =
+ new SortedMapCanBuildFrom[A, B]
+}
+
+/** Explicit instantiation of the `SortedMap` trait to reduce class file size in subclasses. */
+abstract class AbstractSortedMap[A, B] extends scala.collection.mutable.AbstractMap[A, B] with SortedMap[A, B]
diff --git a/src/library/scala/collection/mutable/SortedSet.scala b/src/library/scala/collection/mutable/SortedSet.scala
index 0f2fa75abd..304469916d 100644
--- a/src/library/scala/collection/mutable/SortedSet.scala
+++ b/src/library/scala/collection/mutable/SortedSet.scala
@@ -43,8 +43,13 @@ trait SortedSet[A] extends scala.collection.SortedSet[A] with scala.collection.S
*
*/
object SortedSet extends MutableSortedSetFactory[SortedSet] {
- implicit def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, SortedSet[A]] = new SortedSetCanBuildFrom[A]
+ def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, SortedSet[A]] = new SortedSetCanBuildFrom[A]
def empty[A](implicit ord: Ordering[A]): SortedSet[A] = TreeSet.empty[A]
+ // Force a declaration here so that BitSet (which does not inherit from SortedSetFactory) can be more specific
+ override implicit def newCanBuildFrom[A](implicit ord : Ordering[A]): CanBuildFrom[Coll, A, SortedSet[A]] = super.newCanBuildFrom
}
+
+/** Explicit instantiation of the `SortedSet` trait to reduce class file size in subclasses. */
+abstract class AbstractSortedSet[A] extends scala.collection.mutable.AbstractSet[A] with SortedSet[A]
diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala
index c56d40786e..b5b9498374 100644
--- a/src/library/scala/collection/mutable/StringBuilder.scala
+++ b/src/library/scala/collection/mutable/StringBuilder.scala
@@ -33,7 +33,7 @@ final class StringBuilder(private val underlying: JavaStringBuilder)
with java.lang.CharSequence
with IndexedSeq[Char]
with StringLike[StringBuilder]
- with Builder[Char, String]
+ with ReusableBuilder[Char, String]
with Serializable {
override protected[this] def thisCollection: StringBuilder = this
@@ -435,7 +435,11 @@ final class StringBuilder(private val underlying: JavaStringBuilder)
*/
override def mkString = toString
- /** Returns the result of this Builder (a String)
+ /** Returns the result of this Builder (a String).
+ *
+ * If this method is called multiple times, each call will result in a snapshot of the buffer at that point in time.
+ * In particular, a `StringBuilder` can be used to build multiple independent strings by emptying the buffer with `clear`
+ * after each call to `result`.
*
* @return the string assembled by this StringBuilder
*/
diff --git a/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala b/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala
deleted file mode 100644
index d3c0b85f69..0000000000
--- a/src/library/scala/collection/mutable/SynchronizedPriorityQueue.scala
+++ /dev/null
@@ -1,101 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala
-package collection
-package mutable
-
-/** This class implements synchronized priority queues using a binary heap.
- * The elements of the queue have to be ordered in terms of the `Ordered[T]` class.
- *
- * @tparam A type of the elements contained in this synchronized priority queue
- * @param ord implicit ordering used to compared elements of type `A`
- *
- * @author Matthias Zenger
- * @version 1.0, 03/05/2004
- * @since 1
- * @define Coll `SynchronizedPriorityQueue`
- * @define coll synchronized priority queue
- */
-@deprecated("Comprehensive synchronization via selective overriding of methods is inherently unreliable. Consider java.util.concurrent.ConcurrentSkipListSet as an alternative.", "2.11.0")
-class SynchronizedPriorityQueue[A](implicit ord: Ordering[A]) extends PriorityQueue[A] {
-
- /** Checks if the queue is empty.
- *
- * @return true, iff there is no element in the queue.
- */
- override def isEmpty: Boolean = synchronized { super.isEmpty }
-
- /** Inserts a single element into the priority queue.
- *
- * @param elem the element to insert
- */
- override def +=(elem: A): this.type = {
- synchronized {
- super.+=(elem)
- }
- this
- }
-
- /** Adds all elements of a traversable object into the priority queue.
- *
- * @param xs a traversable object
- */
- override def ++=(xs: TraversableOnce[A]): this.type = {
- synchronized {
- super.++=(xs)
- }
- this
- }
-
- /** Adds all elements to the queue.
- *
- * @param elems the elements to add.
- */
- override def enqueue(elems: A*): Unit = synchronized { super.++=(elems) }
-
- /** Returns the element with the highest priority in the queue,
- * and removes this element from the queue.
- *
- * @return the element with the highest priority.
- */
- override def dequeue(): A = synchronized { super.dequeue() }
-
- /** Returns the element with the highest priority in the queue,
- * or throws an error if there is no element contained in the queue.
- *
- * @return the element with the highest priority.
- */
- override def head: A = synchronized { super.head }
-
- /** Removes all elements from the queue. After this operation is completed,
- * the queue will be empty.
- */
- override def clear(): Unit = synchronized { super.clear() }
-
- /** Returns an iterator which yield all the elements of the priority
- * queue in descending priority order.
- *
- * @return an iterator over all elements sorted in descending order.
- */
- override def iterator: Iterator[A] = synchronized { super.iterator }
-
- /** Checks if two queues are structurally identical.
- *
- * @return true, iff both queues contain the same sequence of elements.
- */
- override def equals(that: Any): Boolean = synchronized { super.equals(that) }
-
- /** Returns a textual representation of a queue as a string.
- *
- * @return the string representation of this queue.
- */
- override def toString(): String = synchronized { super.toString() }
-}
diff --git a/src/library/scala/collection/mutable/SynchronizedStack.scala b/src/library/scala/collection/mutable/SynchronizedStack.scala
index bbb6f5a9bb..c77a6fad62 100644
--- a/src/library/scala/collection/mutable/SynchronizedStack.scala
+++ b/src/library/scala/collection/mutable/SynchronizedStack.scala
@@ -27,7 +27,6 @@ package mutable
*/
@deprecated("Synchronization via selective overriding of methods is inherently unreliable. Consider java.util.concurrent.LinkedBlockingDequeue instead.", "2.11.0")
class SynchronizedStack[A] extends Stack[A] {
- import scala.collection.Traversable
/** Checks if the stack is empty.
*
diff --git a/src/library/scala/collection/mutable/TreeMap.scala b/src/library/scala/collection/mutable/TreeMap.scala
new file mode 100644
index 0000000000..dc7d5d750e
--- /dev/null
+++ b/src/library/scala/collection/mutable/TreeMap.scala
@@ -0,0 +1,185 @@
+package scala
+package collection
+package mutable
+
+import scala.collection.generic._
+import scala.collection.mutable.{RedBlackTree => RB}
+
+/**
+ * $factoryInfo
+ *
+ * @define Coll mutable.TreeMap
+ * @define coll mutable tree map
+ */
+object TreeMap extends MutableSortedMapFactory[TreeMap] {
+
+ def empty[A, B](implicit ord: Ordering[A]) = new TreeMap[A, B]()(ord)
+
+ /** $sortedMapCanBuildFromInfo */
+ implicit def canBuildFrom[A, B](implicit ord: Ordering[A]): CanBuildFrom[Coll, (A, B), TreeMap[A, B]] =
+ new SortedMapCanBuildFrom[A, B]
+}
+
+/**
+ * A mutable sorted map implemented using a mutable red-black tree as underlying data structure.
+ *
+ * @param ordering the implicit ordering used to compare objects of type `A`.
+ * @tparam A the type of the keys contained in this tree map.
+ * @tparam B the type of the values associated with the keys.
+ *
+ * @author Rui Gonçalves
+ * @version 2.12
+ * @since 2.12
+ *
+ * @define Coll mutable.TreeMap
+ * @define coll mutable tree map
+ */
+@SerialVersionUID(-2558985573956740112L)
+sealed class TreeMap[A, B] private (tree: RB.Tree[A, B])(implicit val ordering: Ordering[A])
+ extends AbstractSortedMap[A, B]
+ with SortedMap[A, B]
+ with MapLike[A, B, TreeMap[A, B]]
+ with SortedMapLike[A, B, TreeMap[A, B]]
+ with Serializable {
+
+ /**
+ * Creates an empty `TreeMap`.
+ * @param ord the implicit ordering used to compare objects of type `A`.
+ * @return an empty `TreeMap`.
+ */
+ def this()(implicit ord: Ordering[A]) = this(RB.Tree.empty)(ord)
+
+ override def empty = TreeMap.empty
+ override protected[this] def newBuilder = TreeMap.newBuilder[A, B]
+
+ /**
+ * Creates a ranged projection of this map. Any mutations in the ranged projection will update the original map and
+ * vice versa.
+ *
+ * Only entries with keys between this projection's key range will ever appear as elements of this map, independently
+ * of whether the entries are added through the original map or through this view. That means that if one inserts a
+ * key-value in a view whose key is outside the view's bounds, calls to `get` or `contains` will _not_ consider the
+ * newly added entry. Mutations are always reflected in the original map, though.
+ *
+ * @param from the lower bound (inclusive) of this projection wrapped in a `Some`, or `None` if there is no lower
+ * bound.
+ * @param until the upper bound (exclusive) of this projection wrapped in a `Some`, or `None` if there is no upper
+ * bound.
+ */
+ def rangeImpl(from: Option[A], until: Option[A]): TreeMap[A, B] = new TreeMapView(from, until)
+
+ def -=(key: A): this.type = { RB.delete(tree, key); this }
+ def +=(kv: (A, B)): this.type = { RB.insert(tree, kv._1, kv._2); this }
+
+ def get(key: A) = RB.get(tree, key)
+
+ def iterator = RB.iterator(tree)
+ def iteratorFrom(start: A) = RB.iterator(tree, Some(start))
+ def keysIteratorFrom(start: A) = RB.keysIterator(tree, Some(start))
+ def valuesIteratorFrom(start: A) = RB.valuesIterator(tree, Some(start))
+
+ override def size = RB.size(tree)
+ override def isEmpty = RB.isEmpty(tree)
+ override def contains(key: A) = RB.contains(tree, key)
+
+ override def head = RB.min(tree).get
+ override def headOption = RB.min(tree)
+ override def last = RB.max(tree).get
+ override def lastOption = RB.max(tree)
+
+ override def keysIterator = RB.keysIterator(tree)
+ override def valuesIterator = RB.valuesIterator(tree)
+
+ override def foreach[U](f: ((A, B)) => U): Unit = RB.foreach(tree, f)
+ override def transform(f: (A, B) => B) = { RB.transform(tree, f); this }
+ override def clear(): Unit = RB.clear(tree)
+
+ override def stringPrefix = "TreeMap"
+
+ /**
+ * A ranged projection of a [[TreeMap]]. Mutations on this map affect the original map and vice versa.
+ *
+ * Only entries with keys between this projection's key range will ever appear as elements of this map, independently
+ * of whether the entries are added through the original map or through this view. That means that if one inserts a
+ * key-value in a view whose key is outside the view's bounds, calls to `get` or `contains` will _not_ consider the
+ * newly added entry. Mutations are always reflected in the original map, though.
+ *
+ * @param from the lower bound (inclusive) of this projection wrapped in a `Some`, or `None` if there is no lower
+ * bound.
+ * @param until the upper bound (exclusive) of this projection wrapped in a `Some`, or `None` if there is no upper
+ * bound.
+ */
+ @SerialVersionUID(2219159283273389116L)
+ private[this] final class TreeMapView(from: Option[A], until: Option[A]) extends TreeMap[A, B](tree) {
+
+ /**
+ * Given a possible new lower bound, chooses and returns the most constraining one (the maximum).
+ */
+ private[this] def pickLowerBound(newFrom: Option[A]): Option[A] = (from, newFrom) match {
+ case (Some(fr), Some(newFr)) => Some(ordering.max(fr, newFr))
+ case (None, _) => newFrom
+ case _ => from
+ }
+
+ /**
+ * Given a possible new upper bound, chooses and returns the most constraining one (the minimum).
+ */
+ private[this] def pickUpperBound(newUntil: Option[A]): Option[A] = (until, newUntil) match {
+ case (Some(unt), Some(newUnt)) => Some(ordering.min(unt, newUnt))
+ case (None, _) => newUntil
+ case _ => until
+ }
+
+ /**
+ * Returns true if the argument is inside the view bounds (between `from` and `until`).
+ */
+ private[this] def isInsideViewBounds(key: A): Boolean = {
+ val afterFrom = from.isEmpty || ordering.compare(from.get, key) <= 0
+ val beforeUntil = until.isEmpty || ordering.compare(key, until.get) < 0
+ afterFrom && beforeUntil
+ }
+
+ override def rangeImpl(from: Option[A], until: Option[A]): TreeMap[A, B] =
+ new TreeMapView(pickLowerBound(from), pickUpperBound(until))
+
+ override def get(key: A) = if (isInsideViewBounds(key)) RB.get(tree, key) else None
+
+ override def iterator = RB.iterator(tree, from, until)
+ override def iteratorFrom(start: A) = RB.iterator(tree, pickLowerBound(Some(start)), until)
+ override def keysIteratorFrom(start: A) = RB.keysIterator(tree, pickLowerBound(Some(start)), until)
+ override def valuesIteratorFrom(start: A) = RB.valuesIterator(tree, pickLowerBound(Some(start)), until)
+
+ override def size = iterator.length
+ override def isEmpty = !iterator.hasNext
+ override def contains(key: A) = isInsideViewBounds(key) && RB.contains(tree, key)
+
+ override def head = headOption.get
+ override def headOption = {
+ val entry = if (from.isDefined) RB.minAfter(tree, from.get) else RB.min(tree)
+ (entry, until) match {
+ case (Some(e), Some(unt)) if ordering.compare(e._1, unt) >= 0 => None
+ case _ => entry
+ }
+ }
+
+ override def last = lastOption.get
+ override def lastOption = {
+ val entry = if (until.isDefined) RB.maxBefore(tree, until.get) else RB.max(tree)
+ (entry, from) match {
+ case (Some(e), Some(fr)) if ordering.compare(e._1, fr) < 0 => None
+ case _ => entry
+ }
+ }
+
+ // Using the iterator should be efficient enough; if performance is deemed a problem later, specialized
+ // `foreach(f, from, until)` and `transform(f, from, until)` methods can be created in `RedBlackTree`. See
+ // https://github.com/scala/scala/pull/4608#discussion_r34307985 for a discussion about this.
+ override def foreach[U](f: ((A, B)) => U): Unit = iterator.foreach(f)
+ override def transform(f: (A, B) => B) = {
+ iterator.foreach { case (key, value) => update(key, f(key, value)) }
+ this
+ }
+
+ override def clone() = super.clone().rangeImpl(from, until)
+ }
+}
diff --git a/src/library/scala/collection/mutable/TreeSet.scala b/src/library/scala/collection/mutable/TreeSet.scala
index f849eea569..ada6f145ad 100644
--- a/src/library/scala/collection/mutable/TreeSet.scala
+++ b/src/library/scala/collection/mutable/TreeSet.scala
@@ -11,8 +11,7 @@ package collection
package mutable
import generic._
-import scala.collection.immutable.{RedBlackTree => RB}
-import scala.runtime.ObjectRef
+import scala.collection.mutable.{RedBlackTree => RB}
/**
* @define Coll `mutable.TreeSet`
@@ -29,88 +28,162 @@ object TreeSet extends MutableSortedSetFactory[TreeSet] {
*/
def empty[A](implicit ordering: Ordering[A]) = new TreeSet[A]()
+ /** $sortedMapCanBuildFromInfo */
+ implicit def canBuildFrom[A](implicit ord: Ordering[A]): CanBuildFrom[Coll, A, TreeSet[A]] =
+ new SortedSetCanBuildFrom[A]
}
/**
- * A mutable SortedSet using an immutable RedBlack Tree as underlying data structure.
+ * A mutable sorted set implemented using a mutable red-black tree as underlying data structure.
*
- * @author Lucien Pereira
+ * @param ordering the implicit ordering used to compare objects of type `A`.
+ * @tparam A the type of the keys contained in this tree set.
+ *
+ * @author Rui Gonçalves
+ * @version 2.12
+ * @since 2.10
*
+ * @define Coll mutable.TreeSet
+ * @define coll mutable tree set
*/
-@deprecatedInheritance("TreeSet is not designed to enable meaningful subclassing.", "2.11.0")
-class TreeSet[A] private (treeRef: ObjectRef[RB.Tree[A, Null]], from: Option[A], until: Option[A])(implicit val ordering: Ordering[A])
- extends SortedSet[A] with SetLike[A, TreeSet[A]]
- with SortedSetLike[A, TreeSet[A]] with Set[A] with Serializable {
+// Original API designed in part by Lucien Pereira
+@SerialVersionUID(-3642111301929493640L)
+sealed class TreeSet[A] private (tree: RB.Tree[A, Null])(implicit val ordering: Ordering[A])
+ extends AbstractSortedSet[A]
+ with SortedSet[A]
+ with SetLike[A, TreeSet[A]]
+ with SortedSetLike[A, TreeSet[A]]
+ with Serializable {
if (ordering eq null)
throw new NullPointerException("ordering must not be null")
- def this()(implicit ordering: Ordering[A]) = this(new ObjectRef(null), None, None)
+ /**
+ * Creates an empty `TreeSet`.
+ * @param ord the implicit ordering used to compare objects of type `A`.
+ * @return an empty `TreeSet`.
+ */
+ def this()(implicit ord: Ordering[A]) = this(RB.Tree.empty)(ord)
- override def size: Int = RB.countInRange(treeRef.elem, from, until)
+ override def empty = TreeSet.empty
+ override protected[this] def newBuilder = TreeSet.newBuilder[A]
- override def stringPrefix = "TreeSet"
+ /**
+ * Creates a ranged projection of this set. Any mutations in the ranged projection affect will update the original set
+ * and vice versa.
+ *
+ * Only keys between this projection's key range will ever appear as elements of this set, independently of whether
+ * the elements are added through the original set or through this view. That means that if one inserts an element in
+ * a view whose key is outside the view's bounds, calls to `contains` will _not_ consider the newly added element.
+ * Mutations are always reflected in the original set, though.
+ *
+ * @param from the lower bound (inclusive) of this projection wrapped in a `Some`, or `None` if there is no lower
+ * bound.
+ * @param until the upper bound (exclusive) of this projection wrapped in a `Some`, or `None` if there is no upper
+ * bound.
+ */
+ def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] = new TreeSetView(from, until)
- override def empty: TreeSet[A] = TreeSet.empty
+ def -=(key: A): this.type = { RB.delete(tree, key); this }
+ def +=(elem: A): this.type = { RB.insert(tree, elem, null); this }
- private def pickBound(comparison: (A, A) => A, oldBound: Option[A], newBound: Option[A]) = (newBound, oldBound) match {
- case (Some(newB), Some(oldB)) => Some(comparison(newB, oldB))
- case (None, _) => oldBound
- case _ => newBound
- }
+ def contains(elem: A) = RB.contains(tree, elem)
- override def rangeImpl(fromArg: Option[A], untilArg: Option[A]): TreeSet[A] = {
- val newFrom = pickBound(ordering.max, fromArg, from)
- val newUntil = pickBound(ordering.min, untilArg, until)
+ def iterator = RB.keysIterator(tree)
+ def keysIteratorFrom(start: A) = RB.keysIterator(tree, Some(start))
+ override def iteratorFrom(start: A) = RB.keysIterator(tree, Some(start))
- new TreeSet(treeRef, newFrom, newUntil)
- }
+ override def size = RB.size(tree)
+ override def isEmpty = RB.isEmpty(tree)
- override def -=(elem: A): this.type = {
- treeRef.elem = RB.delete(treeRef.elem, elem)
- this
- }
+ override def head = RB.minKey(tree).get
+ override def headOption = RB.minKey(tree)
+ override def last = RB.maxKey(tree).get
+ override def lastOption = RB.maxKey(tree)
- override def +=(elem: A): this.type = {
- treeRef.elem = RB.update(treeRef.elem, elem, null, overwrite = false)
- this
- }
+ override def foreach[U](f: A => U): Unit = RB.foreachKey(tree, f)
+ override def clear(): Unit = RB.clear(tree)
+
+ override def stringPrefix = "TreeSet"
/**
- * Thanks to the immutable nature of the
- * underlying Tree, we can share it with
- * the clone. So clone complexity in time is O(1).
+ * A ranged projection of a [[TreeSet]]. Mutations on this set affect the original set and vice versa.
*
+ * Only keys between this projection's key range will ever appear as elements of this set, independently of whether
+ * the elements are added through the original set or through this view. That means that if one inserts an element in
+ * a view whose key is outside the view's bounds, calls to `contains` will _not_ consider the newly added element.
+ * Mutations are always reflected in the original set, though.
+ *
+ * @param from the lower bound (inclusive) of this projection wrapped in a `Some`, or `None` if there is no lower
+ * bound.
+ * @param until the upper bound (exclusive) of this projection wrapped in a `Some`, or `None` if there is no upper
+ * bound.
*/
- override def clone(): TreeSet[A] =
- new TreeSet[A](new ObjectRef(treeRef.elem), from, until)
-
- private val notProjection = !(from.isDefined || until.isDefined)
+ @SerialVersionUID(7087824939194006086L)
+ private[this] final class TreeSetView(from: Option[A], until: Option[A]) extends TreeSet[A](tree) {
+
+ /**
+ * Given a possible new lower bound, chooses and returns the most constraining one (the maximum).
+ */
+ private[this] def pickLowerBound(newFrom: Option[A]): Option[A] = (from, newFrom) match {
+ case (Some(fr), Some(newFr)) => Some(ordering.max(fr, newFr))
+ case (None, _) => newFrom
+ case _ => from
+ }
- override def contains(elem: A): Boolean = {
- def leftAcceptable: Boolean = from match {
- case Some(lb) => ordering.gteq(elem, lb)
- case _ => true
+ /**
+ * Given a possible new upper bound, chooses and returns the most constraining one (the minimum).
+ */
+ private[this] def pickUpperBound(newUntil: Option[A]): Option[A] = (until, newUntil) match {
+ case (Some(unt), Some(newUnt)) => Some(ordering.min(unt, newUnt))
+ case (None, _) => newUntil
+ case _ => until
}
- def rightAcceptable: Boolean = until match {
- case Some(ub) => ordering.lt(elem, ub)
- case _ => true
+ /**
+ * Returns true if the argument is inside the view bounds (between `from` and `until`).
+ */
+ private[this] def isInsideViewBounds(key: A): Boolean = {
+ val afterFrom = from.isEmpty || ordering.compare(from.get, key) <= 0
+ val beforeUntil = until.isEmpty || ordering.compare(key, until.get) < 0
+ afterFrom && beforeUntil
}
- (notProjection || (leftAcceptable && rightAcceptable)) &&
- RB.contains(treeRef.elem, elem)
- }
+ override def rangeImpl(from: Option[A], until: Option[A]): TreeSet[A] =
+ new TreeSetView(pickLowerBound(from), pickUpperBound(until))
+
+ override def contains(key: A) = isInsideViewBounds(key) && RB.contains(tree, key)
+
+ override def iterator = RB.keysIterator(tree, from, until)
+ override def keysIteratorFrom(start: A) = RB.keysIterator(tree, pickLowerBound(Some(start)), until)
+ override def iteratorFrom(start: A) = RB.keysIterator(tree, pickLowerBound(Some(start)), until)
- override def iterator: Iterator[A] = iteratorFrom(None)
+ override def size = iterator.length
+ override def isEmpty = !iterator.hasNext
- override def keysIteratorFrom(start: A) = iteratorFrom(Some(start))
+ override def head = headOption.get
+ override def headOption = {
+ val elem = if (from.isDefined) RB.minKeyAfter(tree, from.get) else RB.minKey(tree)
+ (elem, until) match {
+ case (Some(e), Some(unt)) if ordering.compare(e, unt) >= 0 => None
+ case _ => elem
+ }
+ }
- private def iteratorFrom(start: Option[A]) = {
- val it = RB.keysIterator(treeRef.elem, pickBound(ordering.max, from, start))
- until match {
- case None => it
- case Some(ub) => it takeWhile (k => ordering.lt(k, ub))
+ override def last = lastOption.get
+ override def lastOption = {
+ val elem = if (until.isDefined) RB.maxKeyBefore(tree, until.get) else RB.maxKey(tree)
+ (elem, from) match {
+ case (Some(e), Some(fr)) if ordering.compare(e, fr) < 0 => None
+ case _ => elem
+ }
}
+
+ // Using the iterator should be efficient enough; if performance is deemed a problem later, a specialized
+ // `foreachKey(f, from, until)` method can be created in `RedBlackTree`. See
+ // https://github.com/scala/scala/pull/4608#discussion_r34307985 for a discussion about this.
+ override def foreach[U](f: A => U): Unit = iterator.foreach(f)
+
+ override def clone() = super.clone().rangeImpl(from, until)
}
}
diff --git a/src/library/scala/collection/mutable/UnrolledBuffer.scala b/src/library/scala/collection/mutable/UnrolledBuffer.scala
index 2212486bcf..b49d009a17 100644
--- a/src/library/scala/collection/mutable/UnrolledBuffer.scala
+++ b/src/library/scala/collection/mutable/UnrolledBuffer.scala
@@ -43,8 +43,7 @@ import scala.reflect.ClassTag
*
*/
@SerialVersionUID(1L)
-@deprecatedInheritance("UnrolledBuffer is not designed to enable meaningful subclassing.", "2.11.0")
-class UnrolledBuffer[T](implicit val tag: ClassTag[T])
+sealed class UnrolledBuffer[T](implicit val tag: ClassTag[T])
extends scala.collection.mutable.AbstractBuffer[T]
with scala.collection.mutable.Buffer[T]
with scala.collection.mutable.BufferLike[T, UnrolledBuffer[T]]
@@ -350,3 +349,11 @@ object UnrolledBuffer extends ClassTagTraversableFactory[UnrolledBuffer] {
}
}
+
+
+// This is used by scala.collection.parallel.mutable.UnrolledParArrayCombiner:
+// Todo -- revisit whether inheritance is the best way to achieve this functionality
+private[collection] class DoublingUnrolledBuffer[T](implicit t: ClassTag[T]) extends UnrolledBuffer[T]()(t) {
+ override def calcNextLength(sz: Int) = if (sz < 10000) sz * 2 else sz
+ protected override def newUnrolled = new UnrolledBuffer.Unrolled[T](0, new Array[T](4), null, this)
+}
diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala
index 8740bda835..01dcd9bde5 100644
--- a/src/library/scala/collection/mutable/WrappedArray.scala
+++ b/src/library/scala/collection/mutable/WrappedArray.scala
@@ -13,7 +13,6 @@ package collection
package mutable
import scala.reflect.ClassTag
-import scala.runtime.ScalaRunTime._
import scala.collection.generic._
import scala.collection.parallel.mutable.ParArray
@@ -46,7 +45,7 @@ extends AbstractSeq[T]
def elemTag: ClassTag[T]
@deprecated("use elemTag instead", "2.10.0")
- def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](arrayElementClass(elemTag).asInstanceOf[Class[T]])
+ def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](elemTag.runtimeClass.asInstanceOf[Class[T]])
/** The length of the array */
def length: Int
@@ -63,10 +62,10 @@ extends AbstractSeq[T]
override def par = ParArray.handoff(array)
private def elementClass: Class[_] =
- arrayElementClass(array.getClass)
+ array.getClass.getComponentType
override def toArray[U >: T : ClassTag]: Array[U] = {
- val thatElementClass = arrayElementClass(implicitly[ClassTag[U]])
+ val thatElementClass = implicitly[ClassTag[U]].runtimeClass
if (elementClass eq thatElementClass)
array.asInstanceOf[Array[U]]
else
@@ -122,7 +121,7 @@ object WrappedArray {
def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer
final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable {
- lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass))
+ lazy val elemTag = ClassTag[T](array.getClass.getComponentType)
def length: Int = array.length
def apply(index: Int): T = array(index).asInstanceOf[T]
def update(index: Int, elem: T) { array(index) = elem }
diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
index bfe95a11ab..5bc5811450 100644
--- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
+++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala
@@ -13,16 +13,17 @@ package collection
package mutable
import scala.reflect.ClassTag
-import scala.runtime.ScalaRunTime._
/** A builder class for arrays.
*
+ * This builder can be reused.
+ *
* @tparam A type of elements that can be added to this builder.
* @param tag class tag for objects of type `A`.
*
* @since 2.8
*/
-class WrappedArrayBuilder[A](tag: ClassTag[A]) extends Builder[A, WrappedArray[A]] {
+class WrappedArrayBuilder[A](tag: ClassTag[A]) extends ReusableBuilder[A, WrappedArray[A]] {
@deprecated("use tag instead", "2.10.0")
val manifest: ClassTag[A] = tag
@@ -32,7 +33,7 @@ class WrappedArrayBuilder[A](tag: ClassTag[A]) extends Builder[A, WrappedArray[A
private var size: Int = 0
private def mkArray(size: Int): WrappedArray[A] = {
- val runtimeClass = arrayElementClass(tag)
+ val runtimeClass = tag.runtimeClass
val newelems = runtimeClass match {
case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](size)).asInstanceOf[WrappedArray[A]]
case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](size)).asInstanceOf[WrappedArray[A]]
@@ -73,12 +74,13 @@ class WrappedArrayBuilder[A](tag: ClassTag[A]) extends Builder[A, WrappedArray[A
this
}
- def clear() {
- size = 0
- }
+ def clear() { size = 0 }
def result() = {
- if (capacity != 0 && capacity == size) elems
+ if (capacity != 0 && capacity == size) {
+ capacity = 0
+ elems
+ }
else mkArray(size)
}
diff --git a/src/library/scala/collection/package.scala b/src/library/scala/collection/package.scala
index 856f901b77..6df254c0e0 100644
--- a/src/library/scala/collection/package.scala
+++ b/src/library/scala/collection/package.scala
@@ -76,13 +76,9 @@ package scala
* The concrete parallel collections also have specific performance characteristics which are
* described in [[http://docs.scala-lang.org/overviews/parallel-collections/concrete-parallel-collections.html#performance-characteristics the parallel collections guide]]
*
- * === Converting between Java Collections ===
+ * === Converting to and from Java Collections ===
*
- * The [[scala.collection.JavaConversions]] object provides implicit defs that
- * will allow mostly seamless integration between APIs using Java Collections
- * and the Scala collections library.
- *
- * Alternatively the [[scala.collection.JavaConverters]] object provides a collection
+ * The [[scala.collection.JavaConverters]] object provides a collection
* of decorators that allow converting between Scala and Java collections using `asScala`
* and `asJava` methods.
*/
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index 8c9b959569..2ed7bc075e 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -9,6 +9,8 @@
package scala
package collection.parallel
+import scala.language.{ higherKinds, implicitConversions }
+
import scala.collection.mutable.Builder
import scala.collection.mutable.ArrayBuffer
import scala.collection.IterableLike
@@ -21,13 +23,9 @@ import scala.collection.GenIterable
import scala.collection.GenTraversableOnce
import scala.collection.GenTraversable
import immutable.HashMapCombiner
-import scala.reflect.{ClassTag, classTag}
-
-import java.util.concurrent.atomic.AtomicBoolean
+import scala.reflect.ClassTag
import scala.annotation.unchecked.uncheckedVariance
-import scala.annotation.unchecked.uncheckedStable
-import scala.language.{ higherKinds, implicitConversions }
import scala.collection.parallel.ParallelCollectionImplicits._
@@ -195,7 +193,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
* import scala.collection.parallel._
* val pc = mutable.ParArray(1, 2, 3)
* pc.tasksupport = new ForkJoinTaskSupport(
- * new scala.concurrent.forkjoin.ForkJoinPool(2))
+ * new java.util.concurrent.ForkJoinPool(2))
* }}}
*
* @see [[scala.collection.parallel.TaskSupport]]
@@ -1284,7 +1282,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
extends Transformer[Combiner[(U, S), That], Zip[U, S, That]] {
@volatile var result: Result = null
def leaf(prev: Option[Result]) = result = pit.zip2combiner[U, S, That](othpit, pbf())
- protected[this] def newSubtask(p: IterableSplitter[T]) = unsupported
+ protected[this] def newSubtask(p: IterableSplitter[T]) = throw new UnsupportedOperationException
override def split = {
val pits = pit.splitWithSignalling
val sizes = pits.map(_.remaining)
@@ -1300,7 +1298,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
extends Transformer[Combiner[(U, S), That], ZipAll[U, S, That]] {
@volatile var result: Result = null
def leaf(prev: Option[Result]) = result = pit.zipAll2combiner[U, S, That](othpit, thiselem, thatelem, pbf())
- protected[this] def newSubtask(p: IterableSplitter[T]) = unsupported
+ protected[this] def newSubtask(p: IterableSplitter[T]) = throw new UnsupportedOperationException
override def split = if (pit.remaining <= len) {
val pits = pit.splitWithSignalling
val sizes = pits.map(_.remaining)
@@ -1322,7 +1320,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
extends Accessor[Unit, CopyToArray[U, This]] {
@volatile var result: Unit = ()
def leaf(prev: Option[Unit]) = pit.copyToArray(array, from, len)
- protected[this] def newSubtask(p: IterableSplitter[T]) = unsupported
+ protected[this] def newSubtask(p: IterableSplitter[T]) = throw new UnsupportedOperationException
override def split = {
val pits = pit.splitWithSignalling
for ((p, untilp) <- pits zip pits.scanLeft(0)(_ + _.remaining); if untilp < len) yield {
@@ -1379,7 +1377,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
val half = howmany / 2
ScanNode(mergeTrees(trees, from, half), mergeTrees(trees, from + half, howmany - half))
} else trees(from)
- protected[this] def newSubtask(pit: IterableSplitter[T]) = unsupported
+ protected[this] def newSubtask(pit: IterableSplitter[T]) = throw new UnsupportedOperationException
override def split = {
val pits = pit.splitWithSignalling
for ((p, untilp) <- pits zip pits.scanLeft(from)(_ + _.remaining)) yield {
@@ -1416,7 +1414,7 @@ self: ParIterableLike[T, Repr, Sequential] =>
new FromScanTree(left, z, op, cbf),
new FromScanTree(right, z, op, cbf)
)
- case _ => unsupportedop("Cannot be split further")
+ case _ => throw new UnsupportedOperationException("Cannot be split further")
}
def shouldSplitFurther = tree match {
case ScanNode(_, _) => true
diff --git a/src/library/scala/collection/parallel/ParMap.scala b/src/library/scala/collection/parallel/ParMap.scala
index 9f92e6c1e8..70afe5174b 100644
--- a/src/library/scala/collection/parallel/ParMap.scala
+++ b/src/library/scala/collection/parallel/ParMap.scala
@@ -11,7 +11,6 @@ package collection.parallel
import scala.collection.Map
import scala.collection.GenMap
-import scala.collection.mutable.Builder
import scala.collection.generic.ParMapFactory
import scala.collection.generic.GenericParMapTemplate
import scala.collection.generic.GenericParMapCompanion
diff --git a/src/library/scala/collection/parallel/ParMapLike.scala b/src/library/scala/collection/parallel/ParMapLike.scala
index 0a671fb085..a3ac388587 100644
--- a/src/library/scala/collection/parallel/ParMapLike.scala
+++ b/src/library/scala/collection/parallel/ParMapLike.scala
@@ -12,10 +12,8 @@ package collection.parallel
import scala.collection.MapLike
import scala.collection.GenMapLike
import scala.collection.Map
-import scala.collection.mutable.Builder
+
import scala.annotation.unchecked.uncheckedVariance
-import scala.collection.generic.IdleSignalling
-import scala.collection.generic.Signalling
/** A template trait for mutable parallel maps. This trait is to be mixed in
* with concrete parallel maps to override the representation type.
diff --git a/src/library/scala/collection/parallel/ParSeqLike.scala b/src/library/scala/collection/parallel/ParSeqLike.scala
index 0b6fec364e..60fa1858e7 100644
--- a/src/library/scala/collection/parallel/ParSeqLike.scala
+++ b/src/library/scala/collection/parallel/ParSeqLike.scala
@@ -9,11 +9,10 @@
package scala
package collection.parallel
-import scala.collection.{ Parallel, SeqLike, GenSeqLike, GenSeq, GenIterable, Iterator }
+import scala.collection.{ SeqLike, GenSeq, GenIterable, Iterator }
import scala.collection.generic.DefaultSignalling
import scala.collection.generic.AtomicIndexFlag
import scala.collection.generic.CanBuildFrom
-import scala.collection.generic.CanCombineFrom
import scala.collection.generic.VolatileAbort
import scala.collection.parallel.ParallelCollectionImplicits._
@@ -365,7 +364,7 @@ self =>
pit.setIndexFlagIfLesser(from)
}
}
- protected[this] def newSubtask(p: SuperParIterator) = unsupported
+ protected[this] def newSubtask(p: SuperParIterator) = throw new UnsupportedOperationException
override def split = {
val pits = pit.splitWithSignalling
for ((p, untilp) <- pits zip pits.scanLeft(from)(_ + _.remaining)) yield new IndexWhere(pred, untilp, p)
@@ -386,7 +385,7 @@ self =>
pit.setIndexFlagIfGreater(pos)
}
}
- protected[this] def newSubtask(p: SuperParIterator) = unsupported
+ protected[this] def newSubtask(p: SuperParIterator) = throw new UnsupportedOperationException
override def split = {
val pits = pit.splitWithSignalling
for ((p, untilp) <- pits zip pits.scanLeft(pos)(_ + _.remaining)) yield new LastIndexWhere(pred, untilp, p)
@@ -420,7 +419,7 @@ self =>
result = pit.sameElements(otherpit)
if (!result) pit.abort()
}
- protected[this] def newSubtask(p: SuperParIterator) = unsupported
+ protected[this] def newSubtask(p: SuperParIterator) = throw new UnsupportedOperationException
override def split = {
val fp = pit.remaining / 2
val sp = pit.remaining - fp
@@ -434,7 +433,7 @@ self =>
extends Transformer[Combiner[U, That], Updated[U, That]] {
@volatile var result: Combiner[U, That] = null
def leaf(prev: Option[Combiner[U, That]]) = result = pit.updated2combiner(pos, elem, pbf())
- protected[this] def newSubtask(p: SuperParIterator) = unsupported
+ protected[this] def newSubtask(p: SuperParIterator) = throw new UnsupportedOperationException
override def split = {
val pits = pit.splitWithSignalling
for ((p, untilp) <- pits zip pits.scanLeft(0)(_ + _.remaining)) yield new Updated(pos - untilp, elem, pbf, p)
@@ -447,7 +446,7 @@ self =>
extends Transformer[Combiner[(U, S), That], Zip[U, S, That]] {
@volatile var result: Result = null
def leaf(prev: Option[Result]) = result = pit.zip2combiner[U, S, That](otherpit, cf())
- protected[this] def newSubtask(p: SuperParIterator) = unsupported
+ protected[this] def newSubtask(p: SuperParIterator) = throw new UnsupportedOperationException
override def split = {
val fp = len / 2
val sp = len - len / 2
@@ -468,7 +467,7 @@ self =>
result = pit.corresponds(corr)(otherpit)
if (!result) pit.abort()
}
- protected[this] def newSubtask(p: SuperParIterator) = unsupported
+ protected[this] def newSubtask(p: SuperParIterator) = throw new UnsupportedOperationException
override def split = {
val fp = pit.remaining / 2
val sp = pit.remaining - fp
diff --git a/src/library/scala/collection/parallel/RemainsIterator.scala b/src/library/scala/collection/parallel/RemainsIterator.scala
index 5f2ceac0e0..63d63d9ef3 100644
--- a/src/library/scala/collection/parallel/RemainsIterator.scala
+++ b/src/library/scala/collection/parallel/RemainsIterator.scala
@@ -9,13 +9,10 @@
package scala
package collection.parallel
-import scala.collection.Parallel
import scala.collection.generic.Signalling
import scala.collection.generic.DelegatedSignalling
import scala.collection.generic.IdleSignalling
-import scala.collection.generic.CanCombineFrom
import scala.collection.mutable.Builder
-import scala.collection.Iterator.empty
import scala.collection.GenTraversableOnce
import scala.collection.parallel.immutable.repetition
@@ -456,6 +453,15 @@ self =>
}
it
}
+ /** Drop implemented as simple eager consumption. */
+ override def drop(n: Int): IterableSplitter[T] = {
+ var i = 0
+ while (i < n && hasNext) {
+ next()
+ i += 1
+ }
+ this
+ }
override def take(n: Int): IterableSplitter[T] = newTaken(n)
override def slice(from1: Int, until1: Int): IterableSplitter[T] = newSliceInternal(newTaken(until1), from1)
diff --git a/src/library/scala/collection/parallel/TaskSupport.scala b/src/library/scala/collection/parallel/TaskSupport.scala
index 9064018d46..6ab694de04 100644
--- a/src/library/scala/collection/parallel/TaskSupport.scala
+++ b/src/library/scala/collection/parallel/TaskSupport.scala
@@ -10,7 +10,7 @@ package scala
package collection.parallel
import java.util.concurrent.ThreadPoolExecutor
-import scala.concurrent.forkjoin.ForkJoinPool
+import java.util.concurrent.ForkJoinPool
import scala.concurrent.ExecutionContext
/** A trait implementing the scheduling of a parallel collection operation.
@@ -41,7 +41,7 @@ import scala.concurrent.ExecutionContext
* import scala.collection.parallel._
* val pc = mutable.ParArray(1, 2, 3)
* pc.tasksupport = new ForkJoinTaskSupport(
- * new scala.concurrent.forkjoin.ForkJoinPool(2))
+ * new java.util.concurrent.ForkJoinPool(2))
* }}}
*
* @see [[http://docs.scala-lang.org/overviews/parallel-collections/configuration.html Configuring Parallel Collections]] section
diff --git a/src/library/scala/collection/parallel/Tasks.scala b/src/library/scala/collection/parallel/Tasks.scala
index fcf0dff846..2a4e40dd16 100644
--- a/src/library/scala/collection/parallel/Tasks.scala
+++ b/src/library/scala/collection/parallel/Tasks.scala
@@ -10,7 +10,7 @@ package scala
package collection.parallel
import java.util.concurrent.ThreadPoolExecutor
-import scala.concurrent.forkjoin._
+import java.util.concurrent.{ForkJoinPool, RecursiveAction, ForkJoinWorkerThread}
import scala.concurrent.ExecutionContext
import scala.util.control.Breaks._
import scala.annotation.unchecked.uncheckedVariance
@@ -66,13 +66,10 @@ trait Task[R, +Tp] {
}
private[parallel] def mergeThrowables(that: Task[_, _]) {
- // TODO: As soon as we target Java >= 7, use Throwable#addSuppressed
- // to pass additional Throwables to the caller, e. g.
- // if (this.throwable != null && that.throwable != null)
- // this.throwable.addSuppressed(that.throwable)
- // For now, we just use whatever Throwable comes across “first”.
- if (this.throwable == null && that.throwable != null)
- this.throwable = that.throwable
+ if (this.throwable != null && that.throwable != null)
+ this.throwable.addSuppressed(that.throwable)
+ else if (this.throwable == null && that.throwable != null)
+ this.throwable = that.throwable
}
// override in concrete task implementations to signal abort to other tasks
diff --git a/src/library/scala/collection/parallel/immutable/ParHashSet.scala b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
index 65a632470e..3a1ec7fff8 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashSet.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
@@ -197,7 +197,7 @@ extends scala.collection.parallel.BucketCombiner[T, ParHashSet[T], Any, HashSetC
while (i < chunksz) {
val v = chunkarr(i).asInstanceOf[T]
val hc = trie.computeHash(v)
- trie = trie.updated0(v, hc, rootbits)
+ trie = trie.updated0(v, hc, rootbits) // internal API, private[collection]
i += 1
}
i = 0
diff --git a/src/library/scala/collection/parallel/immutable/ParMap.scala b/src/library/scala/collection/parallel/immutable/ParMap.scala
index 2956c2a883..65bb2e12c5 100644
--- a/src/library/scala/collection/parallel/immutable/ParMap.scala
+++ b/src/library/scala/collection/parallel/immutable/ParMap.scala
@@ -16,7 +16,6 @@ import scala.collection.generic.GenericParMapCompanion
import scala.collection.generic.CanCombineFrom
import scala.collection.parallel.ParMapLike
import scala.collection.parallel.Combiner
-import scala.collection.GenMapLike
/** A template trait for immutable parallel maps.
*
diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala
index ec90de3a7d..8fd5382ce9 100644
--- a/src/library/scala/collection/parallel/immutable/ParRange.scala
+++ b/src/library/scala/collection/parallel/immutable/ParRange.scala
@@ -12,7 +12,6 @@ package collection.parallel.immutable
import scala.collection.immutable.Range
import scala.collection.parallel.Combiner
import scala.collection.parallel.SeqSplitter
-import scala.collection.generic.CanCombineFrom
import scala.collection.Iterator
/** Parallel ranges.
diff --git a/src/library/scala/collection/parallel/mutable/LazyCombiner.scala b/src/library/scala/collection/parallel/mutable/LazyCombiner.scala
index 5ab2bb81c6..cc25b5b4b2 100644
--- a/src/library/scala/collection/parallel/mutable/LazyCombiner.scala
+++ b/src/library/scala/collection/parallel/mutable/LazyCombiner.scala
@@ -30,7 +30,6 @@ trait LazyCombiner[Elem, +To, Buff <: Growable[Elem] with Sizing] extends Combin
def result: To = allocateAndCopy
def clear() = { chain.clear() }
def combine[N <: Elem, NewTo >: To](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this ne other) {
- import language.existentials // FIXME: See SI-7750
if (other.isInstanceOf[LazyCombiner[_, _, _]]) {
val that = other.asInstanceOf[LazyCombiner[Elem, To, Buff]]
newLazyCombiner(chain ++= that.chain)
diff --git a/src/library/scala/collection/parallel/mutable/ParArray.scala b/src/library/scala/collection/parallel/mutable/ParArray.scala
index d0d022db4b..8a2cf2716a 100644
--- a/src/library/scala/collection/parallel/mutable/ParArray.scala
+++ b/src/library/scala/collection/parallel/mutable/ParArray.scala
@@ -18,7 +18,6 @@ import scala.collection.generic.GenericParCompanion
import scala.collection.generic.CanCombineFrom
import scala.collection.generic.CanBuildFrom
import scala.collection.generic.ParFactory
-import scala.collection.generic.Sizing
import scala.collection.parallel.Combiner
import scala.collection.parallel.SeqSplitter
import scala.collection.parallel.ParSeqLike
diff --git a/src/library/scala/collection/parallel/mutable/ParTrieMap.scala b/src/library/scala/collection/parallel/mutable/ParTrieMap.scala
index a1dc37cec9..2faf223b99 100644
--- a/src/library/scala/collection/parallel/mutable/ParTrieMap.scala
+++ b/src/library/scala/collection/parallel/mutable/ParTrieMap.scala
@@ -152,18 +152,9 @@ extends TrieMapIterator[K, V](lev, ct, mustInit)
/** Only used within the `ParTrieMap`. */
private[mutable] trait ParTrieMapCombiner[K, V] extends Combiner[(K, V), ParTrieMap[K, V]] {
- def combine[N <: (K, V), NewTo >: ParTrieMap[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[ParTrieMap[K, V]]
- val that = other.asInstanceOf[ParTrieMap[K, V]]
- val result = new ParTrieMap[K, V]
-
- result ++= thiz.iterator
- result ++= that.iterator
-
- result
- }
+ def combine[N <: (K, V), NewTo >: ParTrieMap[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.")
override def canBeShared = true
}
diff --git a/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala b/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
index 79322c85b1..6883457fef 100644
--- a/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
+++ b/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
@@ -9,18 +9,10 @@
package scala
package collection.parallel.mutable
-
-
-import scala.collection.generic.Sizing
import scala.collection.mutable.ArraySeq
import scala.collection.mutable.ArrayBuffer
-import scala.collection.parallel.TaskSupport
-import scala.collection.parallel.unsupportedop
-import scala.collection.parallel.Combiner
import scala.collection.parallel.Task
-
-
/** An array combiner that uses a chain of arraybuffers to store elements. */
trait ResizableParArrayCombiner[T] extends LazyCombiner[T, ParArray[T], ExposedArrayBuffer[T]] {
diff --git a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala
index d1379cde11..e71e61f2f1 100644
--- a/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala
+++ b/src/library/scala/collection/parallel/mutable/UnrolledParArrayCombiner.scala
@@ -9,23 +9,11 @@
package scala
package collection.parallel.mutable
-import scala.collection.generic.Sizing
import scala.collection.mutable.ArraySeq
-import scala.collection.mutable.ArrayBuffer
-import scala.collection.mutable.UnrolledBuffer
+import scala.collection.mutable.DoublingUnrolledBuffer
import scala.collection.mutable.UnrolledBuffer.Unrolled
-import scala.collection.parallel.TaskSupport
-import scala.collection.parallel.unsupportedop
import scala.collection.parallel.Combiner
import scala.collection.parallel.Task
-import scala.reflect.ClassTag
-
-// Todo -- revisit whether inheritance is the best way to achieve this functionality
-private[mutable] class DoublingUnrolledBuffer[T](implicit t: ClassTag[T]) extends UnrolledBuffer[T]()(t) {
- override def calcNextLength(sz: Int) = if (sz < 10000) sz * 2 else sz
- protected override def newUnrolled = new Unrolled[T](0, new Array[T](4), null, this)
-}
-
/** An array combiner that uses doubling unrolled buffers to store elements. */
trait UnrolledParArrayCombiner[T]
@@ -62,7 +50,7 @@ extends Combiner[T, ParArray[T]] {
case that: UnrolledParArrayCombiner[t] =>
buff concat that.buff
this
- case _ => unsupportedop("Cannot combine with combiner of different type.")
+ case _ => throw new UnsupportedOperationException("Cannot combine with combiner of different type.")
}
def size = buff.size
diff --git a/src/library/scala/collection/parallel/package.scala b/src/library/scala/collection/parallel/package.scala
index d77dcb0658..ba64ca505b 100644
--- a/src/library/scala/collection/parallel/package.scala
+++ b/src/library/scala/collection/parallel/package.scala
@@ -35,15 +35,7 @@ package object parallel {
else sz
}
- private[parallel] def unsupported = throw new UnsupportedOperationException
-
- private[parallel] def unsupportedop(msg: String) = throw new UnsupportedOperationException(msg)
-
- private[parallel] def outofbounds(idx: Int) = throw new IndexOutOfBoundsException(idx.toString)
-
- private[parallel] def getTaskSupport: TaskSupport = new ExecutionContextTaskSupport
-
- val defaultTaskSupport: TaskSupport = getTaskSupport
+ val defaultTaskSupport: TaskSupport = new ExecutionContextTaskSupport
def setTaskSupport[Coll](c: Coll, t: TaskSupport): Coll = {
c match {
@@ -98,7 +90,7 @@ package parallel {
}
}
}
-
+
trait FactoryOps[From, Elem, To] {
trait Otherwise[R] {
def otherwise(notbody: => R): R
diff --git a/src/library/scala/compat/Platform.scala b/src/library/scala/compat/Platform.scala
index 42dfcbfdde..f3745bc189 100644
--- a/src/library/scala/compat/Platform.scala
+++ b/src/library/scala/compat/Platform.scala
@@ -105,8 +105,7 @@ object Platform {
/** The default line separator.
*
* On the JVM, this is equivalent to calling the method:
- * `System.getProperty("line.separator")`
- * with a default value of "\n".
+ * `java.lang.System.lineSeparator`
*/
val EOL = scala.util.Properties.lineSeparator
diff --git a/src/library/scala/concurrent/BlockContext.scala b/src/library/scala/concurrent/BlockContext.scala
index 747cc393c3..2b8ed4c7ca 100644
--- a/src/library/scala/concurrent/BlockContext.scala
+++ b/src/library/scala/concurrent/BlockContext.scala
@@ -41,7 +41,7 @@ package scala.concurrent
trait BlockContext {
/** Used internally by the framework;
- * Designates (and eventually executes) a thunk which potentially blocks the calling `Thread`.
+ * Designates (and eventually executes) a thunk which potentially blocks the calling `java.lang.Thread`.
*
* Clients must use `scala.concurrent.blocking` or `scala.concurrent.Await` instead.
*/
@@ -53,9 +53,16 @@ object BlockContext {
override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = thunk
}
+ /**
+ * @return the `BlockContext` that will be used if no other is found.
+ **/
+ def defaultBlockContext: BlockContext = DefaultBlockContext
+
private val contextLocal = new ThreadLocal[BlockContext]()
- /** Obtain the current thread's current `BlockContext`. */
+ /**
+ @return the `BlockContext` that would be used for the current `java.lang.Thread` at this point
+ **/
def current: BlockContext = contextLocal.get match {
case null => Thread.currentThread match {
case ctx: BlockContext => ctx
@@ -64,7 +71,9 @@ object BlockContext {
case some => some
}
- /** Pushes a current `BlockContext` while executing `body`. */
+ /**
+ * Installs a current `BlockContext` around executing `body`.
+ **/
def withBlockContext[T](blockContext: BlockContext)(body: => T): T = {
val old = contextLocal.get // can be null
try {
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index e380c55880..e022b94ea8 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -11,7 +11,6 @@ package scala.concurrent
import java.util.concurrent.{ ExecutorService, Executor }
import scala.annotation.implicitNotFound
-import scala.util.Try
/**
* An `ExecutionContext` can execute program logic asynchronously,
@@ -72,22 +71,24 @@ trait ExecutionContext {
*/
def reportFailure(@deprecatedName('t) cause: Throwable): Unit
- /** Prepares for the execution of a task. Returns the prepared execution context.
- *
- * `prepare` should be called at the site where an `ExecutionContext` is received (for
- * example, through an implicit method parameter). The returned execution context may
- * then be used to execute tasks. The role of `prepare` is to save any context relevant
- * to an execution's ''call site'', so that this context may be restored at the
- * ''execution site''. (These are often different: for example, execution may be
- * suspended through a `Promise`'s future until the `Promise` is completed, which may
- * be done in another thread, on another stack.)
- *
- * Note: a valid implementation of `prepare` is one that simply returns `this`.
- *
- * @return the prepared execution context
- */
+ /** Prepares for the execution of a task. Returns the prepared
+ * execution context. The recommended implementation of
+ * `prepare` is to return `this`.
+ *
+ * This method should no longer be overridden or called. It was
+ * originally expected that `prepare` would be called by
+ * all libraries that consume ExecutionContexts, in order to
+ * capture thread local context. However, this usage has proven
+ * difficult to implement in practice and instead it is
+ * now better to avoid using `prepare` entirely.
+ *
+ * Instead, if an `ExecutionContext` needs to capture thread
+ * local context, it should capture that context when it is
+ * constructed, so that it doesn't need any additional
+ * preparation later.
+ */
+ @deprecated("Preparation of ExecutionContexts will be removed.", "2.12")
def prepare(): ExecutionContext = this
-
}
/**
@@ -116,7 +117,7 @@ object ExecutionContext {
*
* @return the global `ExecutionContext`
*/
- def global: ExecutionContextExecutor = Implicits.global
+ def global: ExecutionContextExecutor = Implicits.global.asInstanceOf[ExecutionContextExecutor]
object Implicits {
/**
@@ -127,7 +128,7 @@ object ExecutionContext {
* the thread pool uses a target number of worker threads equal to the number of
* [[https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#availableProcessors-- available processors]].
*/
- implicit lazy val global: ExecutionContextExecutor = impl.ExecutionContextImpl.fromExecutor(null: Executor)
+ implicit lazy val global: ExecutionContext = impl.ExecutionContextImpl.fromExecutor(null: Executor)
}
/** Creates an `ExecutionContext` from the given `ExecutorService`.
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index ebc1e76ca1..d9d3d572e8 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -10,34 +10,27 @@ package scala.concurrent
import scala.language.higherKinds
-import java.util.concurrent.{ ConcurrentLinkedQueue, TimeUnit, Callable }
-import java.util.concurrent.TimeUnit.{ NANOSECONDS => NANOS, MILLISECONDS ⇒ MILLIS }
-import java.lang.{ Iterable => JIterable }
-import java.util.{ LinkedList => JLinkedList }
-import java.util.concurrent.atomic.{ AtomicReferenceFieldUpdater, AtomicInteger, AtomicLong, AtomicBoolean }
+import java.util.concurrent.{CountDownLatch, TimeUnit}
+import java.util.concurrent.atomic.AtomicInteger
import scala.util.control.NonFatal
-import scala.Option
import scala.util.{Try, Success, Failure}
-
-import scala.annotation.tailrec
-import scala.collection.mutable.Builder
+import scala.concurrent.duration._
import scala.collection.generic.CanBuildFrom
import scala.reflect.ClassTag
-
/** The trait that represents futures.
*
- * Asynchronous computations that yield futures are created with the `Future` call:
+ * Asynchronous computations that yield futures are created with the `Future.apply` call:
*
* {{{
* val s = "Hello"
* val f: Future[String] = Future {
* s + " future!"
* }
- * f onSuccess {
- * case msg => println(msg)
+ * f foreach {
+ * msg => println(msg)
* }
* }}}
*
@@ -62,6 +55,10 @@ import scala.reflect.ClassTag
* If a future is failed with a `scala.runtime.NonLocalReturnControl`,
* it is completed with a value from that throwable instead.
*
+ * @define swallowsExceptions
+ * Since this method executes asynchronously and does not produce a return value,
+ * any non-fatal exceptions thrown will be reported to the `ExecutionContext`.
+ *
* @define nonDeterministic
* Note: using this method yields nondeterministic dataflow programs.
*
@@ -93,14 +90,7 @@ import scala.reflect.ClassTag
* `execute()` either immediately or asynchronously.
*/
trait Future[+T] extends Awaitable[T] {
-
- // The executor within the lexical scope
- // of the Future trait. Note that this will
- // (modulo bugs) _never_ execute a callback
- // other than those below in this same file.
- //
- // See the documentation on `InternalCallbackExecutor` for more details.
- private def internalExecutor = Future.InternalCallbackExecutor
+ import Future.{ InternalCallbackExecutor => internalExecutor }
/* Callbacks */
@@ -111,9 +101,11 @@ trait Future[+T] extends Awaitable[T] {
* If the future has already been completed with a value,
* this will either be applied immediately or be scheduled asynchronously.
*
+ * $swallowsExceptions
* $multipleCallbacks
* $callbackInContext
*/
+ @deprecated("use `foreach` or `onComplete` instead (keep in mind that they take total rather than partial functions)", "2.12")
def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = onComplete {
case Success(v) =>
pf.applyOrElse[T, Any](v, Predef.conforms[T]) // Exploiting the cached function to avoid MatchError
@@ -130,9 +122,11 @@ trait Future[+T] extends Awaitable[T] {
*
* Will not be called in case that the future is completed with a value.
*
+ * $swallowsExceptions
* $multipleCallbacks
* $callbackInContext
*/
+ @deprecated("use `onComplete` or `failed.foreach` instead (keep in mind that they take total rather than partial functions)", "2.12")
def onFailure[U](@deprecatedName('callback) pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = onComplete {
case Failure(t) =>
pf.applyOrElse[Throwable, Any](t, Predef.conforms[Throwable]) // Exploiting the cached function to avoid MatchError
@@ -145,8 +139,12 @@ trait Future[+T] extends Awaitable[T] {
* If the future has already been completed,
* this will either be applied immediately or be scheduled asynchronously.
*
+ * $swallowsExceptions
* $multipleCallbacks
* $callbackInContext
+ *
+ * @tparam U only used to accept any return type of the given callback function
+ * @param f the function to be executed when this `Future` completes
*/
def onComplete[U](@deprecatedName('func) f: Try[T] => U)(implicit executor: ExecutionContext): Unit
@@ -162,46 +160,47 @@ trait Future[+T] extends Awaitable[T] {
*/
def isCompleted: Boolean
- /** The value of this `Future`.
+ /** The current value of this `Future`.
+ *
+ * $nonDeterministic
*
* If the future is not completed the returned value will be `None`.
* If the future is completed the value will be `Some(Success(t))`
* if it contains a valid result, or `Some(Failure(error))` if it contains
* an exception.
+ *
+ * @return `None` if the `Future` wasn't completed, `Some` if it was.
*/
def value: Option[Try[T]]
/* Projections */
- /** Returns a failed projection of this future.
+ /** The returned `Future` will be successfully completed with the `Throwable` of the original `Future`
+ * if the original `Future` fails.
*
- * The failed projection is a future holding a value of type `Throwable`.
+ * If the original `Future` is successful, the returned `Future` is failed with a `NoSuchElementException`.
*
- * It is completed with a value which is the throwable of the original future
- * in case the original future is failed.
- *
- * It is failed with a `NoSuchElementException` if the original future is completed successfully.
- *
- * Blocking on this future returns a value if the original future is completed with an exception
- * and throws a corresponding exception if the original future fails.
+ * @return a failed projection of this `Future`.
*/
- def failed: Future[Throwable] = {
- implicit val ec = internalExecutor
- val p = Promise[Throwable]()
- onComplete {
- case Failure(t) => p success t
- case Success(v) => p failure (new NoSuchElementException("Future.failed not completed with a throwable."))
- }
- p.future
- }
+ def failed: Future[Throwable] =
+ transform({
+ case Failure(t) => Success(t)
+ case Success(v) => Failure(new NoSuchElementException("Future.failed not completed with a throwable."))
+ })(internalExecutor)
/* Monadic operations */
/** Asynchronously processes the value in the future once the value becomes available.
*
- * Will not be called if the future fails.
+ * WARNING: Will not be called if this future is never completed or if it is completed with a failure.
+ *
+ * $swallowsExceptions
+ *
+ * @tparam U only used to accept any return type of the given callback function
+ * @param f the function which will be executed if this `Future` completes with a result,
+ * the return value of `f` will be discarded.
*/
def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit = onComplete { _ foreach f }
@@ -210,33 +209,59 @@ trait Future[+T] extends Awaitable[T] {
* exception thrown when 's' or 'f' is applied, that exception will be propagated
* to the resulting future.
*
- * @param s function that transforms a successful result of the receiver into a
- * successful result of the returned future
- * @param f function that transforms a failure of the receiver into a failure of
- * the returned future
- * @return a future that will be completed with the transformed value
- */
- def transform[S](s: T => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] = {
- val p = Promise[S]()
- // transform on Try has the wrong shape for us here
- onComplete {
- case Success(r) => p complete Try(s(r))
- case Failure(t) => p complete Try(throw f(t)) // will throw fatal errors!
+ * @tparam S the type of the returned `Future`
+ * @param s function that transforms a successful result of the receiver into a successful result of the returned future
+ * @param f function that transforms a failure of the receiver into a failure of the returned future
+ * @return a `Future` that will be completed with the transformed value
+ */
+ def transform[S](s: T => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] =
+ transform {
+ case Success(r) => Try(s(r))
+ case Failure(t) => Try(throw f(t)) // will throw fatal errors!
}
- p.future
- }
+
+ /** Creates a new Future by applying the specified function to the result
+ * of this Future. If there is any non-fatal exception thrown when 'f'
+ * is applied then that exception will be propagated to the resulting future.
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f function that transforms the result of this future
+ * @return a `Future` that will be completed with the transformed value
+ */
+ def transform[S](f: Try[T] => Try[S])(implicit executor: ExecutionContext): Future[S]
+
+ /** Creates a new Future by applying the specified function, which produces a Future, to the result
+ * of this Future. If there is any non-fatal exception thrown when 'f'
+ * is applied then that exception will be propagated to the resulting future.
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f function that transforms the result of this future
+ * @return a `Future` that will be completed with the transformed value
+ */
+ def transformWith[S](f: Try[T] => Future[S])(implicit executor: ExecutionContext): Future[S]
+
/** Creates a new future by applying a function to the successful result of
* this future. If this future is completed with an exception then the new
* future will also contain this exception.
*
- * $forComprehensionExamples
+ * Example:
+ *
+ * {{{
+ * val f = Future { "The future" }
+ * val g = f map { x: String => x + " is now!" }
+ * }}}
+ *
+ * Note that a for comprehension involving a `Future`
+ * may expand to include a call to `map` and or `flatMap`
+ * and `withFilter`. See [[scala.concurrent.Future#flatMap]] for an example of such a comprehension.
+ *
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f the function which will be applied to the successful result of this `Future`
+ * @return a `Future` which will be completed with the result of the application of the function
*/
- def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity)
- val p = Promise[S]()
- onComplete { v => p complete (v map f) }
- p.future
- }
+ def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = transform(_.map(f))
/** Creates a new future by applying a function to the successful result of
* this future, and returns the result of the function as the new future.
@@ -244,21 +269,23 @@ trait Future[+T] extends Awaitable[T] {
* also contain this exception.
*
* $forComprehensionExamples
+ *
+ * @tparam S the type of the returned `Future`
+ * @param f the function which will be applied to the successful result of this `Future`
+ * @return a `Future` which will be completed with the result of the application of the function
*/
- def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = {
- import impl.Promise.DefaultPromise
- val p = new DefaultPromise[S]()
- onComplete {
- case f: Failure[_] => p complete f.asInstanceOf[Failure[S]]
- case Success(v) => try f(v) match {
- // If possible, link DefaultPromises to avoid space leaks
- case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p)
- case fut => fut.onComplete(p.complete)(internalExecutor)
- } catch { case NonFatal(t) => p failure t }
- }
- p.future
+ def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = transformWith {
+ case Success(s) => f(s)
+ case Failure(_) => this.asInstanceOf[Future[S]]
}
+ /** Creates a new future with one level of nesting flattened, this method is equivalent
+ * to `flatMap(identity)`.
+ *
+ * @tparam S the type of the returned `Future`
+ */
+ def flatten[S](implicit ev: T <:< Future[S]): Future[S] = flatMap(ev)(internalExecutor)
+
/** Creates a new future by filtering the value of the current future with a predicate.
*
* If the current future contains a value which satisfies the predicate, the new future will also hold that value.
@@ -271,14 +298,15 @@ trait Future[+T] extends Awaitable[T] {
* val f = Future { 5 }
* val g = f filter { _ % 2 == 1 }
* val h = f filter { _ % 2 == 0 }
- * Await.result(g, Duration.Zero) // evaluates to 5
+ * g foreach println // Eventually prints 5
* Await.result(h, Duration.Zero) // throw a NoSuchElementException
* }}}
+ *
+ * @param p the predicate to apply to the successful result of this `Future`
+ * @return a `Future` which will hold the successful result of this `Future` if it matches the predicate or a `NoSuchElementException`
*/
def filter(@deprecatedName('pred) p: T => Boolean)(implicit executor: ExecutionContext): Future[T] =
- map {
- r => if (p(r)) r else throw new NoSuchElementException("Future.filter predicate is not satisfied")
- }
+ map { r => if (p(r)) r else throw new NoSuchElementException("Future.filter predicate is not satisfied") }
/** Used by for-comprehensions.
*/
@@ -300,9 +328,13 @@ trait Future[+T] extends Awaitable[T] {
* val h = f collect {
* case x if x > 0 => x * 2
* }
- * Await.result(g, Duration.Zero) // evaluates to 5
+ * g foreach println // Eventually prints 5
* Await.result(h, Duration.Zero) // throw a NoSuchElementException
* }}}
+ *
+ * @tparam S the type of the returned `Future`
+ *  @param pf the `PartialFunction` to apply to the successful result of this `Future`
+ * @return a `Future` holding the result of application of the `PartialFunction` or a `NoSuchElementException`
*/
def collect[S](pf: PartialFunction[T, S])(implicit executor: ExecutionContext): Future[S] =
map {
@@ -320,12 +352,13 @@ trait Future[+T] extends Awaitable[T] {
* Future (6 / 0) recover { case e: NotFoundException => 0 } // result: exception
* Future (6 / 2) recover { case e: ArithmeticException => 0 } // result: 3
* }}}
+ *
+ * @tparam U the type of the returned `Future`
+ * @param pf the `PartialFunction` to apply if this `Future` fails
+ * @return a `Future` with the successful value of this `Future` or the result of the `PartialFunction`
*/
- def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = {
- val p = Promise[U]()
- onComplete { v => p complete (v recover pf) }
- p.future
- }
+ def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] =
+ transform { _ recover pf }
/** Creates a new future that will handle any matching throwable that this
* future might contain by assigning it a value of another future.
@@ -339,15 +372,16 @@ trait Future[+T] extends Awaitable[T] {
* val f = Future { Int.MaxValue }
* Future (6 / 0) recoverWith { case e: ArithmeticException => f } // result: Int.MaxValue
* }}}
+ *
+ * @tparam U the type of the returned `Future`
+ * @param pf the `PartialFunction` to apply if this `Future` fails
+ * @return a `Future` with the successful value of this `Future` or the outcome of the `Future` returned by the `PartialFunction`
*/
- def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = {
- val p = Promise[U]()
- onComplete {
- case Failure(t) => try pf.applyOrElse(t, (_: Throwable) => this).onComplete(p.complete)(internalExecutor) catch { case NonFatal(t) => p failure t }
- case other => p complete other
+ def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] =
+ transformWith {
+ case Failure(t) => pf.applyOrElse(t, (_: Throwable) => this)
+ case Success(_) => this
}
- p.future
- }
/** Zips the values of `this` and `that` future, and creates
* a new future holding the tuple of their results.
@@ -356,17 +390,35 @@ trait Future[+T] extends Awaitable[T] {
* with the throwable stored in `this`.
* Otherwise, if `that` future fails, the resulting future is failed
* with the throwable stored in `that`.
+ *
+ * @tparam U the type of the other `Future`
+ * @param that the other `Future`
+ * @return a `Future` with the results of both futures or the failure of the first of them that failed
*/
def zip[U](that: Future[U]): Future[(T, U)] = {
implicit val ec = internalExecutor
- val p = Promise[(T, U)]()
- onComplete {
- case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]]
- case Success(s) => that onComplete { c => p.complete(c map { s2 => (s, s2) }) }
- }
- p.future
+ flatMap { r1 => that.map(r2 => (r1, r2)) }
}
+ /** Zips the values of `this` and `that` future using a function `f`,
+ * and creates a new future holding the result.
+ *
+ * If `this` future fails, the resulting future is failed
+ * with the throwable stored in `this`.
+ * Otherwise, if `that` future fails, the resulting future is failed
+ * with the throwable stored in `that`.
+ * If the application of `f` throws a throwable, the resulting future
+ * is failed with that throwable if it is non-fatal.
+ *
+ * @tparam U the type of the other `Future`
+ * @tparam R the type of the resulting `Future`
+ * @param that the other `Future`
+ * @param f the function to apply to the results of `this` and `that`
+ * @return a `Future` with the result of the application of `f` to the results of `this` and `that`
+ */
+ def zipWith[U, R](that: Future[U])(f: (T, U) => R)(implicit executor: ExecutionContext): Future[R] =
+ flatMap(r1 => that.map(r2 => f(r1, r2)))(internalExecutor)
+
/** Creates a new future which holds the result of this future if it was completed successfully, or, if not,
* the result of the `that` future if `that` is completed successfully.
* If both futures are failed, the resulting future holds the throwable object of the first future.
@@ -378,24 +430,26 @@ trait Future[+T] extends Awaitable[T] {
* val f = Future { sys.error("failed") }
* val g = Future { 5 }
* val h = f fallbackTo g
- * Await.result(h, Duration.Zero) // evaluates to 5
+ * h foreach println // Eventually prints 5
* }}}
+ *
+ * @tparam U the type of the other `Future` and the resulting `Future`
+ * @param that the `Future` whose result we want to use if this `Future` fails.
+ * @return a `Future` with the successful result of this or that `Future` or the failure of this `Future` if both fail
*/
- def fallbackTo[U >: T](that: Future[U]): Future[U] = {
- implicit val ec = internalExecutor
- val p = Promise[U]()
- onComplete {
- case s @ Success(_) => p complete s
- case f @ Failure(_) => that onComplete {
- case s2 @ Success(_) => p complete s2
- case _ => p complete f // Use the first failure as the failure
- }
+ def fallbackTo[U >: T](that: Future[U]): Future[U] =
+ if (this eq that) this
+ else {
+ implicit val ec = internalExecutor
+ recoverWith { case _ => that } recoverWith { case _ => this }
}
- 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.
+ *
+ * @tparam S the type of the returned `Future`
+ * @param tag the `ClassTag` which will be used to cast the result of this `Future`
+ * @return a `Future` holding the casted result of this `Future` or a `ClassCastException` otherwise
*/
def mapTo[S](implicit tag: ClassTag[S]): Future[S] = {
implicit val ec = internalExecutor
@@ -429,15 +483,19 @@ trait Future[+T] extends Awaitable[T] {
* case Success(v) => println(v)
* }
* }}}
+ *
+ * @tparam U only used to accept any return type of the given `PartialFunction`
+ * @param pf a `PartialFunction` which will be conditionally applied to the outcome of this `Future`
+ * @return a `Future` which will be completed with the exact same outcome as this `Future` but after the `PartialFunction` has been executed.
*/
- def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] = {
- val p = Promise[T]()
- onComplete {
- case r => try pf.applyOrElse[Try[T], Any](r, Predef.conforms[Try[T]]) finally p complete r
- }
- p.future
- }
+ def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T] =
+ transform {
+ result =>
+ try pf.applyOrElse[Try[T], Any](result, Predef.conforms[Try[T]])
+ catch { case NonFatal(t) => executor reportFailure t }
+ result
+ }
}
@@ -461,40 +519,102 @@ object Future {
classOf[Unit] -> classOf[scala.runtime.BoxedUnit]
)
+ /** A Future which is never completed.
+ */
+ final object never extends Future[Nothing] {
+
+ @throws(classOf[TimeoutException])
+ @throws(classOf[InterruptedException])
+ override def ready(atMost: Duration)(implicit permit: CanAwait): this.type = {
+ atMost match {
+ case e if e eq Duration.Undefined => throw new IllegalArgumentException("cannot wait for Undefined period")
+ case Duration.Inf => new CountDownLatch(1).await()
+ case Duration.MinusInf => // Drop out
+ case f: FiniteDuration =>
+ if (f > Duration.Zero) new CountDownLatch(1).await(f.toNanos, TimeUnit.NANOSECONDS)
+ }
+ throw new TimeoutException(s"Future timed out after [$atMost]")
+ }
+
+ @throws(classOf[Exception])
+ override def result(atMost: Duration)(implicit permit: CanAwait): Nothing = {
+ ready(atMost)
+ throw new TimeoutException(s"Future timed out after [$atMost]")
+ }
+
+ override def onSuccess[U](pf: PartialFunction[Nothing, U])(implicit executor: ExecutionContext): Unit = ()
+ override def onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = ()
+ override def onComplete[U](f: Try[Nothing] => U)(implicit executor: ExecutionContext): Unit = ()
+ override def isCompleted: Boolean = false
+ override def value: Option[Try[Nothing]] = None
+ override def failed: Future[Throwable] = this
+ override def foreach[U](f: Nothing => U)(implicit executor: ExecutionContext): Unit = ()
+ override def transform[S](s: Nothing => S, f: Throwable => Throwable)(implicit executor: ExecutionContext): Future[S] = this
+ override def transform[S](f: Try[Nothing] => Try[S])(implicit executor: ExecutionContext): Future[S] = this
+ override def transformWith[S](f: Try[Nothing] => Future[S])(implicit executor: ExecutionContext): Future[S] = this
+ override def map[S](f: Nothing => S)(implicit executor: ExecutionContext): Future[S] = this
+ override def flatMap[S](f: Nothing => Future[S])(implicit executor: ExecutionContext): Future[S] = this
+ override def flatten[S](implicit ev: Nothing <:< Future[S]): Future[S] = this
+ override def filter(p: Nothing => Boolean)(implicit executor: ExecutionContext): Future[Nothing] = this
+ override def collect[S](pf: PartialFunction[Nothing, S])(implicit executor: ExecutionContext): Future[S] = this
+ override def recover[U >: Nothing](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = this
+ override def recoverWith[U >: Nothing](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = this
+ override def zip[U](that: Future[U]): Future[(Nothing, U)] = this
+ override def zipWith[U, R](that: Future[U])(f: (Nothing, U) => R)(implicit executor: ExecutionContext): Future[R] = this
+ override def fallbackTo[U >: Nothing](that: Future[U]): Future[U] = this
+ override def mapTo[S](implicit tag: ClassTag[S]): Future[S] = this
+ override def andThen[U](pf: PartialFunction[Try[Nothing], U])(implicit executor: ExecutionContext): Future[Nothing] = this
+
+ override def toString: String = "Future(<never>)"
+ }
+
+ /** A Future which is always completed with the Unit value.
+ */
+ val unit: Future[Unit] = successful(())
+
/** Creates an already completed Future with the specified exception.
*
- * @tparam T the type of the value in the future
- * @return the newly created `Future` object
+ * @tparam T the type of the value in the future
+ * @param exception the non-null instance of `Throwable`
+ * @return the newly created `Future` instance
*/
def failed[T](exception: Throwable): Future[T] = Promise.failed(exception).future
/** Creates an already completed Future with the specified result.
*
* @tparam T the type of the value in the future
- * @return the newly created `Future` object
+ * @param result the given successful value
+ * @return the newly created `Future` instance
*/
def successful[T](result: T): Future[T] = Promise.successful(result).future
/** Creates an already completed Future with the specified result or exception.
*
- * @tparam T the type of the value in the promise
- * @return the newly created `Future` object
+ * @tparam T the type of the value in the `Future`
+ * @param result the result of the returned `Future` instance
+ * @return the newly created `Future` instance
*/
def fromTry[T](result: Try[T]): Future[T] = Promise.fromTry(result).future
- /** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
+ /** Starts an asynchronous computation and returns a `Future` instance with the result of that computation.
*
* The result becomes available once the asynchronous computation is completed.
*
- * @tparam T the type of the result
- * @param body the asynchronous computation
+ * @tparam T the type of the result
+ * @param body the asynchronous computation
* @param executor the execution context on which the future is run
- * @return the `Future` holding the result of the computation
+ * @return the `Future` holding the result of the computation
*/
- def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] = impl.Future(body)
+ def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] =
+ unit.map(_ => body)
- /** Simple version of `Future.traverse`. Transforms a `TraversableOnce[Future[A]]` into a `Future[TraversableOnce[A]]`.
- * Useful for reducing many `Future`s into a single `Future`.
+ /** Simple version of `Future.traverse`. Asynchronously and non-blockingly transforms a `TraversableOnce[Future[A]]`
+ * into a `Future[TraversableOnce[A]]`. Useful for reducing many `Future`s into a single `Future`.
+ *
+ * @tparam A the type of the value inside the Futures
+ * @tparam M the type of the `TraversableOnce` of Futures
+ * @param in the `TraversableOnce` of Futures which will be sequenced
+ * @return the `Future` of the `TraversableOnce` of results
*/
def sequence[A, M[X] <: TraversableOnce[X]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = {
in.foldLeft(successful(cbf(in))) {
@@ -502,7 +622,12 @@ object Future {
}.map(_.result())(InternalCallbackExecutor)
}
- /** Returns a new `Future` to the result of the first future in the list that is completed.
+ /** Asynchronously and non-blockingly returns a new `Future` to the result of the first future
+ * in the list that is completed. This means no matter if it is completed as a success or as a failure.
+ *
+ * @tparam T the type of the value in the future
+ * @param futures the `TraversableOnce` of Futures in which to find the first completed
+ * @return the `Future` holding the result of the future that is first to be completed
*/
def firstCompletedOf[T](futures: TraversableOnce[Future[T]])(implicit executor: ExecutionContext): Future[T] = {
val p = Promise[T]()
@@ -511,8 +636,15 @@ object Future {
p.future
}
- /** Returns a `Future` that will hold the optional result of the first `Future` with a result that matches the predicate.
+ /** Asynchronously and non-blockingly returns a `Future` that will hold the optional result
+ * of the first `Future` with a result that matches the predicate.
+ *
+ * @tparam T the type of the value in the future
+ * @param futures the `TraversableOnce` of Futures to search
+ * @param p the predicate which indicates if it's a match
+ * @return the `Future` holding the optional result of the search
*/
+ @deprecated("Use the overloaded version of this method that takes a scala.collection.immutable.Iterable instead", "2.12")
def find[T](@deprecatedName('futurestravonce) futures: TraversableOnce[Future[T]])(@deprecatedName('predicate) p: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = {
val futuresBuffer = futures.toBuffer
if (futuresBuffer.isEmpty) successful[Option[T]](None)
@@ -536,40 +668,127 @@ object Future {
}
}
- /** A non-blocking fold over the specified futures, with the start value of the given zero.
+
+ /** Asynchronously and non-blockingly returns a `Future` that will hold the optional result
+ * of the first `Future` with a result that matches the predicate, failed `Future`s will be ignored.
+ *
+ * @tparam T the type of the value in the future
+ * @param futures the `scala.collection.immutable.Iterable` of Futures to search
+ * @param p the predicate which indicates if it's a match
+ * @return the `Future` holding the optional result of the search
+ */
+ def find[T](futures: scala.collection.immutable.Iterable[Future[T]])(p: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = {
+ def searchNext(i: Iterator[Future[T]]): Future[Option[T]] =
+ if (!i.hasNext) successful[Option[T]](None)
+ else {
+ i.next().transformWith {
+ case Success(r) if p(r) => successful(Some(r))
+ case other => searchNext(i)
+ }
+ }
+ searchNext(futures.iterator)
+ }
+
+ /** A non-blocking, asynchronous left fold over the specified futures,
+ * with the start value of the given zero.
+ * The fold is performed asynchronously in left-to-right order as the futures become completed.
+ * The result will be the first failure of any of the futures, or any failure in the actual fold,
+ * or the result of the fold.
+ *
+ * Example:
+ * {{{
+ * val futureSum = Future.foldLeft(futures)(0)(_ + _)
+ * }}}
+ *
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `scala.collection.immutable.Iterable` of Futures to be folded
+ * @param zero the start value of the fold
+ * @param op the fold operation to be applied to the zero and futures
+ * @return the `Future` holding the result of the fold
+ */
+ def foldLeft[T, R](futures: scala.collection.immutable.Iterable[Future[T]])(zero: R)(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] =
+ foldNext(futures.iterator, zero, op)
+
+ private[this] def foldNext[T, R](i: Iterator[Future[T]], prevValue: R, op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] =
+ if (!i.hasNext) successful(prevValue)
+ else i.next().flatMap { value => foldNext(i, op(prevValue, value), op) }
+
+ /** A non-blocking, asynchronous fold over the specified futures, with the start value of the given zero.
* The fold is performed on the thread where the last future is completed,
* the result will be the first failure of any of the futures, or any failure in the actual fold,
* or the result of the fold.
*
* Example:
* {{{
- * val result = Await.result(Future.fold(futures)(0)(_ + _), 5 seconds)
+ * val futureSum = Future.fold(futures)(0)(_ + _)
* }}}
+ *
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `TraversableOnce` of Futures to be folded
+ * @param zero the start value of the fold
+ * @param op the fold operation to be applied to the zero and futures
+ * @return the `Future` holding the result of the fold
*/
+ @deprecated("Use Future.foldLeft instead", "2.12")
def fold[T, R](futures: TraversableOnce[Future[T]])(zero: R)(@deprecatedName('foldFun) op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
if (futures.isEmpty) successful(zero)
else sequence(futures).map(_.foldLeft(zero)(op))
}
- /** Initiates a fold over the supplied futures where the fold-zero is the result value of the `Future` that's completed first.
+ /** Initiates a non-blocking, asynchronous, fold over the supplied futures
+ * where the fold-zero is the result value of the `Future` that's completed first.
*
* Example:
* {{{
- * val result = Await.result(Future.reduce(futures)(_ + _), 5 seconds)
+ * val futureSum = Future.reduce(futures)(_ + _)
* }}}
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `TraversableOnce` of Futures to be reduced
+ * @param op the reduce operation which is applied to the results of the futures
+ * @return the `Future` holding the result of the reduce
*/
+ @deprecated("Use Future.reduceLeft instead", "2.12")
def reduce[T, R >: T](futures: TraversableOnce[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
if (futures.isEmpty) failed(new NoSuchElementException("reduce attempted on empty collection"))
else sequence(futures).map(_ reduceLeft op)
}
- /** Transforms a `TraversableOnce[A]` into a `Future[TraversableOnce[B]]` using the provided function `A => Future[B]`.
+ /** Initiates a non-blocking, asynchronous, left reduction over the supplied futures
+ * where the zero is the result value of the first `Future`.
+ *
+ * Example:
+ * {{{
+ * val futureSum = Future.reduceLeft(futures)(_ + _)
+ * }}}
+ * @tparam T the type of the value of the input Futures
+ * @tparam R the type of the value of the returned `Future`
+ * @param futures the `scala.collection.immutable.Iterable` of Futures to be reduced
+ * @param op the reduce operation which is applied to the results of the futures
+ * @return the `Future` holding the result of the reduce
+ */
+ def reduceLeft[T, R >: T](futures: scala.collection.immutable.Iterable[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
+ val i = futures.iterator
+ if (!i.hasNext) failed(new NoSuchElementException("reduceLeft attempted on empty collection"))
+ else i.next() flatMap { v => foldNext(i, v, op) }
+ }
+
+ /** Asynchronously and non-blockingly transforms a `TraversableOnce[A]` into a `Future[TraversableOnce[B]]`
+ * using the provided function `A => Future[B]`.
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
* in parallel:
*
* {{{
* val myFutureList = Future.traverse(myList)(x => Future(myFunc(x)))
* }}}
+ * @tparam A the type of the value inside the Futures in the `TraversableOnce`
+ * @tparam B the type of the value of the returned `Future`
+ * @tparam M the type of the `TraversableOnce` of Futures
+ * @param in the `TraversableOnce` of Futures which will be sequenced
+ * @param fn the function to apply to the `TraversableOnce` of Futures to produce the results
+ * @return the `Future` of the `TraversableOnce` of results
*/
def traverse[A, B, M[X] <: TraversableOnce[X]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
in.foldLeft(successful(cbf(in))) { (fr, a) =>
@@ -577,6 +796,7 @@ object Future {
for (r <- fr; b <- fb) yield (r += b)
}.map(_.result())
+
// This is used to run callbacks which are internal
// to scala.concurrent; our own callbacks are only
// ever used to eventually run another callback,
diff --git a/src/library/scala/concurrent/FutureTaskRunner.scala b/src/library/scala/concurrent/FutureTaskRunner.scala
deleted file mode 100644
index 089e67cedd..0000000000
--- a/src/library/scala/concurrent/FutureTaskRunner.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2009-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent
-
-import scala.language.{implicitConversions, higherKinds}
-
-/** The `FutureTaskRunner` trait is a base trait of task runners
- * that provide some sort of future abstraction.
- *
- * @author Philipp Haller
- */
-@deprecated("Use `ExecutionContext` instead.", "2.10.0")
-private[scala] trait FutureTaskRunner extends TaskRunner {
-
- /** The type of the futures that the underlying task runner supports.
- */
- type Future[T]
-
- /** An implicit conversion from futures to zero-parameter functions.
- */
- implicit def futureAsFunction[S](x: Future[S]): () => S
-
- /** Submits a task to run which returns its result in a future.
- */
- def submit[S](task: Task[S]): Future[S]
-
- /* Possibly blocks the current thread, for example, waiting for
- * a lock or condition.
- */
- @deprecated("Use `blocking` instead.", "2.10.0")
- def managedBlock(blocker: ManagedBlocker): Unit
-
-}
diff --git a/src/library/scala/concurrent/ManagedBlocker.scala b/src/library/scala/concurrent/ManagedBlocker.scala
deleted file mode 100644
index b5a6e21893..0000000000
--- a/src/library/scala/concurrent/ManagedBlocker.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent
-
-/** The `ManagedBlocker` trait...
- *
- * @author Philipp Haller
- */
-@deprecated("Use `blocking` instead.", "2.10.0")
-private[scala] trait ManagedBlocker {
-
- /**
- * Possibly blocks the current thread, for example waiting for
- * a lock or condition.
- *
- * @return true if no additional blocking is necessary (i.e.,
- * if `isReleasable` would return `true`).
- * @throws InterruptedException if interrupted while waiting
- * (the method is not required to do so, but is allowed to).
- */
- def block(): Boolean
-
- /**
- * Returns `true` if blocking is unnecessary.
- */
- def isReleasable: Boolean
-
-}
diff --git a/src/library/scala/concurrent/Promise.scala b/src/library/scala/concurrent/Promise.scala
index 0f4e98db57..894b134e83 100644
--- a/src/library/scala/concurrent/Promise.scala
+++ b/src/library/scala/concurrent/Promise.scala
@@ -26,12 +26,6 @@ import scala.util.{ Try, Success, Failure }
* Note: Using this method may result in non-deterministic concurrent programs.
*/
trait Promise[T] {
-
- // used for internal callbacks defined in
- // the lexical scope of this trait;
- // _never_ for application callbacks.
- private implicit def internalExecutor: ExecutionContext = Future.InternalCallbackExecutor
-
/** Future containing the value of this promise.
*/
def future: Future[T]
@@ -73,7 +67,9 @@ trait Promise[T] {
* @return This promise
*/
final def tryCompleteWith(other: Future[T]): this.type = {
- other onComplete { this tryComplete _ }
+ if (other ne this.future) { // this tryCompleteWith this doesn't make much sense
+ other.onComplete(this tryComplete _)(Future.InternalCallbackExecutor)
+ }
this
}
@@ -139,5 +135,5 @@ object Promise {
* @tparam T the type of the value in the promise
* @return the newly created `Promise` object
*/
- def fromTry[T](result: Try[T]): Promise[T] = new impl.Promise.KeptPromise[T](result)
+ def fromTry[T](result: Try[T]): Promise[T] = impl.Promise.KeptPromise[T](result)
}
diff --git a/src/library/scala/concurrent/SyncChannel.scala b/src/library/scala/concurrent/SyncChannel.scala
index ec584b3eb0..735598935c 100644
--- a/src/library/scala/concurrent/SyncChannel.scala
+++ b/src/library/scala/concurrent/SyncChannel.scala
@@ -31,10 +31,10 @@ class SyncChannel[A] {
pendingReads = pendingReads.tail
// let reader continue
- readReq set data
+ readReq put data
// resolve write request
- writeReq set true
+ writeReq put true
}
else {
// enqueue write request
@@ -57,10 +57,10 @@ class SyncChannel[A] {
pendingWrites = pendingWrites.tail
// let writer continue
- writeReq set true
+ writeReq.put(true)
// resolve read request
- readReq set data
+ readReq.put (data)
}
else {
// enqueue read request
diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala
index 1ee27b0f36..127e6b58d2 100644
--- a/src/library/scala/concurrent/SyncVar.scala
+++ b/src/library/scala/concurrent/SyncVar.scala
@@ -19,17 +19,17 @@ import java.util.concurrent.TimeUnit
*/
class SyncVar[A] {
private var isDefined: Boolean = false
- private var value: Option[A] = None
+ private var value: A = _
/**
- * Waits for this SyncVar to become defined and returns
- * the result, without modifying the stored value.
+ * Wait for this SyncVar to become defined and then get
+ * the stored value without modifying it.
*
* @return value that is held in this container
*/
def get: A = synchronized {
while (!isDefined) wait()
- value.get
+ value
}
/** Waits `timeout` millis. If `timeout <= 0` just returns 0.
@@ -44,11 +44,10 @@ class SyncVar[A] {
if (elapsed < 0) 0 else TimeUnit.NANOSECONDS.toMillis(elapsed)
}
- /** Waits for this SyncVar to become defined at least for
- * `timeout` milliseconds (possibly more), and gets its
- * value.
+ /** Wait at least `timeout` milliseconds (possibly more) for this `SyncVar`
+ * to become defined and then get its value.
*
- * @param timeout the amount of milliseconds to wait, 0 means forever
+ * @param timeout time in milliseconds to wait
* @return `None` if variable is undefined after `timeout`, `Some(value)` otherwise
*/
def get(timeout: Long): Option[A] = synchronized {
@@ -61,12 +60,12 @@ class SyncVar[A] {
val elapsed = waitMeasuringElapsed(rest)
rest -= elapsed
}
- value
+ if (isDefined) Some(value) else None
}
/**
- * Waits for this SyncVar to become defined and returns
- * the result, unsetting the stored value before returning.
+ * Wait for this SyncVar to become defined and then get
+ * the stored value, unsetting it as a side effect.
*
* @return value that was held in this container
*/
@@ -75,12 +74,11 @@ class SyncVar[A] {
finally unsetVal()
}
- /** Waits for this SyncVar to become defined at least for
- * `timeout` milliseconds (possibly more), and takes its
- * value by first reading and then removing the value from
- * the SyncVar.
+ /** Wait at least `timeout` milliseconds (possibly more) for this `SyncVar`
+ * to become defined and then get the stored value, unsetting it
+ * as a side effect.
*
- * @param timeout the amount of milliseconds to wait, 0 means forever
+ * @param timeout the amount of milliseconds to wait
* @return the value or a throws an exception if the timeout occurs
* @throws NoSuchElementException on timeout
*/
@@ -97,14 +95,14 @@ class SyncVar[A] {
// NOTE: Used by SBT 0.13.0-M2 and below
def set(x: A): Unit = setVal(x)
- /** Places a value in the SyncVar. If the SyncVar already has a stored value,
- * it waits until another thread takes it */
+ /** Place a value in the SyncVar. If the SyncVar already has a stored value,
+ * wait until another thread takes it. */
def put(x: A): Unit = synchronized {
while (isDefined) wait()
setVal(x)
}
- /** Checks whether a value is stored in the synchronized variable */
+ /** Check whether a value is stored in the synchronized variable. */
def isSet: Boolean = synchronized {
isDefined
}
@@ -117,7 +115,7 @@ class SyncVar[A] {
// NOTE: Used by SBT 0.13.0-M2 and below
def unset(): Unit = synchronized {
isDefined = false
- value = None
+ value = null.asInstanceOf[A]
notifyAll()
}
@@ -126,7 +124,7 @@ class SyncVar[A] {
// implementation of `set` was moved to `setVal` to achieve this
private def setVal(x: A): Unit = synchronized {
isDefined = true
- value = Some(x)
+ value = x
notifyAll()
}
@@ -135,8 +133,7 @@ class SyncVar[A] {
// implementation of `unset` was moved to `unsetVal` to achieve this
private def unsetVal(): Unit = synchronized {
isDefined = false
- value = None
+ value = null.asInstanceOf[A]
notifyAll()
}
-
}
diff --git a/src/library/scala/concurrent/TaskRunner.scala b/src/library/scala/concurrent/TaskRunner.scala
deleted file mode 100644
index 1ea23b35e8..0000000000
--- a/src/library/scala/concurrent/TaskRunner.scala
+++ /dev/null
@@ -1,27 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent
-
-import scala.language.{higherKinds, implicitConversions}
-
-/** The `TaskRunner` trait...
- *
- * @author Philipp Haller
- */
-@deprecated("Use `ExecutionContext` instead.", "2.10.0")
-private[scala] trait TaskRunner {
-
- type Task[T]
-
- implicit def functionAsTask[S](fun: () => S): Task[S]
-
- def execute[S](task: Task[S]): Unit
-
- def shutdown(): Unit
-}
diff --git a/src/library/scala/concurrent/ThreadPoolRunner.scala b/src/library/scala/concurrent/ThreadPoolRunner.scala
deleted file mode 100644
index 7784681f71..0000000000
--- a/src/library/scala/concurrent/ThreadPoolRunner.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent
-
-import java.util.concurrent.{ExecutorService, Callable, TimeUnit}
-import scala.language.implicitConversions
-
-/** The `ThreadPoolRunner` trait uses a `java.util.concurrent.ExecutorService`
- * to run submitted tasks.
- *
- * @author Philipp Haller
- */
-@deprecated("Use `ExecutionContext` instead.", "2.10.0")
-private[scala] trait ThreadPoolRunner extends FutureTaskRunner {
-
- type Task[T] = Callable[T] with Runnable
- type Future[T] = java.util.concurrent.Future[T]
-
- private class RunCallable[S](fun: () => S) extends Runnable with Callable[S] {
- def run() = fun()
- def call() = fun()
- }
-
- implicit def functionAsTask[S](fun: () => S): Task[S] =
- new RunCallable(fun)
-
- implicit def futureAsFunction[S](x: Future[S]): () => S =
- () => x.get()
-
- protected def executor: ExecutorService
-
- def submit[S](task: Task[S]): Future[S] = {
- executor.submit[S](task)
- }
-
- def execute[S](task: Task[S]) {
- executor execute task
- }
-
- @deprecated("Use `blocking` instead.", "2.10.0")
- def managedBlock(blocker: ManagedBlocker) {
- blocker.block()
- }
-
-}
diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala
index e68a897f82..f69030bd3d 100644
--- a/src/library/scala/concurrent/duration/Duration.scala
+++ b/src/library/scala/concurrent/duration/Duration.scala
@@ -9,8 +9,6 @@
package scala.concurrent.duration
import java.lang.{ Double => JDouble, Long => JLong }
-import scala.language.implicitConversions
-import scala.language.postfixOps
object Duration {
@@ -57,7 +55,7 @@ object Duration {
case "Inf" | "PlusInf" | "+Inf" => Inf
case "MinusInf" | "-Inf" => MinusInf
case _ =>
- val unitName = s1.reverse takeWhile (_.isLetter) reverse;
+ val unitName = s1.reverse.takeWhile(_.isLetter).reverse;
timeUnit get unitName match {
case Some(unit) =>
val valueStr = s1 dropRight unitName.length
@@ -87,11 +85,11 @@ object Duration {
// TimeUnit => standard label
protected[duration] val timeUnitName: Map[TimeUnit, String] =
- timeUnitLabels.toMap mapValues (s => words(s).last) toMap
+ timeUnitLabels.toMap.mapValues(s => words(s).last).toMap
// Label => TimeUnit
protected[duration] val timeUnit: Map[String, TimeUnit] =
- timeUnitLabels flatMap { case (unit, names) => expandLabels(names) map (_ -> unit) } toMap
+ timeUnitLabels.flatMap{ case (unit, names) => expandLabels(names) map (_ -> unit) }.toMap
/**
* Extract length and time unit out of a string, where the format must match the description for [[Duration$.apply(s:String)* apply(String)]].
@@ -708,7 +706,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/concurrent/forkjoin/package.scala b/src/library/scala/concurrent/forkjoin/package.scala
new file mode 100644
index 0000000000..7f4524fccf
--- /dev/null
+++ b/src/library/scala/concurrent/forkjoin/package.scala
@@ -0,0 +1,60 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2015, LAMP/EPFL and Typesafe, Inc. **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.concurrent
+import java.util.{concurrent => juc}
+import java.util.Collection
+
+package object forkjoin {
+ @deprecated("Use java.util.concurrent.ForkJoinPool directly, instead of this alias.", "2.12.0")
+ type ForkJoinPool = juc.ForkJoinPool
+ @deprecated("Use java.util.concurrent.ForkJoinPool directly, instead of this alias.", "2.12.0")
+ object ForkJoinPool {
+ type ForkJoinWorkerThreadFactory = juc.ForkJoinPool.ForkJoinWorkerThreadFactory
+ type ManagedBlocker = juc.ForkJoinPool.ManagedBlocker
+
+ val defaultForkJoinWorkerThreadFactory: ForkJoinWorkerThreadFactory = juc.ForkJoinPool.defaultForkJoinWorkerThreadFactory
+ def managedBlock(blocker: ManagedBlocker): Unit = juc.ForkJoinPool.managedBlock(blocker)
+ }
+
+ @deprecated("Use java.util.concurrent.ForkJoinTask directly, instead of this alias.", "2.12.0")
+ type ForkJoinTask[T] = juc.ForkJoinTask[T]
+ @deprecated("Use java.util.concurrent.ForkJoinTask directly, instead of this alias.", "2.12.0")
+ object ForkJoinTask {
+ def adapt(runnable: Runnable): ForkJoinTask[_] = juc.ForkJoinTask.adapt(runnable)
+ def adapt[T](callable: juc.Callable[_ <: T]): ForkJoinTask[T] = juc.ForkJoinTask.adapt(callable)
+ def adapt[T](runnable: Runnable, result: T): ForkJoinTask[T] = juc.ForkJoinTask.adapt(runnable, result)
+ def getPool(): ForkJoinPool = juc.ForkJoinTask.getPool
+ def getQueuedTaskCount(): Int = juc.ForkJoinTask.getQueuedTaskCount
+ def getSurplusQueuedTaskCount(): Int = juc.ForkJoinTask.getSurplusQueuedTaskCount
+ def helpQuiesce(): Unit = juc.ForkJoinTask.helpQuiesce
+ def inForkJoinPool(): Boolean = juc.ForkJoinTask.inForkJoinPool
+ def invokeAll[T <: ForkJoinTask[_]](tasks: Collection[T]): Collection[T] = juc.ForkJoinTask.invokeAll(tasks)
+ def invokeAll[T](t1: ForkJoinTask[T]): Unit = juc.ForkJoinTask.invokeAll(t1)
+ def invokeAll[T](tasks: ForkJoinTask[T]*): Unit = juc.ForkJoinTask.invokeAll(tasks: _*)
+ }
+
+ @deprecated("Use java.util.concurrent.ForkJoinWorkerThread directly, instead of this alias.", "2.12.0")
+ type ForkJoinWorkerThread = juc.ForkJoinWorkerThread
+ @deprecated("Use java.util.concurrent.LinkedTransferQueue directly, instead of this alias.", "2.12.0")
+ type LinkedTransferQueue[T] = juc.LinkedTransferQueue[T]
+ @deprecated("Use java.util.concurrent.RecursiveAction directly, instead of this alias.", "2.12.0")
+ type RecursiveAction = juc.RecursiveAction
+ @deprecated("Use java.util.concurrent.RecursiveTask directly, instead of this alias.", "2.12.0")
+ type RecursiveTask[T] = juc.RecursiveTask[T]
+
+ @deprecated("Use java.util.concurrent.ThreadLocalRandom directly, instead of this alias.", "2.12.0")
+ type ThreadLocalRandom = juc.ThreadLocalRandom
+ @deprecated("Use java.util.concurrent.ThreadLocalRandom directly, instead of this alias.", "2.12.0")
+ object ThreadLocalRandom {
+ // For source compatibility, current must declare the empty argument list.
+ // Having no argument list makes more sense since it doesn't have any side effects,
+ // but existing callers will break if they invoked it as `current()`.
+ def current() = juc.ThreadLocalRandom.current
+ }
+}
diff --git a/src/library/scala/concurrent/impl/AbstractPromise.java b/src/library/scala/concurrent/impl/AbstractPromise.java
deleted file mode 100644
index c2520a1692..0000000000
--- a/src/library/scala/concurrent/impl/AbstractPromise.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2015, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent.impl;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-@Deprecated // Since 2.11.8. Extend java.util.concurrent.atomic.AtomicReference instead.
-abstract class AbstractPromise extends AtomicReference<Object> {
- protected final boolean updateState(Object oldState, Object newState) { return compareAndSet(oldState, newState); }
- protected final Object getState() { return get(); }
-}
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 479720287c..7bf5cc5729 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -8,55 +8,87 @@
package scala.concurrent.impl
-
-
-import java.util.concurrent.{ LinkedBlockingQueue, Callable, Executor, ExecutorService, Executors, ThreadFactory, TimeUnit, ThreadPoolExecutor }
+import java.util.concurrent.{ ForkJoinPool, ForkJoinWorkerThread, ForkJoinTask, Callable, Executor, ExecutorService, ThreadFactory, TimeUnit }
+import java.util.concurrent.atomic.AtomicInteger
import java.util.Collection
-import scala.concurrent.forkjoin._
-import scala.concurrent.{ BlockContext, ExecutionContext, Awaitable, CanAwait, ExecutionContextExecutor, ExecutionContextExecutorService }
-import scala.util.control.NonFatal
+import scala.concurrent.{ BlockContext, ExecutionContext, CanAwait, ExecutionContextExecutor, ExecutionContextExecutorService }
+import scala.annotation.tailrec
+private[scala] class ExecutionContextImpl private[impl] (val executor: Executor, val reporter: Throwable => Unit) extends ExecutionContextExecutor {
+ require(executor ne null, "Executor must not be null")
+ override def execute(runnable: Runnable) = executor execute runnable
+ override def reportFailure(t: Throwable) = reporter(t)
+}
-private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter: Throwable => Unit) extends ExecutionContextExecutor {
- // Placed here since the creation of the executor needs to read this val
- private[this] val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler {
- def uncaughtException(thread: Thread, cause: Throwable): Unit = reporter(cause)
- }
- val executor: Executor = es match {
- case null => createExecutorService
- case some => some
- }
+private[concurrent] object ExecutionContextImpl {
// Implement BlockContext on FJP threads
- class DefaultThreadFactory(daemonic: Boolean) extends ThreadFactory with ForkJoinPool.ForkJoinWorkerThreadFactory {
+ final class DefaultThreadFactory(
+ daemonic: Boolean,
+ maxThreads: Int,
+ prefix: String,
+ uncaught: Thread.UncaughtExceptionHandler) extends ThreadFactory with ForkJoinPool.ForkJoinWorkerThreadFactory {
+
+ require(prefix ne null, "DefaultThreadFactory.prefix must be non null")
+ require(maxThreads > 0, "DefaultThreadFactory.maxThreads must be greater than 0")
+
+ private final val currentNumberOfThreads = new AtomicInteger(0)
+
+ @tailrec private final def reserveThread(): Boolean = currentNumberOfThreads.get() match {
+ case `maxThreads` | Int.`MaxValue` => false
+ case other => currentNumberOfThreads.compareAndSet(other, other + 1) || reserveThread()
+ }
+
+ @tailrec private final def deregisterThread(): Boolean = currentNumberOfThreads.get() match {
+ case 0 => false
+ case other => currentNumberOfThreads.compareAndSet(other, other - 1) || deregisterThread()
+ }
+
def wire[T <: Thread](thread: T): T = {
thread.setDaemon(daemonic)
- thread.setUncaughtExceptionHandler(uncaughtExceptionHandler)
+ thread.setUncaughtExceptionHandler(uncaught)
+ thread.setName(prefix + "-" + thread.getId())
thread
}
- def newThread(runnable: Runnable): Thread = wire(new Thread(runnable))
-
- def newThread(fjp: ForkJoinPool): ForkJoinWorkerThread = wire(new ForkJoinWorkerThread(fjp) with BlockContext {
- override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
- var result: T = null.asInstanceOf[T]
- ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker {
- @volatile var isdone = false
- override def block(): Boolean = {
- result = try thunk finally { isdone = true }
- true
+ // As per ThreadFactory contract newThread should return `null` if cannot create new thread.
+ def newThread(runnable: Runnable): Thread =
+ if (reserveThread())
+ wire(new Thread(new Runnable {
+ // We have to decrement the current thread count when the thread exits
+ override def run() = try runnable.run() finally deregisterThread()
+ })) else null
+
+ def newThread(fjp: ForkJoinPool): ForkJoinWorkerThread =
+ if (reserveThread()) {
+ wire(new ForkJoinWorkerThread(fjp) with BlockContext {
+ // We have to decrement the current thread count when the thread exits
+ final override def onTermination(exception: Throwable): Unit = deregisterThread()
+ final override def blockOn[T](thunk: =>T)(implicit permission: CanAwait): T = {
+ var result: T = null.asInstanceOf[T]
+ ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker {
+ @volatile var isdone = false
+ override def block(): Boolean = {
+ result = try {
+ // When we block, switch out the BlockContext temporarily so that nested blocking does not created N new Threads
+ BlockContext.withBlockContext(BlockContext.defaultBlockContext) { thunk }
+ } finally {
+ isdone = true
+ }
+
+ true
+ }
+ override def isReleasable = isdone
+ })
+ result
}
- override def isReleasable = isdone
})
- result
- }
- })
+ } else null
}
- def createExecutorService: ExecutorService = {
-
+ def createDefaultExecutorService(reporter: Throwable => Unit): ExecutorService = {
def getInt(name: String, default: String) = (try System.getProperty(name, default) catch {
case e: SecurityException => default
}) match {
@@ -65,87 +97,79 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter:
}
def range(floor: Int, desired: Int, ceiling: Int) = scala.math.min(scala.math.max(floor, desired), ceiling)
+ val numThreads = getInt("scala.concurrent.context.numThreads", "x1")
+ // The hard limit on the number of active threads that the thread factory will produce
+ // SI-8955 Deadlocks can happen if maxNoOfThreads is too low, although we're currently not sure
+ // about what the exact threshhold is. numThreads + 256 is conservatively high.
+ val maxNoOfThreads = getInt("scala.concurrent.context.maxThreads", "x1")
val desiredParallelism = range(
getInt("scala.concurrent.context.minThreads", "1"),
- getInt("scala.concurrent.context.numThreads", "x1"),
- getInt("scala.concurrent.context.maxThreads", "x1"))
-
- val threadFactory = new DefaultThreadFactory(daemonic = true)
-
- try {
- new ForkJoinPool(
- desiredParallelism,
- threadFactory,
- uncaughtExceptionHandler,
- true) // Async all the way baby
- } catch {
- case NonFatal(t) =>
- System.err.println("Failed to create ForkJoinPool for the default ExecutionContext, falling back to ThreadPoolExecutor")
- t.printStackTrace(System.err)
- val exec = new ThreadPoolExecutor(
- desiredParallelism,
- desiredParallelism,
- 5L,
- TimeUnit.MINUTES,
- new LinkedBlockingQueue[Runnable],
- threadFactory
- )
- exec.allowCoreThreadTimeOut(true)
- exec
- }
- }
+ numThreads,
+ maxNoOfThreads)
- def execute(runnable: Runnable): Unit = executor match {
- case fj: ForkJoinPool =>
- val fjt: ForkJoinTask[_] = runnable match {
- case t: ForkJoinTask[_] => t
- case r => new ExecutionContextImpl.AdaptedForkJoinTask(r)
- }
- Thread.currentThread match {
- case fjw: ForkJoinWorkerThread if fjw.getPool eq fj => fjt.fork()
- case _ => fj execute fjt
- }
- case generic => generic execute runnable
- }
+ // The thread factory must provide additional threads to support managed blocking.
+ val maxExtraThreads = getInt("scala.concurrent.context.maxExtraThreads", "256")
- def reportFailure(t: Throwable) = reporter(t)
-}
+ val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler {
+ override def uncaughtException(thread: Thread, cause: Throwable): Unit = reporter(cause)
+ }
+ val threadFactory = new ExecutionContextImpl.DefaultThreadFactory(daemonic = true,
+ maxThreads = maxNoOfThreads + maxExtraThreads,
+ prefix = "scala-execution-context-global",
+ uncaught = uncaughtExceptionHandler)
-private[concurrent] object ExecutionContextImpl {
+ new ForkJoinPool(desiredParallelism, threadFactory, uncaughtExceptionHandler, true) {
+ override def execute(runnable: Runnable): Unit = {
+ val fjt: ForkJoinTask[_] = runnable match {
+ case t: ForkJoinTask[_] => t
+ case r => new ExecutionContextImpl.AdaptedForkJoinTask(r)
+ }
+ Thread.currentThread match {
+ case fjw: ForkJoinWorkerThread if fjw.getPool eq this => fjt.fork()
+ case _ => super.execute(fjt)
+ }
+ }
+ }
+ }
final class AdaptedForkJoinTask(runnable: Runnable) extends ForkJoinTask[Unit] {
- final override def setRawResult(u: Unit): Unit = ()
- final override def getRawResult(): Unit = ()
- final override def exec(): Boolean = try { runnable.run(); true } catch {
- case anything: Throwable ⇒
- val t = Thread.currentThread
- t.getUncaughtExceptionHandler match {
- case null ⇒
- case some ⇒ some.uncaughtException(t, anything)
- }
- throw anything
- }
+ final override def setRawResult(u: Unit): Unit = ()
+ final override def getRawResult(): Unit = ()
+ final override def exec(): Boolean = try { runnable.run(); true } catch {
+ case anything: Throwable =>
+ val t = Thread.currentThread
+ t.getUncaughtExceptionHandler match {
+ case null =>
+ case some => some.uncaughtException(t, anything)
}
+ throw anything
+ }
+ }
- def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl = new ExecutionContextImpl(e, reporter)
- def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl with ExecutionContextExecutorService =
- new ExecutionContextImpl(es, reporter) with ExecutionContextExecutorService {
- final def asExecutorService: ExecutorService = executor.asInstanceOf[ExecutorService]
- override def execute(command: Runnable) = executor.execute(command)
- override def shutdown() { asExecutorService.shutdown() }
- override def shutdownNow() = asExecutorService.shutdownNow()
- override def isShutdown = asExecutorService.isShutdown
- override def isTerminated = asExecutorService.isTerminated
- override def awaitTermination(l: Long, timeUnit: TimeUnit) = asExecutorService.awaitTermination(l, timeUnit)
- override def submit[T](callable: Callable[T]) = asExecutorService.submit(callable)
- override def submit[T](runnable: Runnable, t: T) = asExecutorService.submit(runnable, t)
- override def submit(runnable: Runnable) = asExecutorService.submit(runnable)
- override def invokeAll[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAll(callables)
- override def invokeAll[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAll(callables, l, timeUnit)
- override def invokeAny[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAny(callables)
- override def invokeAny[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAny(callables, l, timeUnit)
+ def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl =
+ new ExecutionContextImpl(Option(e).getOrElse(createDefaultExecutorService(reporter)), reporter)
+
+ def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter):
+ ExecutionContextImpl with ExecutionContextExecutorService = {
+ new ExecutionContextImpl(Option(es).getOrElse(createDefaultExecutorService(reporter)), reporter)
+ with ExecutionContextExecutorService {
+ final def asExecutorService: ExecutorService = executor.asInstanceOf[ExecutorService]
+ override def execute(command: Runnable) = executor.execute(command)
+ override def shutdown() { asExecutorService.shutdown() }
+ override def shutdownNow() = asExecutorService.shutdownNow()
+ override def isShutdown = asExecutorService.isShutdown
+ override def isTerminated = asExecutorService.isTerminated
+ override def awaitTermination(l: Long, timeUnit: TimeUnit) = asExecutorService.awaitTermination(l, timeUnit)
+ override def submit[T](callable: Callable[T]) = asExecutorService.submit(callable)
+ override def submit[T](runnable: Runnable, t: T) = asExecutorService.submit(runnable, t)
+ override def submit(runnable: Runnable) = asExecutorService.submit(runnable)
+ override def invokeAll[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAll(callables)
+ override def invokeAll[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAll(callables, l, timeUnit)
+ override def invokeAny[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAny(callables)
+ override def invokeAny[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAny(callables, l, timeUnit)
+ }
}
}
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
deleted file mode 100644
index 042d32c234..0000000000
--- a/src/library/scala/concurrent/impl/Future.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.concurrent.impl
-
-
-
-import scala.concurrent.ExecutionContext
-import scala.util.control.NonFatal
-import scala.util.{ Success, Failure }
-
-
-private[concurrent] object Future {
- class PromiseCompletingRunnable[T](body: => T) extends Runnable {
- val promise = new Promise.DefaultPromise[T]()
-
- override def run() = {
- promise complete {
- try Success(body) catch { case NonFatal(e) => Failure(e) }
- }
- }
- }
-
- def apply[T](body: =>T)(implicit executor: ExecutionContext): scala.concurrent.Future[T] = {
- val runnable = new PromiseCompletingRunnable(body)
- executor.prepare.execute(runnable)
- runnable.promise.future
- }
-}
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index 6d2fc5c87c..626540425f 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -8,17 +8,41 @@
package scala.concurrent.impl
-import scala.concurrent.{ ExecutionContext, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException, blocking }
+import scala.concurrent.{ ExecutionContext, CanAwait, OnCompleteRunnable, TimeoutException, ExecutionException }
import scala.concurrent.Future.InternalCallbackExecutor
-import scala.concurrent.duration.{ Duration, Deadline, FiniteDuration, NANOSECONDS }
+import scala.concurrent.duration.{ Duration, FiniteDuration }
import scala.annotation.tailrec
import scala.util.control.NonFatal
import scala.util.{ Try, Success, Failure }
-import java.io.ObjectInputStream
+
import java.util.concurrent.locks.AbstractQueuedSynchronizer
+import java.util.concurrent.atomic.AtomicReference
private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] {
def future: this.type = this
+
+ import scala.concurrent.Future
+ import scala.concurrent.impl.Promise.DefaultPromise
+
+ override def transform[S](f: Try[T] => Try[S])(implicit executor: ExecutionContext): Future[S] = {
+ val p = new DefaultPromise[S]()
+ onComplete { result => p.complete(try f(result) catch { case NonFatal(t) => Failure(t) }) }
+ p.future
+ }
+
+ // If possible, link DefaultPromises to avoid space leaks
+ override def transformWith[S](f: Try[T] => Future[S])(implicit executor: ExecutionContext): Future[S] = {
+ val p = new DefaultPromise[S]()
+ onComplete {
+ v => try f(v) match {
+ case fut if fut eq this => p complete v.asInstanceOf[Try[S]]
+ case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p)
+ case fut => p completeWith fut
+ } catch { case NonFatal(t) => p failure t }
+ }
+ p.future
+ }
+
override def toString: String = value match {
case Some(result) => "Future("+result+")"
case None => "Future(<not completed>)"
@@ -27,7 +51,7 @@ private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with sc
/* Precondition: `executor` is prepared, i.e., `executor` has been returned from invocation of `prepare` on some other `ExecutionContext`.
*/
-private class CallbackRunnable[T](val executor: ExecutionContext, val onComplete: Try[T] => Any) extends Runnable with OnCompleteRunnable {
+private final class CallbackRunnable[T](val executor: ExecutionContext, val onComplete: Try[T] => Any) extends Runnable with OnCompleteRunnable {
// must be filled in before running it
var value: Try[T] = null
@@ -93,7 +117,7 @@ private[concurrent] object Promise {
* incomplete, or as complete with the same result value.
*
* A DefaultPromise stores its state entirely in the AnyRef cell exposed by
- * AbstractPromise. The type of object stored in the cell fully describes the
+ * AtomicReference. The type of object stored in the cell fully describes the
* current state of the promise.
*
* 1. List[CallbackRunnable] - The promise is incomplete and has zero or more callbacks
@@ -154,8 +178,9 @@ private[concurrent] object Promise {
* DefaultPromises, and `linkedRootOf` is currently only designed to be called
* by Future.flatMap.
*/
- class DefaultPromise[T] extends AbstractPromise with Promise[T] { self =>
- updateState(null, Nil) // The promise is incomplete and has no callbacks
+ // Left non-final to enable addition of extra fields by Java/Scala converters
+ // in scala-java8-compat.
+ class DefaultPromise[T] extends AtomicReference[AnyRef](Nil) with Promise[T] {
/** Get the root promise for this promise, compressing the link chain to that
* promise if necessary.
@@ -171,14 +196,23 @@ private[concurrent] object Promise {
* be garbage collected. Also, subsequent calls to this method should be
* faster as the link chain will be shorter.
*/
- @tailrec
- private def compressedRoot(): DefaultPromise[T] = {
- getState match {
- case linked: DefaultPromise[_] =>
- val target = linked.asInstanceOf[DefaultPromise[T]].root
- if (linked eq target) target else if (updateState(linked, target)) target else compressedRoot()
+ private def compressedRoot(): DefaultPromise[T] =
+ get() match {
+ case linked: DefaultPromise[_] => compressedRoot(linked)
case _ => this
}
+
+ @tailrec
+ private[this] final def compressedRoot(linked: DefaultPromise[_]): DefaultPromise[T] = {
+ val target = linked.asInstanceOf[DefaultPromise[T]].root
+ if (linked eq target) target
+ else if (compareAndSet(linked, target)) target
+ else {
+ get() match {
+ case newLinked: DefaultPromise[_] => compressedRoot(newLinked)
+ case _ => this
+ }
+ }
}
/** Get the promise at the root of the chain of linked promises. Used by `compressedRoot()`.
@@ -186,18 +220,16 @@ private[concurrent] object Promise {
* to compress the link chain whenever possible.
*/
@tailrec
- private def root: DefaultPromise[T] = {
- getState match {
+ private def root: DefaultPromise[T] =
+ get() match {
case linked: DefaultPromise[_] => linked.asInstanceOf[DefaultPromise[T]].root
case _ => this
}
- }
/** Try waiting for this promise to be completed.
*/
protected final def tryAwait(atMost: Duration): Boolean = if (!isCompleted) {
import Duration.Undefined
- import scala.concurrent.Future.InternalCallbackExecutor
atMost match {
case e if e eq Undefined => throw new IllegalArgumentException("cannot wait for Undefined period")
case Duration.Inf =>
@@ -218,33 +250,33 @@ private[concurrent] object Promise {
@throws(classOf[TimeoutException])
@throws(classOf[InterruptedException])
- def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
+ final def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
if (tryAwait(atMost)) this
else throw new TimeoutException("Futures timed out after [" + atMost + "]")
@throws(classOf[Exception])
- def result(atMost: Duration)(implicit permit: CanAwait): T =
+ final def result(atMost: Duration)(implicit permit: CanAwait): T =
ready(atMost).value.get.get // ready throws TimeoutException if timeout so value.get is safe here
def value: Option[Try[T]] = value0
@tailrec
- private def value0: Option[Try[T]] = getState match {
+ private def value0: Option[Try[T]] = get() match {
case c: Try[_] => Some(c.asInstanceOf[Try[T]])
- case _: DefaultPromise[_] => compressedRoot().value0
+ case dp: DefaultPromise[_] => compressedRoot(dp).value0
case _ => None
}
- override def isCompleted: Boolean = isCompleted0
+ override final def isCompleted: Boolean = isCompleted0
@tailrec
- private def isCompleted0: Boolean = getState match {
+ private def isCompleted0: Boolean = get() match {
case _: Try[_] => true
- case _: DefaultPromise[_] => compressedRoot().isCompleted0
+ case dp: DefaultPromise[_] => compressedRoot(dp).isCompleted0
case _ => false
}
- def tryComplete(value: Try[T]): Boolean = {
+ final def tryComplete(value: Try[T]): Boolean = {
val resolved = resolveTry(value)
tryCompleteAndGetListeners(resolved) match {
case null => false
@@ -258,37 +290,34 @@ private[concurrent] object Promise {
*/
@tailrec
private def tryCompleteAndGetListeners(v: Try[T]): List[CallbackRunnable[T]] = {
- getState match {
+ get() match {
case raw: List[_] =>
val cur = raw.asInstanceOf[List[CallbackRunnable[T]]]
- if (updateState(cur, v)) cur else tryCompleteAndGetListeners(v)
- case _: DefaultPromise[_] =>
- compressedRoot().tryCompleteAndGetListeners(v)
+ if (compareAndSet(cur, v)) cur else tryCompleteAndGetListeners(v)
+ case dp: DefaultPromise[_] => compressedRoot(dp).tryCompleteAndGetListeners(v)
case _ => null
}
}
- def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit = {
- val preparedEC = executor.prepare()
- val runnable = new CallbackRunnable[T](preparedEC, func)
- dispatchOrAddCallback(runnable)
- }
+ final def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
+ dispatchOrAddCallback(new CallbackRunnable[T](executor.prepare(), func))
/** Tries to add the callback, if already completed, it dispatches the callback to be executed.
* Used by `onComplete()` to add callbacks to a promise and by `link()` to transfer callbacks
- * to the root promise when linking two promises togehter.
+ * to the root promise when linking two promises together.
*/
@tailrec
private def dispatchOrAddCallback(runnable: CallbackRunnable[T]): Unit = {
- getState match {
+ get() match {
case r: Try[_] => runnable.executeWithValue(r.asInstanceOf[Try[T]])
- case _: DefaultPromise[_] => compressedRoot().dispatchOrAddCallback(runnable)
- case listeners: List[_] => if (updateState(listeners, runnable :: listeners)) () else dispatchOrAddCallback(runnable)
+ case dp: DefaultPromise[_] => compressedRoot(dp).dispatchOrAddCallback(runnable)
+ case listeners: List[_] => if (compareAndSet(listeners, runnable :: listeners)) ()
+ else dispatchOrAddCallback(runnable)
}
}
/** Link this promise to the root of another promise using `link()`. Should only be
- * be called by Future.flatMap.
+ * be called by transformWith.
*/
protected[concurrent] final def linkRootOf(target: DefaultPromise[T]): Unit = link(target.compressedRoot())
@@ -303,18 +332,17 @@ private[concurrent] object Promise {
*/
@tailrec
private def link(target: DefaultPromise[T]): Unit = if (this ne target) {
- getState match {
+ get() match {
case r: Try[_] =>
- if (!target.tryComplete(r.asInstanceOf[Try[T]])) {
- // Currently linking is done from Future.flatMap, which should ensure only
- // one promise can be completed. Therefore this situation is unexpected.
+ if (!target.tryComplete(r.asInstanceOf[Try[T]]))
throw new IllegalStateException("Cannot link completed promises together")
- }
- case _: DefaultPromise[_] =>
- compressedRoot().link(target)
- case listeners: List[_] => if (updateState(listeners, target)) {
- if (!listeners.isEmpty) listeners.asInstanceOf[List[CallbackRunnable[T]]].foreach(target.dispatchOrAddCallback(_))
- } else link(target)
+ case dp: DefaultPromise[_] =>
+ compressedRoot(dp).link(target)
+ case listeners: List[_] if compareAndSet(listeners, target) =>
+ if (listeners.nonEmpty)
+ listeners.asInstanceOf[List[CallbackRunnable[T]]].foreach(target.dispatchOrAddCallback(_))
+ case _ =>
+ link(target)
}
}
}
@@ -323,23 +351,58 @@ private[concurrent] object Promise {
*
* Useful in Future-composition when a value to contribute is already available.
*/
- final class KeptPromise[T](suppliedValue: Try[T]) extends Promise[T] {
+ object KeptPromise {
+ import scala.concurrent.Future
+ import scala.reflect.ClassTag
+
+ private[this] sealed trait Kept[T] extends Promise[T] {
+ def result: Try[T]
+
+ override def value: Option[Try[T]] = Some(result)
- val value = Some(resolveTry(suppliedValue))
+ override def isCompleted: Boolean = true
- override def isCompleted: Boolean = true
+ override def tryComplete(value: Try[T]): Boolean = false
- def tryComplete(value: Try[T]): Boolean = false
+ override def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
+ (new CallbackRunnable(executor.prepare(), func)).executeWithValue(result)
- def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit = {
- val completedAs = value.get
- val preparedEC = executor.prepare()
- (new CallbackRunnable(preparedEC, func)).executeWithValue(completedAs)
+ override def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
+
+ override def result(atMost: Duration)(implicit permit: CanAwait): T = result.get
}
- def ready(atMost: Duration)(implicit permit: CanAwait): this.type = this
+ private[this] final class Successful[T](val result: Success[T]) extends Kept[T] {
+ override def onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit = ()
+ override def failed: Future[Throwable] = KeptPromise(Failure(new NoSuchElementException("Future.failed not completed with a throwable."))).future
+ override def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = this
+ override def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = this
+ override def fallbackTo[U >: T](that: Future[U]): Future[U] = this
+ }
- def result(atMost: Duration)(implicit permit: CanAwait): T = value.get.get
+ private[this] final class Failed[T](val result: Failure[T]) extends Kept[T] {
+ private[this] final def thisAs[S]: Future[S] = future.asInstanceOf[Future[S]]
+
+ override def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit = ()
+ override def failed: Future[Throwable] = thisAs[Throwable]
+ override def foreach[U](f: T => U)(implicit executor: ExecutionContext): Unit = ()
+ override def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = thisAs[S]
+ override def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = thisAs[S]
+ override def flatten[S](implicit ev: T <:< Future[S]): Future[S] = thisAs[S]
+ override def filter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T] = this
+ override def collect[S](pf: PartialFunction[T, S])(implicit executor: ExecutionContext): Future[S] = thisAs[S]
+ override def zip[U](that: Future[U]): Future[(T, U)] = thisAs[(T,U)]
+ override def zipWith[U, R](that: Future[U])(f: (T, U) => R)(implicit executor: ExecutionContext): Future[R] = thisAs[R]
+ override def fallbackTo[U >: T](that: Future[U]): Future[U] =
+ if (this eq that) this else that.recoverWith({ case _ => this })(InternalCallbackExecutor)
+ override def mapTo[S](implicit tag: ClassTag[S]): Future[S] = thisAs[S]
+ }
+
+ def apply[T](result: Try[T]): scala.concurrent.Promise[T] =
+ resolveTry(result) match {
+ case s @ Success(_) => new Successful(s)
+ case f @ Failure(_) => new Failed(f)
+ }
}
}
diff --git a/src/library/scala/deprecatedInheritance.scala b/src/library/scala/deprecatedInheritance.scala
index 7d20219d4d..7614a96f95 100644
--- a/src/library/scala/deprecatedInheritance.scala
+++ b/src/library/scala/deprecatedInheritance.scala
@@ -19,5 +19,4 @@ package scala
* @since 2.10
* @see [[scala.deprecatedOverriding]]
*/
-private[scala] // for now, this needs to be generalized to communicate other modifier deltas
class deprecatedInheritance(message: String = "", since: String = "") extends scala.annotation.StaticAnnotation
diff --git a/src/library/scala/deprecatedName.scala b/src/library/scala/deprecatedName.scala
index 07c5c8925c..a0d3aa829b 100644
--- a/src/library/scala/deprecatedName.scala
+++ b/src/library/scala/deprecatedName.scala
@@ -29,4 +29,6 @@ import scala.annotation.meta._
* @since 2.8.1
*/
@param
-class deprecatedName(name: Symbol) extends scala.annotation.StaticAnnotation
+class deprecatedName(name: Symbol) extends scala.annotation.StaticAnnotation {
+ def this() = this(Symbol("<none>"))
+}
diff --git a/src/library/scala/deprecatedOverriding.scala b/src/library/scala/deprecatedOverriding.scala
index 04bce343a0..26a9d9ee7d 100644
--- a/src/library/scala/deprecatedOverriding.scala
+++ b/src/library/scala/deprecatedOverriding.scala
@@ -17,5 +17,4 @@ package scala
* @since 2.10
* @see [[scala.deprecatedInheritance]]
*/
-private[scala] // for the same reasons as deprecatedInheritance
class deprecatedOverriding(message: String = "", since: String = "") extends scala.annotation.StaticAnnotation
diff --git a/src/library/scala/inline.scala b/src/library/scala/inline.scala
index a21cced928..dc55af301c 100644
--- a/src/library/scala/inline.scala
+++ b/src/library/scala/inline.scala
@@ -11,8 +11,30 @@
package scala
/**
- * An annotation on methods that requests that the compiler should
- * try especially hard to inline the annotated method.
+ * An annotation on methods that requests that the compiler should try especially hard to inline the
+ * annotated method. The annotation can be used at definition site or at callsite.
+ *
+ * {{{
+ * @inline final def f1(x: Int) = x
+ * @noinline final def f2(x: Int) = x
+ * final def f3(x: Int) = x
+ *
+ * def t1 = f1(1) // inlined if possible
+ * def t2 = f2(1) // not inlined
+ * def t3 = f3(1) // may be inlined (heuristics)
+ * def t4 = f1(1): @noinline // not inlined (override at callsite)
+ * def t5 = f2(1): @inline // not inlined (cannot override the @noinline at f2's definition)
+ * def t6 = f3(1): @inline // inlined if possible
+ * def t7 = f3(1): @noinline // not inlined
+ * }
+ * }}}
+ *
+ * Note: parentheses are required when annotating a callsite withing a larger expression.
+ *
+ * {{{
+ * def t1 = f1(1) + f1(1): @noinline // equivalent to (f1(1) + f1(1)): @noinline
+ * def t2 = f1(1) + (f1(1): @noinline) // the second call to f1 is not inlined
+ * }}}
*
* @author Lex Spoon
* @version 1.0, 2007-5-21
diff --git a/src/library/scala/io/BufferedSource.scala b/src/library/scala/io/BufferedSource.scala
index 52fa525b24..33b5a1468e 100644
--- a/src/library/scala/io/BufferedSource.scala
+++ b/src/library/scala/io/BufferedSource.scala
@@ -8,11 +8,9 @@
package scala.io
-import java.util.Arrays
import java.io.{ InputStream, BufferedReader, InputStreamReader, PushbackReader }
import Source.DefaultBufSize
import scala.collection.{ Iterator, AbstractIterator }
-import scala.collection.mutable.ArrayBuffer
/** This object provides convenience methods to create an iterable
* representation of a source file.
diff --git a/src/library/scala/io/Source.scala b/src/library/scala/io/Source.scala
index 9f0b56b4fe..7513b423a1 100644
--- a/src/library/scala/io/Source.scala
+++ b/src/library/scala/io/Source.scala
@@ -10,7 +10,7 @@ package scala
package io
import scala.collection.AbstractIterator
-import java.io.{ FileInputStream, InputStream, PrintStream, File => JFile }
+import java.io.{ FileInputStream, InputStream, PrintStream, File => JFile, Closeable }
import java.net.{ URI, URL }
/** This object provides convenience methods to create an iterable
@@ -167,27 +167,35 @@ object Source {
def fromInputStream(is: InputStream)(implicit codec: Codec): BufferedSource =
createBufferedSource(is, reset = () => fromInputStream(is)(codec), close = () => is.close())(codec)
+
+ /** Reads data from a classpath resource, using either a context classloader (default) or a passed one.
+ *
+ * @param resource name of the resource to load from the classpath
+ * @param classLoader classloader to be used, or context classloader if not specified
+ * @return the buffered source
+ */
+ def fromResource(resource: String, classLoader: ClassLoader = Thread.currentThread().getContextClassLoader())(implicit codec: Codec): BufferedSource =
+ fromInputStream(classLoader.getResourceAsStream(resource))
+
}
/** An iterable representation of source data.
- * It may be reset with the optional `reset` method.
+ * It may be reset with the optional [[reset]] method.
*
- * Subclasses must supply [[scala.io.Source@iter the underlying iterator]].
+ * Subclasses must supply [[scala.io.Source.iter the underlying iterator]].
*
- * Error handling may be customized by overriding the [[scala.io.Source@report report]] method.
+ * Error handling may be customized by overriding the [[scala.io.Source.report report]] method.
*
- * The [[scala.io.Source@ch current input]] and [[scala.io.Source@pos position]],
- * as well as the [[scala.io.Source@next next character]] methods delegate to
- * [[scala.io.Source$Positioner the positioner]].
+ * The [[scala.io.Source.ch current input]] and [[scala.io.Source.pos position]],
+ * as well as the [[scala.io.Source.next next character]] methods delegate to
+ * [[scala.io.Source#Positioner the positioner]].
*
- * The default positioner encodes line and column numbers in the position passed to `report`.
+ * The default positioner encodes line and column numbers in the position passed to [[report]].
* This behavior can be changed by supplying a
- * [[scala.io.Source@withPositioning(pos:Source.this.Positioner):Source.this.type custom positioner]].
+ * [[scala.io.Source.withPositioning(pos:* custom positioner]].
*
- * @author Burak Emir
- * @version 1.0
*/
-abstract class Source extends Iterator[Char] {
+abstract class Source extends Iterator[Char] with Closeable {
/** the actual iterator */
protected val iter: Iterator[Char]
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index bb337e7a1d..e769dfb8cb 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -10,13 +10,12 @@
package scala
package math
-import java.{ lang => jl }
-import java.math.{ MathContext, BigDecimal => BigDec }
-import scala.collection.immutable.NumericRange
import scala.language.implicitConversions
+import java.math.{ MathContext, BigDecimal => BigDec }
+import scala.collection.immutable.NumericRange
-/**
+/**
* @author Stephane Micheloud
* @author Rex Kerr
* @version 1.1
@@ -44,17 +43,17 @@ object BigDecimal {
val HALF_UP = Value(RM.HALF_UP.ordinal)
val HALF_DOWN = Value(RM.HALF_DOWN.ordinal)
val HALF_EVEN = Value(RM.HALF_EVEN.ordinal)
- val UNNECESSARY = Value(RM.UNNECESSARY.ordinal)
+ val UNNECESSARY = Value(RM.UNNECESSARY.ordinal)
}
-
+
/** Constructs a `BigDecimal` using the decimal text representation of `Double` value `d`, rounding if necessary. */
def decimal(d: Double, mc: MathContext): BigDecimal =
new BigDecimal(new BigDec(java.lang.Double.toString(d), mc), mc)
/** Constructs a `BigDecimal` using the decimal text representation of `Double` value `d`. */
def decimal(d: Double): BigDecimal = decimal(d, defaultMathContext)
-
- /** Constructs a `BigDecimal` using the decimal text representation of `Float` value `f`, rounding if necessary.
+
+ /** Constructs a `BigDecimal` using the decimal text representation of `Float` value `f`, rounding if necessary.
* Note that `BigDecimal.decimal(0.1f) != 0.1f` since equality agrees with the `Double` representation, and
* `0.1 != 0.1f`.
*/
@@ -66,18 +65,18 @@ object BigDecimal {
* `0.1 != 0.1f`.
*/
def decimal(f: Float): BigDecimal = decimal(f, defaultMathContext)
-
+
// This exists solely to avoid conversion from Int/Long to Float, screwing everything up.
/** Constructs a `BigDecimal` from a `Long`, rounding if necessary. This is identical to `BigDecimal(l, mc)`. */
def decimal(l: Long, mc: MathContext): BigDecimal = apply(l, mc)
-
+
// This exists solely to avoid conversion from Int/Long to Float, screwing everything up.
/** Constructs a `BigDecimal` from a `Long`. This is identical to `BigDecimal(l)`. */
def decimal(l: Long): BigDecimal = apply(l)
-
+
/** Constructs a `BigDecimal` using a `java.math.BigDecimal`, rounding if necessary. */
def decimal(bd: BigDec, mc: MathContext): BigDecimal = new BigDecimal(bd.round(mc), mc)
-
+
/** Constructs a `BigDecimal` by expanding the binary fraction
* contained by `Double` value `d` into a decimal representation,
* rounding if necessary. When a `Float` is converted to a
@@ -85,50 +84,50 @@ object BigDecimal {
* also works for converted `Float`s.
*/
def binary(d: Double, mc: MathContext): BigDecimal = new BigDecimal(new BigDec(d, mc), mc)
-
+
/** Constructs a `BigDecimal` by expanding the binary fraction
* contained by `Double` value `d` into a decimal representation.
* Note: this also works correctly on converted `Float`s.
*/
def binary(d: Double): BigDecimal = binary(d, defaultMathContext)
-
+
/** Constructs a `BigDecimal` from a `java.math.BigDecimal`. The
* precision is the default for `BigDecimal` or enough to represent
* the `java.math.BigDecimal` exactly, whichever is greater.
*/
def exact(repr: BigDec): BigDecimal = {
- val mc =
+ val mc =
if (repr.precision <= defaultMathContext.getPrecision) defaultMathContext
else new MathContext(repr.precision, java.math.RoundingMode.HALF_EVEN)
new BigDecimal(repr, mc)
}
-
+
/** Constructs a `BigDecimal` by fully expanding the binary fraction
* contained by `Double` value `d`, adjusting the precision as
* necessary. Note: this works correctly on converted `Float`s also.
*/
def exact(d: Double): BigDecimal = exact(new BigDec(d))
-
+
/** Constructs a `BigDecimal` that exactly represents a `BigInt`.
*/
def exact(bi: BigInt): BigDecimal = exact(new BigDec(bi.bigInteger))
-
+
/** Constructs a `BigDecimal` that exactly represents a `Long`. Note that
* all creation methods for `BigDecimal` that do not take a `MathContext`
* represent a `Long`; this is equivalent to `apply`, `valueOf`, etc..
*/
def exact(l: Long): BigDecimal = apply(l)
-
+
/** Constructs a `BigDecimal` that exactly represents the number
* specified in a `String`.
*/
def exact(s: String): BigDecimal = exact(new BigDec(s))
-
+
/** Constructs a `BigDecimal` that exactly represents the number
* specified in base 10 in a character array.
*/
def exact(cs: Array[Char]): BigDecimal = exact(new BigDec(cs))
-
+
/** Constructs a `BigDecimal` using the java BigDecimal static
* valueOf constructor. Equivalent to `BigDecimal.decimal`.
@@ -137,7 +136,7 @@ object BigDecimal {
* @return the constructed `BigDecimal`
*/
def valueOf(d: Double): BigDecimal = apply(BigDec valueOf d)
-
+
/** Constructs a `BigDecimal` using the java BigDecimal static
* valueOf constructor, specifying a `MathContext` that is
* used for computations but isn't used for rounding. Use
@@ -151,7 +150,7 @@ object BigDecimal {
*/
@deprecated("MathContext is not applied to Doubles in valueOf. Use BigDecimal.decimal to use rounding, or java.math.BigDecimal.valueOf to avoid it.","2.11")
def valueOf(d: Double, mc: MathContext): BigDecimal = apply(BigDec valueOf d, mc)
-
+
/** Constructs a `BigDecimal` using the java BigDecimal static
* valueOf constructor.
*
@@ -159,14 +158,14 @@ object BigDecimal {
* @return the constructed `BigDecimal`
*/
def valueOf(x: Long): BigDecimal = apply(x)
-
+
/** Constructs a `BigDecimal` using the java BigDecimal static
* valueOf constructor. This is unlikely to do what you want;
* use `valueOf(f.toDouble)` or `decimal(f)` instead.
*/
@deprecated("Float arguments to valueOf may not do what you wish. Use decimal or valueOf(f.toDouble).","2.11")
def valueOf(f: Float): BigDecimal = valueOf(f.toDouble)
-
+
/** Constructs a `BigDecimal` using the java BigDecimal static
* valueOf constructor. This is unlikely to do what you want;
* use `valueOf(f.toDouble)` or `decimal(f)` instead.
@@ -174,7 +173,7 @@ object BigDecimal {
@deprecated("Float arguments to valueOf may not do what you wish. Use decimal or valueOf(f.toDouble).","2.11")
def valueOf(f: Float, mc: MathContext): BigDecimal = valueOf(f.toDouble, mc)
-
+
/** Constructs a `BigDecimal` whose value is equal to that of the
* specified `Integer` value.
*
@@ -247,7 +246,7 @@ object BigDecimal {
* @return the constructed `BigDecimal`
*/
def apply(d: Double): BigDecimal = decimal(d, defaultMathContext)
-
+
// note we don't use the static valueOf because it doesn't let us supply
// a MathContext, but we should be duplicating its logic, modulo caching.
/** Constructs a `BigDecimal` whose value is equal to that of the
@@ -281,7 +280,7 @@ object BigDecimal {
* into a `BigDecimal`.
*/
def apply(x: String): BigDecimal = exact(x)
-
+
/** Translates the decimal String representation of a `BigDecimal`
* into a `BigDecimal`, rounding if necessary.
*/
@@ -295,12 +294,12 @@ object BigDecimal {
* @return the constructed `BigDecimal`
*/
def apply(x: BigInt): BigDecimal = exact(x)
-
+
/** Constructs a `BigDecimal` whose value is equal to that of the
* specified `BigInt` value, rounding if necessary.
*
* @param x the specified `BigInt` value
- * @param mc the precision and rounding mode for creation of this value and future operations on it
+ * @param mc the precision and rounding mode for creation of this value and future operations on it
* @return the constructed `BigDecimal`
*/
def apply(x: BigInt, mc: MathContext): BigDecimal =
@@ -315,13 +314,13 @@ object BigDecimal {
*/
def apply(unscaledVal: BigInt, scale: Int): BigDecimal =
exact(new BigDec(unscaledVal.bigInteger, scale))
-
+
/** Constructs a `BigDecimal` whose unscaled value is equal to that
* of the specified `BigInt` value.
*
* @param unscaledVal the specified `BigInt` value
* @param scale the scale
- * @param mc the precision and rounding mode for creation of this value and future operations on it
+ * @param mc the precision and rounding mode for creation of this value and future operations on it
* @return the constructed `BigDecimal`
*/
def apply(unscaledVal: BigInt, scale: Int, mc: MathContext): BigDecimal =
@@ -329,7 +328,7 @@ object BigDecimal {
/** Constructs a `BigDecimal` from a `java.math.BigDecimal`. */
def apply(bd: BigDec): BigDecimal = apply(bd, defaultMathContext)
-
+
@deprecated("This method appears to round a java.math.BigDecimal but actually doesn't. Use new BigDecimal(bd, mc) instead for no rounding, or BigDecimal.decimal(bd, mc) for rounding.", "2.11")
def apply(bd: BigDec, mc: MathContext): BigDecimal = new BigDecimal(bd, mc)
@@ -398,11 +397,11 @@ object BigDecimal {
* @version 1.1
*/
final class BigDecimal(val bigDecimal: BigDec, val mc: MathContext)
-extends ScalaNumber with ScalaNumericConversions with Serializable {
+extends ScalaNumber with ScalaNumericConversions with Serializable with Ordered[BigDecimal] {
def this(bigDecimal: BigDec) = this(bigDecimal, BigDecimal.defaultMathContext)
import BigDecimal.RoundingMode._
import BigDecimal.{decimal, binary, exact}
-
+
if (bigDecimal eq null) throw new IllegalArgumentException("null value for BigDecimal")
if (mc eq null) throw new IllegalArgumentException("null MathContext for BigDecimal")
@@ -423,7 +422,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
scala.util.hashing.MurmurHash3.mixLast( temp.scaleByPowerOfTen(temp.scale).toBigInteger.hashCode, temp.scale )
}
}
-
+
/** Returns the hash code for this BigDecimal.
* Note that this does not merely use the underlying java object's
* `hashCode` because we compare `BigDecimal`s with `compareTo`
@@ -444,15 +443,15 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
*/
override def equals (that: Any): Boolean = that match {
case that: BigDecimal => this equals that
- case that: BigInt =>
- that.bitLength > (precision-scale-2)*BigDecimal.deci2binary &&
+ case that: BigInt =>
+ that.bitLength > (precision-scale-2)*BigDecimal.deci2binary &&
this.toBigIntExact.exists(that equals _)
- case that: Double =>
+ case that: Double =>
!that.isInfinity && {
val d = toDouble
!d.isInfinity && d == that && equals(decimal(d))
}
- case that: Float =>
+ case that: Float =>
!that.isInfinity && {
val f = toFloat
!f.isInfinity && f == that && equals(decimal(f.toDouble))
@@ -482,43 +481,43 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
val d = toDouble
!d.isInfinity && bigDecimal.compareTo(new BigDec(d)) == 0
}
-
+
/** Tests whether this `BigDecimal` holds the decimal representation of a `Double`. */
def isDecimalDouble = {
val d = toDouble
!d.isInfinity && equals(decimal(d))
}
-
+
/** Tests whether this `BigDecimal` holds the decimal representation of a `Float`. */
def isDecimalFloat = {
val f = toFloat
!f.isInfinity && equals(decimal(f))
}
-
+
/** Tests whether this `BigDecimal` holds, to within precision, the binary representation of a `Double`. */
def isBinaryDouble = {
val d = toDouble
!d.isInfinity && equals(binary(d,mc))
}
-
+
/** Tests whether this `BigDecimal` holds, to within precision, the binary representation of a `Float`. */
def isBinaryFloat = {
val f = toFloat
!f.isInfinity && equals(binary(f,mc))
}
-
+
/** Tests whether this `BigDecimal` holds the exact expansion of a `Double`'s binary fractional form into base 10. */
def isExactDouble = {
val d = toDouble
!d.isInfinity && equals(exact(d))
}
-
+
/** Tests whether this `BigDecimal` holds the exact expansion of a `Float`'s binary fractional form into base 10. */
def isExactFloat = {
val f = toFloat
!f.isInfinity && equals(exact(f.toDouble))
}
-
+
private def noArithmeticException(body: => Unit): Boolean = {
try { body ; true }
@@ -526,9 +525,9 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
}
def isWhole() = scale <= 0 || bigDecimal.stripTrailingZeros.scale <= 0
-
+
def underlying = bigDecimal
-
+
/** Compares this BigDecimal with the specified BigDecimal for equality.
*/
@@ -538,22 +537,6 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
*/
def compare (that: BigDecimal): Int = this.bigDecimal compareTo that.bigDecimal
- /** Less-than-or-equals comparison of BigDecimals
- */
- def <= (that: BigDecimal): Boolean = compare(that) <= 0
-
- /** Greater-than-or-equals comparison of BigDecimals
- */
- def >= (that: BigDecimal): Boolean = compare(that) >= 0
-
- /** Less-than of BigDecimals
- */
- def < (that: BigDecimal): Boolean = compare(that) < 0
-
- /** Greater-than comparison of BigDecimals
- */
- def > (that: BigDecimal): Boolean = compare(that) > 0
-
/** Addition of BigDecimals
*/
def + (that: BigDecimal): BigDecimal = new BigDecimal(this.bigDecimal add that.bigDecimal, mc)
@@ -589,14 +572,14 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
case x if x <= 0 => this
case _ => that
}
-
+
/** Returns the maximum of this and that, or this if the two are equal
*/
def max (that: BigDecimal): BigDecimal = (this compare that) match {
case x if x >= 0 => this
case _ => that
}
-
+
/** Remainder after dividing this by that.
*/
def remainder (that: BigDecimal): BigDecimal = new BigDecimal(this.bigDecimal remainder that.bigDecimal, mc)
@@ -635,7 +618,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
val r = this.bigDecimal round mc
if (r eq bigDecimal) this else new BigDecimal(r, this.mc)
}
-
+
/** Returns a `BigDecimal` rounded according to its own `MathContext` */
def rounded: BigDecimal = {
val r = bigDecimal round mc
@@ -657,7 +640,7 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
/** Returns a `BigDecimal` whose scale is the specified value, and whose value is
* numerically equal to this BigDecimal's.
*/
- def setScale(scale: Int): BigDecimal =
+ def setScale(scale: Int): BigDecimal =
if (this.scale == scale) this
else new BigDecimal(this.bigDecimal setScale scale, mc)
diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala
index abc7371d9f..3ae3b9bf6c 100644
--- a/src/library/scala/math/BigInt.scala
+++ b/src/library/scala/math/BigInt.scala
@@ -109,7 +109,12 @@ object BigInt {
* @author Martin Odersky
* @version 1.0, 15/07/2003
*/
-final class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericConversions with Serializable {
+final class BigInt(val bigInteger: BigInteger)
+ extends ScalaNumber
+ with ScalaNumericConversions
+ with Serializable
+ with Ordered[BigInt]
+{
/** Returns the hash code for this BigInt. */
override def hashCode(): Int =
if (isValidLong) unifiedPrimitiveHashcode()
@@ -176,22 +181,6 @@ final class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNum
*/
def compare (that: BigInt): Int = this.bigInteger.compareTo(that.bigInteger)
- /** Less-than-or-equals comparison of BigInts
- */
- def <= (that: BigInt): Boolean = compare(that) <= 0
-
- /** Greater-than-or-equals comparison of BigInts
- */
- def >= (that: BigInt): Boolean = compare(that) >= 0
-
- /** Less-than of BigInts
- */
- def < (that: BigInt): Boolean = compare(that) < 0
-
- /** Greater-than comparison of BigInts
- */
- def > (that: BigInt): Boolean = compare(that) > 0
-
/** Addition of BigInts
*/
def + (that: BigInt): BigInt = new BigInt(this.bigInteger.add(that.bigInteger))
diff --git a/src/library/scala/math/Integral.scala b/src/library/scala/math/Integral.scala
index ff1f695f6d..44009fd4a2 100644
--- a/src/library/scala/math/Integral.scala
+++ b/src/library/scala/math/Integral.scala
@@ -6,8 +6,6 @@
** |/ **
\* */
-
-
package scala
package math
diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala
index 827cccc77e..37096d5ed0 100644
--- a/src/library/scala/math/Ordering.scala
+++ b/src/library/scala/math/Ordering.scala
@@ -224,42 +224,32 @@ object Ordering extends LowPriorityOrderingImplicits {
implicit object Unit extends UnitOrdering
trait BooleanOrdering extends Ordering[Boolean] {
- def compare(x: Boolean, y: Boolean) = (x, y) match {
- case (false, true) => -1
- case (true, false) => 1
- case _ => 0
- }
+ def compare(x: Boolean, y: Boolean) = java.lang.Boolean.compare(x, y)
}
implicit object Boolean extends BooleanOrdering
trait ByteOrdering extends Ordering[Byte] {
- def compare(x: Byte, y: Byte) = x.toInt - y.toInt
+ def compare(x: Byte, y: Byte) = java.lang.Byte.compare(x, y)
}
implicit object Byte extends ByteOrdering
trait CharOrdering extends Ordering[Char] {
- def compare(x: Char, y: Char) = x.toInt - y.toInt
+ def compare(x: Char, y: Char) = java.lang.Character.compare(x, y)
}
implicit object Char extends CharOrdering
trait ShortOrdering extends Ordering[Short] {
- def compare(x: Short, y: Short) = x.toInt - y.toInt
+ def compare(x: Short, y: Short) = java.lang.Short.compare(x, y)
}
implicit object Short extends ShortOrdering
trait IntOrdering extends Ordering[Int] {
- def compare(x: Int, y: Int) =
- if (x < y) -1
- else if (x == y) 0
- else 1
+ def compare(x: Int, y: Int) = java.lang.Integer.compare(x, y)
}
implicit object Int extends IntOrdering
trait LongOrdering extends Ordering[Long] {
- def compare(x: Long, y: Long) =
- if (x < y) -1
- else if (x == y) 0
- else 1
+ def compare(x: Long, y: Long) = java.lang.Long.compare(x, y)
}
implicit object Long extends LongOrdering
diff --git a/src/library/scala/math/package.scala b/src/library/scala/math/package.scala
index a75979385c..54c81ed613 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/noinline.scala b/src/library/scala/noinline.scala
index 38fd4c39d6..a427e170f4 100644
--- a/src/library/scala/noinline.scala
+++ b/src/library/scala/noinline.scala
@@ -11,8 +11,30 @@
package scala
/**
- * An annotation on methods that forbids the compiler to inline the
- * method, no matter how safe the inlining appears to be.
+ * An annotation on methods that forbids the compiler to inline the method, no matter how safe the
+ * inlining appears to be. The annotation can be used at definition site or at callsite.
+ *
+ * {{{
+ * @inline final def f1(x: Int) = x
+ * @noinline final def f2(x: Int) = x
+ * final def f3(x: Int) = x
+ *
+ * def t1 = f1(1) // inlined if possible
+ * def t2 = f2(1) // not inlined
+ * def t3 = f3(1) // may be inlined (heuristics)
+ * def t4 = f1(1): @noinline // not inlined (override at callsite)
+ * def t5 = f2(1): @inline // not inlined (cannot override the @noinline at f2's definition)
+ * def t6 = f3(1): @inline // inlined if possible
+ * def t7 = f3(1): @noinline // not inlined
+ * }
+ * }}}
+ *
+ * Note: parentheses are required when annotating a callsite withing a larger expression.
+ *
+ * {{{
+ * def t1 = f1(1) + f1(1): @noinline // equivalent to (f1(1) + f1(1)): @noinline
+ * def t2 = f1(1) + (f1(1): @noinline) // the second call to f1 is not inlined
+ * }}}
*
* @author Lex Spoon
* @version 1.0, 2007-5-21
diff --git a/src/library/scala/ref/SoftReference.scala b/src/library/scala/ref/SoftReference.scala
index e4ce667981..5e60f00788 100644
--- a/src/library/scala/ref/SoftReference.scala
+++ b/src/library/scala/ref/SoftReference.scala
@@ -20,6 +20,19 @@ class SoftReference[+T <: AnyRef](value : T, queue : ReferenceQueue[T]) extends
}
/**
+ * A companion object that implements an extractor for `SoftReference` values
+ * @author Rebecca Claire Murphy
+ */
+object SoftReference {
+
+ /** Creates a `SoftReference` pointing to `value` */
+ def apply[T <: AnyRef](value: T) = new SoftReference(value)
+
+ /** Optionally returns the referenced value, or `None` if that value no longer exists */
+ def unapply[T <: AnyRef](sr: SoftReference[T]): Option[T] = Option(sr.underlying.get)
+}
+
+/**
* @author Philipp Haller
*/
private class SoftReferenceWithWrapper[T <: AnyRef](value: T, queue: ReferenceQueue[T], val wrapper: SoftReference[T])
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index 9dd96183da..1811d3a00f 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -2,7 +2,6 @@ package scala
package reflect
import java.lang.{ Class => jClass }
-import scala.runtime.ScalaRunTime.arrayElementClass
/**
*
@@ -102,10 +101,10 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial
// case class accessories
override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]]
override def equals(x: Any) = x.isInstanceOf[ClassTag[_]] && this.runtimeClass == x.asInstanceOf[ClassTag[_]].runtimeClass
- override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass)
+ override def hashCode = runtimeClass.##
override def toString = {
def prettyprint(clazz: jClass[_]): String =
- if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else
+ if (clazz.isArray) s"Array[${prettyprint(clazz.getComponentType)}]" else
clazz.getName
prettyprint(runtimeClass)
}
diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala
index 986cd0390f..630966d0d4 100644
--- a/src/library/scala/runtime/AbstractPartialFunction.scala
+++ b/src/library/scala/runtime/AbstractPartialFunction.scala
@@ -9,8 +9,6 @@
package scala
package runtime
-import scala.annotation.unspecialized
-
/** `AbstractPartialFunction` reformulates all operations of its supertrait `PartialFunction`
* in terms of `isDefinedAt` and `applyOrElse`.
*
diff --git a/src/library/scala/runtime/ArrayRuntime.java b/src/library/scala/runtime/ArrayRuntime.java
deleted file mode 100644
index 1a0f748931..0000000000
--- a/src/library/scala/runtime/ArrayRuntime.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-
-
-package scala.runtime;
-
-/**
- * Methods on Java arrays
- */
-class ArrayRuntime {
- static boolean[] cloneArray(boolean[] array) { return array.clone(); }
- static byte[] cloneArray(byte[] array) { return array.clone(); }
- static short[] cloneArray(short[] array) { return array.clone(); }
- static char[] cloneArray(char[] array) { return array.clone(); }
- static int[] cloneArray(int[] array) { return array.clone(); }
- static long[] cloneArray(long[] array) { return array.clone(); }
- static float[] cloneArray(float[] array) { return array.clone(); }
- static double[] cloneArray(double[] array) { return array.clone(); }
- static Object[] cloneArray(Object[] array) { return array.clone(); }
-}
diff --git a/src/library/scala/runtime/Boxed.scala b/src/library/scala/runtime/Boxed.scala
deleted file mode 100644
index 933444773d..0000000000
--- a/src/library/scala/runtime/Boxed.scala
+++ /dev/null
@@ -1,12 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala
-package runtime
-
-trait Boxed { }
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index 9cb1dee41c..6b3874fc1f 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -179,7 +179,7 @@ public final class BoxesRunTime
return xc.equals(y);
}
- private static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) {
+ public static boolean equalsNumChar(java.lang.Number xn, java.lang.Character yc) {
if (yc == null)
return xn == null;
@@ -198,70 +198,6 @@ public final class BoxesRunTime
}
}
- /** Hashcode algorithm is driven by the requirements imposed
- * by primitive equality semantics, namely that equal objects
- * have equal hashCodes. The first priority are the integral/char
- * types, which already have the same hashCodes for the same
- * values except for Long. So Long's hashCode is altered to
- * conform to Int's for all values in Int's range.
- *
- * Float is problematic because it's far too small to hold
- * all the Ints, so for instance Int.MaxValue.toFloat claims
- * to be == to each of the largest 64 Ints. There is no way
- * to preserve equals/hashCode alignment without compromising
- * the hashCode distribution, so Floats are only guaranteed
- * to have the same hashCode for whole Floats in the range
- * Short.MinValue to Short.MaxValue (2^16 total.)
- *
- * Double has its hashCode altered to match the entire Int range,
- * but is not guaranteed beyond that. (But could/should it be?
- * The hashCode is only 32 bits so this is a more tractable
- * issue than Float's, but it might be better simply to exclude it.)
- *
- * Note: BigInt and BigDecimal, being arbitrary precision, could
- * be made consistent with all other types for the Int range, but
- * as yet have not.
- *
- * Note: Among primitives, Float.NaN != Float.NaN, but the boxed
- * versions are equal. This still needs reconciliation.
- */
- public static int hashFromLong(java.lang.Long n) {
- int iv = n.intValue();
- if (iv == n.longValue()) return iv;
- else return n.hashCode();
- }
- public static int hashFromDouble(java.lang.Double n) {
- int iv = n.intValue();
- double dv = n.doubleValue();
- if (iv == dv) return iv;
-
- long lv = n.longValue();
- if (lv == dv) return java.lang.Long.valueOf(lv).hashCode();
-
- float fv = n.floatValue();
- if (fv == dv) return java.lang.Float.valueOf(fv).hashCode();
- else return n.hashCode();
- }
- public static int hashFromFloat(java.lang.Float n) {
- int iv = n.intValue();
- float fv = n.floatValue();
- if (iv == fv) return iv;
-
- long lv = n.longValue();
- if (lv == fv) return java.lang.Long.valueOf(lv).hashCode();
- else return n.hashCode();
- }
- public static int hashFromNumber(java.lang.Number n) {
- if (n instanceof java.lang.Long) return hashFromLong((java.lang.Long)n);
- else if (n instanceof java.lang.Double) return hashFromDouble((java.lang.Double)n);
- else if (n instanceof java.lang.Float) return hashFromFloat((java.lang.Float)n);
- else return n.hashCode();
- }
- public static int hashFromObject(Object a) {
- if (a instanceof Number) return hashFromNumber((Number)a);
- else return a.hashCode();
- }
-
private static int unboxCharOrInt(Object arg1, int code) {
if (code == CHAR)
return ((java.lang.Character) arg1).charValue();
diff --git a/src/library/scala/runtime/LambdaDeserialize.java b/src/library/scala/runtime/LambdaDeserialize.java
new file mode 100644
index 0000000000..e239debf25
--- /dev/null
+++ b/src/library/scala/runtime/LambdaDeserialize.java
@@ -0,0 +1,29 @@
+package scala.runtime;
+
+
+import java.lang.invoke.*;
+import java.util.Arrays;
+import java.util.HashMap;
+
+public final class LambdaDeserialize {
+
+ private MethodHandles.Lookup lookup;
+ private final HashMap<String, MethodHandle> cache = new HashMap<>();
+ private final LambdaDeserializer$ l = LambdaDeserializer$.MODULE$;
+
+ private LambdaDeserialize(MethodHandles.Lookup lookup) {
+ this.lookup = lookup;
+ }
+
+ public Object deserializeLambda(SerializedLambda serialized) {
+ return l.deserializeLambda(lookup, cache, serialized);
+ }
+
+ public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName,
+ MethodType invokedType) throws Throwable {
+ MethodType type = MethodType.fromMethodDescriptorString("(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", lookup.getClass().getClassLoader());
+ MethodHandle deserializeLambda = lookup.findVirtual(LambdaDeserialize.class, "deserializeLambda", type);
+ MethodHandle exact = deserializeLambda.bindTo(new LambdaDeserialize(lookup)).asType(invokedType);
+ return new ConstantCallSite(exact);
+ }
+}
diff --git a/src/library/scala/runtime/LambdaDeserializer.scala b/src/library/scala/runtime/LambdaDeserializer.scala
new file mode 100644
index 0000000000..ad7d12ba5d
--- /dev/null
+++ b/src/library/scala/runtime/LambdaDeserializer.scala
@@ -0,0 +1,132 @@
+package scala.runtime
+
+import java.lang.invoke._
+
+/**
+ * This class is only intended to be called by synthetic `$deserializeLambda$` method that the Scala 2.12
+ * compiler will add to classes hosting lambdas.
+ *
+ * It is not intended to be consumed directly.
+ */
+object LambdaDeserializer {
+ /**
+ * Deserialize a lambda by calling `LambdaMetafactory.altMetafactory` to spin up a lambda class
+ * and instantiating this class with the captured arguments.
+ *
+ * A cache may be provided to ensure that subsequent deserialization of the same lambda expression
+ * is cheap, it amounts to a reflective call to the constructor of the previously created class.
+ * However, deserialization of the same lambda expression is not guaranteed to use the same class,
+ * concurrent deserialization of the same lambda expression may spin up more than one class.
+ *
+ * Assumptions:
+ * - No additional marker interfaces are required beyond `{java.io,scala.}Serializable`. These are
+ * not stored in `SerializedLambda`, so we can't reconstitute them.
+ * - No additional bridge methods are passed to `altMetafactory`. Again, these are not stored.
+ *
+ * @param lookup The factory for method handles. Must have access to the implementation method, the
+ * functional interface class, and `java.io.Serializable` or `scala.Serializable` as
+ * required.
+ * @param cache A cache used to avoid spinning up a class for each deserialization of a given lambda. May be `null`
+ * @param serialized The lambda to deserialize. Note that this is typically created by the `readResolve`
+ * member of the anonymous class created by `LambdaMetaFactory`.
+ * @return An instance of the functional interface
+ */
+ def deserializeLambda(lookup: MethodHandles.Lookup, cache: java.util.Map[String, MethodHandle], serialized: SerializedLambda): AnyRef = {
+ def slashDot(name: String) = name.replaceAll("/", ".")
+ val loader = lookup.lookupClass().getClassLoader
+ val implClass = loader.loadClass(slashDot(serialized.getImplClass))
+
+ def makeCallSite: CallSite = {
+ import serialized._
+ def parseDescriptor(s: String) =
+ MethodType.fromMethodDescriptorString(s, loader)
+
+ val funcInterfaceSignature = parseDescriptor(getFunctionalInterfaceMethodSignature)
+ val instantiated = parseDescriptor(getInstantiatedMethodType)
+ val functionalInterfaceClass = loader.loadClass(slashDot(getFunctionalInterfaceClass))
+
+ val implMethodSig = parseDescriptor(getImplMethodSignature)
+ // Construct the invoked type from the impl method type. This is the type of a factory
+ // that will be generated by the meta-factory. It is a method type, with param types
+ // coming form the types of the captures, and return type being the functional interface.
+ val invokedType: MethodType = {
+ // 1. Add receiver for non-static impl methods
+ val withReceiver = getImplMethodKind match {
+ case MethodHandleInfo.REF_invokeStatic | MethodHandleInfo.REF_newInvokeSpecial =>
+ implMethodSig
+ case _ =>
+ implMethodSig.insertParameterTypes(0, implClass)
+ }
+ // 2. Remove lambda parameters, leaving only captures. Note: the receiver may be a lambda parameter,
+ // such as in `Function<Object, String> s = Object::toString`
+ val lambdaArity = funcInterfaceSignature.parameterCount()
+ val from = withReceiver.parameterCount() - lambdaArity
+ val to = withReceiver.parameterCount()
+
+ // 3. Drop the lambda return type and replace with the functional interface.
+ withReceiver.dropParameterTypes(from, to).changeReturnType(functionalInterfaceClass)
+ }
+
+ // Lookup the implementation method
+ val implMethod: MethodHandle = try {
+ findMember(lookup, getImplMethodKind, implClass, getImplMethodName, implMethodSig)
+ } catch {
+ case e: ReflectiveOperationException => throw new IllegalArgumentException("Illegal lambda deserialization", e)
+ }
+
+ val flags: Int = LambdaMetafactory.FLAG_SERIALIZABLE | LambdaMetafactory.FLAG_MARKERS
+ val isScalaFunction = functionalInterfaceClass.getName.startsWith("scala.Function")
+ val markerInterface: Class[_] = loader.loadClass(if (isScalaFunction) ScalaSerializable else JavaIOSerializable)
+
+ LambdaMetafactory.altMetafactory(
+ lookup, getFunctionalInterfaceMethodName, invokedType,
+
+ /* samMethodType = */ funcInterfaceSignature,
+ /* implMethod = */ implMethod,
+ /* instantiatedMethodType = */ instantiated,
+ /* flags = */ flags.asInstanceOf[AnyRef],
+ /* markerInterfaceCount = */ 1.asInstanceOf[AnyRef],
+ /* markerInterfaces[0] = */ markerInterface,
+ /* bridgeCount = */ 0.asInstanceOf[AnyRef]
+ )
+ }
+
+ val key = serialized.getImplMethodName + " : " + serialized.getImplMethodSignature
+ val factory: MethodHandle = if (cache == null) {
+ makeCallSite.getTarget
+ } else cache.get(key) match {
+ case null =>
+ val callSite = makeCallSite
+ val temp = callSite.getTarget
+ cache.put(key, temp)
+ temp
+ case target => target
+ }
+
+ val captures = Array.tabulate(serialized.getCapturedArgCount)(n => serialized.getCapturedArg(n))
+ factory.invokeWithArguments(captures: _*)
+ }
+
+ private val ScalaSerializable = "scala.Serializable"
+
+ private val JavaIOSerializable = {
+ // We could actually omit this marker interface as LambdaMetaFactory will add it if
+ // the FLAG_SERIALIZABLE is set and of the provided markers extend it. But the code
+ // is cleaner if we uniformly add a single marker, so I'm leaving it in place.
+ "java.io.Serializable"
+ }
+
+ private def findMember(lookup: MethodHandles.Lookup, kind: Int, owner: Class[_],
+ name: String, signature: MethodType): MethodHandle = {
+ kind match {
+ case MethodHandleInfo.REF_invokeStatic =>
+ lookup.findStatic(owner, name, signature)
+ case MethodHandleInfo.REF_newInvokeSpecial =>
+ lookup.findConstructor(owner, signature)
+ case MethodHandleInfo.REF_invokeVirtual | MethodHandleInfo.REF_invokeInterface =>
+ lookup.findVirtual(owner, name, signature)
+ case MethodHandleInfo.REF_invokeSpecial =>
+ lookup.findSpecial(owner, name, signature, owner)
+ }
+ }
+}
diff --git a/src/library/scala/runtime/ScalaNumberProxy.scala b/src/library/scala/runtime/ScalaNumberProxy.scala
index 5e4da24c0d..9b4899aef6 100644
--- a/src/library/scala/runtime/ScalaNumberProxy.scala
+++ b/src/library/scala/runtime/ScalaNumberProxy.scala
@@ -9,8 +9,8 @@
package scala
package runtime
-import scala.collection.{ mutable, immutable }
-import scala.math.{ ScalaNumericConversions, ScalaNumericAnyConversions }
+import scala.collection.immutable
+import scala.math.ScalaNumericAnyConversions
import immutable.NumericRange
import Proxy.Typed
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 20f067f34f..b31a94576a 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -9,16 +9,14 @@
package scala
package runtime
-import scala.collection.{ Seq, IndexedSeq, TraversableView, AbstractIterator }
+import scala.collection.{ TraversableView, AbstractIterator, GenIterable }
import scala.collection.mutable.WrappedArray
-import scala.collection.immutable.{ StringLike, NumericRange, List, Stream, Nil, :: }
+import scala.collection.immutable.{ StringLike, NumericRange }
import scala.collection.generic.{ Sorted, IsTraversableLike }
import scala.reflect.{ ClassTag, classTag }
-import scala.util.control.ControlThrowable
import java.lang.{ Class => jClass }
-import java.lang.Double.doubleToLongBits
-import java.lang.reflect.{ Modifier, Method => JMethod }
+import java.lang.reflect.{ Method => JMethod }
/** The object ScalaRunTime provides support methods required by
* the scala runtime. All these methods should be considered
@@ -31,15 +29,6 @@ object ScalaRunTime {
private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean =
clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1))
- def isValueClass(clazz: jClass[_]) = clazz.isPrimitive()
-
- // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22)
- def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple")
- def isAnyVal(x: Any) = x match {
- case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true
- case _ => false
- }
-
// A helper method to make my life in the pattern matcher a lot easier.
def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr =
traversable conversion coll drop num
@@ -52,15 +41,6 @@ object ScalaRunTime {
else java.lang.reflect.Array.newInstance(clazz, 0).getClass
}
- /** Return the class object representing elements in arrays described by a given schematic.
- */
- def arrayElementClass(schematic: Any): jClass[_] = schematic match {
- case cls: jClass[_] => cls.getComponentType
- case tag: ClassTag[_] => tag.runtimeClass
- case _ =>
- throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})")
- }
-
/** Return the class object representing an unboxed value type,
* e.g., classOf[int], not classOf[java.lang.Integer]. The compiler
* rewrites expressions like 5.getClass to come here.
@@ -118,15 +98,15 @@ object ScalaRunTime {
}
def array_clone(xs: AnyRef): AnyRef = xs match {
- case x: Array[AnyRef] => ArrayRuntime.cloneArray(x)
- case x: Array[Int] => ArrayRuntime.cloneArray(x)
- case x: Array[Double] => ArrayRuntime.cloneArray(x)
- case x: Array[Long] => ArrayRuntime.cloneArray(x)
- case x: Array[Float] => ArrayRuntime.cloneArray(x)
- case x: Array[Char] => ArrayRuntime.cloneArray(x)
- case x: Array[Byte] => ArrayRuntime.cloneArray(x)
- case x: Array[Short] => ArrayRuntime.cloneArray(x)
- case x: Array[Boolean] => ArrayRuntime.cloneArray(x)
+ case x: Array[AnyRef] => x.clone()
+ case x: Array[Int] => x.clone()
+ case x: Array[Double] => x.clone()
+ case x: Array[Long] => x.clone()
+ case x: Array[Float] => x.clone()
+ case x: Array[Char] => x.clone()
+ case x: Array[Byte] => x.clone()
+ case x: Array[Short] => x.clone()
+ case x: Array[Boolean] => x.clone()
case x: Array[Unit] => x
case null => throw new NullPointerException
}
@@ -159,9 +139,6 @@ object ScalaRunTime {
// More background at ticket #2318.
def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m)
- def checkInitialized[T <: AnyRef](x: T): T =
- if (x == null) throw new UninitializedError else x
-
def _toString(x: Product): String =
x.productIterator.mkString(x.productPrefix + "(", ",", ")")
@@ -181,71 +158,9 @@ object ScalaRunTime {
}
}
- /** Fast path equality method for inlining; used when -optimise is set.
- */
- @inline def inlinedEquals(x: Object, y: Object): Boolean =
- if (x eq y) true
- else if (x eq null) false
- else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y)
- else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y)
- else x.equals(y)
-
- def _equals(x: Product, y: Any): Boolean = y match {
- case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator
- case _ => false
- }
-
- // hashcode -----------------------------------------------------------
- //
- // Note that these are the implementations called by ##, so they
- // must not call ## themselves.
-
- def hash(x: Any): Int =
- if (x == null) 0
- else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number])
- else x.hashCode
-
- def hash(dv: Double): Int = {
- val iv = dv.toInt
- if (iv == dv) return iv
-
- val lv = dv.toLong
- if (lv == dv) return lv.hashCode
-
- val fv = dv.toFloat
- if (fv == dv) fv.hashCode else dv.hashCode
- }
- def hash(fv: Float): Int = {
- val iv = fv.toInt
- if (iv == fv) return iv
-
- val lv = fv.toLong
- if (lv == fv) hash(lv)
- else fv.hashCode
- }
- def hash(lv: Long): Int = {
- val low = lv.toInt
- val lowSign = low >>> 31
- val high = (lv >>> 32).toInt
- low ^ (high + lowSign)
- }
- def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x)
-
- // The remaining overloads are here for completeness, but the compiler
- // inlines these definitions directly so they're not generally used.
- def hash(x: Int): Int = x
- def hash(x: Short): Int = x.toInt
- def hash(x: Byte): Int = x.toInt
- def hash(x: Char): Int = x.toInt
- def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode
- def hash(x: Unit): Int = 0
-
- /** A helper method for constructing case class equality methods,
- * because existential types get in the way of a clean outcome and
- * it's performing a series of Any/Any equals comparisons anyway.
- * See ticket #2867 for specifics.
- */
- def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2
+ /** Old implementation of `##`. */
+ @deprecated("Use scala.runtime.Statics.anyHash instead.", "2.12.0")
+ def hash(x: Any): Int = Statics.anyHash(x.asInstanceOf[Object])
/** Given any Scala value, convert it to a String.
*
@@ -268,6 +183,9 @@ object ScalaRunTime {
def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala."
def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc."
+ // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22)
+ def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple")
+
// We use reflection because the scala.xml package might not be available
def isSubClassOf(potentialSubClass: Class[_], ofClass: String) =
try {
@@ -325,7 +243,7 @@ object ScalaRunTime {
case x if useOwnToString(x) => x.toString
case x: AnyRef if isArray(x) => arrayToString(x)
case x: scala.collection.Map[_, _] => x.iterator take maxElements map mapInner mkString (x.stringPrefix + "(", ", ", ")")
- case x: Iterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
+ case x: GenIterable[_] => x.iterator take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Traversable[_] => x take maxElements map inner mkString (x.stringPrefix + "(", ", ", ")")
case x: Product1[_] if isTuple(x) => "(" + inner(x._1) + ",)" // that special trailing comma
case x: Product if isTuple(x) => x.productIterator map inner mkString ("(", ",", ")")
@@ -347,17 +265,4 @@ object ScalaRunTime {
nl + s + "\n"
}
-
- def box[T](clazz: jClass[T]): jClass[_] = clazz match {
- case java.lang.Byte.TYPE => classOf[java.lang.Byte]
- case java.lang.Short.TYPE => classOf[java.lang.Short]
- case java.lang.Character.TYPE => classOf[java.lang.Character]
- case java.lang.Integer.TYPE => classOf[java.lang.Integer]
- case java.lang.Long.TYPE => classOf[java.lang.Long]
- case java.lang.Float.TYPE => classOf[java.lang.Float]
- case java.lang.Double.TYPE => classOf[java.lang.Double]
- case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit]
- case java.lang.Boolean.TYPE => classOf[java.lang.Boolean]
- case _ => clazz
- }
}
diff --git a/src/library/scala/runtime/SeqCharSequence.scala b/src/library/scala/runtime/SeqCharSequence.scala
index 74e67bb9e7..293bf950db 100644
--- a/src/library/scala/runtime/SeqCharSequence.scala
+++ b/src/library/scala/runtime/SeqCharSequence.scala
@@ -9,8 +9,6 @@
package scala
package runtime
-import java.util.Arrays.copyOfRange
-
@deprecated("Use Predef.SeqCharSequence", "2.11.0")
final class SeqCharSequence(val xs: scala.collection.IndexedSeq[Char]) extends CharSequence {
def length: Int = xs.length
diff --git a/src/library/scala/runtime/Statics.java b/src/library/scala/runtime/Statics.java
index 485511ecbb..62390cb9d0 100644
--- a/src/library/scala/runtime/Statics.java
+++ b/src/library/scala/runtime/Statics.java
@@ -36,10 +36,11 @@ public final class Statics {
}
public static int longHash(long lv) {
- if ((int)lv == lv)
- return (int)lv;
- else
- return (int)(lv ^ (lv >>> 32));
+ int iv = (int)lv;
+ if (iv == lv)
+ return iv;
+
+ return java.lang.Long.hashCode(lv);
}
public static int doubleHash(double dv) {
@@ -47,16 +48,15 @@ public final class Statics {
if (iv == dv)
return iv;
- float fv = (float)dv;
- if (fv == dv)
- return java.lang.Float.floatToIntBits(fv);
-
long lv = (long)dv;
if (lv == dv)
- return (int)lv;
+ return java.lang.Long.hashCode(lv);
+
+ float fv = (float)dv;
+ if (fv == dv)
+ return java.lang.Float.hashCode(fv);
- lv = Double.doubleToLongBits(dv);
- return (int)(lv ^ (lv >>> 32));
+ return java.lang.Double.hashCode(dv);
}
public static int floatHash(float fv) {
@@ -66,11 +66,39 @@ public final class Statics {
long lv = (long)fv;
if (lv == fv)
- return (int)(lv^(lv>>>32));
+ return java.lang.Long.hashCode(lv);
- return java.lang.Float.floatToIntBits(fv);
+ return java.lang.Float.hashCode(fv);
}
+ /**
+ * Hashcode algorithm is driven by the requirements imposed
+ * by primitive equality semantics, namely that equal objects
+ * have equal hashCodes. The first priority are the integral/char
+ * types, which already have the same hashCodes for the same
+ * values except for Long. So Long's hashCode is altered to
+ * conform to Int's for all values in Int's range.
+ *
+ * Float is problematic because it's far too small to hold
+ * all the Ints, so for instance Int.MaxValue.toFloat claims
+ * to be == to each of the largest 64 Ints. There is no way
+ * to preserve equals/hashCode alignment without compromising
+ * the hashCode distribution, so Floats are only guaranteed
+ * to have the same hashCode for whole Floats in the range
+ * Short.MinValue to Short.MaxValue (2^16 total.)
+ *
+ * Double has its hashCode altered to match the entire Int range,
+ * but is not guaranteed beyond that. (But could/should it be?
+ * The hashCode is only 32 bits so this is a more tractable
+ * issue than Float's, but it might be better simply to exclude it.)
+ *
+ * Note: BigInt and BigDecimal, being arbitrary precision, could
+ * be made consistent with all other types for the Int range, but
+ * as yet have not.
+ *
+ * Note: Among primitives, Float.NaN != Float.NaN, but the boxed
+ * versions are equal. This still needs reconciliation.
+ */
public static int anyHash(Object x) {
if (x == null)
return 0;
diff --git a/src/library/scala/runtime/StructuralCallSite.java b/src/library/scala/runtime/StructuralCallSite.java
new file mode 100644
index 0000000000..f73b4f08e6
--- /dev/null
+++ b/src/library/scala/runtime/StructuralCallSite.java
@@ -0,0 +1,43 @@
+package scala.runtime;
+
+
+import java.lang.invoke.*;
+import java.lang.ref.SoftReference;
+import java.lang.reflect.Method;
+
+public final class StructuralCallSite {
+
+ private Class<?>[] parameterTypes;
+ private SoftReference<MethodCache> cache = new SoftReference<>(new EmptyMethodCache());
+
+ private StructuralCallSite(MethodType callType) {
+ parameterTypes = callType.parameterArray();
+ }
+
+ public MethodCache get() {
+ MethodCache cache = this.cache.get();
+ if (cache == null) {
+ cache = new EmptyMethodCache();
+ this.cache = new SoftReference<>(cache);
+ }
+ return cache;
+ }
+
+ public Method find(Class<?> receiver) {
+ return get().find(receiver);
+ }
+
+ public Method add(Class<?> receiver, Method m) {
+ cache = new SoftReference<MethodCache>(get().add(receiver, m));
+ return m;
+ }
+ public Class<?>[] parameterTypes() {
+ return parameterTypes;
+ }
+
+ public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName,
+ MethodType invokedType, MethodType reflectiveCallType) throws Throwable {
+ StructuralCallSite structuralCallSite = new StructuralCallSite(reflectiveCallType);
+ return new ConstantCallSite(MethodHandles.constant(StructuralCallSite.class, structuralCallSite));
+ }
+}
diff --git a/src/library/scala/runtime/SymbolLiteral.java b/src/library/scala/runtime/SymbolLiteral.java
new file mode 100644
index 0000000000..09a66c83d5
--- /dev/null
+++ b/src/library/scala/runtime/SymbolLiteral.java
@@ -0,0 +1,20 @@
+package scala.runtime;
+
+import java.lang.invoke.*;
+import java.util.regex.Pattern;
+
+public final class SymbolLiteral {
+ private SymbolLiteral() {
+ }
+
+ public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName,
+ MethodType invokedType,
+ String value) throws Throwable {
+ ClassLoader classLoader = lookup.lookupClass().getClassLoader();
+ MethodType type = MethodType.fromMethodDescriptorString("(Ljava/lang/Object;)Ljava/lang/Object;", classLoader);
+ Class<?> symbolClass = Class.forName("scala.Symbol", false, classLoader);
+ MethodHandle factoryMethod = lookup.findStatic(symbolClass, "apply", type);
+ Object symbolValue = factoryMethod.invokeWithArguments(value);
+ return new ConstantCallSite(MethodHandles.constant(symbolClass, symbolValue));
+ }
+}
diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala
index 4109f5cb4b..15331d4160 100644
--- a/src/library/scala/runtime/Tuple2Zipped.scala
+++ b/src/library/scala/runtime/Tuple2Zipped.scala
@@ -110,6 +110,8 @@ final class Tuple2Zipped[El1, Repr1, El2, Repr2](val colls: (TraversableLike[El1
return
}
}
+
+ override def toString = "(%s, %s).zipped".format(colls._1.toString, colls._2.toString)
}
object Tuple2Zipped {
diff --git a/src/library/scala/runtime/Tuple3Zipped.scala b/src/library/scala/runtime/Tuple3Zipped.scala
index cde7699d40..62bee5ff0e 100644
--- a/src/library/scala/runtime/Tuple3Zipped.scala
+++ b/src/library/scala/runtime/Tuple3Zipped.scala
@@ -118,6 +118,8 @@ final class Tuple3Zipped[El1, Repr1, El2, Repr2, El3, Repr3](val colls: (Travers
return
}
}
+
+ override def toString: String = "(%s, %s, %s).zipped".format(colls._1.toString, colls._2.toString, colls._3.toString)
}
object Tuple3Zipped {
diff --git a/src/library/scala/runtime/java8/JFunction.java b/src/library/scala/runtime/java8/JFunction.java
new file mode 100644
index 0000000000..326aad3fec
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction.java
@@ -0,0 +1,146 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+public final class JFunction {
+ private JFunction() {}
+ public static <R> scala.Function0<R> func(JFunction0<R> f) { return f; }
+ public static scala.Function0<BoxedUnit> proc(JProcedure0 p) { return p; }
+ public static scala.Function0<BoxedUnit> procSpecialized(JFunction0$mcV$sp f) { return f; }
+ public static scala.Function0<Byte> funcSpecialized(JFunction0$mcB$sp f) { return f; }
+ public static scala.Function0<Short> funcSpecialized(JFunction0$mcS$sp f) { return f; }
+ public static scala.Function0<Integer> funcSpecialized(JFunction0$mcI$sp f) { return f; }
+ public static scala.Function0<Long> funcSpecialized(JFunction0$mcJ$sp f) { return f; }
+ public static scala.Function0<Character> funcSpecialized(JFunction0$mcC$sp f) { return f; }
+ public static scala.Function0<Float> funcSpecialized(JFunction0$mcF$sp f) { return f; }
+ public static scala.Function0<Double> funcSpecialized(JFunction0$mcD$sp f) { return f; }
+ public static scala.Function0<Boolean> funcSpecialized(JFunction0$mcZ$sp f) { return f; }
+ public static <T1, R> scala.Function1<T1, R> func(JFunction1<T1, R> f) { return f; }
+ public static <T1> scala.Function1<T1, BoxedUnit> proc(JProcedure1<T1> p) { return p; }
+ public static scala.Function1<Integer, BoxedUnit> procSpecialized(JFunction1$mcVI$sp f) { return f; }
+ public static scala.Function1<Integer, Boolean> funcSpecialized(JFunction1$mcZI$sp f) { return f; }
+ public static scala.Function1<Integer, Integer> funcSpecialized(JFunction1$mcII$sp f) { return f; }
+ public static scala.Function1<Integer, Float> funcSpecialized(JFunction1$mcFI$sp f) { return f; }
+ public static scala.Function1<Integer, Long> funcSpecialized(JFunction1$mcJI$sp f) { return f; }
+ public static scala.Function1<Integer, Double> funcSpecialized(JFunction1$mcDI$sp f) { return f; }
+ public static scala.Function1<Long, BoxedUnit> procSpecialized(JFunction1$mcVJ$sp f) { return f; }
+ public static scala.Function1<Long, Boolean> funcSpecialized(JFunction1$mcZJ$sp f) { return f; }
+ public static scala.Function1<Long, Integer> funcSpecialized(JFunction1$mcIJ$sp f) { return f; }
+ public static scala.Function1<Long, Float> funcSpecialized(JFunction1$mcFJ$sp f) { return f; }
+ public static scala.Function1<Long, Long> funcSpecialized(JFunction1$mcJJ$sp f) { return f; }
+ public static scala.Function1<Long, Double> funcSpecialized(JFunction1$mcDJ$sp f) { return f; }
+ public static scala.Function1<Float, BoxedUnit> procSpecialized(JFunction1$mcVF$sp f) { return f; }
+ public static scala.Function1<Float, Boolean> funcSpecialized(JFunction1$mcZF$sp f) { return f; }
+ public static scala.Function1<Float, Integer> funcSpecialized(JFunction1$mcIF$sp f) { return f; }
+ public static scala.Function1<Float, Float> funcSpecialized(JFunction1$mcFF$sp f) { return f; }
+ public static scala.Function1<Float, Long> funcSpecialized(JFunction1$mcJF$sp f) { return f; }
+ public static scala.Function1<Float, Double> funcSpecialized(JFunction1$mcDF$sp f) { return f; }
+ public static scala.Function1<Double, BoxedUnit> procSpecialized(JFunction1$mcVD$sp f) { return f; }
+ public static scala.Function1<Double, Boolean> funcSpecialized(JFunction1$mcZD$sp f) { return f; }
+ public static scala.Function1<Double, Integer> funcSpecialized(JFunction1$mcID$sp f) { return f; }
+ public static scala.Function1<Double, Float> funcSpecialized(JFunction1$mcFD$sp f) { return f; }
+ public static scala.Function1<Double, Long> funcSpecialized(JFunction1$mcJD$sp f) { return f; }
+ public static scala.Function1<Double, Double> funcSpecialized(JFunction1$mcDD$sp f) { return f; }
+ public static <T1, T2, R> scala.Function2<T1, T2, R> func(JFunction2<T1, T2, R> f) { return f; }
+ public static <T1, T2> scala.Function2<T1, T2, BoxedUnit> proc(JProcedure2<T1, T2> p) { return p; }
+ public static scala.Function2<Integer, Integer, BoxedUnit> procSpecialized(JFunction2$mcVII$sp f) { return f; }
+ public static scala.Function2<Integer, Integer, Boolean> funcSpecialized(JFunction2$mcZII$sp f) { return f; }
+ public static scala.Function2<Integer, Integer, Integer> funcSpecialized(JFunction2$mcIII$sp f) { return f; }
+ public static scala.Function2<Integer, Integer, Float> funcSpecialized(JFunction2$mcFII$sp f) { return f; }
+ public static scala.Function2<Integer, Integer, Long> funcSpecialized(JFunction2$mcJII$sp f) { return f; }
+ public static scala.Function2<Integer, Integer, Double> funcSpecialized(JFunction2$mcDII$sp f) { return f; }
+ public static scala.Function2<Integer, Long, BoxedUnit> procSpecialized(JFunction2$mcVIJ$sp f) { return f; }
+ public static scala.Function2<Integer, Long, Boolean> funcSpecialized(JFunction2$mcZIJ$sp f) { return f; }
+ public static scala.Function2<Integer, Long, Integer> funcSpecialized(JFunction2$mcIIJ$sp f) { return f; }
+ public static scala.Function2<Integer, Long, Float> funcSpecialized(JFunction2$mcFIJ$sp f) { return f; }
+ public static scala.Function2<Integer, Long, Long> funcSpecialized(JFunction2$mcJIJ$sp f) { return f; }
+ public static scala.Function2<Integer, Long, Double> funcSpecialized(JFunction2$mcDIJ$sp f) { return f; }
+ public static scala.Function2<Integer, Double, BoxedUnit> procSpecialized(JFunction2$mcVID$sp f) { return f; }
+ public static scala.Function2<Integer, Double, Boolean> funcSpecialized(JFunction2$mcZID$sp f) { return f; }
+ public static scala.Function2<Integer, Double, Integer> funcSpecialized(JFunction2$mcIID$sp f) { return f; }
+ public static scala.Function2<Integer, Double, Float> funcSpecialized(JFunction2$mcFID$sp f) { return f; }
+ public static scala.Function2<Integer, Double, Long> funcSpecialized(JFunction2$mcJID$sp f) { return f; }
+ public static scala.Function2<Integer, Double, Double> funcSpecialized(JFunction2$mcDID$sp f) { return f; }
+ public static scala.Function2<Long, Integer, BoxedUnit> procSpecialized(JFunction2$mcVJI$sp f) { return f; }
+ public static scala.Function2<Long, Integer, Boolean> funcSpecialized(JFunction2$mcZJI$sp f) { return f; }
+ public static scala.Function2<Long, Integer, Integer> funcSpecialized(JFunction2$mcIJI$sp f) { return f; }
+ public static scala.Function2<Long, Integer, Float> funcSpecialized(JFunction2$mcFJI$sp f) { return f; }
+ public static scala.Function2<Long, Integer, Long> funcSpecialized(JFunction2$mcJJI$sp f) { return f; }
+ public static scala.Function2<Long, Integer, Double> funcSpecialized(JFunction2$mcDJI$sp f) { return f; }
+ public static scala.Function2<Long, Long, BoxedUnit> procSpecialized(JFunction2$mcVJJ$sp f) { return f; }
+ public static scala.Function2<Long, Long, Boolean> funcSpecialized(JFunction2$mcZJJ$sp f) { return f; }
+ public static scala.Function2<Long, Long, Integer> funcSpecialized(JFunction2$mcIJJ$sp f) { return f; }
+ public static scala.Function2<Long, Long, Float> funcSpecialized(JFunction2$mcFJJ$sp f) { return f; }
+ public static scala.Function2<Long, Long, Long> funcSpecialized(JFunction2$mcJJJ$sp f) { return f; }
+ public static scala.Function2<Long, Long, Double> funcSpecialized(JFunction2$mcDJJ$sp f) { return f; }
+ public static scala.Function2<Long, Double, BoxedUnit> procSpecialized(JFunction2$mcVJD$sp f) { return f; }
+ public static scala.Function2<Long, Double, Boolean> funcSpecialized(JFunction2$mcZJD$sp f) { return f; }
+ public static scala.Function2<Long, Double, Integer> funcSpecialized(JFunction2$mcIJD$sp f) { return f; }
+ public static scala.Function2<Long, Double, Float> funcSpecialized(JFunction2$mcFJD$sp f) { return f; }
+ public static scala.Function2<Long, Double, Long> funcSpecialized(JFunction2$mcJJD$sp f) { return f; }
+ public static scala.Function2<Long, Double, Double> funcSpecialized(JFunction2$mcDJD$sp f) { return f; }
+ public static scala.Function2<Double, Integer, BoxedUnit> procSpecialized(JFunction2$mcVDI$sp f) { return f; }
+ public static scala.Function2<Double, Integer, Boolean> funcSpecialized(JFunction2$mcZDI$sp f) { return f; }
+ public static scala.Function2<Double, Integer, Integer> funcSpecialized(JFunction2$mcIDI$sp f) { return f; }
+ public static scala.Function2<Double, Integer, Float> funcSpecialized(JFunction2$mcFDI$sp f) { return f; }
+ public static scala.Function2<Double, Integer, Long> funcSpecialized(JFunction2$mcJDI$sp f) { return f; }
+ public static scala.Function2<Double, Integer, Double> funcSpecialized(JFunction2$mcDDI$sp f) { return f; }
+ public static scala.Function2<Double, Long, BoxedUnit> procSpecialized(JFunction2$mcVDJ$sp f) { return f; }
+ public static scala.Function2<Double, Long, Boolean> funcSpecialized(JFunction2$mcZDJ$sp f) { return f; }
+ public static scala.Function2<Double, Long, Integer> funcSpecialized(JFunction2$mcIDJ$sp f) { return f; }
+ public static scala.Function2<Double, Long, Float> funcSpecialized(JFunction2$mcFDJ$sp f) { return f; }
+ public static scala.Function2<Double, Long, Long> funcSpecialized(JFunction2$mcJDJ$sp f) { return f; }
+ public static scala.Function2<Double, Long, Double> funcSpecialized(JFunction2$mcDDJ$sp f) { return f; }
+ public static scala.Function2<Double, Double, BoxedUnit> procSpecialized(JFunction2$mcVDD$sp f) { return f; }
+ public static scala.Function2<Double, Double, Boolean> funcSpecialized(JFunction2$mcZDD$sp f) { return f; }
+ public static scala.Function2<Double, Double, Integer> funcSpecialized(JFunction2$mcIDD$sp f) { return f; }
+ public static scala.Function2<Double, Double, Float> funcSpecialized(JFunction2$mcFDD$sp f) { return f; }
+ public static scala.Function2<Double, Double, Long> funcSpecialized(JFunction2$mcJDD$sp f) { return f; }
+ public static scala.Function2<Double, Double, Double> funcSpecialized(JFunction2$mcDDD$sp f) { return f; }
+ public static <T1, T2, T3, R> scala.Function3<T1, T2, T3, R> func(JFunction3<T1, T2, T3, R> f) { return f; }
+ public static <T1, T2, T3> scala.Function3<T1, T2, T3, BoxedUnit> proc(JProcedure3<T1, T2, T3> p) { return p; }
+ public static <T1, T2, T3, T4, R> scala.Function4<T1, T2, T3, T4, R> func(JFunction4<T1, T2, T3, T4, R> f) { return f; }
+ public static <T1, T2, T3, T4> scala.Function4<T1, T2, T3, T4, BoxedUnit> proc(JProcedure4<T1, T2, T3, T4> p) { return p; }
+ public static <T1, T2, T3, T4, T5, R> scala.Function5<T1, T2, T3, T4, T5, R> func(JFunction5<T1, T2, T3, T4, T5, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5> scala.Function5<T1, T2, T3, T4, T5, BoxedUnit> proc(JProcedure5<T1, T2, T3, T4, T5> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, R> scala.Function6<T1, T2, T3, T4, T5, T6, R> func(JFunction6<T1, T2, T3, T4, T5, T6, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6> scala.Function6<T1, T2, T3, T4, T5, T6, BoxedUnit> proc(JProcedure6<T1, T2, T3, T4, T5, T6> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, R> scala.Function7<T1, T2, T3, T4, T5, T6, T7, R> func(JFunction7<T1, T2, T3, T4, T5, T6, T7, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7> scala.Function7<T1, T2, T3, T4, T5, T6, T7, BoxedUnit> proc(JProcedure7<T1, T2, T3, T4, T5, T6, T7> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, R> scala.Function8<T1, T2, T3, T4, T5, T6, T7, T8, R> func(JFunction8<T1, T2, T3, T4, T5, T6, T7, T8, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8> scala.Function8<T1, T2, T3, T4, T5, T6, T7, T8, BoxedUnit> proc(JProcedure8<T1, T2, T3, T4, T5, T6, T7, T8> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> scala.Function9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> func(JFunction9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9> scala.Function9<T1, T2, T3, T4, T5, T6, T7, T8, T9, BoxedUnit> proc(JProcedure9<T1, T2, T3, T4, T5, T6, T7, T8, T9> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> scala.Function10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> func(JFunction10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> scala.Function10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, BoxedUnit> proc(JProcedure10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> scala.Function11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> func(JFunction11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> scala.Function11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, BoxedUnit> proc(JProcedure11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> scala.Function12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> func(JFunction12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> scala.Function12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, BoxedUnit> proc(JProcedure12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> scala.Function13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> func(JFunction13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> scala.Function13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, BoxedUnit> proc(JProcedure13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> scala.Function14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> func(JFunction14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> scala.Function14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, BoxedUnit> proc(JProcedure14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> scala.Function15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> func(JFunction15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> scala.Function15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, BoxedUnit> proc(JProcedure15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> scala.Function16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> func(JFunction16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> scala.Function16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, BoxedUnit> proc(JProcedure16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R> scala.Function17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R> func(JFunction17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> scala.Function17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, BoxedUnit> proc(JProcedure17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R> scala.Function18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R> func(JFunction18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> scala.Function18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, BoxedUnit> proc(JProcedure18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R> scala.Function19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R> func(JFunction19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> scala.Function19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, BoxedUnit> proc(JProcedure19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R> scala.Function20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R> func(JFunction20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> scala.Function20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, BoxedUnit> proc(JProcedure20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R> scala.Function21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R> func(JFunction21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> scala.Function21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, BoxedUnit> proc(JProcedure21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> p) { return p; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R> scala.Function22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R> func(JFunction22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R> f) { return f; }
+ public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> scala.Function22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, BoxedUnit> proc(JProcedure22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> p) { return p; }
+}
+
diff --git a/src/library/scala/runtime/java8/JFunction0$mcB$sp.java b/src/library/scala/runtime/java8/JFunction0$mcB$sp.java
new file mode 100644
index 0000000000..c882757630
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcB$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcB$sp extends JFunction0 {
+ byte apply$mcB$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToByte(apply$mcB$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcC$sp.java b/src/library/scala/runtime/java8/JFunction0$mcC$sp.java
new file mode 100644
index 0000000000..c804529f71
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcC$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcC$sp extends JFunction0 {
+ char apply$mcC$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToCharacter(apply$mcC$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcD$sp.java b/src/library/scala/runtime/java8/JFunction0$mcD$sp.java
new file mode 100644
index 0000000000..dacf50237c
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcD$sp extends JFunction0 {
+ double apply$mcD$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcD$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcF$sp.java b/src/library/scala/runtime/java8/JFunction0$mcF$sp.java
new file mode 100644
index 0000000000..2a9f824924
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcF$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcF$sp extends JFunction0 {
+ float apply$mcF$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcF$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcI$sp.java b/src/library/scala/runtime/java8/JFunction0$mcI$sp.java
new file mode 100644
index 0000000000..75c612f916
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcI$sp extends JFunction0 {
+ int apply$mcI$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcI$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcJ$sp.java b/src/library/scala/runtime/java8/JFunction0$mcJ$sp.java
new file mode 100644
index 0000000000..d08984c794
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcJ$sp extends JFunction0 {
+ long apply$mcJ$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJ$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcS$sp.java b/src/library/scala/runtime/java8/JFunction0$mcS$sp.java
new file mode 100644
index 0000000000..d9e36a39f0
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcS$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcS$sp extends JFunction0 {
+ short apply$mcS$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToShort(apply$mcS$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcV$sp.java b/src/library/scala/runtime/java8/JFunction0$mcV$sp.java
new file mode 100644
index 0000000000..abd5e6ebbe
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcV$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcV$sp extends JFunction0 {
+ void apply$mcV$sp();
+
+ default Object apply() { apply$mcV$sp(); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0$mcZ$sp.java b/src/library/scala/runtime/java8/JFunction0$mcZ$sp.java
new file mode 100644
index 0000000000..e1cd62a913
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0$mcZ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0$mcZ$sp extends JFunction0 {
+ boolean apply$mcZ$sp();
+
+ default Object apply() { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZ$sp()); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction0.java b/src/library/scala/runtime/java8/JFunction0.java
new file mode 100644
index 0000000000..bdeb7d5f8e
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction0.java
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction0<R> extends scala.Function0<R> {
+ default void $init$() {
+ };
+ default void apply$mcV$sp() {
+ apply();
+ }
+ default byte apply$mcB$sp() {
+ return scala.runtime.BoxesRunTime.unboxToByte(apply());
+ }
+ default short apply$mcS$sp() {
+ return scala.runtime.BoxesRunTime.unboxToShort(apply());
+ }
+ default int apply$mcI$sp() {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply());
+ }
+ default long apply$mcJ$sp() {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply());
+ }
+ default char apply$mcC$sp() {
+ return scala.runtime.BoxesRunTime.unboxToChar(apply());
+ }
+ default float apply$mcF$sp() {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply());
+ }
+ default double apply$mcD$sp() {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply());
+ }
+ default boolean apply$mcZ$sp() {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply());
+ }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDD$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDD$sp.java
new file mode 100644
index 0000000000..4fbb370b8b
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcDD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcDD$sp extends JFunction1 {
+ double apply$mcDD$sp(double v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDF$sp.java
new file mode 100644
index 0000000000..ce45666dd1
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcDF$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcDF$sp extends JFunction1 {
+ double apply$mcDF$sp(float v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDI$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDI$sp.java
new file mode 100644
index 0000000000..09cac947c9
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcDI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcDI$sp extends JFunction1 {
+ double apply$mcDI$sp(int v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDI$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.java
new file mode 100644
index 0000000000..f5154c3854
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcDJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcDJ$sp extends JFunction1 {
+ double apply$mcDJ$sp(long v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFD$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFD$sp.java
new file mode 100644
index 0000000000..758b432d99
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcFD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcFD$sp extends JFunction1 {
+ float apply$mcFD$sp(double v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFD$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFF$sp.java
new file mode 100644
index 0000000000..7e13e287a5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcFF$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcFF$sp extends JFunction1 {
+ float apply$mcFF$sp(float v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFI$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFI$sp.java
new file mode 100644
index 0000000000..e3c4a203c7
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcFI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcFI$sp extends JFunction1 {
+ float apply$mcFI$sp(int v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFI$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.java
new file mode 100644
index 0000000000..d989fa1ea8
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcFJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcFJ$sp extends JFunction1 {
+ float apply$mcFJ$sp(long v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcID$sp.java b/src/library/scala/runtime/java8/JFunction1$mcID$sp.java
new file mode 100644
index 0000000000..bde5d88d46
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcID$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcID$sp extends JFunction1 {
+ int apply$mcID$sp(double v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcID$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcIF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcIF$sp.java
new file mode 100644
index 0000000000..d1d235aef1
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcIF$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcIF$sp extends JFunction1 {
+ int apply$mcIF$sp(float v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcII$sp.java b/src/library/scala/runtime/java8/JFunction1$mcII$sp.java
new file mode 100644
index 0000000000..ef44b3830c
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcII$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcII$sp extends JFunction1 {
+ int apply$mcII$sp(int v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcII$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.java
new file mode 100644
index 0000000000..373d13cd46
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcIJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcIJ$sp extends JFunction1 {
+ int apply$mcIJ$sp(long v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcJD$sp.java b/src/library/scala/runtime/java8/JFunction1$mcJD$sp.java
new file mode 100644
index 0000000000..86fd7b7779
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcJD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcJD$sp extends JFunction1 {
+ long apply$mcJD$sp(double v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJD$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcJF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcJF$sp.java
new file mode 100644
index 0000000000..3bcf264034
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcJF$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcJF$sp extends JFunction1 {
+ long apply$mcJF$sp(float v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcJI$sp.java b/src/library/scala/runtime/java8/JFunction1$mcJI$sp.java
new file mode 100644
index 0000000000..11bc15ef6e
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcJI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcJI$sp extends JFunction1 {
+ long apply$mcJI$sp(int v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJI$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcJJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcJJ$sp.java
new file mode 100644
index 0000000000..2e1ad7878f
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcJJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcJJ$sp extends JFunction1 {
+ long apply$mcJJ$sp(long v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcVD$sp.java b/src/library/scala/runtime/java8/JFunction1$mcVD$sp.java
new file mode 100644
index 0000000000..c8077e1268
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcVD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcVD$sp extends JFunction1 {
+ void apply$mcVD$sp(double v1);
+
+ default Object apply(Object t) { apply$mcVD$sp(scala.runtime.BoxesRunTime.unboxToDouble(t)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcVF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcVF$sp.java
new file mode 100644
index 0000000000..e7be77f8e3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcVF$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcVF$sp extends JFunction1 {
+ void apply$mcVF$sp(float v1);
+
+ default Object apply(Object t) { apply$mcVF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcVI$sp.java b/src/library/scala/runtime/java8/JFunction1$mcVI$sp.java
new file mode 100644
index 0000000000..7597ca5294
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcVI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcVI$sp extends JFunction1 {
+ void apply$mcVI$sp(int v1);
+
+ default Object apply(Object t) { apply$mcVI$sp(scala.runtime.BoxesRunTime.unboxToInt(t)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcVJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcVJ$sp.java
new file mode 100644
index 0000000000..55c6c3997f
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcVJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcVJ$sp extends JFunction1 {
+ void apply$mcVJ$sp(long v1);
+
+ default Object apply(Object t) { apply$mcVJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcZD$sp.java b/src/library/scala/runtime/java8/JFunction1$mcZD$sp.java
new file mode 100644
index 0000000000..883a0e84fa
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcZD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcZD$sp extends JFunction1 {
+ boolean apply$mcZD$sp(double v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZD$sp(scala.runtime.BoxesRunTime.unboxToDouble(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcZF$sp.java b/src/library/scala/runtime/java8/JFunction1$mcZF$sp.java
new file mode 100644
index 0000000000..884832ca37
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcZF$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcZF$sp extends JFunction1 {
+ boolean apply$mcZF$sp(float v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZF$sp(scala.runtime.BoxesRunTime.unboxToFloat(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcZI$sp.java b/src/library/scala/runtime/java8/JFunction1$mcZI$sp.java
new file mode 100644
index 0000000000..8a51aa99a2
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcZI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcZI$sp extends JFunction1 {
+ boolean apply$mcZI$sp(int v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZI$sp(scala.runtime.BoxesRunTime.unboxToInt(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1$mcZJ$sp.java b/src/library/scala/runtime/java8/JFunction1$mcZJ$sp.java
new file mode 100644
index 0000000000..dc619666dc
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1$mcZJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1$mcZJ$sp extends JFunction1 {
+ boolean apply$mcZJ$sp(long v1);
+
+ default Object apply(Object t) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZJ$sp(scala.runtime.BoxesRunTime.unboxToLong(t))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction1.java b/src/library/scala/runtime/java8/JFunction1.java
new file mode 100644
index 0000000000..2b8580271a
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction1.java
@@ -0,0 +1,228 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction1<T1, R> extends scala.Function1<T1, R> {
+ default void apply$mcVI$sp(int v1) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1));
+ }
+ default boolean apply$mcZI$sp(int v1) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1)));
+ }
+ default int apply$mcII$sp(int v1) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1)));
+ }
+ default float apply$mcFI$sp(int v1) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1)));
+ }
+ default long apply$mcJI$sp(int v1) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1)));
+ }
+ default double apply$mcDI$sp(int v1) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1)));
+ }
+ default void apply$mcVJ$sp(long v1) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1));
+ }
+ default boolean apply$mcZJ$sp(long v1) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1)));
+ }
+ default int apply$mcIJ$sp(long v1) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1)));
+ }
+ default float apply$mcFJ$sp(long v1) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1)));
+ }
+ default long apply$mcJJ$sp(long v1) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1)));
+ }
+ default double apply$mcDJ$sp(long v1) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1)));
+ }
+ default void apply$mcVF$sp(float v1) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToFloat(v1));
+ }
+ default boolean apply$mcZF$sp(float v1) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToFloat(v1)));
+ }
+ default int apply$mcIF$sp(float v1) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToFloat(v1)));
+ }
+ default float apply$mcFF$sp(float v1) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToFloat(v1)));
+ }
+ default long apply$mcJF$sp(float v1) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToFloat(v1)));
+ }
+ default double apply$mcDF$sp(float v1) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToFloat(v1)));
+ }
+ default void apply$mcVD$sp(double v1) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1));
+ }
+ default boolean apply$mcZD$sp(double v1) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1)));
+ }
+ default int apply$mcID$sp(double v1) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1)));
+ }
+ default float apply$mcFD$sp(double v1) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1)));
+ }
+ default long apply$mcJD$sp(double v1) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1)));
+ }
+ default double apply$mcDD$sp(double v1) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1)));
+ }
+
+ default scala.Function1 compose$mcVI$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcZI$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcII$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcFI$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcJI$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcDI$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcVJ$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcZJ$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcIJ$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcFJ$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcJJ$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcDJ$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcVF$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcZF$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcIF$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcFF$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcJF$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcDF$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcVD$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcZD$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcID$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcFD$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcJD$sp(scala.Function1 g) {
+ return compose(g);
+ }
+ default scala.Function1 compose$mcDD$sp(scala.Function1 g) {
+ return compose(g);
+ }
+
+ default scala.Function1 andThen$mcVI$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcZI$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcII$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcFI$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcJI$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcDI$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcVJ$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcZJ$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcIJ$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcFJ$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcJJ$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcDJ$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcVF$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcZF$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcIF$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcFF$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcJF$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcDF$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcVD$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcZD$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcID$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcFD$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcJD$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+ default scala.Function1 andThen$mcDD$sp(scala.Function1 g) {
+ return andThen(g);
+ }
+}
diff --git a/src/library/scala/runtime/java8/JFunction10.java b/src/library/scala/runtime/java8/JFunction10.java
new file mode 100644
index 0000000000..9b9ab4a6c5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction10.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> extends scala.Function10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction11.java b/src/library/scala/runtime/java8/JFunction11.java
new file mode 100644
index 0000000000..b24c9a1ed0
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction11.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> extends scala.Function11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction12.java b/src/library/scala/runtime/java8/JFunction12.java
new file mode 100644
index 0000000000..09c90cb7e7
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction12.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> extends scala.Function12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction13.java b/src/library/scala/runtime/java8/JFunction13.java
new file mode 100644
index 0000000000..e8cc2b53e6
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction13.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> extends scala.Function13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction14.java b/src/library/scala/runtime/java8/JFunction14.java
new file mode 100644
index 0000000000..327e442b4c
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction14.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> extends scala.Function14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction15.java b/src/library/scala/runtime/java8/JFunction15.java
new file mode 100644
index 0000000000..bd2e3c00da
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction15.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> extends scala.Function15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction16.java b/src/library/scala/runtime/java8/JFunction16.java
new file mode 100644
index 0000000000..fb961e60ec
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction16.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> extends scala.Function16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction17.java b/src/library/scala/runtime/java8/JFunction17.java
new file mode 100644
index 0000000000..90a0b1d441
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction17.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R> extends scala.Function17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction18.java b/src/library/scala/runtime/java8/JFunction18.java
new file mode 100644
index 0000000000..cac24309e2
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction18.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R> extends scala.Function18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction19.java b/src/library/scala/runtime/java8/JFunction19.java
new file mode 100644
index 0000000000..bbfceac8c3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction19.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R> extends scala.Function19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDDD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDDD$sp.java
new file mode 100644
index 0000000000..1c11fb5252
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDDD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDDD$sp extends JFunction2 {
+ double apply$mcDDD$sp(double v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDDI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDDI$sp.java
new file mode 100644
index 0000000000..e080bc87fa
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDDI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDDI$sp extends JFunction2 {
+ double apply$mcDDI$sp(double v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDDI$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.java
new file mode 100644
index 0000000000..f96b19dff7
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDDJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDDJ$sp extends JFunction2 {
+ double apply$mcDDJ$sp(double v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDDJ$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDID$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDID$sp.java
new file mode 100644
index 0000000000..944f469a6d
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDID$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDID$sp extends JFunction2 {
+ double apply$mcDID$sp(int v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDID$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDII$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDII$sp.java
new file mode 100644
index 0000000000..a04f616b5a
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDII$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDII$sp extends JFunction2 {
+ double apply$mcDII$sp(int v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDII$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.java
new file mode 100644
index 0000000000..3a7d33d4a5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDIJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDIJ$sp extends JFunction2 {
+ double apply$mcDIJ$sp(int v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDIJ$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDJD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDJD$sp.java
new file mode 100644
index 0000000000..86b48486e6
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDJD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDJD$sp extends JFunction2 {
+ double apply$mcDJD$sp(long v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDJD$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDJI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDJI$sp.java
new file mode 100644
index 0000000000..b9375c7870
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDJI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDJI$sp extends JFunction2 {
+ double apply$mcDJI$sp(long v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDJI$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.java
new file mode 100644
index 0000000000..4adbd17e14
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcDJJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcDJJ$sp extends JFunction2 {
+ double apply$mcDJJ$sp(long v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToDouble(apply$mcDJJ$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFDD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFDD$sp.java
new file mode 100644
index 0000000000..7e53d117c7
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFDD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFDD$sp extends JFunction2 {
+ float apply$mcFDD$sp(double v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFDI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFDI$sp.java
new file mode 100644
index 0000000000..64c4b2f133
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFDI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFDI$sp extends JFunction2 {
+ float apply$mcFDI$sp(double v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFDI$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.java
new file mode 100644
index 0000000000..c7ffcbc66a
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFDJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFDJ$sp extends JFunction2 {
+ float apply$mcFDJ$sp(double v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFDJ$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFID$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFID$sp.java
new file mode 100644
index 0000000000..43944751e6
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFID$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFID$sp extends JFunction2 {
+ float apply$mcFID$sp(int v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFID$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFII$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFII$sp.java
new file mode 100644
index 0000000000..a9a4540ca3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFII$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFII$sp extends JFunction2 {
+ float apply$mcFII$sp(int v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFII$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.java
new file mode 100644
index 0000000000..217615c7a3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFIJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFIJ$sp extends JFunction2 {
+ float apply$mcFIJ$sp(int v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFIJ$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFJD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFJD$sp.java
new file mode 100644
index 0000000000..8400e47876
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFJD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFJD$sp extends JFunction2 {
+ float apply$mcFJD$sp(long v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFJD$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFJI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFJI$sp.java
new file mode 100644
index 0000000000..e6b6259f96
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFJI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFJI$sp extends JFunction2 {
+ float apply$mcFJI$sp(long v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFJI$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.java
new file mode 100644
index 0000000000..68a4c8ecc0
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcFJJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcFJJ$sp extends JFunction2 {
+ float apply$mcFJJ$sp(long v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToFloat(apply$mcFJJ$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIDD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIDD$sp.java
new file mode 100644
index 0000000000..76fe0b6ead
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIDD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIDD$sp extends JFunction2 {
+ int apply$mcIDD$sp(double v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIDI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIDI$sp.java
new file mode 100644
index 0000000000..908078f735
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIDI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIDI$sp extends JFunction2 {
+ int apply$mcIDI$sp(double v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIDI$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.java
new file mode 100644
index 0000000000..35c943e324
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIDJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIDJ$sp extends JFunction2 {
+ int apply$mcIDJ$sp(double v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIDJ$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIID$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIID$sp.java
new file mode 100644
index 0000000000..f245ec8788
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIID$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIID$sp extends JFunction2 {
+ int apply$mcIID$sp(int v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIID$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIII$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIII$sp.java
new file mode 100644
index 0000000000..f3a7a56dff
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIII$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIII$sp extends JFunction2 {
+ int apply$mcIII$sp(int v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIII$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.java
new file mode 100644
index 0000000000..9736196b9e
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIIJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIIJ$sp extends JFunction2 {
+ int apply$mcIIJ$sp(int v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIIJ$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIJD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIJD$sp.java
new file mode 100644
index 0000000000..3211432ccb
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIJD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIJD$sp extends JFunction2 {
+ int apply$mcIJD$sp(long v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIJD$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIJI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIJI$sp.java
new file mode 100644
index 0000000000..74f76404e0
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIJI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIJI$sp extends JFunction2 {
+ int apply$mcIJI$sp(long v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIJI$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.java
new file mode 100644
index 0000000000..7b9060bcb8
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcIJJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcIJJ$sp extends JFunction2 {
+ int apply$mcIJJ$sp(long v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToInteger(apply$mcIJJ$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJDD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJDD$sp.java
new file mode 100644
index 0000000000..b4595cdf6a
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJDD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJDD$sp extends JFunction2 {
+ long apply$mcJDD$sp(double v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJDI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJDI$sp.java
new file mode 100644
index 0000000000..59aad669e7
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJDI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJDI$sp extends JFunction2 {
+ long apply$mcJDI$sp(double v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJDI$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.java
new file mode 100644
index 0000000000..8111e03617
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJDJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJDJ$sp extends JFunction2 {
+ long apply$mcJDJ$sp(double v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJDJ$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJID$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJID$sp.java
new file mode 100644
index 0000000000..8a06a40a4a
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJID$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJID$sp extends JFunction2 {
+ long apply$mcJID$sp(int v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJID$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJII$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJII$sp.java
new file mode 100644
index 0000000000..3d2e03ddbc
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJII$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJII$sp extends JFunction2 {
+ long apply$mcJII$sp(int v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJII$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.java
new file mode 100644
index 0000000000..32408269c8
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJIJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJIJ$sp extends JFunction2 {
+ long apply$mcJIJ$sp(int v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJIJ$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJJD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJJD$sp.java
new file mode 100644
index 0000000000..cf75bc5c19
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJJD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJJD$sp extends JFunction2 {
+ long apply$mcJJD$sp(long v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJJD$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJJI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJJI$sp.java
new file mode 100644
index 0000000000..eddcea671d
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJJI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJJI$sp extends JFunction2 {
+ long apply$mcJJI$sp(long v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJJI$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.java
new file mode 100644
index 0000000000..4f5626a3e6
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcJJJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcJJJ$sp extends JFunction2 {
+ long apply$mcJJJ$sp(long v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToLong(apply$mcJJJ$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVDD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVDD$sp.java
new file mode 100644
index 0000000000..45b9739c91
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVDD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVDD$sp extends JFunction2 {
+ void apply$mcVDD$sp(double v1, double v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVDI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVDI$sp.java
new file mode 100644
index 0000000000..c344ea5017
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVDI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVDI$sp extends JFunction2 {
+ void apply$mcVDI$sp(double v1, int v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVDI$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToInt(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.java
new file mode 100644
index 0000000000..94b01d59d5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVDJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVDJ$sp extends JFunction2 {
+ void apply$mcVDJ$sp(double v1, long v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVDJ$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToLong(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVID$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVID$sp.java
new file mode 100644
index 0000000000..47c29525a7
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVID$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVID$sp extends JFunction2 {
+ void apply$mcVID$sp(int v1, double v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVID$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVII$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVII$sp.java
new file mode 100644
index 0000000000..546a994cb9
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVII$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVII$sp extends JFunction2 {
+ void apply$mcVII$sp(int v1, int v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVII$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToInt(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.java
new file mode 100644
index 0000000000..d9871efee3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVIJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVIJ$sp extends JFunction2 {
+ void apply$mcVIJ$sp(int v1, long v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVIJ$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToLong(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVJD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVJD$sp.java
new file mode 100644
index 0000000000..525c8ee059
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVJD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVJD$sp extends JFunction2 {
+ void apply$mcVJD$sp(long v1, double v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVJD$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVJI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVJI$sp.java
new file mode 100644
index 0000000000..98f33bf942
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVJI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVJI$sp extends JFunction2 {
+ void apply$mcVJI$sp(long v1, int v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVJI$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToInt(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.java
new file mode 100644
index 0000000000..adb8934b57
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcVJJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcVJJ$sp extends JFunction2 {
+ void apply$mcVJJ$sp(long v1, long v2);
+
+ default Object apply(Object v1, Object v2) { apply$mcVJJ$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToLong(v2)); return scala.runtime.BoxedUnit.UNIT; }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZDD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZDD$sp.java
new file mode 100644
index 0000000000..9272e025a6
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZDD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZDD$sp extends JFunction2 {
+ boolean apply$mcZDD$sp(double v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZDD$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZDI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZDI$sp.java
new file mode 100644
index 0000000000..4406e00abd
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZDI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZDI$sp extends JFunction2 {
+ boolean apply$mcZDI$sp(double v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZDI$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.java
new file mode 100644
index 0000000000..1f92dddfaf
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZDJ$sp extends JFunction2 {
+ boolean apply$mcZDJ$sp(double v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZDJ$sp(scala.runtime.BoxesRunTime.unboxToDouble(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZID$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZID$sp.java
new file mode 100644
index 0000000000..06b73f9897
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZID$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZID$sp extends JFunction2 {
+ boolean apply$mcZID$sp(int v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZID$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZII$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZII$sp.java
new file mode 100644
index 0000000000..729f86063f
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZII$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZII$sp extends JFunction2 {
+ boolean apply$mcZII$sp(int v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZII$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.java
new file mode 100644
index 0000000000..38da681cd1
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZIJ$sp extends JFunction2 {
+ boolean apply$mcZIJ$sp(int v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZIJ$sp(scala.runtime.BoxesRunTime.unboxToInt(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZJD$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZJD$sp.java
new file mode 100644
index 0000000000..6dc9534811
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZJD$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZJD$sp extends JFunction2 {
+ boolean apply$mcZJD$sp(long v1, double v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZJD$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToDouble(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZJI$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZJI$sp.java
new file mode 100644
index 0000000000..a86f63be36
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZJI$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZJI$sp extends JFunction2 {
+ boolean apply$mcZJI$sp(long v1, int v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZJI$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToInt(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.java b/src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.java
new file mode 100644
index 0000000000..728a781e8e
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.java
@@ -0,0 +1,13 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2$mcZJJ$sp extends JFunction2 {
+ boolean apply$mcZJJ$sp(long v1, long v2);
+
+ default Object apply(Object v1, Object v2) { return scala.runtime.BoxesRunTime.boxToBoolean(apply$mcZJJ$sp(scala.runtime.BoxesRunTime.unboxToLong(v1), scala.runtime.BoxesRunTime.unboxToLong(v2))); }
+}
diff --git a/src/library/scala/runtime/java8/JFunction2.java b/src/library/scala/runtime/java8/JFunction2.java
new file mode 100644
index 0000000000..1e0293a7e8
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction2.java
@@ -0,0 +1,498 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction2<T1, T2, R> extends scala.Function2<T1, T2, R> {
+ default void apply$mcVII$sp(int v1, int v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2));
+ }
+ default boolean apply$mcZII$sp(int v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default int apply$mcIII$sp(int v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default float apply$mcFII$sp(int v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default long apply$mcJII$sp(int v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default double apply$mcDII$sp(int v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default void apply$mcVIJ$sp(int v1, long v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2));
+ }
+ default boolean apply$mcZIJ$sp(int v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default int apply$mcIIJ$sp(int v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default float apply$mcFIJ$sp(int v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default long apply$mcJIJ$sp(int v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default double apply$mcDIJ$sp(int v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default void apply$mcVID$sp(int v1, double v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2));
+ }
+ default boolean apply$mcZID$sp(int v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default int apply$mcIID$sp(int v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default float apply$mcFID$sp(int v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default long apply$mcJID$sp(int v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default double apply$mcDID$sp(int v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToInteger(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default void apply$mcVJI$sp(long v1, int v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2));
+ }
+ default boolean apply$mcZJI$sp(long v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default int apply$mcIJI$sp(long v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default float apply$mcFJI$sp(long v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default long apply$mcJJI$sp(long v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default double apply$mcDJI$sp(long v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default void apply$mcVJJ$sp(long v1, long v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2));
+ }
+ default boolean apply$mcZJJ$sp(long v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default int apply$mcIJJ$sp(long v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default float apply$mcFJJ$sp(long v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default long apply$mcJJJ$sp(long v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default double apply$mcDJJ$sp(long v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default void apply$mcVJD$sp(long v1, double v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2));
+ }
+ default boolean apply$mcZJD$sp(long v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default int apply$mcIJD$sp(long v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default float apply$mcFJD$sp(long v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default long apply$mcJJD$sp(long v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default double apply$mcDJD$sp(long v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToLong(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default void apply$mcVDI$sp(double v1, int v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2));
+ }
+ default boolean apply$mcZDI$sp(double v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default int apply$mcIDI$sp(double v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default float apply$mcFDI$sp(double v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default long apply$mcJDI$sp(double v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default double apply$mcDDI$sp(double v1, int v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToInteger(v2)));
+ }
+ default void apply$mcVDJ$sp(double v1, long v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2));
+ }
+ default boolean apply$mcZDJ$sp(double v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default int apply$mcIDJ$sp(double v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default float apply$mcFDJ$sp(double v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default long apply$mcJDJ$sp(double v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default double apply$mcDDJ$sp(double v1, long v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToLong(v2)));
+ }
+ default void apply$mcVDD$sp(double v1, double v2) {
+ apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2));
+ }
+ default boolean apply$mcZDD$sp(double v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToBoolean(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default int apply$mcIDD$sp(double v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToInt(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default float apply$mcFDD$sp(double v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToFloat(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default long apply$mcJDD$sp(double v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToLong(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+ default double apply$mcDDD$sp(double v1, double v2) {
+ return scala.runtime.BoxesRunTime.unboxToDouble(apply((T1) scala.runtime.BoxesRunTime.boxToDouble(v1), (T2) scala.runtime.BoxesRunTime.boxToDouble(v2)));
+ }
+
+ default scala.Function1 curried$mcVII$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZII$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIII$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFII$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJII$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDII$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVIJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZIJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIIJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFIJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJIJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDIJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVID$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZID$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIID$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFID$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJID$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDID$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVJI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZJI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIJI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFJI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJJI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDJI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVJJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZJJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIJJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFJJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJJJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDJJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVJD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZJD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIJD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFJD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJJD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDJD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVDI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZDI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIDI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFDI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJDI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDDI$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVDJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZDJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIDJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFDJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJDJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDDJ$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcVDD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcZDD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcIDD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcFDD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcJDD$sp() {
+ return curried();
+ }
+ default scala.Function1 curried$mcDDD$sp() {
+ return curried();
+ }
+
+ default scala.Function1 tupled$mcVII$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZII$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIII$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFII$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJII$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDII$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVIJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZIJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIIJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFIJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJIJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDIJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVID$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZID$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIID$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFID$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJID$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDID$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVJI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZJI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIJI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFJI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJJI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDJI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVJJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZJJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIJJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFJJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJJJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDJJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVJD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZJD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIJD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFJD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJJD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDJD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVDI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZDI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIDI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFDI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJDI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDDI$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVDJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZDJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIDJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFDJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJDJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDDJ$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcVDD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcZDD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcIDD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcFDD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcJDD$sp() {
+ return tupled();
+ }
+ default scala.Function1 tupled$mcDDD$sp() {
+ return tupled();
+ }
+}
diff --git a/src/library/scala/runtime/java8/JFunction20.java b/src/library/scala/runtime/java8/JFunction20.java
new file mode 100644
index 0000000000..543e657ea7
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction20.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R> extends scala.Function20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction21.java b/src/library/scala/runtime/java8/JFunction21.java
new file mode 100644
index 0000000000..ecb0d8d287
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction21.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R> extends scala.Function21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction22.java b/src/library/scala/runtime/java8/JFunction22.java
new file mode 100644
index 0000000000..4945cd9db3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction22.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R> extends scala.Function22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction3.java b/src/library/scala/runtime/java8/JFunction3.java
new file mode 100644
index 0000000000..ff657dbfd3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction3.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction3<T1, T2, T3, R> extends scala.Function3<T1, T2, T3, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction4.java b/src/library/scala/runtime/java8/JFunction4.java
new file mode 100644
index 0000000000..246c0d5c72
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction4.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction4<T1, T2, T3, T4, R> extends scala.Function4<T1, T2, T3, T4, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction5.java b/src/library/scala/runtime/java8/JFunction5.java
new file mode 100644
index 0000000000..1d85c2989e
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction5.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction5<T1, T2, T3, T4, T5, R> extends scala.Function5<T1, T2, T3, T4, T5, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction6.java b/src/library/scala/runtime/java8/JFunction6.java
new file mode 100644
index 0000000000..0699c90830
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction6.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction6<T1, T2, T3, T4, T5, T6, R> extends scala.Function6<T1, T2, T3, T4, T5, T6, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction7.java b/src/library/scala/runtime/java8/JFunction7.java
new file mode 100644
index 0000000000..57bc16a066
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction7.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction7<T1, T2, T3, T4, T5, T6, T7, R> extends scala.Function7<T1, T2, T3, T4, T5, T6, T7, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction8.java b/src/library/scala/runtime/java8/JFunction8.java
new file mode 100644
index 0000000000..af22b888a3
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction8.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction8<T1, T2, T3, T4, T5, T6, T7, T8, R> extends scala.Function8<T1, T2, T3, T4, T5, T6, T7, T8, R> {
+}
diff --git a/src/library/scala/runtime/java8/JFunction9.java b/src/library/scala/runtime/java8/JFunction9.java
new file mode 100644
index 0000000000..d3c6b26769
--- /dev/null
+++ b/src/library/scala/runtime/java8/JFunction9.java
@@ -0,0 +1,10 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+@FunctionalInterface
+public interface JFunction9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> extends scala.Function9<T1, T2, T3, T4, T5, T6, T7, T8, T9, R> {
+}
diff --git a/src/library/scala/runtime/java8/JProcedure0.java b/src/library/scala/runtime/java8/JProcedure0.java
new file mode 100644
index 0000000000..6004364d03
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure0.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure0 extends JFunction0<BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid();
+
+ default BoxedUnit apply() {
+ applyVoid();
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure1.java b/src/library/scala/runtime/java8/JProcedure1.java
new file mode 100644
index 0000000000..184d943042
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure1.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure1<T1> extends JFunction1<T1, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1);
+
+ default BoxedUnit apply(T1 t1) {
+ applyVoid(t1);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure10.java b/src/library/scala/runtime/java8/JProcedure10.java
new file mode 100644
index 0000000000..2aadd7d215
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure10.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> extends JFunction10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure11.java b/src/library/scala/runtime/java8/JProcedure11.java
new file mode 100644
index 0000000000..c29853be1f
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure11.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> extends JFunction11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure12.java b/src/library/scala/runtime/java8/JProcedure12.java
new file mode 100644
index 0000000000..0607600c33
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure12.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> extends JFunction12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure13.java b/src/library/scala/runtime/java8/JProcedure13.java
new file mode 100644
index 0000000000..c390fed2a5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure13.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> extends JFunction13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure14.java b/src/library/scala/runtime/java8/JProcedure14.java
new file mode 100644
index 0000000000..d67cff1b5a
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure14.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> extends JFunction14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure15.java b/src/library/scala/runtime/java8/JProcedure15.java
new file mode 100644
index 0000000000..81e0f524f5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure15.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> extends JFunction15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure16.java b/src/library/scala/runtime/java8/JProcedure16.java
new file mode 100644
index 0000000000..3d29ae25c5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure16.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> extends JFunction16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure17.java b/src/library/scala/runtime/java8/JProcedure17.java
new file mode 100644
index 0000000000..85f40b2cd5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure17.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> extends JFunction17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure18.java b/src/library/scala/runtime/java8/JProcedure18.java
new file mode 100644
index 0000000000..fe2ab6f22c
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure18.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> extends JFunction18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure19.java b/src/library/scala/runtime/java8/JProcedure19.java
new file mode 100644
index 0000000000..9289d639a5
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure19.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> extends JFunction19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure2.java b/src/library/scala/runtime/java8/JProcedure2.java
new file mode 100644
index 0000000000..273357a3b0
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure2.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure2<T1, T2> extends JFunction2<T1, T2, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2);
+
+ default BoxedUnit apply(T1 t1, T2 t2) {
+ applyVoid(t1, t2);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure20.java b/src/library/scala/runtime/java8/JProcedure20.java
new file mode 100644
index 0000000000..8701e9d422
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure20.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> extends JFunction20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure21.java b/src/library/scala/runtime/java8/JProcedure21.java
new file mode 100644
index 0000000000..f8e38f6c70
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure21.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> extends JFunction21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure22.java b/src/library/scala/runtime/java8/JProcedure22.java
new file mode 100644
index 0000000000..8bae4d7e0d
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure22.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> extends JFunction22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21, T22 t22);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21, T22 t22) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure3.java b/src/library/scala/runtime/java8/JProcedure3.java
new file mode 100644
index 0000000000..7c53187f31
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure3.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure3<T1, T2, T3> extends JFunction3<T1, T2, T3, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3) {
+ applyVoid(t1, t2, t3);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure4.java b/src/library/scala/runtime/java8/JProcedure4.java
new file mode 100644
index 0000000000..33161bc151
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure4.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure4<T1, T2, T3, T4> extends JFunction4<T1, T2, T3, T4, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4) {
+ applyVoid(t1, t2, t3, t4);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure5.java b/src/library/scala/runtime/java8/JProcedure5.java
new file mode 100644
index 0000000000..c834c48bf6
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure5.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure5<T1, T2, T3, T4, T5> extends JFunction5<T1, T2, T3, T4, T5, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
+ applyVoid(t1, t2, t3, t4, t5);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure6.java b/src/library/scala/runtime/java8/JProcedure6.java
new file mode 100644
index 0000000000..995bdd6734
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure6.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure6<T1, T2, T3, T4, T5, T6> extends JFunction6<T1, T2, T3, T4, T5, T6, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) {
+ applyVoid(t1, t2, t3, t4, t5, t6);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure7.java b/src/library/scala/runtime/java8/JProcedure7.java
new file mode 100644
index 0000000000..1821d8d406
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure7.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure7<T1, T2, T3, T4, T5, T6, T7> extends JFunction7<T1, T2, T3, T4, T5, T6, T7, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure8.java b/src/library/scala/runtime/java8/JProcedure8.java
new file mode 100644
index 0000000000..4b9dd0929a
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure8.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure8<T1, T2, T3, T4, T5, T6, T7, T8> extends JFunction8<T1, T2, T3, T4, T5, T6, T7, T8, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/runtime/java8/JProcedure9.java b/src/library/scala/runtime/java8/JProcedure9.java
new file mode 100644
index 0000000000..c4cbc65b6c
--- /dev/null
+++ b/src/library/scala/runtime/java8/JProcedure9.java
@@ -0,0 +1,21 @@
+
+/*
+ * Copyright (C) 2012-2015 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+package scala.runtime.java8;
+
+import scala.runtime.BoxedUnit;
+
+@FunctionalInterface
+public interface JProcedure9<T1, T2, T3, T4, T5, T6, T7, T8, T9> extends JFunction9<T1, T2, T3, T4, T5, T6, T7, T8, T9, BoxedUnit> {
+ default void $init$() {
+ }
+
+ void applyVoid(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9);
+
+ default BoxedUnit apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) {
+ applyVoid(t1, t2, t3, t4, t5, t6, t7, t8, t9);
+ return BoxedUnit.UNIT;
+ }
+}
diff --git a/src/library/scala/sys/SystemProperties.scala b/src/library/scala/sys/SystemProperties.scala
index d2ebf8c044..ebe94651f9 100644
--- a/src/library/scala/sys/SystemProperties.scala
+++ b/src/library/scala/sys/SystemProperties.scala
@@ -32,11 +32,18 @@ class SystemProperties
extends mutable.AbstractMap[String, String]
with mutable.Map[String, String] {
- override def empty = new SystemProperties
+ override def empty = mutable.Map[String, String]()
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) =
@@ -62,23 +69,25 @@ object SystemProperties {
def exclusively[T](body: => T) = this synchronized body
implicit def systemPropertiesToCompanion(p: SystemProperties): SystemProperties.type = this
- private lazy val propertyHelp = mutable.Map[String, String]()
- private def addHelp[P <: Prop[_]](p: P, helpText: String): P = {
- propertyHelp(p.key) = helpText
- p
+
+ private final val HeadlessKey = "java.awt.headless"
+ private final val PreferIPv4StackKey = "java.net.preferIPv4Stack"
+ private final val PreferIPv6AddressesKey = "java.net.preferIPv6Addresses"
+ private final val NoTraceSuppressionKey = "scala.control.noTraceSuppression"
+
+ def help(key: String): String = key match {
+ case HeadlessKey => "system should not utilize a display device"
+ case PreferIPv4StackKey => "system should prefer IPv4 sockets"
+ case PreferIPv6AddressesKey => "system should prefer IPv6 addresses"
+ case NoTraceSuppressionKey => "scala should not suppress any stack trace creation"
+ case _ => ""
}
- private def bool(key: String, helpText: String): BooleanProp = addHelp[BooleanProp](
- if (key startsWith "java.") BooleanProp.valueIsTrue(key) else BooleanProp.keyExists(key),
- helpText
- )
- def help(key: String) = propertyHelp.getOrElse(key, "")
-
- // Todo: bring some sanity to the intersection of system properties aka "mutable
- // state shared by everyone and everything" and the reality that there is no other
- // mechanism for accomplishing some things on the jvm.
- lazy val headless = bool("java.awt.headless", "system should not utilize a display device")
- lazy val preferIPv4Stack = bool("java.net.preferIPv4Stack", "system should prefer IPv4 sockets")
- lazy val preferIPv6Addresses = bool("java.net.preferIPv6Addresses", "system should prefer IPv6 addresses")
- lazy val noTraceSupression = bool("scala.control.noTraceSuppression", "scala should not suppress any stack trace creation")
+
+ lazy val headless: BooleanProp = BooleanProp.keyExists(HeadlessKey)
+ lazy val preferIPv4Stack: BooleanProp = BooleanProp.keyExists(PreferIPv4StackKey)
+ lazy val preferIPv6Addresses: BooleanProp = BooleanProp.keyExists(PreferIPv6AddressesKey)
+ lazy val noTraceSuppression: BooleanProp = BooleanProp.valueIsTrue(NoTraceSuppressionKey)
+ @deprecated("Use noTraceSuppression", "2.12.0")
+ def noTraceSupression = noTraceSuppression
}
diff --git a/src/library/scala/sys/process/BasicIO.scala b/src/library/scala/sys/process/BasicIO.scala
index 066b2f5373..b39ae77c62 100644
--- a/src/library/scala/sys/process/BasicIO.scala
+++ b/src/library/scala/sys/process/BasicIO.scala
@@ -33,7 +33,7 @@ object BasicIO {
final val BufferSize = 8192
/** Used to separate lines in the `processFully` function that takes `Appendable`. */
- final val Newline = props("line.separator")
+ final val Newline = System.lineSeparator
private[process] final class Streamed[T](
val process: T => Unit,
@@ -221,7 +221,7 @@ object BasicIO {
*/
def transferFully(in: InputStream, out: OutputStream): Unit =
try transferFullyImpl(in, out)
- catch onInterrupt(())
+ catch onIOInterrupt(())
private[this] def appendLine(buffer: Appendable): String => Unit = line => {
buffer append line
diff --git a/src/library/scala/sys/process/Process.scala b/src/library/scala/sys/process/Process.scala
index 06b9967908..0ec749e78a 100644
--- a/src/library/scala/sys/process/Process.scala
+++ b/src/library/scala/sys/process/Process.scala
@@ -26,11 +26,11 @@ import scala.language.implicitConversions
* make it possible for one to block until the process exits and get the exit value,
* or destroy the process altogether.
*
- * Presently, one cannot poll the `Process` to see if it has finished.
- *
* @see [[scala.sys.process.ProcessBuilder]]
*/
trait Process {
+ /** Returns this process alive status */
+ def isAlive(): Boolean
/** Blocks until this process exits and returns the exit code.*/
def exitValue(): Int
/** Destroys this process. */
diff --git a/src/library/scala/sys/process/ProcessBuilderImpl.scala b/src/library/scala/sys/process/ProcessBuilderImpl.scala
index 236baaf038..eef140c16a 100644
--- a/src/library/scala/sys/process/ProcessBuilderImpl.scala
+++ b/src/library/scala/sys/process/ProcessBuilderImpl.scala
@@ -56,7 +56,7 @@ private[process] trait ProcessBuilderImpl {
success put false
val t = Spawn({
runImpl(io)
- success set true
+ success.put(true)
}, io.daemonizeThreads)
new ThreadProcess(t, success)
diff --git a/src/library/scala/sys/process/ProcessImpl.scala b/src/library/scala/sys/process/ProcessImpl.scala
index 2b7fcdeb73..6da0dee056 100644
--- a/src/library/scala/sys/process/ProcessImpl.scala
+++ b/src/library/scala/sys/process/ProcessImpl.scala
@@ -27,18 +27,18 @@ private[process] trait ProcessImpl {
}
}
private[process] object Future {
- def apply[T](f: => T): () => T = {
+ def apply[T](f: => T): (Thread, () => T) = {
val result = new SyncVar[Either[Throwable, T]]
def run(): Unit =
- try result set Right(f)
- catch { case e: Exception => result set Left(e) }
+ try result.put(Right(f))
+ catch { case e: Exception => result.put(Left(e)) }
- Spawn(run())
+ val t = Spawn(run())
- () => result.get match {
+ (t, () => result.get match {
case Right(value) => value
case Left(exception) => throw exception
- }
+ })
}
}
@@ -84,16 +84,18 @@ private[process] trait ProcessImpl {
}
private[process] abstract class CompoundProcess extends BasicProcess {
+ def isAlive() = processThread.isAlive()
def destroy() = destroyer()
- def exitValue() = getExitValue() getOrElse scala.sys.error("No exit code: process destroyed.")
+ def exitValue() = getExitValue._2() getOrElse scala.sys.error("No exit code: process destroyed.")
def start() = getExitValue
- protected lazy val (getExitValue, destroyer) = {
+ protected lazy val (processThread, getExitValue, destroyer) = {
val code = new SyncVar[Option[Int]]()
- code set None
- val thread = Spawn(code set runAndExitValue())
+ code.put(None)
+ val thread = Spawn(code.put(runAndExitValue()))
(
+ thread,
Future { thread.join(); code.get },
() => thread.interrupt()
)
@@ -109,45 +111,46 @@ private[process] trait ProcessImpl {
}
private[process] class PipedProcesses(a: ProcessBuilder, b: ProcessBuilder, defaultIO: ProcessIO, toError: Boolean) extends CompoundProcess {
- protected[this] override def runAndExitValue() = {
- val currentSource = new SyncVar[Option[InputStream]]
- val pipeOut = new PipedOutputStream
- val source = new PipeSource(currentSource, pipeOut, a.toString)
+ protected[this] override def runAndExitValue() = runAndExitValue(new PipeSource(a.toString), new PipeSink(b.toString))
+ protected[this] def runAndExitValue(source: PipeSource, sink: PipeSink): Option[Int] = {
+ source connectOut sink
source.start()
-
- val pipeIn = new PipedInputStream(pipeOut)
- val currentSink = new SyncVar[Option[OutputStream]]
- val sink = new PipeSink(pipeIn, currentSink, b.toString)
sink.start()
- def handleOutOrError(fromOutput: InputStream) = currentSource put Some(fromOutput)
+ /** Release PipeSource, PipeSink and Process in the correct order.
+ * If once connect Process with Source or Sink, then the order of releasing them
+ * must be Source -> Sink -> Process, otherwise IOException will be thrown. */
+ def releaseResources(so: PipeSource, sk: PipeSink, p: Process *) = {
+ so.release()
+ sk.release()
+ p foreach( _.destroy() )
+ }
val firstIO =
- if (toError)
- defaultIO.withError(handleOutOrError)
- else
- defaultIO.withOutput(handleOutOrError)
- val secondIO = defaultIO.withInput(toInput => currentSink put Some(toInput))
-
- val second = b.run(secondIO)
- val first = a.run(firstIO)
- try {
- runInterruptible {
- val exit1 = first.exitValue()
- currentSource put None
- currentSink put None
- val exit2 = second.exitValue()
- // Since file redirection (e.g. #>) is implemented as a piped process,
- // we ignore its exit value so cmd #> file doesn't always return 0.
- if (b.hasExitValue) exit2 else exit1
- } {
- first.destroy()
- second.destroy()
+ if (toError) defaultIO.withError(source.connectIn)
+ else defaultIO.withOutput(source.connectIn)
+ val secondIO = defaultIO.withInput(sink.connectOut)
+
+ val second =
+ try b.run(secondIO)
+ catch onError { err =>
+ releaseResources(source, sink)
+ throw err
}
- }
- finally {
- BasicIO close pipeIn
- BasicIO close pipeOut
+ val first =
+ try a.run(firstIO)
+ catch onError { err =>
+ releaseResources(source, sink, second)
+ throw err
+ }
+ runInterruptible {
+ val exit1 = first.exitValue()
+ val exit2 = second.exitValue()
+ // Since file redirection (e.g. #>) is implemented as a piped process,
+ // we ignore its exit value so cmd #> file doesn't always return 0.
+ if (b.hasExitValue) exit2 else exit1
+ } {
+ releaseResources(source, sink, first, second)
}
}
}
@@ -168,37 +171,46 @@ private[process] trait ProcessImpl {
}
}
- private[process] class PipeSource(
- currentSource: SyncVar[Option[InputStream]],
- pipe: PipedOutputStream,
- label: => String
- ) extends PipeThread(false, () => label) {
-
- final override def run(): Unit = currentSource.get match {
- case Some(source) =>
- try runloop(source, pipe)
- finally currentSource.unset()
-
- run()
- case None =>
- currentSource.unset()
- BasicIO close pipe
+ private[process] class PipeSource(label: => String) extends PipeThread(false, () => label) {
+ protected[this] val pipe = new PipedOutputStream
+ protected[this] val source = new LinkedBlockingQueue[Option[InputStream]]
+ override def run(): Unit = {
+ try {
+ source.take match {
+ case Some(in) => runloop(in, pipe)
+ case None =>
+ }
+ }
+ catch onInterrupt(())
+ finally BasicIO close pipe
+ }
+ def connectIn(in: InputStream): Unit = source add Some(in)
+ def connectOut(sink: PipeSink): Unit = sink connectIn pipe
+ def release(): Unit = {
+ interrupt()
+ source add None
+ join()
}
}
- private[process] class PipeSink(
- pipe: PipedInputStream,
- currentSink: SyncVar[Option[OutputStream]],
- label: => String
- ) extends PipeThread(true, () => label) {
-
- final override def run(): Unit = currentSink.get match {
- case Some(sink) =>
- try runloop(pipe, sink)
- finally currentSink.unset()
-
- run()
- case None =>
- currentSink.unset()
+ private[process] class PipeSink(label: => String) extends PipeThread(true, () => label) {
+ protected[this] val pipe = new PipedInputStream
+ protected[this] val sink = new LinkedBlockingQueue[Option[OutputStream]]
+ override def run(): Unit = {
+ try {
+ sink.take match {
+ case Some(out) => runloop(pipe, out)
+ case None =>
+ }
+ }
+ catch onInterrupt(())
+ finally BasicIO close pipe
+ }
+ def connectOut(out: OutputStream): Unit = sink add Some(out)
+ def connectIn(pipeOut: PipedOutputStream): Unit = pipe connect pipeOut
+ def release(): Unit = {
+ interrupt()
+ sink add None
+ join()
}
}
@@ -206,7 +218,8 @@ private[process] trait ProcessImpl {
* The implementation of `exitValue` waits until these threads die before returning. */
private[process] class DummyProcess(action: => Int) extends Process {
private[this] val exitCode = Future(action)
- override def exitValue() = exitCode()
+ override def isAlive() = exitCode._1.isAlive()
+ override def exitValue() = exitCode._2()
override def destroy() { }
}
/** A thin wrapper around a java.lang.Process. `outputThreads` are the Threads created to read from the
@@ -215,6 +228,7 @@ private[process] trait ProcessImpl {
* The implementation of `exitValue` interrupts `inputThread` and then waits until all I/O threads die before
* returning. */
private[process] class SimpleProcess(p: JProcess, inputThread: Thread, outputThreads: List[Thread]) extends Process {
+ override def isAlive() = p.isAlive()
override def exitValue() = {
try p.waitFor() // wait for the process to terminate
finally inputThread.interrupt() // we interrupt the input thread to notify it that it can terminate
@@ -231,6 +245,7 @@ private[process] trait ProcessImpl {
}
}
private[process] final class ThreadProcess(thread: Thread, success: SyncVar[Boolean]) extends Process {
+ override def isAlive() = thread.isAlive()
override def exitValue() = {
thread.join()
if (success.get) 0 else 1
diff --git a/src/library/scala/sys/process/package.scala b/src/library/scala/sys/process/package.scala
index 445c3aee60..ff0fd920c9 100644
--- a/src/library/scala/sys/process/package.scala
+++ b/src/library/scala/sys/process/package.scala
@@ -203,9 +203,9 @@ package scala.sys {
package object process extends ProcessImplicits {
/** The arguments passed to `java` when creating this process */
def javaVmArguments: List[String] = {
- import scala.collection.JavaConversions._
+ import scala.collection.JavaConverters._
- java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toList
+ java.lang.management.ManagementFactory.getRuntimeMXBean.getInputArguments.asScala.toList
}
/** The input stream of this process */
def stdin = java.lang.System.in
@@ -225,16 +225,26 @@ package scala.sys {
final val processDebug = props contains "scala.process.debug"
dbg("Initializing process package.")
- type =?>[-A, +B] = PartialFunction[A, B]
- type Closeable = java.io.Closeable
- type File = java.io.File
- type IOException = java.io.IOException
- type InputStream = java.io.InputStream
- type JProcess = java.lang.Process
- type JProcessBuilder = java.lang.ProcessBuilder
- type OutputStream = java.io.OutputStream
- type SyncVar[T] = scala.concurrent.SyncVar[T]
- type URL = java.net.URL
+ type =?>[-A, +B] = PartialFunction[A, B]
+ type Closeable = java.io.Closeable
+ type File = java.io.File
+ type IOException = java.io.IOException
+ type InterruptedIOException = java.io.InterruptedIOException
+ type InputStream = java.io.InputStream
+ type JProcess = java.lang.Process
+ type JProcessBuilder = java.lang.ProcessBuilder
+ type LinkedBlockingQueue[T] = java.util.concurrent.LinkedBlockingQueue[T]
+ type OutputStream = java.io.OutputStream
+ type SyncVar[T] = scala.concurrent.SyncVar[T]
+ type URL = java.net.URL
+
+ def onError[T](handler: Throwable => T): Throwable =?> T = {
+ case e @ _ => handler(e)
+ }
+
+ def onIOInterrupt[T](handler: => T): Throwable =?> T = {
+ case _: InterruptedIOException => handler
+ }
def onInterrupt[T](handler: => T): Throwable =?> T = {
case _: InterruptedException => handler
diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala
index 32b7ec4487..01da0c1ef2 100644
--- a/src/library/scala/util/Either.scala
+++ b/src/library/scala/util/Either.scala
@@ -11,8 +11,6 @@
package scala
package util
-import scala.language.implicitConversions
-
/** Represents a value of one of two possible types (a disjoint union.)
* Instances of Either are either an instance of [[scala.util.Left]] or [[scala.util.Right]].
*
@@ -68,7 +66,7 @@ import scala.language.implicitConversions
* @version 1.0, 11/10/2008
* @since 2.7
*/
-sealed abstract class Either[+A, +B] {
+sealed abstract class Either[+A, +B] extends Product with Serializable {
/**
* Projects this `Either` as a `Left`.
*/
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index 7ea597eac9..a176748cd6 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -120,7 +120,7 @@ private[scala] trait PropertiesTrait {
/** The default end of line character.
*/
- def lineSeparator = propOrElse("line.separator", "\n")
+ def lineSeparator = System.lineSeparator()
/* Various well-known properties. */
def javaClassPath = propOrEmpty("java.class.path")
@@ -148,6 +148,8 @@ private[scala] trait PropertiesTrait {
// the reason why we don't follow developer.apple.com/library/mac/#technotes/tn2002/tn2110.
/** Returns `true` iff the underlying operating system is a version of Apple Mac OSX. */
def isMac = osName startsWith "Mac OS X"
+ /** Returns `true` iff the underlying operating system is a Linux distribution. */
+ def isLinux = osName startsWith "Linux"
/* Some runtime values. */
private[scala] def isAvian = javaVmName contains "Avian"
diff --git a/src/library/scala/util/Sorting.scala b/src/library/scala/util/Sorting.scala
index b4f965f69b..3bda7c0d39 100644
--- a/src/library/scala/util/Sorting.scala
+++ b/src/library/scala/util/Sorting.scala
@@ -45,7 +45,7 @@ object Sorting {
/** Sort an array of Floats using `java.util.Arrays.sort`. */
def quickSort(a: Array[Float]): Unit = java.util.Arrays.sort(a)
-
+
private final val qsortThreshold = 16
/** Sort array `a` with quicksort, using the Ordering on its elements.
@@ -57,9 +57,9 @@ object Sorting {
def inner(a: Array[K], i0: Int, iN: Int, ord: Ordering[K]): Unit = {
if (iN - i0 < qsortThreshold) insertionSort(a, i0, iN, ord)
else {
- var iK = (i0 + iN) >>> 1 // Unsigned div by 2
+ val iK = (i0 + iN) >>> 1 // Unsigned div by 2
// Find index of median of first, central, and last elements
- var pL =
+ var pL =
if (ord.compare(a(i0), a(iN - 1)) <= 0)
if (ord.compare(a(i0), a(iK)) < 0)
if (ord.compare(a(iN - 1), a(iK)) < 0) iN - 1 else iK
@@ -140,9 +140,9 @@ object Sorting {
}
inner(a, 0, a.length, implicitly[Ordering[K]])
}
-
+
private final val mergeThreshold = 32
-
+
// Ordering[T] might be slow especially for boxed primitives, so use binary search variant of insertion sort
// Caller must pass iN >= i0 or math will fail. Also, i0 >= 0.
private def insertionSort[@specialized T](a: Array[T], i0: Int, iN: Int, ord: Ordering[T]): Unit = {
@@ -176,7 +176,7 @@ object Sorting {
m += 1
}
}
-
+
// Caller is required to pass iN >= i0, else math will fail. Also, i0 >= 0.
private def mergeSort[@specialized T: ClassTag](a: Array[T], i0: Int, iN: Int, ord: Ordering[T], scratch: Array[T] = null): Unit = {
if (iN - i0 < mergeThreshold) insertionSort(a, i0, iN, ord)
@@ -188,7 +188,7 @@ object Sorting {
mergeSorted(a, i0, iK, iN, ord, sc)
}
}
-
+
// Must have 0 <= i0 < iK < iN
private def mergeSorted[@specialized T](a: Array[T], i0: Int, iK: Int, iN: Int, ord: Ordering[T], scratch: Array[T]): Unit = {
// Check to make sure we're not already in order
@@ -212,7 +212,7 @@ object Sorting {
// Don't need to finish a(i) because it's already in place, k = i
}
}
-
+
// Why would you even do this?
private def booleanSort(a: Array[Boolean]): Unit = {
var i = 0
@@ -235,7 +235,7 @@ object Sorting {
// TODO: add upper bound: T <: AnyRef, propagate to callers below (not binary compatible)
// Maybe also rename all these methods to `sort`.
@inline private def sort[T](a: Array[T], ord: Ordering[T]): Unit = a match {
- case _: Array[AnyRef] =>
+ case _: Array[AnyRef] =>
// Note that runtime matches are covariant, so could actually be any Array[T] s.t. T is not primitive (even boxed value classes)
if (a.length > 1 && (ord eq null)) throw new NullPointerException("Ordering")
java.util.Arrays.sort(a, ord)
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index b0eae74043..3c8b21b03c 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -9,9 +9,7 @@
package scala
package util
-import scala.collection.Seq
import scala.util.control.NonFatal
-import scala.language.implicitConversions
/**
* The `Try` type represents a computation that may either result in an exception, or return a
@@ -61,7 +59,7 @@ import scala.language.implicitConversions
* @author based on Twitter's original implementation in com.twitter.util.
* @since 2.10
*/
-sealed abstract class Try[+T] {
+sealed abstract class Try[+T] extends Product with Serializable {
/** Returns `true` if the `Try` is a `Failure`, `false` otherwise.
*/
@@ -75,16 +73,11 @@ sealed abstract class Try[+T] {
*
* ''Note:'': This will throw an exception if it is not a success and default throws an exception.
*/
- def getOrElse[U >: T](default: => U): U =
- if (isSuccess) get else default
+ def getOrElse[U >: T](default: => U): U
/** Returns this `Try` if it's a `Success` or the given `default` argument if this is a `Failure`.
*/
- def orElse[U >: T](default: => Try[U]): Try[U] =
- try if (isSuccess) this else default
- catch {
- case NonFatal(e) => Failure(e)
- }
+ def orElse[U >: T](default: => Try[U]): Try[U]
/** Returns the value from this `Success` or throws the exception if this is a `Failure`.
*/
@@ -108,6 +101,11 @@ sealed abstract class Try[+T] {
def map[U](f: T => U): Try[U]
/**
+ * Applies the given partial function to the value from this `Success` or returns this if this is a `Failure`.
+ */
+ def collect[U](pf: PartialFunction[T, U]): Try[U]
+
+ /**
* Converts this to a `Failure` if the predicate is not satisfied.
*/
def filter(p: T => Boolean): Try[T]
@@ -134,6 +132,7 @@ sealed abstract class Try[+T] {
* collection" contract even though it seems unlikely to matter much in a
* collection with max size 1.
*/
+ @deprecatedInheritance("You were never supposed to be able to extend this class.", "2.12")
class WithFilter(p: T => Boolean) {
def map[U](f: T => U): Try[U] = Try.this filter p map f
def flatMap[U](f: T => Try[U]): Try[U] = Try.this filter p flatMap f
@@ -145,18 +144,18 @@ sealed abstract class Try[+T] {
* Applies the given function `f` if this is a `Failure`, otherwise returns this if this is a `Success`.
* This is like `flatMap` for the exception.
*/
- def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U]
+ def recoverWith[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, Try[U]]): Try[U]
/**
* Applies the given function `f` if this is a `Failure`, otherwise returns this if this is a `Success`.
* This is like map for the exception.
*/
- def recover[U >: T](f: PartialFunction[Throwable, U]): Try[U]
+ def recover[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, U]): Try[U]
/**
* Returns `None` if this is a `Failure` or a `Some` containing the value if this is a `Success`.
*/
- def toOption: Option[T] = if (isSuccess) Some(get) else None
+ def toOption: Option[T]
/**
* Transforms a nested `Try`, ie, a `Try` of type `Try[Try[T]]`,
@@ -173,13 +172,31 @@ sealed abstract class Try[+T] {
/** Completes this `Try` by applying the function `f` to this if this is of type `Failure`, or conversely, by applying
* `s` if this is a `Success`.
*/
- def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] =
- try this match {
- case Success(v) => s(v)
- case Failure(e) => f(e)
- } catch {
- case NonFatal(e) => Failure(e)
- }
+ def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U]
+
+ /**
+ * Returns `Left` with `Throwable` if this is a `Failure`, otherwise returns `Right` with `Success` value.
+ */
+ def toEither: Either[Throwable, T]
+
+ /**
+ * Applies `fa` if this is a `Failure` or `fb` if this is a `Success`.
+ * If `fb` is initially applied and throws an exception,
+ * then `fa` is applied with this exception.
+ *
+ * @example {{{
+ * val result: Try[Throwable, Int] = Try { string.toInt }
+ * log(result.fold(
+ * ex => "Operation failed with " + ex,
+ * v => "Operation produced value: " + v
+ * ))
+ * }}}
+ *
+ * @param fa the function to apply if this is a `Failure`
+ * @param fb the function to apply if this is a `Success`
+ * @return the results of applying the function
+ */
+ def fold[U](fa: Throwable => U, fb: T => U): U
}
@@ -192,57 +209,60 @@ object Try {
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
-
}
final case class Failure[+T](exception: Throwable) extends Try[T] {
- def isFailure: Boolean = true
- def isSuccess: Boolean = false
- def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U] =
- try {
- if (f isDefinedAt exception) f(exception) else this
- } catch {
- case NonFatal(e) => Failure(e)
- }
- def get: T = throw exception
- def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]
- def flatten[U](implicit ev: T <:< Try[U]): Try[U] = this.asInstanceOf[Try[U]]
- def foreach[U](f: T => U): Unit = ()
- def map[U](f: T => U): Try[U] = this.asInstanceOf[Try[U]]
- def filter(p: T => Boolean): Try[T] = this
- def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] =
- try {
- if (rescueException isDefinedAt exception) {
- Try(rescueException(exception))
- } else this
- } catch {
- case NonFatal(e) => Failure(e)
- }
- def failed: Try[Throwable] = Success(exception)
+ override def isFailure: Boolean = true
+ override def isSuccess: Boolean = false
+ override def get: T = throw exception
+ override def getOrElse[U >: T](default: => U): U = default
+ override def orElse[U >: T](default: => Try[U]): Try[U] =
+ try default catch { case NonFatal(e) => Failure(e) }
+ override def flatMap[U](f: T => Try[U]): Try[U] = this.asInstanceOf[Try[U]]
+ override def flatten[U](implicit ev: T <:< Try[U]): Try[U] = this.asInstanceOf[Try[U]]
+ override def foreach[U](f: T => U): Unit = ()
+ override def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] =
+ try f(exception) catch { case NonFatal(e) => Failure(e) }
+ override def map[U](f: T => U): Try[U] = this.asInstanceOf[Try[U]]
+ override def collect[U](pf: PartialFunction[T, U]): Try[U] = this.asInstanceOf[Try[U]]
+ override def filter(p: T => Boolean): Try[T] = this
+ override def recover[U >: T](@deprecatedName('rescueException) pf: PartialFunction[Throwable, U]): Try[U] =
+ try { if (pf isDefinedAt exception) Success(pf(exception)) else this } catch { case NonFatal(e) => Failure(e) }
+ override def recoverWith[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, Try[U]]): Try[U] =
+ try { if (pf isDefinedAt exception) pf(exception) else this } catch { case NonFatal(e) => Failure(e) }
+ override def failed: Try[Throwable] = Success(exception)
+ override def toOption: Option[T] = None
+ override def toEither: Either[Throwable, T] = Left(exception)
+ override def fold[U](fa: Throwable => U, fb: T => U): U = fa(exception)
}
final case class Success[+T](value: T) extends Try[T] {
- def isFailure: Boolean = false
- def isSuccess: Boolean = true
- def recoverWith[U >: T](f: PartialFunction[Throwable, Try[U]]): Try[U] = this
- def get = value
- def flatMap[U](f: T => Try[U]): Try[U] =
- try f(value)
- catch {
- case NonFatal(e) => Failure(e)
- }
- def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
- def foreach[U](f: T => U): Unit = f(value)
- def map[U](f: T => U): Try[U] = Try[U](f(value))
- def filter(p: T => Boolean): Try[T] = {
+ override def isFailure: Boolean = false
+ override def isSuccess: Boolean = true
+ override def get = value
+ override def getOrElse[U >: T](default: => U): U = get
+ override def orElse[U >: T](default: => Try[U]): Try[U] = this
+ override def flatMap[U](f: T => Try[U]): Try[U] =
+ try f(value) catch { case NonFatal(e) => Failure(e) }
+ override def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
+ override def foreach[U](f: T => U): Unit = f(value)
+ override def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U] = this flatMap s
+ override def map[U](f: T => U): Try[U] = Try[U](f(value))
+ override def collect[U](pf: PartialFunction[T, U]): Try[U] =
try {
- if (p(value)) this
+ if (pf isDefinedAt value) Success(pf(value))
else Failure(new NoSuchElementException("Predicate does not hold for " + value))
- } catch {
- case NonFatal(e) => Failure(e)
- }
- }
- def recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U] = this
- def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
+ } catch { case NonFatal(e) => Failure(e) }
+ override def filter(p: T => Boolean): Try[T] =
+ try {
+ if (p(value)) this else Failure(new NoSuchElementException("Predicate does not hold for " + value))
+ } catch { case NonFatal(e) => Failure(e) }
+ override def recover[U >: T](@deprecatedName('rescueException) pf: PartialFunction[Throwable, U]): Try[U] = this
+ override def recoverWith[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, Try[U]]): Try[U] = this
+ override def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
+ override def toOption: Option[T] = Some(value)
+ override def toEither: Either[Throwable, T] = Right(value)
+ override def fold[U](fa: Throwable => U, fb: T => U): U =
+ try { fb(value) } catch { case NonFatal(e) => fa(e) }
}
diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala
index 24c297a2fc..64f491d7f0 100644
--- a/src/library/scala/util/control/Exception.scala
+++ b/src/library/scala/util/control/Exception.scala
@@ -10,26 +10,139 @@ package scala
package util
package control
-import scala.collection.immutable.List
import scala.reflect.{ ClassTag, classTag }
-import java.lang.reflect.InvocationTargetException
import scala.language.implicitConversions
-
/** Classes representing the components of exception handling.
- * Each class is independently composable. Some example usages:
+ *
+ * Each class is independently composable.
+ *
+ * This class differs from [[scala.util.Try]] in that it focuses on composing exception handlers rather than
+ * composing behavior. All behavior should be composed first and fed to a [[Catch]] object using one of the
+ * `opt`, `either` or `withTry` methods. Taken together the classes provide a DSL for composing catch and finally
+ * behaviors.
+ *
+ * === Examples ===
+ *
+ * Create a `Catch` which handles specified exceptions.
* {{{
* import scala.util.control.Exception._
* import java.net._
*
* val s = "http://www.scala-lang.org/"
- * val x1 = catching(classOf[MalformedURLException]) opt new URL(s)
- * val x2 = catching(classOf[MalformedURLException], classOf[NullPointerException]) either new URL(s)
+ *
+ * // Some(http://www.scala-lang.org/)
+ * val x1: Option[URL] = catching(classOf[MalformedURLException]) opt new URL(s)
+ *
+ * // Right(http://www.scala-lang.org/)
+ * val x2: Either[Throwable,URL] =
+ * catching(classOf[MalformedURLException], classOf[NullPointerException]) either new URL(s)
+ *
+ * // Success(http://www.scala-lang.org/)
+ * val x3: Try[URL] = catching(classOf[MalformedURLException], classOf[NullPointerException]) withTry new URL(s)
+ *
+ * val defaultUrl = new URL("http://example.com")
+ * // URL(http://example.com) because htt/xx throws MalformedURLException
+ * val x4: URL = failAsValue(classOf[MalformedURLException])(defaultUrl)(new URL("htt/xx"))
+ * }}}
+ *
+ * Create a `Catch` which logs exceptions using `handling` and `by`.
+ * {{{
+ * def log(t: Throwable): Unit = t.printStackTrace
+ *
+ * val withThrowableLogging: Catch[Unit] = handling(classOf[MalformedURLException]) by (log)
+ *
+ * def printUrl(url: String) : Unit = {
+ * val con = new URL(url) openConnection()
+ * val source = scala.io.Source.fromInputStream(con.getInputStream())
+ * source.getLines.foreach(println)
+ * }
+ *
+ * val badUrl = "htt/xx"
+ * // Prints stacktrace,
+ * // java.net.MalformedURLException: no protocol: htt/xx
+ * // at java.net.URL.<init>(URL.java:586)
+ * withThrowableLogging { printUrl(badUrl) }
+ *
+ * val goodUrl = "http://www.scala-lang.org/"
+ * // Prints page content,
+ * // &lt;!DOCTYPE html&gt;
+ * // &lt;html&gt;
+ * withThrowableLogging { printUrl(goodUrl) }
+ * }}}
+ *
+ * Use `unwrapping` to create a `Catch` that unwraps exceptions before rethrowing.
+ * {{{
+ * class AppException(cause: Throwable) extends RuntimeException(cause)
+ *
+ * val unwrappingCatch: Catch[Nothing] = unwrapping(classOf[AppException])
+ *
+ * def calcResult: Int = throw new AppException(new NullPointerException)
+ *
+ * // Throws NPE not AppException,
+ * // java.lang.NullPointerException
+ * // at .calcResult(&lt;console&gt;:17)
+ * val result = unwrappingCatch(calcResult)
+ * }}}
+ *
+ * Use `failAsValue` to provide a default when a specified exception is caught.
+ *
+ * {{{
+ * val inputDefaulting: Catch[Int] = failAsValue(classOf[NumberFormatException])(0)
+ * val candidatePick = "seven" // scala.io.StdIn.readLine()
+ *
+ * // Int = 0
+ * val pick = inputDefaulting(candidatePick.toInt)
+ * }}}
+ *
+ * Compose multiple `Catch`s with `or` to build a `Catch` that provides default values varied by exception.
+ * {{{
+ * val formatDefaulting: Catch[Int] = failAsValue(classOf[NumberFormatException])(0)
+ * val nullDefaulting: Catch[Int] = failAsValue(classOf[NullPointerException])(-1)
+ * val otherDefaulting: Catch[Int] = nonFatalCatch withApply(_ => -100)
+ *
+ * val combinedDefaulting: Catch[Int] = formatDefaulting or nullDefaulting or otherDefaulting
+ *
+ * def p(s: String): Int = s.length * s.toInt
+ *
+ * // Int = 0
+ * combinedDefaulting(p("tenty-nine"))
+ *
+ * // Int = -1
+ * combinedDefaulting(p(null: String))
+ *
+ * // Int = -100
+ * combinedDefaulting(throw new IllegalStateException)
+ *
+ * // Int = 22
+ * combinedDefaulting(p("11"))
* }}}
*
- * This class differs from `scala.util.Try` in that it focuses on composing exception handlers rather than
- * composing behavior. All behavior should be composed first and fed to a `Catch` object using one of the
- * `opt` or `either` methods.
+ * @groupname composition-catch Catch behavior composition
+ * @groupprio composition-catch 10
+ * @groupdesc composition-catch Build Catch objects from exception lists and catch logic
+ *
+ * @groupname composition-finally Finally behavior composition
+ * @groupprio composition-finally 20
+ * @groupdesc composition-finally Build Catch objects from finally logic
+ *
+ * @groupname canned-behavior General purpose catch objects
+ * @groupprio canned-behavior 30
+ * @groupdesc canned-behavior Catch objects with predefined behavior. Use combinator methods to compose additional behavior.
+ *
+ * @groupname dsl DSL behavior composition
+ * @groupprio dsl 40
+ * @groupdesc dsl Expressive Catch behavior composition
+ *
+ * @groupname composition-catch-promiscuously Promiscuous Catch behaviors
+ * @groupprio composition-catch-promiscuously 50
+ * @groupdesc composition-catch-promiscuously Useful if catching `ControlThrowable` or `InterruptedException` is required.
+ *
+ * @groupname logic-container Logic Containers
+ * @groupprio logic-container 60
+ * @groupdesc logic-container Containers for catch and finally behavior.
+ *
+ * @define protectedExceptions `ControlThrowable` or `InterruptedException`
*
* @author Paul Phillips
*/
@@ -53,6 +166,7 @@ object Exception {
/** !!! Not at all sure of every factor which goes into this,
* and/or whether we need multiple standard variations.
+ * @return true if `x` is $protectedExceptions otherwise false.
*/
def shouldRethrow(x: Throwable): Boolean = x match {
case _: ControlThrowable => true
@@ -72,7 +186,9 @@ object Exception {
override def toString() = name + "(" + desc + ")"
}
- /** A container class for finally code. */
+ /** A container class for finally code.
+ * @group logic-container
+ */
class Finally private[Exception](body: => Unit) extends Described {
protected val name = "Finally"
@@ -85,6 +201,11 @@ object Exception {
* Pass a different value for rethrow if you want to probably
* unwisely allow catching control exceptions and other throwables
* which the rest of the world may expect to get through.
+ * @tparam T result type of bodies used in try and catch blocks
+ * @param pf Partial function used when applying catch logic to determine result value
+ * @param fin Finally logic which if defined will be invoked after catch logic
+ * @param rethrow Predicate on throwables determining when to rethrow a caught [[Throwable]]
+ * @group logic-container
*/
class Catch[+T](
val pf: Catcher[T],
@@ -107,10 +228,12 @@ object Exception {
}
finally fin foreach (_.invoke())
- /* Create an empty Try container with this Catch and the supplied `Finally`. */
- def andFinally(body: => Unit): Catch[T] = fin match {
- case None => new Catch(pf, Some(new Finally(body)), rethrow)
- case Some(f) => new Catch(pf, Some(f and body), rethrow)
+ /** Create a new Catch container from this object and the supplied finally body.
+ * @param body The additional logic to apply after all existing finally bodies
+ */
+ def andFinally(body: => Unit): Catch[T] = {
+ val appendedFin = fin map(_ and body) getOrElse new Finally(body)
+ new Catch(pf, Some(appendedFin), rethrow)
}
/** Apply this catch logic to the supplied body, mapping the result
@@ -119,13 +242,13 @@ object Exception {
def opt[U >: T](body: => U): Option[U] = toOption(Some(body))
/** Apply this catch logic to the supplied body, mapping the result
- * into Either[Throwable, T] - Left(exception) if an exception was caught,
- * Right(T) otherwise.
+ * into `Either[Throwable, T]` - `Left(exception)` if an exception was caught,
+ * `Right(T)` otherwise.
*/
def either[U >: T](body: => U): Either[Throwable, U] = toEither(Right(body))
/** Apply this catch logic to the supplied body, mapping the result
- * into Try[T] - Failure if an exception was caught, Success(T) otherwise.
+ * into `Try[T]` - `Failure` if an exception was caught, `Success(T)` otherwise.
*/
def withTry[U >: T](body: => U): scala.util.Try[U] = toTry(Success(body))
@@ -149,23 +272,30 @@ object Exception {
final def nonFatalCatcher[T]: Catcher[T] = mkThrowableCatcher({ case NonFatal(_) => true; case _ => false }, throw _)
final def allCatcher[T]: Catcher[T] = mkThrowableCatcher(_ => true, throw _)
- /** The empty `Catch` object. */
+ /** The empty `Catch` object.
+ * @group canned-behavior
+ **/
final val noCatch: Catch[Nothing] = new Catch(nothingCatcher) withDesc "<nothing>"
- /** A `Catch` object which catches everything. */
+ /** A `Catch` object which catches everything.
+ * @group canned-behavior
+ **/
final def allCatch[T]: Catch[T] = new Catch(allCatcher[T]) withDesc "<everything>"
- /** A `Catch` object which catches non-fatal exceptions. */
+ /** A `Catch` object which catches non-fatal exceptions.
+ * @group canned-behavior
+ **/
final def nonFatalCatch[T]: Catch[T] = new Catch(nonFatalCatcher[T]) withDesc "<non-fatal>"
/** Creates a `Catch` object which will catch any of the supplied exceptions.
* Since the returned `Catch` object has no specific logic defined and will simply
- * rethrow the exceptions it catches, you will typically want to call `opt` or
- * `either` on the return value, or assign custom logic by calling "withApply".
+ * rethrow the exceptions it catches, you will typically want to call `opt`,
+ * `either` or `withTry` on the return value, or assign custom logic by calling "withApply".
*
* Note that `Catch` objects automatically rethrow `ControlExceptions` and others
* which should only be caught in exceptional circumstances. If you really want
* to catch exactly what you specify, use `catchingPromiscuously` instead.
+ * @group composition-catch
*/
def catching[T](exceptions: Class[_]*): Catch[T] =
new Catch(pfFromExceptions(exceptions : _*)) withDesc (exceptions map (_.getName) mkString ", ")
@@ -174,42 +304,56 @@ object Exception {
/** Creates a `Catch` object which will catch any of the supplied exceptions.
* Unlike "catching" which filters out those in shouldRethrow, this one will
- * catch whatever you ask of it: `ControlThrowable`, `InterruptedException`,
- * `OutOfMemoryError`, you name it.
+ * catch whatever you ask of it including $protectedExceptions.
+ * @group composition-catch-promiscuously
*/
def catchingPromiscuously[T](exceptions: Class[_]*): Catch[T] = catchingPromiscuously(pfFromExceptions(exceptions : _*))
def catchingPromiscuously[T](c: Catcher[T]): Catch[T] = new Catch(c, None, _ => false)
- /** Creates a `Catch` object which catches and ignores any of the supplied exceptions. */
+ /** Creates a `Catch` object which catches and ignores any of the supplied exceptions.
+ * @group composition-catch
+ */
def ignoring(exceptions: Class[_]*): Catch[Unit] =
catching(exceptions: _*) withApply (_ => ())
- /** Creates a `Catch` object which maps all the supplied exceptions to `None`. */
+ /** Creates a `Catch` object which maps all the supplied exceptions to `None`.
+ * @group composition-catch
+ */
def failing[T](exceptions: Class[_]*): Catch[Option[T]] =
catching(exceptions: _*) withApply (_ => None)
- /** Creates a `Catch` object which maps all the supplied exceptions to the given value. */
+ /** Creates a `Catch` object which maps all the supplied exceptions to the given value.
+ * @group composition-catch
+ */
def failAsValue[T](exceptions: Class[_]*)(value: => T): Catch[T] =
catching(exceptions: _*) withApply (_ => value)
+ class By[T,R](f: T => R) {
+ def by(x: T): R = f(x)
+ }
+
/** Returns a partially constructed `Catch` object, which you must give
- * an exception handler function as an argument to `by`. Example:
+ * an exception handler function as an argument to `by`.
+ * @example
* {{{
- * handling(ex1, ex2) by (_.printStackTrace)
+ * handling(classOf[MalformedURLException], classOf[NullPointerException]) by (_.printStackTrace)
* }}}
+ * @group dsl
*/
- class By[T,R](f: T => R) {
- def by(x: T): R = f(x)
- }
+ // TODO: Add return type
def handling[T](exceptions: Class[_]*) = {
def fun(f: Throwable => T) = catching(exceptions: _*) withApply f
new By[Throwable => T, Catch[T]](fun _)
}
- /** Returns a `Catch` object with no catch logic and the argument as `Finally`. */
+ /** Returns a `Catch` object with no catch logic and the argument as the finally logic.
+ * @group composition-finally
+ */
def ultimately[T](body: => Unit): Catch[T] = noCatch andFinally body
- /** Creates a `Catch` object which unwraps any of the supplied exceptions. */
+ /** Creates a `Catch` object which unwraps any of the supplied exceptions.
+ * @group composition-catch
+ */
def unwrapping[T](exceptions: Class[_]*): Catch[T] = {
def unwrap(x: Throwable): Throwable =
if (wouldMatch(x, exceptions) && x.getCause != null) unwrap(x.getCause)
diff --git a/src/library/scala/util/control/NoStackTrace.scala b/src/library/scala/util/control/NoStackTrace.scala
index b33b6a18dd..3647af4ac3 100644
--- a/src/library/scala/util/control/NoStackTrace.scala
+++ b/src/library/scala/util/control/NoStackTrace.scala
@@ -14,6 +14,8 @@ package util.control
* on a global basis via a system property wrapper in
* [[scala.sys.SystemProperties]].
*
+ * @note Since JDK 1.7, a similar effect can be achieved with `class Ex extends Throwable(..., writableStackTrace = false)`
+ *
* @author Paul Phillips
* @since 2.8
*/
@@ -26,7 +28,7 @@ trait NoStackTrace extends Throwable {
object NoStackTrace {
final def noSuppression = _noSuppression
- // two-stage init to make checkinit happy, since sys.SystemProperties.noTraceSupression.value calls back into NoStackTrace.noSuppression
+ // two-stage init to make checkinit happy, since sys.SystemProperties.noTraceSuppression.value calls back into NoStackTrace.noSuppression
final private var _noSuppression = false
- _noSuppression = sys.SystemProperties.noTraceSupression.value
+ _noSuppression = sys.SystemProperties.noTraceSuppression.value
}
diff --git a/src/library/scala/util/control/TailCalls.scala b/src/library/scala/util/control/TailCalls.scala
index 953d5b407e..c7fefb1eba 100644
--- a/src/library/scala/util/control/TailCalls.scala
+++ b/src/library/scala/util/control/TailCalls.scala
@@ -55,7 +55,7 @@ object TailCalls {
case Done(a) => Call(() => f(a))
case c@Call(_) => Cont(c, f)
// Take advantage of the monad associative law to optimize the size of the required stack
- case c: Cont[a1, b1] => Cont(c.a, (x: a1) => c f x flatMap f)
+ case c: Cont[a1, b1] => Cont(c.a, (x: a1) => c.f(x) flatMap f)
}
/** Returns either the next step of the tailcalling computation,