@@ -13,15 +13,16 @@ import java.net.URLClassLoader
13
13
import java .security .MessageDigest
14
14
import java .util .jar .JarFile
15
15
16
- import cats .effect .{Concurrent , ConcurrentEffect , Timer }
16
+ import cats .effect .syntax .concurrent .catsEffectSyntaxConcurrent
17
+ import cats .effect .{ConcurrentEffect , Timer }
17
18
import cats .implicits ._
18
19
import coursier ._
19
20
import coursier .cache .{ArtifactError , FileCache }
20
21
import coursier .util .Sync
21
22
import org .scalaexercises .evaluator .Eval .CompilerException
23
+ import org .scalaexercises .evaluator .{Dependency => EvaluatorDependency }
22
24
23
25
import scala .concurrent .duration ._
24
- import scala .language .reflectiveCalls
25
26
import scala .reflect .internal .util .{AbstractFileClassLoader , BatchSourceFile , Position }
26
27
import scala .tools .nsc .io .{AbstractFile , VirtualDirectory }
27
28
import scala .tools .nsc .reporters ._
@@ -41,7 +42,7 @@ class Evaluator[F[_]: Sync](timeout: FiniteDuration = 20.seconds)(
41
42
42
43
def remoteToRepository (remote : Remote ): Repository = MavenRepository (remote)
43
44
44
- def dependencyToModule (dependency : Dependency ): coursier. Dependency = {
45
+ def dependencyToModule (dependency : EvaluatorDependency ): Dependency = {
45
46
val exclusions : Set [(Organization , ModuleName )] =
46
47
dependency.exclusions
47
48
.fold(List [(Organization , ModuleName )]())(
@@ -60,7 +61,9 @@ class Evaluator[F[_]: Sync](timeout: FiniteDuration = 20.seconds)(
60
61
61
62
val cache : FileCache [F ] = FileCache [F ].noCredentials
62
63
63
- def resolveArtifacts (remotes : Seq [Remote ], dependencies : Seq [Dependency ]): F [Resolution ] = {
64
+ def resolveArtifacts (
65
+ remotes : Seq [Remote ],
66
+ dependencies : Seq [EvaluatorDependency ]): F [Resolution ] = {
64
67
Resolve [F ](cache)
65
68
.addDependencies(dependencies.map(dependencyToModule): _* )
66
69
.addRepositories(remotes.map(remoteToRepository): _* )
@@ -70,7 +73,7 @@ class Evaluator[F[_]: Sync](timeout: FiniteDuration = 20.seconds)(
70
73
71
74
def fetchArtifacts (
72
75
remotes : Seq [Remote ],
73
- dependencies : Seq [Dependency ]): F [Either [ArtifactError , List [File ]]] =
76
+ dependencies : Seq [EvaluatorDependency ]): F [Either [ArtifactError , List [File ]]] =
74
77
for {
75
78
resolution <- resolveArtifacts(remotes, dependencies)
76
79
gatheredArtifacts <- resolution.artifacts().toList.traverse(cache.file(_).run)
@@ -96,11 +99,12 @@ class Evaluator[F[_]: Sync](timeout: FiniteDuration = 20.seconds)(
96
99
}
97
100
}
98
101
99
- override lazy val compilerMessageHandler : Option [Reporter ] = Some (new AbstractReporter {
100
- override val settings : Settings = compilerSettings
101
- override def displayPrompt () : Unit = ()
102
- override def display (pos : Position , msg : String , severity : this . type # Severity ): Unit =
102
+ override lazy val compilerMessageHandler : Option [Reporter ] = Some (new FilteringReporter {
103
+ override def settings : Settings = compilerSettings
104
+
105
+ override def doReport (pos : Position , msg : String , severity : Severity ): Unit =
103
106
errors += convert((pos, msg, severity.toString))
107
+
104
108
override def reset () = {
105
109
super .reset()
106
110
errors = Map .empty
@@ -117,20 +121,20 @@ class Evaluator[F[_]: Sync](timeout: FiniteDuration = 20.seconds)(
117
121
Console .withOut(outCapture) {
118
122
119
123
val result = for {
120
- _ ← Try (eval.check(code))
121
- result ← Try (eval.execute[T ](code, resetState = true , jars = jars))
124
+ _ <- Try (eval.check(code))
125
+ result <- Try (eval.execute[T ](code, resetState = true , jars = jars))
122
126
} yield result
123
127
124
128
val errors = eval.errors
125
129
126
130
result match {
127
- case scala.util.Success (r) ⇒ EvalSuccess [T ](errors, r, outCapture.toString)
128
- case scala.util.Failure (t) ⇒
131
+ case scala.util.Success (r) => EvalSuccess [T ](errors, r, outCapture.toString)
132
+ case scala.util.Failure (t) =>
129
133
t match {
130
- case e : CompilerException ⇒ CompilationError (errors)
131
- case NonFatal (e) ⇒
134
+ case e : CompilerException => CompilationError (errors)
135
+ case NonFatal (e) =>
132
136
EvalRuntimeError (errors, Option (RuntimeError (e, None )))
133
- case e ⇒ GeneralError (e)
137
+ case e => GeneralError (e)
134
138
}
135
139
}
136
140
}
@@ -139,25 +143,18 @@ class Evaluator[F[_]: Sync](timeout: FiniteDuration = 20.seconds)(
139
143
def eval [T ](
140
144
code : String ,
141
145
remotes : Seq [Remote ] = Nil ,
142
- dependencies : Seq [Dependency ] = Nil
146
+ dependencies : Seq [EvaluatorDependency ] = Nil
143
147
): F [EvalResult [T ]] = {
144
148
for {
145
149
allJars <- fetchArtifacts(remotes, dependencies)
146
150
result <- allJars match {
147
151
case Right (jars) =>
148
- timeoutTo[EvalResult [T ]](F .delay { evaluate(code, jars) }, timeout, Timeout [T ](timeout))
152
+ F .delay[EvalResult [T ]](evaluate(code, jars))
153
+ .timeoutTo(timeout, Timeout [T ](timeout).asInstanceOf [EvalResult [T ]].pure[F ])
149
154
case Left (fileError) => F .pure(UnresolvedDependency [T ](fileError.describe))
150
155
}
151
156
} yield result
152
157
}
153
-
154
- def timeoutTo [A ](fa : F [A ], after : FiniteDuration , fallback : A ): F [A ] = {
155
-
156
- Concurrent [F ].race(fa, T .sleep(after)).flatMap {
157
- case Left (a) => a.pure[F ]
158
- case Right (_) => fallback.pure[F ]
159
- }
160
- }
161
158
}
162
159
163
160
/**
@@ -181,15 +178,15 @@ private class StringCompiler(
181
178
val cache = new scala.collection.mutable.HashMap [String , Class [_]]()
182
179
183
180
trait MessageCollector {
184
- val messages : Seq [List [String ]]
181
+ val messages : scala.collection.mutable. ListBuffer [List [String ]]
185
182
}
186
183
187
- val reporter = messageHandler getOrElse new AbstractReporter with MessageCollector {
184
+ val reporter = messageHandler getOrElse new FilteringReporter with MessageCollector {
188
185
val settings = StringCompiler .this .settings
189
186
val messages = new scala.collection.mutable.ListBuffer [List [String ]]
190
187
191
- def display (pos : Position , message : String , severity : Severity ) = {
192
- severity.count += 1
188
+ def doReport (pos : Position , message : String , severity : Severity ) = {
189
+ increment( severity)
193
190
val severityName = severity match {
194
191
case ERROR => " error: "
195
192
case WARNING => " warning: "
@@ -211,10 +208,6 @@ private class StringCompiler(
211
208
})
212
209
}
213
210
214
- def displayPrompt = {
215
- // no.
216
- }
217
-
218
211
override def reset = {
219
212
super .reset
220
213
messages.clear()
@@ -264,7 +257,7 @@ private class StringCompiler(
264
257
// ...and 1/2 this line:
265
258
compiler.compileSources(sourceFiles)
266
259
267
- if (reporter.hasErrors || reporter.WARNING .count > 0 ) {
260
+ if (reporter.hasErrors || reporter.hasWarnings ) {
268
261
val msgs : List [List [String ]] = reporter match {
269
262
case collector : MessageCollector =>
270
263
collector.messages.toList
0 commit comments