Skip to content

Commit 17633b2

Browse files
committed
Merge branch '2.12.x' into 2.13.x
no interesting merge conflicts. versions.properties is always a conflict factory, and HashMap.scala was because of parallel collections removal. % export mb=$(git merge-base origin/2.12.x origin/2.13.x) % git log --graph --oneline --decorate $mb..origin/2.12.x | cat * 96cdfb4 (origin/HEAD, origin/2.12.x) Merge pull request scala#5741 from monkey-mas/bump-up-sbt-jmh-to-0.2.21 |\ | * 08f753e Bump up sbt-jmh to 0.2.21 * 38baf2b Merge pull request scala#5771 from som-snytt/issue/regex-doc-err |\ | * cc1b8f3 Fix and improve Regex doc * | 6f905fd Merge pull request scala#5747 from dwijnand/fix-root-package-task |\ \ | * | 4c1c8de Rewire package to osgiBundle for OSGi-enabled projects | / * | 57948c8 Merge pull request scala#5791 from SethTisue/cruft-begone |\ \ | * | 4b98161 remove test/pending directory too | * | 25048bc (SethTisue/cruft-begone) rm -r test/{flaky,disabled*,checker-tests,support,debug} | * | 0563c4b remove orphaned checkfiles | * | 36357f3 remove two empty source files | * | 8690809 fix typos | * | 8177b99 unset a stray execute bit * | | c7c2152 Merge pull request scala#5776 from lrytz/numbersCleanup |\ \ \ | * | | 77e0602 cleanups and clarifications in versions.properties | / / * | | 95a263e Merge pull request scala#5789 from ceeph/patch-1 |\ \ \ | |/ / |/| | | * | a9ba3e6 Fix table formatting |/ / * | 6048c66 Merge pull request scala#5780 from lrytz/bootstrapOverwrite |\ \ | * | 6ff3891 Use a single repository in the bootstrap job |/ / * | 0dab108 Merge pull request scala#5777 from som-snytt/issue/10226 |\ \ | * | c77b420 SI-10226 REPL handles paste when colorized |/ / * | d0c2620 Merge pull request scala#5756 from rorygraves/2.12.x_depthboxing |\ \ | * | f7cd76b Reduce boxing of scala.reflect.internal.Depth | / * | 17e057b Merge pull request scala#5755 from rorygraves/2.12.x_map4 |\ \ | * | 0c6d4e5 Performance improvements for Map4 to HashMap nad Set4 to HashSet transitions | * | aefc8f4 Add benchmarks for Map4 to HashMap and Set4 to HashSet transitions | * | fad8b95 Fix compile error on existing ListBenchmark | / * | 3fadf69 Merge pull request scala#5675 from piyush-jaiswal/issue/9729 |\ \ | |/ |/| | * cc99026 Add tests for ConsoleReporter. * 6e9268b Merge pull request scala#5761 from lrytz/sd329 |\ | * 6abb6ba Don't use `equals` for comparing java.lang.Double/Float * 680d866 Merge pull request scala#5719 from retronym/ticket/10187 |\ | * 898fa00 SI-10187 Support mutation of mutable.HashMap in getOrElseUpdate * 0e38f28 Merge pull request scala#5767 from som-snytt/issue/5621 |\ | * dea2171 SI-5621 Missing implicits are supplied by defaults * 482879f Merge pull request scala#5769 from som-snytt/issue/8969 |\ | * 050811b SI-8969 Accept poly+implicit for assignment syntax * cba77ce Merge pull request scala#5766 from lrytz/versionsReadme * 8fcb9f1 Adapt README to new version numbers % git merge origin/2.12.x % git status ... both modified: src/library/scala/collection/mutable/HashMap.scala deleted by them: test/pending/shootout/fasta.scala both modified: versions.properties % git rm --force test/pending/shootout/fasta.scala % emacs versions.properties % git add -u versions.properties % emacs src/library/scala/collection/mutable/HashMap.scala % git add -u src/library/scala/collection/mutable/HashMap.scala
1 parent e2a2cba commit 17633b2

File tree

581 files changed

+510
-84349
lines changed

Some content is hidden

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

581 files changed

+510
-84349
lines changed

README.md

+13-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ We're still using Jira for issue reporting, so please [report any issues](https:
2020
# Get in touch!
2121
If you need some help with your PR at any time, please feel free to @-mention anyone from the list below, and we will do our best to help you out:
2222

