Skip to content

Commit a9b046f

Browse files
Updates Build (#18)
1 parent f76c278 commit a9b046f

File tree

14 files changed

+367
-309
lines changed

14 files changed

+367
-309
lines changed

.scalafmt.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=2.4.2
1+
version=2.6.1
22
style = defaultWithAlign
33
maxColumn = 100
44

build.sbt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ addCommandAlias("ci-publish", ";github; ci-release")
1414
lazy val V = new {
1515
val cats: String = "2.1.1"
1616
val collectioncompat: String = "2.1.6"
17-
val github4s: String = "0.24.0"
18-
val http4s: String = "0.21.4"
17+
val github4s: String = "0.24.1"
18+
val http4s: String = "0.21.6"
1919
val runtime: String = "0.6.0"
20-
val scala: String = "2.13.2"
20+
val scala: String = "2.13.3"
2121
val scala212: String = "2.12.11"
2222
val scalacheck: String = "1.14.3"
2323
val scalacheckShapeless: String = "1.2.5"
2424
val scalamacros: String = "2.1.1"
2525
val scalariform: String = "0.2.10"
26-
val scalatest: String = "3.1.2"
26+
val scalatest: String = "3.2.0"
2727
}
2828

2929
lazy val definitions = (project in file("definitions"))
@@ -46,14 +46,14 @@ lazy val compiler = (project in file("compiler"))
4646
scalacOptions -= "-Xfatal-warnings",
4747
libraryDependencies ++= Seq(
4848
"org.scala-exercises" %% "runtime" % V.runtime,
49-
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
49+
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
5050
"org.scala-lang.modules" %% "scala-collection-compat" % V.collectioncompat,
51-
"org.typelevel" %% "cats-core" % V.cats % Compile,
51+
"org.typelevel" %% "cats-core" % V.cats % Compile,
5252
"org.http4s" %% "http4s-blaze-client" % V.http4s,
5353
"org.http4s" %% "http4s-circe" % V.http4s,
5454
"com.47deg" %% "github4s" % V.github4s,
5555
"org.scalariform" %% "scalariform" % V.scalariform,
56-
"org.typelevel" %% "cats-laws" % V.cats % Test,
56+
"org.typelevel" %% "cats-laws" % V.cats % Test,
5757
"org.scalatest" %% "scalatest" % V.scalatest % Test
5858
)
5959
)

