Skip to content

Commit be1d089

Browse files
lrytzszeiger
authored andcommitted
Use Abstract* base classes consistently to save on classfile size
- Mark some methods non-final due to scala/bug#10853 - Add immutable.AbstractMap, use AbstractMap consistently - Add immutable.AbstractSet, use AbstractSet consistently - Use AbstractIterable consistently - Add AbstractView - Use AbstractSeq consistently
1 parent 02776af commit be1d089

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+187
-145
lines changed

src/compiler/scala/tools/nsc/io/Jar.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ package scala.tools.nsc
77
package io
88

99
import scala.language.postfixOps
10-
11-
import java.io.{ InputStream, OutputStream, DataOutputStream }
10+
import java.io.{DataOutputStream, InputStream, OutputStream}
1211
import java.util.jar._
12+
1313
import scala.collection.JavaConverters._
1414
import Attributes.Name
1515

16+
import scala.collection.AbstractIterable
17+
1618
// Attributes.Name instances:
1719
//
1820
// static Attributes.Name CLASS_PATH
@@ -33,7 +35,7 @@ import Attributes.Name
3335
// static Attributes.Name SPECIFICATION_VENDOR
3436
// static Attributes.Name SPECIFICATION_VERSION
3537

36-
class Jar(file: File) extends Iterable[JarEntry] {
38+
class Jar(file: File) extends AbstractIterable[JarEntry] {
3739
def this(jfile: JFile) = this(File(jfile))
3840
def this(path: String) = this(File(path))
3941

src/library/scala/Enumeration.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ abstract class Enumeration (initial: Int) extends Serializable {
266266
* @define Coll `collection.immutable.SortedSet`
267267
*/
268268
class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet)
269-
extends immutable.SortedSet[Value]
269+
extends immutable.AbstractSet[Value]
270+
with immutable.SortedSet[Value]
270271
with immutable.SetOps[Value, immutable.Set, ValueSet]
271272
with StrictOptimizedIterableOps[Value, immutable.Set, ValueSet]
272273
with Serializable {

src/library/scala/collection/IndexedView.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object IndexedView {
4242
class Take[A](underlying: SomeIndexedSeqOps[A], n: Int)
4343
extends SeqView.Take(underlying, n) with IndexedView[A]
4444

45-
class TakeRight[A](underlying: SomeIndexedSeqOps[A], n: Int) extends IndexedView[A] {
45+
class TakeRight[A](underlying: SomeIndexedSeqOps[A], n: Int) extends AbstractIndexedView[A] {
4646
private[this] val delta = (underlying.size - (n max 0)) max 0
4747
def length = underlying.size - delta
4848
@throws[IndexOutOfBoundsException]
@@ -55,7 +55,7 @@ object IndexedView {
5555
def apply(i: Int) = underlying.apply(i + normN)
5656
}
5757

58-
class DropRight[A](underlying: SomeIndexedSeqOps[A], n: Int) extends IndexedView[A] {
58+
class DropRight[A](underlying: SomeIndexedSeqOps[A], n: Int) extends AbstractIndexedView[A] {
5959
private[this] val len = (underlying.size - (n max 0)) max 0
6060
def length = len
6161
@throws[IndexOutOfBoundsException]
@@ -65,13 +65,13 @@ object IndexedView {
6565
class Map[A, B](underlying: SomeIndexedSeqOps[A], f: A => B)
6666
extends SeqView.Map(underlying, f) with IndexedView[B]
6767

68-
class Reverse[A](underlying: SomeIndexedSeqOps[A]) extends IndexedView[A] {
68+
class Reverse[A](underlying: SomeIndexedSeqOps[A]) extends AbstractIndexedView[A] {
6969
def length = underlying.size
7070
@throws[IndexOutOfBoundsException]
7171
def apply(i: Int) = underlying.apply(size - 1 - i)
7272
}
7373

74-
class Slice[A](underlying: SomeIndexedSeqOps[A], from: Int, until: Int) extends IndexedView[A] {
74+
class Slice[A](underlying: SomeIndexedSeqOps[A], from: Int, until: Int) extends AbstractIndexedView[A] {
7575
protected val lo = from max 0
7676
protected val hi = (until max 0) min underlying.length
7777
protected val len = (hi - lo) max 0
@@ -80,3 +80,6 @@ object IndexedView {
8080
def length: Int = len
8181
}
8282
}
83+
84+
/** Explicit instantiation of the `IndexedView` trait to reduce class file size in subclasses. */
85+
abstract class AbstractIndexedView[+A] extends AbstractSeqView[A] with IndexedView[A]

src/library/scala/collection/Iterable.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,4 +752,5 @@ object Iterable extends IterableFactory.Delegate[Iterable](immutable.Iterable) {
752752
implicit def toLazyZipOps[A, CC[X] <: Iterable[X]](that: CC[A]): LazyZipOps[A, CC[A]] = new LazyZipOps(that)
753753
}
754754

755+
/** Explicit instantiation of the `Iterable` trait to reduce class file size in subclasses. */
755756
abstract class AbstractIterable[+A] extends Iterable[A]

src/library/scala/collection/LazyZipOps.scala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ final class LazyZip2[El1, El2, C1 <: Iterable[El1]] private[collection](coll1: C
3838
def lazyZip[B](that: Iterable[B]): LazyZip3[El1, El2, B, C1] = new LazyZip3(coll1, coll2, that)
3939

4040
def map[B, C](f: (El1, El2) => B)(implicit bf: BuildFrom[C1, B, C]): C = {
41-
bf.fromSpecificIterable(coll1)(new View[B] {
41+
bf.fromSpecificIterable(coll1)(new AbstractView[B] {
4242
def iterator() = new Iterator[B] {
4343
private val elems1 = coll1.iterator()
4444
private val elems2 = coll2.iterator()
@@ -50,7 +50,7 @@ final class LazyZip2[El1, El2, C1 <: Iterable[El1]] private[collection](coll1: C
5050
}
5151

5252
def flatMap[B, C](f: (El1, El2) => Iterable[B])(implicit bf: BuildFrom[C1, B, C]): C = {
53-
bf.fromSpecificIterable(coll1)(new View[B] {
53+
bf.fromSpecificIterable(coll1)(new AbstractView[B] {
5454
def iterator() = new Iterator[B] {
5555
private val elems1 = coll1.iterator()
5656
private val elems2 = coll2.iterator()
@@ -67,7 +67,7 @@ final class LazyZip2[El1, El2, C1 <: Iterable[El1]] private[collection](coll1: C
6767
}
6868

6969
def filter[C](p: (El1, El2) => Boolean)(implicit bf: BuildFrom[C1, (El1, El2), C]): C = {
70-
bf.fromSpecificIterable(coll1)(new View[(El1, El2)] {
70+
bf.fromSpecificIterable(coll1)(new AbstractView[(El1, El2)] {
7171
def iterator() = new Iterator[(El1, El2)] {
7272
private val elems1 = coll1.iterator()
7373
private val elems2 = coll2.iterator()
@@ -111,7 +111,7 @@ final class LazyZip2[El1, El2, C1 <: Iterable[El1]] private[collection](coll1: C
111111
while (elems1.hasNext && elems2.hasNext) f(elems1.next(), elems2.next())
112112
}
113113

114-
private def toIterable = new View[(El1, El2)] {
114+
private def toIterable: View[(El1, El2)] = new AbstractView[(El1, El2)] {
115115
def iterator() = new Iterator[(El1, El2)] {
116116
private val elems1 = coll1.iterator()
117117
private val elems2 = coll2.iterator()
@@ -145,7 +145,7 @@ final class LazyZip3[El1, El2, El3, C1 <: Iterable[El1]] private[collection](col
145145
def lazyZip[B](that: Iterable[B]): LazyZip4[El1, El2, El3, B, C1] = new LazyZip4(coll1, coll2, coll3, that)
146146

147147
def map[B, C](f: (El1, El2, El3) => B)(implicit bf: BuildFrom[C1, B, C]): C = {
148-
bf.fromSpecificIterable(coll1)(new View[B] {
148+
bf.fromSpecificIterable(coll1)(new AbstractView[B] {
149149
def iterator() = new Iterator[B] {
150150
private val elems1 = coll1.iterator()
151151
private val elems2 = coll2.iterator()
@@ -158,7 +158,7 @@ final class LazyZip3[El1, El2, El3, C1 <: Iterable[El1]] private[collection](col
158158
}
159159

160160
def flatMap[B, C](f: (El1, El2, El3) => Iterable[B])(implicit bf: BuildFrom[C1, B, C]): C = {
161-
bf.fromSpecificIterable(coll1)(new View[B] {
161+
bf.fromSpecificIterable(coll1)(new AbstractView[B] {
162162
def iterator() = new Iterator[B] {
163163
private val elems1 = coll1.iterator()
164164
private val elems2 = coll2.iterator()
@@ -176,7 +176,7 @@ final class LazyZip3[El1, El2, El3, C1 <: Iterable[El1]] private[collection](col
176176
}
177177

178178
def filter[C](p: (El1, El2, El3) => Boolean)(implicit bf: BuildFrom[C1, (El1, El2, El3), C]): C = {
179-
bf.fromSpecificIterable(coll1)(new View[(El1, El2, El3)] {
179+
bf.fromSpecificIterable(coll1)(new AbstractView[(El1, El2, El3)] {
180180
def iterator() = new Iterator[(El1, El2, El3)] {
181181
private val elems1 = coll1.iterator()
182182
private val elems2 = coll2.iterator()
@@ -226,7 +226,7 @@ final class LazyZip3[El1, El2, El3, C1 <: Iterable[El1]] private[collection](col
226226
f(elems1.next(), elems2.next(), elems3.next())
227227
}
228228

229-
private def toIterable = new View[(El1, El2, El3)] {
229+
private def toIterable: View[(El1, El2, El3)] = new AbstractView[(El1, El2, El3)] {
230230
def iterator() = new Iterator[(El1, El2, El3)] {
231231
private val elems1 = coll1.iterator()
232232
private val elems2 = coll2.iterator()
@@ -253,7 +253,7 @@ final class LazyZip4[El1, El2, El3, El4, C1 <: Iterable[El1]] private[collection
253253
coll4: Iterable[El4]) {
254254

255255
def map[B, C](f: (El1, El2, El3, El4) => B)(implicit bf: BuildFrom[C1, B, C]): C = {
256-
bf.fromSpecificIterable(coll1)(new View[B] {
256+
bf.fromSpecificIterable(coll1)(new AbstractView[B] {
257257
def iterator() = new Iterator[B] {
258258
private val elems1 = coll1.iterator()
259259
private val elems2 = coll2.iterator()
@@ -267,7 +267,7 @@ final class LazyZip4[El1, El2, El3, El4, C1 <: Iterable[El1]] private[collection
267267
}
268268

269269
def flatMap[B, C](f: (El1, El2, El3, El4) => Iterable[B])(implicit bf: BuildFrom[C1, B, C]): C = {
270-
bf.fromSpecificIterable(coll1)(new View[B] {
270+
bf.fromSpecificIterable(coll1)(new AbstractView[B] {
271271
def iterator() = new Iterator[B] {
272272
private val elems1 = coll1.iterator()
273273
private val elems2 = coll2.iterator()
@@ -286,7 +286,7 @@ final class LazyZip4[El1, El2, El3, El4, C1 <: Iterable[El1]] private[collection
286286
}
287287

288288
def filter[C](p: (El1, El2, El3, El4) => Boolean)(implicit bf: BuildFrom[C1, (El1, El2, El3, El4), C]): C = {
289-
bf.fromSpecificIterable(coll1)(new View[(El1, El2, El3, El4)] {
289+
bf.fromSpecificIterable(coll1)(new AbstractView[(El1, El2, El3, El4)] {
290290
def iterator() = new Iterator[(El1, El2, El3, El4)] {
291291
private val elems1 = coll1.iterator()
292292
private val elems2 = coll2.iterator()
@@ -340,7 +340,7 @@ final class LazyZip4[El1, El2, El3, El4, C1 <: Iterable[El1]] private[collection
340340
f(elems1.next(), elems2.next(), elems3.next(), elems4.next())
341341
}
342342

343-
private def toIterable = new View[(El1, El2, El3, El4)] {
343+
private def toIterable: View[(El1, El2, El3, El4)] = new AbstractView[(El1, El2, El3, El4)] {
344344
def iterator() = new Iterator[(El1, El2, El3, El4)] {
345345
private val elems1 = coll1.iterator()
346346
private val elems2 = coll2.iterator()

src/library/scala/collection/Map.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ trait MapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C]
133133
/** The implementation class of the set returned by `keySet`.
134134
*/
135135
@SerialVersionUID(3L)
136-
protected class KeySet extends Set[K] with GenKeySet {
136+
protected class KeySet extends AbstractSet[K] with GenKeySet {
137137
def diff(that: Set[K]): Set[K] = fromSpecificIterable(view.filterNot(that))
138138
}
139139

@@ -315,4 +315,4 @@ object Map extends MapFactory.Delegate[Map](immutable.Map) {
315315
}
316316

317317
/** Explicit instantiation of the `Map` trait to reduce class file size in subclasses. */
318-
abstract class AbstractMap[A, +B] extends AbstractIterable[(A, B)] with Map[A, B]
318+
abstract class AbstractMap[K, +V] extends AbstractIterable[(K, V)] with Map[K, V]

src/library/scala/collection/MapView.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,23 @@ object MapView {
2727
/** A `MapOps` whose collection type and collection type constructor are (mostly) unknown */
2828
type SomeMapOps[K, +V] = MapOps[K, V, SomeIterableConstr, _]
2929

30-
class Id[K, +V](underlying: SomeMapOps[K, V]) extends MapView[K, V] {
30+
class Id[K, +V](underlying: SomeMapOps[K, V]) extends AbstractMapView[K, V] {
3131
def get(key: K): Option[V] = underlying.get(key)
3232
def iterator(): Iterator[(K, V)] = underlying.iterator()
3333
override def knownSize: Int = underlying.knownSize
3434
}
3535

36-
class MapValues[K, +V, +W](underlying: SomeMapOps[K, V], f: V => W) extends MapView[K, W] {
36+
class MapValues[K, +V, +W](underlying: SomeMapOps[K, V], f: V => W) extends AbstractMapView[K, W] {
3737
def iterator(): Iterator[(K, W)] = underlying.iterator().map(kv => (kv._1, f(kv._2)))
3838
def get(key: K): Option[W] = underlying.get(key).map(f)
3939
override def knownSize: Int = underlying.knownSize
4040
}
4141

42-
class FilterKeys[K, +V](underlying: SomeMapOps[K, V], p: K => Boolean) extends MapView[K, V] {
42+
class FilterKeys[K, +V](underlying: SomeMapOps[K, V], p: K => Boolean) extends AbstractMapView[K, V] {
4343
def iterator(): Iterator[(K, V)] = underlying.iterator().filter { case (k, _) => p(k) }
4444
def get(key: K): Option[V] = if (p(key)) underlying.get(key) else None
4545
}
46-
4746
}
47+
48+
/** Explicit instantiation of the `MapView` trait to reduce class file size in subclasses. */
49+
abstract class AbstractMapView[K, +V] extends AbstractView[(K, V)] with MapView[K, V]

src/library/scala/collection/Seq.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any
8484
/**
8585
* @return This collection as a `Seq[A]`. This is equivalent to `to(Seq)` but might be faster.
8686
*/
87-
def toSeq: Seq[A]
87+
def toSeq: immutable.Seq[A]
8888

8989
/** A copy of the $coll with an element prepended.
9090
*
@@ -939,18 +939,18 @@ object SeqOps {
939939
case iso: IndexedSeq[B] =>
940940
// Already optimized for indexing--use original (or custom view of original)
941941
if (forward && n0==0 && n1==W.length) iso.view
942-
else if (forward) new IndexedView[B] {
942+
else if (forward) new AbstractIndexedView[B] {
943943
val length = n1 - n0
944944
def apply(x: Int) = iso(n0 + x)
945945
}
946-
else new IndexedView[B] {
946+
else new AbstractIndexedView[B] {
947947
def length = n1 - n0
948948
def apply(x: Int) = iso(n1 - 1 - x)
949949
}
950950
case _ =>
951951
// W is probably bad at indexing. Pack in array (in correct orientation)
952952
// Would be marginally faster to special-case each direction
953-
new IndexedView[B] {
953+
new AbstractIndexedView[B] {
954954
private[this] val Warr = new Array[AnyRef](n1-n0)
955955
private[this] val delta = if (forward) 1 else -1
956956
private[this] val done = if (forward) n1-n0 else -1

src/library/scala/collection/SeqView.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ object SeqView {
2020
type SomeSeqOps[+A] = SeqOps[A, AnyConstr, _]
2121

2222
/** A view that doesn’t apply any transformation to an underlying sequence */
23-
class Id[+A](underlying: SeqOps[A, AnyConstr, _]) extends SeqView[A] {
23+
class Id[+A](underlying: SeqOps[A, AnyConstr, _]) extends AbstractSeqView[A] {
2424
def apply(idx: Int): A = underlying.apply(idx)
2525
def length: Int = underlying.length
2626
def iterator(): Iterator[A] = underlying.iterator()
@@ -41,5 +41,7 @@ object SeqView {
4141
def apply(idx: Int): A = if (idx < n) underlying(idx) else throw new IndexOutOfBoundsException(idx.toString)
4242
def length: Int = underlying.length min normN
4343
}
44-
4544
}
45+
46+
/** Explicit instantiation of the `SeqView` trait to reduce class file size in subclasses. */
47+
abstract class AbstractSeqView[+A] extends AbstractView[A] with SeqView[A]

src/library/scala/collection/Set.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
4949
* @param elem the element to test for membership.
5050
* @return `true` if `elem` is contained in this set, `false` otherwise.
5151
*/
52-
@`inline` final def apply(elem: A): Boolean = this.contains(elem)
52+
@deprecatedOverriding("This method should be final, but is not due to scala/bug#10853", "2.13.0")
53+
/*@`inline` final*/ def apply(elem: A): Boolean = this.contains(elem)
5354

5455
/** Tests whether this set is a subset of another set.
5556
*
@@ -199,3 +200,6 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
199200
* @define Coll `Set`
200201
*/
201202
object Set extends IterableFactory.Delegate[Set](immutable.Set)
203+
204+
/** Explicit instantiation of the `Set` trait to reduce class file size in subclasses. */
205+
abstract class AbstractSet[A] extends AbstractIterable[A] with Set[A]

0 commit comments

Comments
 (0)