@@ -18,6 +18,7 @@ import util.concurrent.{Executor, Future}
18
18
import compiletime .uninitialized
19
19
import java .nio .file .Files
20
20
import scala .language .unsafeNulls
21
+ import scala .util .control .NonFatal
21
22
22
23
object Pickler {
23
24
val name : String = " pickler"
@@ -40,7 +41,7 @@ class Pickler extends Phase {
40
41
41
42
// No need to repickle trees coming from TASTY
42
43
override def isRunnable (using Context ): Boolean =
43
- super .isRunnable && ! ctx.settings.fromTasty.value
44
+ super .isRunnable && ! ctx.settings.fromTasty.value && (ctx.isBestEffort || ! ctx.usesBestEffortTasty)
44
45
45
46
private def output (name : String , msg : String ) = {
46
47
val s = new PrintStream (name)
@@ -75,75 +76,78 @@ class Pickler extends Phase {
75
76
private val executor = Executor [Array [Byte ]]()
76
77
77
78
private def useExecutor (using Context ) =
78
- Pickler .ParallelPickling && ! ctx.settings.YtestPickler .value
79
+ Pickler .ParallelPickling && ! ctx.settings.YtestPickler .value && ! ctx.isBestEffort
79
80
80
81
override def run (using Context ): Unit = {
81
82
val unit = ctx.compilationUnit
82
83
val isBestEffort = ctx.reporter.errorsReported || ctx.usesBestEffortTasty
83
84
pickling.println(i " unpickling in run ${ctx.runId}" )
84
-
85
- for
86
- cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree))
87
- tree <- sliceTopLevel(unit.tpdTree, cls)
88
- do
89
- if ctx.settings.YtestPickler .value then beforePickling(cls) = tree.show
90
-
91
- val pickler = new TastyPickler (cls)
92
- val treePkl = new TreePickler (pickler)
93
- treePkl.pickle(tree :: Nil )
94
- Profile .current.recordTasty(treePkl.buf.length)
95
-
96
- val positionWarnings = new mutable.ListBuffer [Message ]()
97
- def reportPositionWarnings () = positionWarnings.foreach(report.warning(_))
98
-
99
- def computePickled (): Array [Byte ] = inContext(ctx.fresh) {
100
- serialized.run { scratch =>
101
- treePkl.compactify(scratch)
102
- if tree.span.exists then
103
- val reference = ctx.settings.sourceroot.value
104
- PositionPickler .picklePositions(
105
- pickler, treePkl.buf.addrOfTree, treePkl.treeAnnots, reference,
106
- unit.source, tree :: Nil , positionWarnings,
107
- scratch.positionBuffer, scratch.pickledIndices)
108
-
109
- if ! ctx.settings.YdropComments .value then
110
- CommentPickler .pickleComments(
111
- pickler, treePkl.buf.addrOfTree, treePkl.docString, tree,
112
- scratch.commentBuffer)
113
-
114
- val pickled = pickler.assembleParts(isBestEffort)
115
-
116
- def rawBytes = // not needed right now, but useful to print raw format.
117
- pickled.iterator.grouped(10 ).toList.zipWithIndex.map {
118
- case (row, i) => s " ${i}0: ${row.mkString(" " )}"
119
- }
120
-
121
- // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
122
- if pickling ne noPrinter then
123
- println(i " **** pickled info of $cls" )
124
- println(TastyPrinter .showContents(pickled, ctx.settings.color.value == " never" ))
125
- pickled
85
+ try
86
+ for
87
+ cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree))
88
+ tree <- sliceTopLevel(unit.tpdTree, cls)
89
+ do
90
+ if ctx.settings.YtestPickler .value then beforePickling(cls) = tree.show
91
+
92
+ val pickler = new TastyPickler (cls)
93
+ val treePkl = new TreePickler (pickler)
94
+ treePkl.pickle(tree :: Nil )
95
+ Profile .current.recordTasty(treePkl.buf.length)
96
+
97
+ val positionWarnings = new mutable.ListBuffer [Message ]()
98
+ def reportPositionWarnings () = positionWarnings.foreach(report.warning(_))
99
+
100
+ def computePickled (): Array [Byte ] = inContext(ctx.fresh) {
101
+ serialized.run { scratch =>
102
+ treePkl.compactify(scratch)
103
+ if tree.span.exists then
104
+ val reference = ctx.settings.sourceroot.value
105
+ PositionPickler .picklePositions(
106
+ pickler, treePkl.buf.addrOfTree, treePkl.treeAnnots, reference,
107
+ unit.source, tree :: Nil , positionWarnings,
108
+ scratch.positionBuffer, scratch.pickledIndices)
109
+
110
+ if ! ctx.settings.YdropComments .value then
111
+ CommentPickler .pickleComments(
112
+ pickler, treePkl.buf.addrOfTree, treePkl.docString, tree,
113
+ scratch.commentBuffer)
114
+
115
+ val pickled = pickler.assembleParts(isBestEffort)
116
+
117
+ def rawBytes = // not needed right now, but useful to print raw format.
118
+ pickled.iterator.grouped(10 ).toList.zipWithIndex.map {
119
+ case (row, i) => s " ${i}0: ${row.mkString(" " )}"
120
+ }
121
+
122
+ // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
123
+ if pickling ne noPrinter then
124
+ println(i " **** pickled info of $cls" )
125
+ println(TastyPrinter .showContents(pickled, ctx.settings.color.value == " never" ))
126
+ pickled
127
+ }
126
128
}
127
- }
128
129
129
- /** A function that returns the pickled bytes. Depending on `Pickler.ParallelPickling`
130
- * either computes the pickled data in a future or eagerly before constructing the
131
- * function value.
132
- */
133
- val demandPickled : () => Array [Byte ] =
134
- if useExecutor then
135
- val futurePickled = executor.schedule(computePickled)
136
- () =>
137
- try futurePickled.force.get
138
- finally reportPositionWarnings()
139
- else
140
- val pickled = computePickled()
141
- reportPositionWarnings()
142
- if ctx.settings.YtestPickler .value then pickledBytes(cls) = pickled
143
- () => pickled
144
-
145
- unit.pickled += (cls -> demandPickled)
146
- end for
130
+ /** A function that returns the pickled bytes. Depending on `Pickler.ParallelPickling`
131
+ * either computes the pickled data in a future or eagerly before constructing the
132
+ * function value.
133
+ */
134
+ val demandPickled : () => Array [Byte ] =
135
+ if useExecutor then
136
+ val futurePickled = executor.schedule(computePickled)
137
+ () =>
138
+ try futurePickled.force.get
139
+ finally reportPositionWarnings()
140
+ else
141
+ val pickled = computePickled()
142
+ reportPositionWarnings()
143
+ if ctx.settings.YtestPickler .value then pickledBytes(cls) = pickled
144
+ () => pickled
145
+
146
+ unit.pickled += (cls -> demandPickled)
147
+ end for
148
+ catch
149
+ case NonFatal (ex) =>
150
+ report.bestEffortError(ex, " Some best-effort tasty files will not be generated." )
147
151
}
148
152
149
153
override def runOn (units : List [CompilationUnit ])(using Context ): List [CompilationUnit ] = {
@@ -168,7 +172,7 @@ class Pickler extends Phase {
168
172
.resolve(" META-INF" )
169
173
.resolve(" best-effort" )
170
174
Files .createDirectories(outpath)
171
- BestEffortTastyWriter .write(outpath.nn, units )
175
+ BestEffortTastyWriter .write(outpath.nn, result )
172
176
result
173
177
}
174
178
0 commit comments