23-
| username | talk to me about... |
23+
| | username | talk to me about... |
2424
--------------------------------------------------------------------------------------------------|----------------------------------------------------------------|---------------------------------------------------|
2525
<img src="https://avatars.githubusercontent.com/adriaanm" height="50px" title="Adriaan Moors"/> | [`@adriaanm`](https://github.com/adriaanm) | type checker, pattern matcher, infrastructure, language spec |
2626
<img src="https://avatars.githubusercontent.com/SethTisue" height="50px" title="Seth Tisue"/> | [`@SethTisue`](https://github.com/SethTisue) | build, developer docs, community build, Jenkins, library, the welcome-to-Scala experience |
@@ -104,10 +104,13 @@ Core commands:
104104
- `partest` runs partest tests (accepts options, try `partest --help`)
105105
- `publishLocal` publishes a distribution locally (can be used as `scalaVersion` in
106106
other sbt projects)
107-
- Optionally `set baseVersionSuffix := "abcd123-SNAPSHOT"`
107+
- Optionally `set baseVersionSuffix := "-bin-abcd123-SNAPSHOT"`
108108
where `abcd123` is the git hash of the revision being published. You can also
109-
use something custom like `"mypatch"`. This changes the version number from
110-
`2.12.0-SNAPSHOT` to something more stable (`2.12.0-abcd123-SNAPSHOT`).
109+
use something custom like `"-bin-mypatch"`. This changes the version number from
110+
`2.12.2-SNAPSHOT` to something more stable (`2.12.2-bin-abcd123-SNAPSHOT`).
111+
- Note that the `-bin` string marks the version binary compatible. Using it in
112+
sbt will cause the `scalaBinaryVersion` to be `2.12`. If the version is not
113+
binary compatible, we recommend using `-pre`, e.g., `2.13.0-pre-abcd123-SNAPSHOT`.
111114
- Optionally `set publishArtifact in (Compile, packageDoc) in ThisBuild := false`
112115
to skip generating / publishing API docs (speeds up the process).
113116

@@ -199,16 +202,17 @@ CI performs a full bootstrap. The first task, `validate-publish-core`, publishes
199202
a build of your commit to the temporary repository
200203
https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots.
201204
Note that this build is not yet bootstrapped, its bytecode is built using the
202-
current `starr`. The version number is `2.12.0-abcd123-SNAPSHOT` where `abcd123`
203-
is the commit hash.
205+
current `starr`. The version number is `2.12.2-bin-abcd123-SNAPSHOT` where `abcd123`
206+
is the commit hash. For binary incompatible builds, the version number is
207+
`2.13.0-pre-abcd123-SNAPSHOT`.
204208

205209
You can use Scala builds in the validation repository locally by adding a resolver
206210
and specifying the corresponding `scalaVersion`:
207211

208212
```
209213
$ sbt
210214
> set resolvers += "pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/"
211-
> set scalaVersion := "2.12.0-abcd123-SNAPSHOT"
215+
> set scalaVersion := "2.12.2-bin-abcd123-SNAPSHOT"
212216
> console
213217
```
214218

@@ -228,10 +232,8 @@ The CI also publishes nightly API docs:
228232
- [2.11.x](http://www.scala-lang.org/files/archive/nightly/2.11.x/api/?C=M;O=D)
229233
- [symlink to the latest](http://www.scala-lang.org/files/archive/nightly/2.11.x/api/2.11.x/)
230234

231-
Note that we currently don't publish nightly (or SNAPSHOT) builds in maven or ivy
232-
format to any repository. You can track progress on this front at
233-
[scala-jenkins-infra#133](https://github.com/scala/scala-jenkins-infra/issues/133)
234-
and [scala-dev#68](https://github.com/scala/scala-dev/issues/68).
235+
Using a nightly build in sbt is explained in
236+
[this answer on Stack Overflow](http://stackoverflow.com/questions/40622878)
235237

236238
## Scala CI Internals
237239

build.sbt

+1-1
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ lazy val test = project
670670
(baseDir / "test/files/lib").list.toSeq.filter(_.endsWith(".jar.desired.sha1"))
671671
.map(f => bootstrapDep(baseDir, "test/files/lib", f.dropRight(17)))
672672
},
673-
// Two hardcoded depenencies in partest, resolved in the otherwise unused scope "test":
673+
// Two hardcoded dependencies in partest, resolved in the otherwise unused scope "test":
674674
libraryDependencies += bootstrapDep((baseDirectory in ThisBuild).value, "test/files/codelib", "code") % "test",
675675
libraryDependencies += bootstrapDep((baseDirectory in ThisBuild).value, "test/files/speclib", "instrumented") % "test",
676676
// no main sources

project/MiMa.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ object MiMa {
5151
"--curr", curr.getAbsolutePath,
5252
"--filters", filter.getAbsolutePath,
5353
"--generate-filters",
54-
// !!! Command line MiMa (which we call rathan the sbt Plugin for reasons alluded to in f2d0f1e85) incorrectly
54+
// !!! Command line MiMa (which we call rather than the sbt Plugin for reasons alluded to in f2d0f1e85) incorrectly
5555
// defaults to no checking (!) if this isn't specified. Fixed in https://github.com/typesafehub/migration-manager/pull/138
5656
// TODO: Try out the new "--direction both" mode of MiMa
5757
"--direction", "backwards"

project/Osgi.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ object Osgi {
5050
"Bundle-SymbolicName" -> (bundleSymbolicName.value + ".source"),
5151
"Bundle-Version" -> versionProperties.value.osgiVersion,
5252
"Eclipse-SourceBundle" -> (bundleSymbolicName.value + ";version=\"" + versionProperties.value.osgiVersion + "\";roots:=\".\"")
53-
)
53+
),
54+
Keys.`package` := bundle.value
5455
)
5556

5657
def bundleTask(headers: Map[String, String], jarlist: Boolean, fullClasspath: Seq[File], artifactPath: File,

project/PartestUtil.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ object PartestUtil {
8787
token(grepOption <~ Space) ~> token(globOrPattern, tokenCompletion)
8888
}
8989

90-
val SrcPath = ((token(srcPathOption) <~ Space) ~ token(StringBasic.examples(Set("files", "pending", "scaladoc")))) map {
90+
val SrcPath = ((token(srcPathOption) <~ Space) ~ token(StringBasic.examples(Set("files", "scaladoc")))) map {
9191
case opt ~ path =>
9292
srcPath = path
9393
opt + " " + path

scripts/jobs/integrate/bootstrap

+5-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Script Overview
44
# - determine scala version
55
# - determine module versions
6-
# - build minimal core (aka locker) of Scala, use the determined version number, publish to scala-release-temp
6+
# - build minimal core (aka locker) of Scala, use the determined version number, publish to scala-integration
77
# - build those modules where a binary compatible version doesn't exist, publish to scala-integration
88
# - build Scala using the previously built core and bootstrap modules, publish to scala-integration
99
# - for releases
@@ -98,15 +98,10 @@ mkdir -p $baseDir/ivy2
9898
rm -rf $baseDir/resolutionScratch_
9999
mkdir -p $baseDir/resolutionScratch_
100100

101-
# repo for the starr and locker builds
102-
releaseTempRepoUrl=${releaseTempRepoUrl-"https://scala-ci.typesafe.com/artifactory/scala-release-temp/"}
103-
# repo for the modules and the quick build
101+
# repo to publish builds
104102
integrationRepoUrl=${integrationRepoUrl-"https://scala-ci.typesafe.com/artifactory/scala-integration/"}
105103

106-
# the `releaseTempRepoUrl` needs to be in the repositories file to get starr when building quick and the modules.
107-
# `integrationRepoUrl` is there to find modules when building quick and other modules (e.g., partest requires xml).
108-
# the file is re-generated for running the stability test, this time with only `integrationRepoUrl`.
109-
generateRepositoriesConfig $releaseTempRepoUrl $integrationRepoUrl
104+
generateRepositoriesConfig $integrationRepoUrl
110105

111106
# ARGH trying to get this to work on multiple versions of sbt-extras...
112107
# the old version (on jenkins, and I don't want to upgrade for risk of breaking other builds) honors -sbt-dir
@@ -413,7 +408,7 @@ bootstrap() {
413408
git clone --reference $WORKSPACE/.git $WORKSPACE/.git $STARR_DIR
414409
cd $STARR_DIR
415410
git co $STARR_REF
416-
$SBT_CMD -no-colors $sbtArgs --warn "setupBootstrapStarr $releaseTempRepoUrl $STARR_VER" $clean publish >> $baseDir/logs/builds 2>&1
411+
$SBT_CMD -no-colors $sbtArgs --warn "setupBootstrapStarr $integrationRepoUrl $STARR_VER" $clean publish >> $baseDir/logs/builds 2>&1
417412
)
418413
fi
419414

@@ -427,7 +422,7 @@ bootstrap() {
427422
# publish more than just core: partest needs scalap
428423
# in sabbus lingo, the resulting Scala build will be used as starr to build the released Scala compiler
429424
if [ ! -z "$STARR_VER" ]; then SET_STARR=-Dstarr.version=$STARR_VER; fi
430-
$SBT_CMD -no-colors $sbtArgs $SET_STARR --warn "setupBootstrapLocker $releaseTempRepoUrl $SCALA_VER" $clean publish >> $baseDir/logs/builds 2>&1
425+
$SBT_CMD -no-colors $sbtArgs $SET_STARR --warn "setupBootstrapLocker $integrationRepoUrl $SCALA_VER" $clean publish >> $baseDir/logs/builds 2>&1
431426

432427
echo "### Building modules using locker"
433428

@@ -530,13 +525,9 @@ determineScalaVersion
530525
deriveModuleVersions
531526

532527
removeExistingBuilds $integrationRepoUrl
533-
removeExistingBuilds $releaseTempRepoUrl
534528

535529
bootstrap
536530

537-
# for stability testing and sonatype publishing, use artifacts in `integrationRepoUrl`
538-
generateRepositoriesConfig $integrationRepoUrl
539-
540531
if [ "$testStability" == "yes" ]
541532
then testStability
542533
fi

spec/04-basic-declarations-and-definitions.md

+9
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,15 @@ def f(a: Int = 0)(b: Int = a + 1) = b // OK
669669
f(10)() // returns 11 (not 1)
670670
```
671671

672+
If an [implicit argument](07-implicits.html#implicit-parameters)
673+
is not found by implicit search, it may be supplied using a default argument.
674+
675+
```scala
676+
implicit val i: Int = 2
677+
def f(implicit x: Int, s: String = "hi") = s * x
678+
f // "hihi"
679+
```
680+
672681
### By-Name Parameters
673682

674683
```ebnf

spec/06-expressions.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ would not typecheck.
320320

321321
### Named and Default Arguments
322322

323-
If an application might uses named arguments $p = e$ or default
323+
If an application is to use named arguments $p = e$ or default
324324
arguments, the following conditions must hold.
325325

326326
- For every named argument $p_i = e_i$ which appears left of a positional argument
@@ -330,7 +330,7 @@ arguments, the following conditions must hold.
330330
argument defines a parameter which is already specified by a
331331
positional argument.
332332
- Every formal parameter $p_j:T_j$ which is not specified by either a positional
333-
or a named argument has a default argument.
333+
or named argument has a default argument.
334334

335335
If the application uses named or default
336336
arguments the following transformation is applied to convert it into
@@ -455,7 +455,7 @@ $e$.
455455

456456
Type applications can be omitted if
457457
[local type inference](#local-type-inference) can infer best type parameters
458-
for a polymorphic functions from the types of the actual function arguments
458+
for a polymorphic function from the types of the actual function arguments
459459
and the expected result type.
460460

461461
## Tuples

src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala

+13-5
Original file line numberDiff line numberDiff line change
@@ -1264,14 +1264,22 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
12641264
def genEqEqPrimitive(l: Tree, r: Tree, success: asm.Label, failure: asm.Label, targetIfNoJump: asm.Label, pos: Position) {
12651265

12661266
/* True if the equality comparison is between values that require the use of the rich equality
1267-
* comparator (scala.runtime.Comparator.equals). This is the case when either side of the
1267+
* comparator (scala.runtime.BoxesRunTime.equals). This is the case when either side of the
12681268
* comparison might have a run-time type subtype of java.lang.Number or java.lang.Character.
1269-
* When it is statically known that both sides are equal and subtypes of Number of Character,
1270-
* not using the rich equality is possible (their own equals method will do ok.)
1269+
*
1270+
* When it is statically known that both sides are equal and subtypes of Number or Character,
1271+
* not using the rich equality is possible (their own equals method will do ok), except for
1272+
* java.lang.Float and java.lang.Double: their `equals` have different behavior around `NaN`
1273+
* and `-0.0`, see Javadoc (scala-dev#329).
12711274
*/
12721275
val mustUseAnyComparator: Boolean = {
1273-
val areSameFinals = l.tpe.isFinalType && r.tpe.isFinalType && (l.tpe =:= r.tpe)
1274-
!areSameFinals && platform.isMaybeBoxed(l.tpe.typeSymbol) && platform.isMaybeBoxed(r.tpe.typeSymbol)
1276+
platform.isMaybeBoxed(l.tpe.typeSymbol) && platform.isMaybeBoxed(r.tpe.typeSymbol) && {
1277+
val areSameFinals = l.tpe.isFinalType && r.tpe.isFinalType && (l.tpe =:= r.tpe) && {
1278+
val sym = l.tpe.typeSymbol
1279+
sym != BoxedFloatClass && sym != BoxedDoubleClass
1280+
}
1281+
!areSameFinals
1282+
}
12751283
}
12761284

12771285
if (mustUseAnyComparator) {

src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
7777
if (reader != null) {
7878
reader.read match {
7979
case 'a' | 'A' =>
80-
new Throwable().printStackTrace()
80+
new Throwable().printStackTrace(writer)
8181
System.exit(1)
8282
case 's' | 'S' =>
83-
new Throwable().printStackTrace()
83+
new Throwable().printStackTrace(writer)
8484
writer.println()
8585
writer.flush()
8686
case _ =>

src/compiler/scala/tools/nsc/transform/AddInterfaces.scala

Whitespace-only changes.

src/compiler/scala/tools/nsc/transform/TailCalls.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ abstract class TailCalls extends Transform {
8484
* </p>
8585
* <p>
8686
* Assumes: `Uncurry` has been run already, and no multiple
87-
* parameter lists exit.
87+
* parameter lists exist.
8888
* </p>
8989
*/
9090
class TailCallElimination(unit: CompilationUnit) extends Transformer {

src/library/scala/collection/immutable/Map.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ object Map extends ImmutableMapFactory[Map] {
198198
else if (key == key2) new Map4(key1, value1, key2, value, key3, value3, key4, value4)
199199
else if (key == key3) new Map4(key1, value1, key2, value2, key3, value, key4, value4)
200200
else if (key == key4) new Map4(key1, value1, key2, value2, key3, value3, key4, value)
201-
else new HashMap + ((key1, value1), (key2, value2), (key3, value3), (key4, value4), (key, value))
201+
else (new HashMap).updated(key1,value1).updated(key2, value2).updated(key3, value3).updated(key4, value4).updated(key, value)
202202
def + [V1 >: V](kv: (K, V1)): Map[K, V1] = updated(kv._1, kv._2)
203203
def - (key: K): Map[K, V] =
204204
if (key == key1) new Map3(key2, value2, key3, value3, key4, value4)

src/library/scala/collection/immutable/Set.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ object Set extends ImmutableSetFactory[Set] {
190190
elem == elem1 || elem == elem2 || elem == elem3 || elem == elem4
191191
def + (elem: A): Set[A] =
192192
if (contains(elem)) this
193-
else new HashSet[A] + (elem1, elem2, elem3, elem4, elem)
193+
else new HashSet[A] + elem1 + elem2 + elem3 + elem4 + elem
194194
def - (elem: A): Set[A] =
195195
if (elem == elem1) new Set3(elem2, elem3, elem4)
196196
else if (elem == elem2) new Set3(elem1, elem3, elem4)

src/library/scala/collection/mutable/HashMap.scala

+35-7
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,45 @@ extends AbstractMap[A, B]
6868
else Some(e.value)
6969
}
7070

71-
override def getOrElseUpdate(key: A, value: => B): B = {
72-
val i = index(elemHashCode(key))
73-
val e = findEntry0(key, i)
74-
if (e ne null) e.value
71+
override def getOrElseUpdate(key: A, defaultValue: => B): B = {
72+
val hash = elemHashCode(key)
73+
val i = index(hash)
74+
val entry = findEntry(key, i)
75+
if (entry != null) entry.value
7576
else {
76-
val newEntry = createNewEntry(key, value)
77-
addEntry0(newEntry, i)
78-
newEntry.value
77+
val table0 = table
78+
val default = defaultValue
79+
// Avoid recomputing index if the `defaultValue()` hasn't triggered
80+
// a table resize.
81+
val newEntryIndex = if (table0 eq table) i else index(hash)
82+
addEntry(createNewEntry(key, default), newEntryIndex)
7983
}
8084
}
8185

86+
/* inlined HashTable.findEntry0 to preserve its visibility */
87+
private[this] def findEntry(key: A, h: Int): Entry = {
88+
var e = table(h).asInstanceOf[Entry]
89+
while (notFound(key, e))
90+
e = e.next
91+
e
92+
}
93+
private[this] def notFound(key: A, e: Entry): Boolean = (e != null) && !elemEquals(e.key, key)
94+
95+
/* inlined HashTable.addEntry0 to preserve its visibility */
96+
private[this] def addEntry(e: Entry, h: Int): B = {
97+
if (tableSize >= threshold) addEntry(e)
98+
else addEntry0(e, h)
99+
e.value
100+
}
101+
102+
/* extracted to make addEntry inlinable */
103+
private[this] def addEntry0(e: Entry, h: Int) {
104+
e.next = table(h).asInstanceOf[Entry]
105+
table(h) = e
106+
tableSize += 1
107+
nnSizeMapAdd(h)
108+
}
109+
82110
override def put(key: A, value: B): Option[B] = {
83111
val e = findOrAddEntry(key, value)
84112
if (e eq null) None

src/library/scala/util/matching/Regex.scala

+30-16
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ import java.util.regex.{ Pattern, Matcher }
4141
* implicitly for strings:
4242
*
4343
* {{{
44-
* val date = """(\d\d\d\d)-(\d\d)-(\d\d)""".r
44+
* val date = raw"(\d{4})-(\d{2})-(\d{2})".r
4545
* }}}
4646
*
4747
* Since escapes are not processed in multi-line string literals, using triple quotes
4848
* avoids having to escape the backslash character, so that `"\\d"` can be written `"""\d"""`.
49+
* The same result is achieved with certain interpolators, such as `raw"\d".r` or
50+
* a custom interpolator `r"\d"` that also compiles the `Regex`.
4951
*
5052
* === Extraction ===
5153
* To extract the capturing groups when a `Regex` is matched, use it as
@@ -116,29 +118,41 @@ import java.util.regex.{ Pattern, Matcher }
116118
* while (mi.hasNext) {
117119
* val d = mi.next
118120
* if (mi.group(1).toInt < 1960) println(s"$d: An oldie but goodie.")
121+
* }
119122
* }}}
120123
*
121-
* Note that `findAllIn` finds matches that don't overlap. (See [[findAllIn]] for more examples.)
124+
* Although the `MatchIterator` returned by `findAllIn` is used like any `Iterator`,
125+
* with alternating calls to `hasNext` and `next`, `hasNext` has the additional
126+
* side effect of advancing the underlying matcher to the next unconsumed match.
127+
* This effect is visible in the `MatchData` representing the "current match".
122128
*
123129
* {{{
124-
* val num = """(\d+)""".r
125-
* val all = num.findAllIn("123").toList // List("123"), not List("123", "23", "3")
130+
* val r = "(ab+c)".r
131+
* val s = "xxxabcyyyabbczzz"
132+
* r.findAllIn(s).start // 3
133+
* val mi = r.findAllIn(s)
134+
* mi.hasNext // true
135+
* mi.start // 3
136+
* mi.next() // "abc"
137+
* mi.start // 3
138+
* mi.hasNext // true
139+
* mi.start // 9
140+
* mi.next() // "abbc"
126141
* }}}
127142
*
128-
* Also, the "current match" of a `MatchIterator` may be advanced by either `hasNext` or `next`.
129-
* By comparison, the `Iterator[Match]` returned by `findAllMatchIn` or `findAllIn.matchData`
130-
* produces `Match` objects that remain valid after the iterator is advanced.
143+
* The example shows that methods on `MatchData` such as `start` will advance to
144+
* the first match, if necessary. It also shows that `hasNext` will advance to
145+
* the next unconsumed match, if `next` has already returned the current match.
146+
*
147+
* The current `MatchData` can be captured using the `matchData` method.
148+
* Alternatively, `findAllMatchIn` returns an `Iterator[Match]`, where there
149+
* is no interaction between the iterator and `Match` objects it has already produced.
150+
*
151+
* Note that `findAllIn` finds matches that don't overlap. (See [[findAllIn]] for more examples.)
131152
*
132153
* {{{
133-
* val ns = num.findAllIn("1 2 3")
134-
* ns.start // 0
135-
* ns.hasNext // true
136-
* ns.start // 2
137-
* val ms = num.findAllMatchIn("1 2 3")
138-
* val m = ms.next()
139-
* m.start // 0
140-
* ms.hasNext // true
141-
* m.start // still 0
154+
* val num = raw"(\d+)".r
155+
* val all = num.findAllIn("123").toList // List("123"), not List("123", "23", "3")
142156
* }}}
143157
*
144158
* === Replace Text ===

0 commit comments

Comments
 (0)