@@ -38,6 +38,7 @@ import dotty.tools.backend.jvm.PostProcessorFrontendAccess.BackendReporting
38
38
import scala .annotation .constructorOnly
39
39
import java .util .concurrent .atomic .AtomicReference
40
40
import java .util .concurrent .atomic .AtomicBoolean
41
+ import java .util .ConcurrentModificationException
41
42
42
43
/** !!!Copied from `dotty.tools.backend.jvm.ClassfileWriters` but no `PostProcessorFrontendAccess` needed.
43
44
* this should probably be changed to wrap that class instead.
@@ -56,6 +57,11 @@ object FileWriters {
56
57
def warning (message : Context ?=> Message , position : SourcePosition ): Unit
57
58
def log (message : String ): Unit
58
59
60
+ final def toBuffered : Option [BufferingReporter ] = this match
61
+ case buffered : BufferingReporter =>
62
+ if buffered.hasReports then Some (buffered) else None
63
+ case _ : EagerReporter => None
64
+
59
65
def error (message : Context ?=> Message ): Unit = error(message, NoSourcePosition )
60
66
def warning (message : Context ?=> Message ): Unit = warning(message, NoSourcePosition )
61
67
final def exception (reason : Context ?=> Message , throwable : Throwable ): Unit =
@@ -94,28 +100,18 @@ object FileWriters {
94
100
95
101
/** Atomically record that an error occurred */
96
102
private def recordError (): Unit =
97
- while
98
- val old = _hasErrors.get
99
- ! old && ! _hasErrors.compareAndSet(old, true )
100
- do ()
103
+ _hasErrors.set(true )
101
104
102
105
/** Atomically add a report to the log */
103
106
private def recordReport (report : Report ): Unit =
104
- while
105
- val old = _bufferedReports.get
106
- ! _bufferedReports.compareAndSet(old, report :: old)
107
- do ()
107
+ _bufferedReports.getAndUpdate(report :: _)
108
108
109
- /** atomically extract and clear the buffered reports */
109
+ /** atomically extract and clear the buffered reports, must only be called at a synchonization point. */
110
110
private def resetReports (): List [Report ] =
111
- while
112
- val old = _bufferedReports.get
113
- if _bufferedReports.compareAndSet(old, Nil ) then
114
- return old
115
- else
116
- true
117
- do ()
118
- throw new AssertionError (" Unreachable" )
111
+ val curr = _bufferedReports.get()
112
+ if curr.nonEmpty && ! _bufferedReports.compareAndSet(curr, Nil ) then
113
+ throw ConcurrentModificationException (" concurrent modification of buffered reports" )
114
+ else curr
119
115
120
116
def hasErrors : Boolean = _hasErrors.get()
121
117
def hasReports : Boolean = _bufferedReports.get().nonEmpty
0 commit comments