@@ -38,6 +38,7 @@ import dotty.tools.backend.jvm.PostProcessorFrontendAccess.BackendReporting
3838import scala .annotation .constructorOnly
3939import java .util .concurrent .atomic .AtomicReference
4040import java .util .concurrent .atomic .AtomicBoolean
41+ import java .util .ConcurrentModificationException
4142
4243/** !!!Copied from `dotty.tools.backend.jvm.ClassfileWriters` but no `PostProcessorFrontendAccess` needed.
4344 * this should probably be changed to wrap that class instead.
@@ -56,6 +57,11 @@ object FileWriters {
5657 def warning (message : Context ?=> Message , position : SourcePosition ): Unit
5758 def log (message : String ): Unit
5859
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+
5965 def error (message : Context ?=> Message ): Unit = error(message, NoSourcePosition )
6066 def warning (message : Context ?=> Message ): Unit = warning(message, NoSourcePosition )
6167 final def exception (reason : Context ?=> Message , throwable : Throwable ): Unit =
@@ -94,28 +100,18 @@ object FileWriters {
94100
95101 /** Atomically record that an error occurred */
96102 private def recordError (): Unit =
97- while
98- val old = _hasErrors.get
99- ! old && ! _hasErrors.compareAndSet(old, true )
100- do ()
103+ _hasErrors.set(true )
101104
102105 /** Atomically add a report to the log */
103106 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 :: _)
108108
109- /** atomically extract and clear the buffered reports */
109+ /** atomically extract and clear the buffered reports, must only be called at a synchonization point. */
110110 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
119115
120116 def hasErrors : Boolean = _hasErrors.get()
121117 def hasReports : Boolean = _bufferedReports.get().nonEmpty
0 commit comments