Skip to content

Commit 6926e8d

Browse files
committed
Merge pull request scala#3228 from retronym/merge/2.10.x-and-pr-3209-to-master
Merge scala#3209 and 2.10.x to master
2 parents 49f7414 + 2ea8aad commit 6926e8d

File tree

17 files changed

+137
-29
lines changed

17 files changed

+137
-29
lines changed

src/interactive/scala/tools/nsc/interactive/CompilerControl.scala

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,20 @@ trait CompilerControl { self: Global =>
186186
postWorkItem(new AskToDoFirstItem(source))
187187

188188
/** If source is not yet loaded, loads it, and starts a new run, otherwise
189-
* continues with current pass.
190-
* Waits until source is fully type checked and returns body in response.
191-
* @param source The source file that needs to be fully typed.
192-
* @param response The response, which is set to the fully attributed tree of `source`.
189+
* continues with current pass.
190+
* Waits until source is fully type checked and returns body in response.
191+
* @param source The source file that needs to be fully typed.
192+
* @param keepLoaded Whether to keep that file in the PC if it was not loaded before. If
193+
the file is already loaded, this flag is ignored.
194+
* @param response The response, which is set to the fully attributed tree of `source`.
193195
* If the unit corresponding to `source` has been removed in the meantime
194196
* the a NoSuchUnitError is raised in the response.
195197
*/
196-
def askLoadedTyped(source: SourceFile, response: Response[Tree]) =
197-
postWorkItem(new AskLoadedTypedItem(source, response))
198+
def askLoadedTyped(source:SourceFile, keepLoaded: Boolean, response: Response[Tree]): Unit =
199+
postWorkItem(new AskLoadedTypedItem(source, keepLoaded, response))
200+
201+
final def askLoadedTyped(source: SourceFile, response: Response[Tree]): Unit =
202+
askLoadedTyped(source, false, response)
198203

199204
/** If source if not yet loaded, get an outline view with askParseEntered.
200205
* If source is loaded, wait for it to be typechecked.
@@ -203,7 +208,7 @@ trait CompilerControl { self: Global =>
203208
*/
204209
def askStructure(keepSrcLoaded: Boolean)(source: SourceFile, response: Response[Tree]) = {
205210
getUnit(source) match {
206-
case Some(_) => askLoadedTyped(source, response)
211+
case Some(_) => askLoadedTyped(source, keepSrcLoaded, response)
207212
case None => askParsedEntered(source, keepSrcLoaded, response)
208213
}
209214
}
@@ -375,8 +380,8 @@ trait CompilerControl { self: Global =>
375380
response raise new MissingResponse
376381
}
377382

378-
case class AskLoadedTypedItem(source: SourceFile, response: Response[Tree]) extends WorkItem {
379-
def apply() = self.waitLoadedTyped(source, response, this.onCompilerThread)
383+
case class AskLoadedTypedItem(source: SourceFile, keepLoaded: Boolean, response: Response[Tree]) extends WorkItem {
384+
def apply() = self.waitLoadedTyped(source, response, keepLoaded, this.onCompilerThread)
380385
override def toString = "wait loaded & typed "+source
381386

382387
def raiseMissing() =

src/interactive/scala/tools/nsc/interactive/Global.scala

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,12 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
327327
* @param result The transformed node
328328
*/
329329
override def signalDone(context: Context, old: Tree, result: Tree) {
330-
if (interruptsEnabled && analyzer.lockedCount == 0) {
330+
val canObserveTree = (
331+
interruptsEnabled
332+
&& analyzer.lockedCount == 0
333+
&& !context.bufferErrors // SI-7558 look away during exploratory typing in "silent mode"
334+
)
335+
if (canObserveTree) {
331336
if (context.unit.exists &&
332337
result.pos.isOpaqueRange &&
333338
(result.pos includes context.unit.targetPos)) {
@@ -338,14 +343,16 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
338343
}
339344
throw new TyperResult(located)
340345
}
341-
try {
342-
checkForMoreWork(old.pos)
343-
} catch {
344-
case ex: ValidateException => // Ignore, this will have been reported elsewhere
345-
debugLog("validate exception caught: "+ex)
346-
case ex: Throwable =>
347-
log.flush()
348-
throw ex
346+
else {
347+
try {
348+
checkForMoreWork(old.pos)
349+
} catch {
350+
case ex: ValidateException => // Ignore, this will have been reported elsewhere
351+
debugLog("validate exception caught: "+ex)
352+
case ex: Throwable =>
353+
log.flush()
354+
throw ex
355+
}
349356
}
350357
}
351358
}
@@ -1127,7 +1134,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
11271134
}
11281135

11291136
/** Implements CompilerControl.askLoadedTyped */
1130-
private[interactive] def waitLoadedTyped(source: SourceFile, response: Response[Tree], onSameThread: Boolean = true) {
1137+
private[interactive] def waitLoadedTyped(source: SourceFile, response: Response[Tree], keepLoaded: Boolean = false, onSameThread: Boolean = true) {
11311138
getUnit(source) match {
11321139
case Some(unit) =>
11331140
if (unit.isUpToDate) {
@@ -1145,7 +1152,10 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
11451152
case None =>
11461153
debugLog("load unit and type")
11471154
try reloadSources(List(source))
1148-
finally waitLoadedTyped(source, response, onSameThread)
1155+
finally {
1156+
waitLoadedTyped(source, response, onSameThread)
1157+
if (!keepLoaded) removeUnitOf(source)
1158+
}
11491159
}
11501160
}
11511161

src/interactive/scala/tools/nsc/interactive/Picklers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ trait Picklers { self: Global =>
170170

171171
implicit def askLoadedTypedItem: CondPickler[AskLoadedTypedItem] =
172172
pkl[SourceFile]
173-
.wrapped { source => new AskLoadedTypedItem(source, new Response) } { _.source }
173+
.wrapped { source => new AskLoadedTypedItem(source, false, new Response) } { _.source }
174174
.asClass (classOf[AskLoadedTypedItem])
175175

176176
implicit def askParsedEnteredItem: CondPickler[AskParsedEnteredItem] =

src/interactive/scala/tools/nsc/interactive/REPL.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ object REPL {
118118
comp.askReload(List(toSourceFile(file)), reloadResult)
119119
Thread.sleep(millis.toLong)
120120
println("ask type now")
121-
comp.askLoadedTyped(toSourceFile(file), typedResult)
121+
comp.askLoadedTyped(toSourceFile(file), keepLoaded = true, typedResult)
122122
typedResult.get
123123
case List("typeat", file, off1, off2) =>
124124
doTypeAt(makePos(file, off1, off2))

src/interactive/scala/tools/nsc/interactive/tests/core/AskCommand.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ trait AskTypeAt extends AskCommand {
113113
trait AskLoadedTyped extends AskCommand {
114114
import compiler.Tree
115115

116-
protected def askLoadedTyped(source: SourceFile)(implicit reporter: Reporter): Response[Tree] = {
116+
protected def askLoadedTyped(source: SourceFile, keepLoaded: Boolean = false)(implicit reporter: Reporter): Response[Tree] = {
117117
ask {
118-
compiler.askLoadedTyped(source, _)
118+
compiler.askLoadedTyped(source, keepLoaded, _)
119119
}
120120
}
121121

src/library/scala/concurrent/Future.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,10 @@ trait Future[+T] extends Awaitable[T] {
384384
val p = Promise[U]()
385385
onComplete {
386386
case s @ Success(_) => p complete s
387-
case _ => p completeWith that
387+
case f @ Failure(_) => that onComplete {
388+
case s2 @ Success(_) => p complete s2
389+
case _ => p complete f // Use the first failure as the failure
390+
}
388391
}
389392
p.future
390393
}

test/files/jvm/future-spec/PromiseTests.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class PromiseTests extends MinimalScalaTest {
3838

3939
Await.result(failure fallbackTo timedOut, defaultTimeout) mustBe ("Timedout")
4040
Await.result(timedOut fallbackTo empty, defaultTimeout) mustBe ("Timedout")
41-
Await.result(failure fallbackTo failure fallbackTo timedOut, defaultTimeout) mustBe ("Timedout")
41+
Await.result(otherFailure fallbackTo failure fallbackTo timedOut, defaultTimeout) mustBe ("Timedout")
4242
intercept[RuntimeException] {
4343
Await.result(failure fallbackTo otherFailure, defaultTimeout)
44-
}.getMessage mustBe ("last")
44+
}.getMessage mustBe ("br0ken")
4545
}
4646

4747
}

test/files/jvm/scala-concurrent-tck.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ def testTransformFailure(): Unit = once {
344344
def testFallbackToFailure(): Unit = once {
345345
done =>
346346
val cause = new Exception
347-
val f = Future { sys.error("failed") }
348-
val g = Future { throw cause }
347+
val f = Future { throw cause }
348+
val g = Future { sys.error("failed") }
349349
val h = f fallbackTo g
350350

351351
h onSuccess { case _ => done(false) }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Test OK
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import scala.tools.nsc.interactive.tests.InteractiveTest
2+
import scala.reflect.internal.util.SourceFile
3+
import scala.tools.nsc.interactive.Response
4+
5+
object Test extends InteractiveTest {
6+
override def execute(): Unit = {
7+
val sourceA = loadSourceAndWaitUntilTypechecked("A.scala")
8+
checkPresent(sourceA)
9+
}
10+
11+
private def loadSourceAndWaitUntilTypechecked(sourceName: String): SourceFile = {
12+
val sourceFile = sourceFiles.find(_.file.name == sourceName).head
13+
askLoadedTyped(sourceFile).get
14+
/* The response to `askLoadedType` may return before `interactive.Global.waitLoadedType`
15+
* fully executes. Because this test expects `waitLoadedType` is fully executed before
16+
* calling `checkPresent`, with the below no-op presentation compiler request we make
17+
* sure this requirement is fulfilled.
18+
*/
19+
compiler.askForResponse(() => ()).get
20+
sourceFile
21+
}
22+
23+
private def checkPresent(source: SourceFile): Unit = compiler.getUnitOf(source) match {
24+
case Some(unit) => reporter.println("Compilation Unit for " + source.file.name + " still loaded after askLoadedTyped")
25+
26+
case None => reporter.println("Test OK")
27+
}
28+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package a
2+
3+
object A {
4+
val tagString = "foo"
5+
Seq.empty[Byte].toArray.toSeq
6+
}

test/files/presentation/t7548.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(x: Int)Unit
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.tools.nsc.interactive.tests.InteractiveTest
2+
3+
object Test extends InteractiveTest {
4+
override protected def loadSources() { /* don't parse or typecheck sources */ }
5+
6+
import compiler._
7+
8+
override def runDefaultTests() {
9+
val res = new Response[Tree]
10+
val pos = compiler.rangePos(sourceFiles.head, 102,102,102)
11+
compiler.askTypeAt(pos, res)
12+
res.get match {
13+
case Left(tree) => compiler.ask(() => reporter.println(tree.tpe))
14+
case Right(ex) => reporter.println(ex)
15+
}
16+
}
17+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Foo {
2+
def foo(x: Int) = {}
3+
def foo(x: String) = {}
4+
def foo(x: Int, y: String) = {}
5+
6+
foo(2)
7+
}

test/files/presentation/t7548b.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Foo.this.I2BI(Foo.this.I).+: (other: Foo.BI.type)Unit
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.tools.nsc.interactive.tests.InteractiveTest
2+
3+
object Test extends InteractiveTest {
4+
override protected def loadSources() { /* don't parse or typecheck sources */ }
5+
6+
import compiler._
7+
8+
override def runDefaultTests() {
9+
val res = new Response[Tree]
10+
val pos = compiler.rangePos(sourceFiles.head, 191, 191, 191) // +
11+
compiler.askTypeAt(pos, res)
12+
res.get match {
13+
case Left(tree) => compiler.ask(() => reporter.println(s"$tree: ${tree.tpe}"))
14+
case Right(ex) => reporter.println(ex)
15+
}
16+
}
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import language._
2+
3+
object Foo {
4+
object I {
5+
def +(other: I.type) : Unit = ()
6+
}
7+
object BI {
8+
def +(other: BI.type): Unit = ()
9+
}
10+
implicit def I2BI(i: I.type): BI.type = BI
11+
I.+(BI)
12+
}

0 commit comments

Comments
 (0)