compiler/src/main/scala/org/scalaexercises/exercises/compiler/Compiler.scala

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ case class Compiler() {
128128
symbol <- internal.instanceToClassSymbol(library)
129129
symbolPath = internal.symbolToPath(symbol)
130130
comment <- (internal
131-
.resolveComment(symbolPath)
132-
.flatMap(Comments.parseAndRender[Mode.Library]))
131+
.resolveComment(symbolPath)
132+
.flatMap(Comments.parseAndRender[Mode.Library]))
133133
.leftMap(enhanceDocError(symbolPath))
134134
sections <- checkEmptySectionList(symbol, library).flatMap {
135135
_.sections
@@ -190,23 +190,26 @@ case class Compiler() {
190190
val symbolPath = internal.symbolToPath(symbol)
191191
val filePath = extracted.symbolPaths.get(symbol.toString).filterNot(_.isEmpty)
192192
for {
193-
comment <- internal
194-
.resolveComment(symbolPath)
195-
.flatMap(Comments.parseAndRender[Mode.Section])
196-
.leftMap(enhanceDocError(symbolPath))
197-
198-
contributions = (if (fetchContributors) filePath else None).fold(
199-
List.empty[ContributionInfo]
200-
)(path => fetchContributions(library.owner, library.repository, path))
201-
202-
exercises <- symbol.toType.decls.toList
203-
.filter(symbol =>
204-
symbol.isPublic && !symbol.isSynthetic &&
205-
symbol.name != termNames.CONSTRUCTOR && symbol.isMethod
206-
)
207-
.map(_.asMethod)
208-
.filterNot(_.isGetter)
209-
.traverse(maybeMakeExerciseInfo)
193+
comment <-
194+
internal
195+
.resolveComment(symbolPath)
196+
.flatMap(Comments.parseAndRender[Mode.Section])
197+
.leftMap(enhanceDocError(symbolPath))
198+
199+
contributions =
200+
(if (fetchContributors) filePath else None).fold(
201+
List.empty[ContributionInfo]
202+
)(path => fetchContributions(library.owner, library.repository, path))
203+
204+
exercises <-
205+
symbol.toType.decls.toList
206+
.filter(symbol =>
207+
symbol.isPublic && !symbol.isSynthetic &&
208+
symbol.name != termNames.CONSTRUCTOR && symbol.isMethod
209+
)
210+
.map(_.asMethod)
211+
.filterNot(_.isGetter)
212+
.traverse(maybeMakeExerciseInfo)
210213
} yield SectionInfo(
211214
symbol = symbol,
212215
comment = comment,
@@ -222,10 +225,11 @@ case class Compiler() {
222225
val symbolPath = internal.symbolToPath(symbol)
223226
val pkgName = symbolPath.headOption.fold("defaultPkg")(identity)
224227
for {
225-
comment <- internal
226-
.resolveComment(symbolPath)
227-
.flatMap(Comments.parseAndRender[Mode.Exercise])
228-
.leftMap(enhanceDocError(symbolPath))
228+
comment <-
229+
internal
230+
.resolveComment(symbolPath)
231+
.flatMap(Comments.parseAndRender[Mode.Exercise])
232+
.leftMap(enhanceDocError(symbolPath))
229233
method <- internal.resolveMethod(symbolPath)
230234
} yield ExerciseInfo(
231235
symbol = symbol,
@@ -362,10 +366,11 @@ case class Compiler() {
362366
process(symbol).reverse
363367
}
364368

365-
private[compiler] def unapplyRawName(name: Name): String = name match {
366-
case TermName(value) => value
367-
case TypeName(value) => value
368-
}
369+
private[compiler] def unapplyRawName(name: Name): String =
370+
name match {
371+
case TermName(value) => value
372+
case TypeName(value) => value
373+
}
369374

370375
private lazy val EMPTY_PACKAGE_NAME_STRING = unapplyRawName(termNames.EMPTY_PACKAGE_NAME)
371376
private lazy val ROOTPKG_STRING = unapplyRawName(termNames.ROOTPKG)

compiler/src/main/scala/org/scalaexercises/exercises/compiler/MethodBodyReader.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import scala.tools.nsc.Global
2323

2424
object MethodBodyReader {
2525

26-
/** Attempts to read (and clean) a method body.
26+
/**
27+
* Attempts to read (and clean) a method body.
2728
*/
2829
def read[G <: Global](g: G)(tree: g.Tree): String = {
2930
val (bodyStart, bodyEnd) = bodyRange(g)(tree)
@@ -36,7 +37,8 @@ object MethodBodyReader {
3637
.mkString("\n")
3738
}
3839

39-
/** Finds the text range for the body of the method.
40+
/**
41+
* Finds the text range for the body of the method.
4042
* This should:
4143
* - ignore the wrapping block brackets
4244
* - include any leading whitespace before the first expression
@@ -76,7 +78,8 @@ object MethodBodyReader {
7678
else endOffset
7779
}
7880

79-
/** This attempts to find all the individual lines in a method body
81+
/**
82+
* This attempts to find all the individual lines in a method body
8083
* while also counting the amount of common prefix whitespace on each line.
8184
*/
8285
private def normalizedLineRanges(str: Array[Char], start: Int, end: Int): List[(Int, Int)] = {

compiler/src/main/scala/org/scalaexercises/exercises/compiler/SourceTextExtraction.scala

Lines changed: 96 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ class SourceTextExtraction {
6969
val compilationUnits = run.units.toList // `units` is only only iterable once!
7070
val extractions = compilationUnits.map(_.body).map(boundExtractRaw)
7171

72-
def nameToString(name: Name) = name match {
73-
case TermName(value) => value
74-
case TypeName(value) => value
75-
}
72+
def nameToString(name: Name) =
73+
name match {
74+
case TermName(value) => value
75+
case TypeName(value) => value
76+
}
7677

7778
def expandPath[T](kv: (List[global.Name], T)): (List[String], T) =
7879
(kv._1.map(nameToString), kv._2)
@@ -116,7 +117,8 @@ class SourceTextExtraction {
116117

117118
}
118119

119-
/** Utility to find doc exercise-worthy comments and source code blobs
120+
/**
121+
* Utility to find doc exercise-worthy comments and source code blobs
120122
* in a tree.
121123
*/
122124
object SourceTextExtraction {
@@ -132,7 +134,8 @@ object SourceTextExtraction {
132134
def extractRaw[G <: Global](g: G)(rootTree: g.Tree): RawAcc[g.type] = {
133135
import g._
134136

135-
/** Define generic accumulating traversal that visits all the nodes of
137+
/**
138+
* Define generic accumulating traversal that visits all the nodes of
136139
* interest.
137140
*/
138141
def traverse[A](
@@ -145,75 +148,86 @@ object SourceTextExtraction {
145148

146149
// a nested function so that we don't have to include visitDocComment and
147150
// visitMethodExpr as trailing params on each recursive call
148-
@tailrec def traversal(trees: List[(Path[g.type], Int, Tree)], acc: A): A = trees match {
149-
case Nil => acc
150-
case (path, _, tree) :: rs =>
151-
tree match {
152-
153-
case DocDef(comment, moduleDef @ ModuleDef(_, _, impl)) =>
154-
val nextPath = moduleDef.name :: path
155-
traversal(
156-
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
157-
visitDocComment(nextPath.reverse, comment, acc)
158-
)
159-
160-
// TODO: is this needed?
161-
case DocDef(comment, classDef @ ClassDef(_, _, Nil, impl)) =>
162-
val nextPath = classDef.name :: path
163-
traversal(
164-
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
165-
visitDocComment(nextPath.reverse, comment, acc)
166-
)
167-
168-
case DocDef(comment, q"def $tname(...$_): $_ = $expr") =>
169-
val nextPath = tname :: path
170-
val nextPathReversed = nextPath.reverse
171-
traversal(
172-
rs,
173-
visitMethodExpr(
174-
nextPathReversed,
175-
expr,
176-
visitDocComment(nextPathReversed, comment, acc)
151+
@tailrec def traversal(trees: List[(Path[g.type], Int, Tree)], acc: A): A =
152+
trees match {
153+
case Nil => acc
154+
case (path, _, tree) :: rs =>
155+
tree match {
156+
157+
case DocDef(comment, moduleDef @ ModuleDef(_, _, impl)) =>
158+
val nextPath = moduleDef.name :: path
159+
traversal(
160+
impl.body.zipWithIndex.map {
161+
case (body, index) => (nextPath, index, body)
162+
} ::: rs,
163+
visitDocComment(nextPath.reverse, comment, acc)
177164
)
178-
)
179-
180-
case moduleDef @ ModuleDef(_, _, impl) =>
181-
val nextPath = moduleDef.name :: path
182-
traversal(
183-
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
184-
acc
185-
)
186-
187-
// TODO: is this needed?
188-
case classDef @ ClassDef(_, _, Nil, impl) =>
189-
val nextPath = classDef.name :: path
190-
traversal(
191-
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
192-
acc
193-
)
194-
195-
case q"package $ref { ..$topstats }" =>
196-
val nextPath =
197-
if (ref.name == termNames.EMPTY_PACKAGE_NAME) path
198-
else TermName(ref.toString) :: path
199-
traversal(
200-
topstats.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
201-
acc
202-
)
203-
204-
case imp: g.Import =>
205-
traversal(
206-
rs,
207-
visitImport(path.reverse, imp, acc)
208-
)
209-
210-
case _ =>
211-
traversal(
212-
rs,
213-
acc
214-
)
215-
}
216-
}
165+
166+
// TODO: is this needed?
167+
case DocDef(comment, classDef @ ClassDef(_, _, Nil, impl)) =>
168+
val nextPath = classDef.name :: path
169+
traversal(
170+
impl.body.zipWithIndex.map {
171+
case (body, index) => (nextPath, index, body)
172+
} ::: rs,
173+
visitDocComment(nextPath.reverse, comment, acc)
174+
)
175+
176+
case DocDef(comment, q"def $tname(...$_): $_ = $expr") =>
177+
val nextPath = tname :: path
178+
val nextPathReversed = nextPath.reverse
179+
traversal(
180+
rs,
181+
visitMethodExpr(
182+
nextPathReversed,
183+
expr,
184+
visitDocComment(nextPathReversed, comment, acc)
185+
)
186+
)
187+
188+
case moduleDef @ ModuleDef(_, _, impl) =>
189+
val nextPath = moduleDef.name :: path
190+
traversal(
191+
impl.body.zipWithIndex.map {
192+
case (body, index) => (nextPath, index, body)
193+
} ::: rs,
194+
acc
195+
)
196+
197+
// TODO: is this needed?
198+
case classDef @ ClassDef(_, _, Nil, impl) =>
199+
val nextPath = classDef.name :: path
200+
traversal(
201+
impl.body.zipWithIndex.map {
202+
case (body, index) => (nextPath, index, body)
203+
} ::: rs,
204+
acc
205+
)
206+
207+
case q"package $ref { ..$topstats }" =>
208+
val nextPath =
209+
if (ref.name == termNames.EMPTY_PACKAGE_NAME) path
210+
else TermName(ref.toString) :: path
211+
traversal(
212+
topstats.zipWithIndex.map {
213+
case (body, index) => (nextPath, index, body)
214+
} ::: rs,
215+
acc
216+
)
217+
218+
case imp: g.Import =>
219+
traversal(
220+
rs,
221+
visitImport(path.reverse, imp, acc)
222+
)
223+
224+
case _ =>
225+
traversal(
226+
rs,
227+
acc
228+
)
229+
}
230+
}
217231
// go
218232
traversal(trees0.map(kv => (kv._1, 0, kv._2)), acc0)
219233
}
@@ -245,7 +259,8 @@ object SourceTextExtraction {
245259

246260
}
247261

248-
/** Scala compiler global needed for extracting doc comments. This uses the
262+
/**
263+
* Scala compiler global needed for extracting doc comments. This uses the
249264
* ScaladocSyntaxAnalyzer, which keeps DocDefs in the parsed AST.
250265
*
251266
* It would be ideal to do this as a compiler plugin. Unfortunately there
@@ -272,9 +287,10 @@ class DocExtractionGlobal(settings: Settings = DocExtractionGlobal.defaultSettin
272287
}
273288

274289
object DocExtractionGlobal {
275-
def defaultSettings = new Settings {
276-
embeddedDefaults[DocExtractionGlobal.type]
277-
// this flag is crucial for method body extraction
278-
Yrangepos.value = true
279-
}
290+
def defaultSettings =
291+
new Settings {
292+
embeddedDefaults[DocExtractionGlobal.type]
293+
// this flag is crucial for method body extraction
294+
Yrangepos.value = true
295+
}
280296
}

0 commit comments

Comments
 (0)