Skip to content

Commit

Permalink
Updates Build (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
juanpedromoreno authored Jun 29, 2020
1 parent f76c278 commit a9b046f
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 309 deletions.
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=2.4.2
version=2.6.1
style = defaultWithAlign
maxColumn = 100

Expand Down
14 changes: 7 additions & 7 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ addCommandAlias("ci-publish", ";github; ci-release")
lazy val V = new {
val cats: String = "2.1.1"
val collectioncompat: String = "2.1.6"
val github4s: String = "0.24.0"
val http4s: String = "0.21.4"
val github4s: String = "0.24.1"
val http4s: String = "0.21.6"
val runtime: String = "0.6.0"
val scala: String = "2.13.2"
val scala: String = "2.13.3"
val scala212: String = "2.12.11"
val scalacheck: String = "1.14.3"
val scalacheckShapeless: String = "1.2.5"
val scalamacros: String = "2.1.1"
val scalariform: String = "0.2.10"
val scalatest: String = "3.1.2"
val scalatest: String = "3.2.0"
}

lazy val definitions = (project in file("definitions"))
Expand All @@ -46,14 +46,14 @@ lazy val compiler = (project in file("compiler"))
scalacOptions -= "-Xfatal-warnings",
libraryDependencies ++= Seq(
"org.scala-exercises" %% "runtime" % V.runtime,
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
"org.scala-lang.modules" %% "scala-collection-compat" % V.collectioncompat,
"org.typelevel" %% "cats-core" % V.cats % Compile,
"org.typelevel" %% "cats-core" % V.cats % Compile,
"org.http4s" %% "http4s-blaze-client" % V.http4s,
"org.http4s" %% "http4s-circe" % V.http4s,
"com.47deg" %% "github4s" % V.github4s,
"org.scalariform" %% "scalariform" % V.scalariform,
"org.typelevel" %% "cats-laws" % V.cats % Test,
"org.typelevel" %% "cats-laws" % V.cats % Test,
"org.scalatest" %% "scalatest" % V.scalatest % Test
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ case class Compiler() {
symbol <- internal.instanceToClassSymbol(library)
symbolPath = internal.symbolToPath(symbol)
comment <- (internal
.resolveComment(symbolPath)
.flatMap(Comments.parseAndRender[Mode.Library]))
.resolveComment(symbolPath)
.flatMap(Comments.parseAndRender[Mode.Library]))
.leftMap(enhanceDocError(symbolPath))
sections <- checkEmptySectionList(symbol, library).flatMap {
_.sections
Expand Down Expand Up @@ -190,23 +190,26 @@ case class Compiler() {
val symbolPath = internal.symbolToPath(symbol)
val filePath = extracted.symbolPaths.get(symbol.toString).filterNot(_.isEmpty)
for {
comment <- internal
.resolveComment(symbolPath)
.flatMap(Comments.parseAndRender[Mode.Section])
.leftMap(enhanceDocError(symbolPath))

contributions = (if (fetchContributors) filePath else None).fold(
List.empty[ContributionInfo]
)(path => fetchContributions(library.owner, library.repository, path))

exercises <- symbol.toType.decls.toList
.filter(symbol =>
symbol.isPublic && !symbol.isSynthetic &&
symbol.name != termNames.CONSTRUCTOR && symbol.isMethod
)
.map(_.asMethod)
.filterNot(_.isGetter)
.traverse(maybeMakeExerciseInfo)
comment <-
internal
.resolveComment(symbolPath)
.flatMap(Comments.parseAndRender[Mode.Section])
.leftMap(enhanceDocError(symbolPath))

contributions =
(if (fetchContributors) filePath else None).fold(
List.empty[ContributionInfo]
)(path => fetchContributions(library.owner, library.repository, path))

exercises <-
symbol.toType.decls.toList
.filter(symbol =>
symbol.isPublic && !symbol.isSynthetic &&
symbol.name != termNames.CONSTRUCTOR && symbol.isMethod
)
.map(_.asMethod)
.filterNot(_.isGetter)
.traverse(maybeMakeExerciseInfo)
} yield SectionInfo(
symbol = symbol,
comment = comment,
Expand All @@ -222,10 +225,11 @@ case class Compiler() {
val symbolPath = internal.symbolToPath(symbol)
val pkgName = symbolPath.headOption.fold("defaultPkg")(identity)
for {
comment <- internal
.resolveComment(symbolPath)
.flatMap(Comments.parseAndRender[Mode.Exercise])
.leftMap(enhanceDocError(symbolPath))
comment <-
internal
.resolveComment(symbolPath)
.flatMap(Comments.parseAndRender[Mode.Exercise])
.leftMap(enhanceDocError(symbolPath))
method <- internal.resolveMethod(symbolPath)
} yield ExerciseInfo(
symbol = symbol,
Expand Down Expand Up @@ -362,10 +366,11 @@ case class Compiler() {
process(symbol).reverse
}

private[compiler] def unapplyRawName(name: Name): String = name match {
case TermName(value) => value
case TypeName(value) => value
}
private[compiler] def unapplyRawName(name: Name): String =
name match {
case TermName(value) => value
case TypeName(value) => value
}

private lazy val EMPTY_PACKAGE_NAME_STRING = unapplyRawName(termNames.EMPTY_PACKAGE_NAME)
private lazy val ROOTPKG_STRING = unapplyRawName(termNames.ROOTPKG)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import scala.tools.nsc.Global

object MethodBodyReader {

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

/** Finds the text range for the body of the method.
/**
* Finds the text range for the body of the method.
* This should:
* - ignore the wrapping block brackets
* - include any leading whitespace before the first expression
Expand Down Expand Up @@ -76,7 +78,8 @@ object MethodBodyReader {
else endOffset
}

/** This attempts to find all the individual lines in a method body
/**
* This attempts to find all the individual lines in a method body
* while also counting the amount of common prefix whitespace on each line.
*/
private def normalizedLineRanges(str: Array[Char], start: Int, end: Int): List[(Int, Int)] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ class SourceTextExtraction {
val compilationUnits = run.units.toList // `units` is only only iterable once!
val extractions = compilationUnits.map(_.body).map(boundExtractRaw)

def nameToString(name: Name) = name match {
case TermName(value) => value
case TypeName(value) => value
}
def nameToString(name: Name) =
name match {
case TermName(value) => value
case TypeName(value) => value
}

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

}

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

/** Define generic accumulating traversal that visits all the nodes of
/**
* Define generic accumulating traversal that visits all the nodes of
* interest.
*/
def traverse[A](
Expand All @@ -145,75 +148,86 @@ object SourceTextExtraction {

// a nested function so that we don't have to include visitDocComment and
// visitMethodExpr as trailing params on each recursive call
@tailrec def traversal(trees: List[(Path[g.type], Int, Tree)], acc: A): A = trees match {
case Nil => acc
case (path, _, tree) :: rs =>
tree match {

case DocDef(comment, moduleDef @ ModuleDef(_, _, impl)) =>
val nextPath = moduleDef.name :: path
traversal(
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
visitDocComment(nextPath.reverse, comment, acc)
)

// TODO: is this needed?
case DocDef(comment, classDef @ ClassDef(_, _, Nil, impl)) =>
val nextPath = classDef.name :: path
traversal(
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
visitDocComment(nextPath.reverse, comment, acc)
)

case DocDef(comment, q"def $tname(...$_): $_ = $expr") =>
val nextPath = tname :: path
val nextPathReversed = nextPath.reverse
traversal(
rs,
visitMethodExpr(
nextPathReversed,
expr,
visitDocComment(nextPathReversed, comment, acc)
@tailrec def traversal(trees: List[(Path[g.type], Int, Tree)], acc: A): A =
trees match {
case Nil => acc
case (path, _, tree) :: rs =>
tree match {

case DocDef(comment, moduleDef @ ModuleDef(_, _, impl)) =>
val nextPath = moduleDef.name :: path
traversal(
impl.body.zipWithIndex.map {
case (body, index) => (nextPath, index, body)
} ::: rs,
visitDocComment(nextPath.reverse, comment, acc)
)
)

case moduleDef @ ModuleDef(_, _, impl) =>
val nextPath = moduleDef.name :: path
traversal(
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
acc
)

// TODO: is this needed?
case classDef @ ClassDef(_, _, Nil, impl) =>
val nextPath = classDef.name :: path
traversal(
impl.body.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
acc
)

case q"package $ref { ..$topstats }" =>
val nextPath =
if (ref.name == termNames.EMPTY_PACKAGE_NAME) path
else TermName(ref.toString) :: path
traversal(
topstats.zipWithIndex.map { case (body, index) => (nextPath, index, body) } ::: rs,
acc
)

case imp: g.Import =>
traversal(
rs,
visitImport(path.reverse, imp, acc)
)

case _ =>
traversal(
rs,
acc
)
}
}

// TODO: is this needed?
case DocDef(comment, classDef @ ClassDef(_, _, Nil, impl)) =>
val nextPath = classDef.name :: path
traversal(
impl.body.zipWithIndex.map {
case (body, index) => (nextPath, index, body)
} ::: rs,
visitDocComment(nextPath.reverse, comment, acc)
)

case DocDef(comment, q"def $tname(...$_): $_ = $expr") =>
val nextPath = tname :: path
val nextPathReversed = nextPath.reverse
traversal(
rs,
visitMethodExpr(
nextPathReversed,
expr,
visitDocComment(nextPathReversed, comment, acc)
)
)

case moduleDef @ ModuleDef(_, _, impl) =>
val nextPath = moduleDef.name :: path
traversal(
impl.body.zipWithIndex.map {
case (body, index) => (nextPath, index, body)
} ::: rs,
acc
)

// TODO: is this needed?
case classDef @ ClassDef(_, _, Nil, impl) =>
val nextPath = classDef.name :: path
traversal(
impl.body.zipWithIndex.map {
case (body, index) => (nextPath, index, body)
} ::: rs,
acc
)

case q"package $ref { ..$topstats }" =>
val nextPath =
if (ref.name == termNames.EMPTY_PACKAGE_NAME) path
else TermName(ref.toString) :: path
traversal(
topstats.zipWithIndex.map {
case (body, index) => (nextPath, index, body)
} ::: rs,
acc
)

case imp: g.Import =>
traversal(
rs,
visitImport(path.reverse, imp, acc)
)

case _ =>
traversal(
rs,
acc
)
}
}
// go
traversal(trees0.map(kv => (kv._1, 0, kv._2)), acc0)
}
Expand Down Expand Up @@ -245,7 +259,8 @@ object SourceTextExtraction {

}

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

object DocExtractionGlobal {
def defaultSettings = new Settings {
embeddedDefaults[DocExtractionGlobal.type]
// this flag is crucial for method body extraction
Yrangepos.value = true
}
def defaultSettings =
new Settings {
embeddedDefaults[DocExtractionGlobal.type]
// this flag is crucial for method body extraction
Yrangepos.value = true
}
}
Loading

0 comments on commit a9b046f

Please sign in to comment.