-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #142
- Loading branch information
Showing
15 changed files
with
194 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
ducktape/src/main/scala/io/github/arainko/ducktape/internal/ConfigWarning.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package io.github.arainko.ducktape.internal | ||
|
||
import scala.quoted.Quotes | ||
|
||
private[ducktape] final case class ConfigWarning(span: Span, overriderSpan: Span, path: Path) { | ||
def render(using Quotes): String = { | ||
val pos = overriderSpan.withEnd(_ - 1).toPosition | ||
val codeAndLocation = s"${pos.sourceCode.mkString} @ ${pos.sourceFile.name}:${pos.endLine + 1}:${pos.endColumn + 1}" | ||
|
||
s"Config for ${path.render} is being overriden by $codeAndLocation" | ||
} | ||
} | ||
|
||
private[ducktape] object ConfigWarning { | ||
def renderAll(warnings: List[ConfigWarning])(using Quotes) = | ||
warnings | ||
.groupBy(_.overriderSpan) | ||
.map { (overriderSpan, warnings) => | ||
val pos = overriderSpan.withEnd(_ - 1).toPosition | ||
val codeAndLocation = s"${pos.sourceCode.mkString} @ ${pos.sourceFile.name}:${pos.endLine + 1}:${pos.endColumn + 1}" | ||
|
||
if warnings.size > 1 then s"""Configs for: | ||
|${warnings.map(warning => " * " + warning.path.render).mkString(System.lineSeparator)} | ||
|are being overriden by $codeAndLocation""".stripMargin | ||
else warnings.map(_.render).mkString | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 11 additions & 30 deletions
41
ducktape/src/main/scala/io/github/arainko/ducktape/internal/PlanRefiner.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,18 @@ | ||
package io.github.arainko.ducktape.internal | ||
|
||
import scala.annotation.tailrec | ||
|
||
private[ducktape] object PlanRefiner { | ||
def run[F <: Fallible](plan: Plan[Plan.Error, F]): Either[NonEmptyList[Plan.Error], Plan[Nothing, F]] = { | ||
|
||
@tailrec | ||
def recurse(stack: List[Plan[Plan.Error, F]], errors: List[Plan.Error]): List[Plan.Error] = | ||
stack match { | ||
case head :: next => | ||
head match { | ||
case plan: Plan.Upcast => recurse(next, errors) | ||
case Plan.BetweenProducts(_, _, fieldPlans) => | ||
recurse(fieldPlans.values.toList ::: next, errors) | ||
case Plan.BetweenCoproducts(_, _, casePlans) => | ||
recurse(casePlans.toList ::: next, errors) | ||
case Plan.BetweenProductFunction(_, _, argPlans) => | ||
recurse(argPlans.values.toList ::: next, errors) | ||
case Plan.BetweenOptions(_, _, plan) => recurse(plan :: next, errors) | ||
case Plan.BetweenNonOptionOption(_, _, plan) => recurse(plan :: next, errors) | ||
case Plan.BetweenCollections(_, _, plan) => recurse(plan :: next, errors) | ||
case plan: Plan.BetweenSingletons => recurse(next, errors) | ||
case plan: Plan.UserDefined[F] => recurse(next, errors) | ||
case plan: Plan.Derived[F] => recurse(next, errors) | ||
case plan: Plan.Configured[F] => recurse(next, errors) | ||
case plan: Plan.BetweenWrappedUnwrapped => recurse(next, errors) | ||
case plan: Plan.BetweenUnwrappedWrapped => recurse(next, errors) | ||
case error: Plan.Error => recurse(next, error :: errors) | ||
} | ||
case Nil => errors | ||
private object ErrorCollector extends PlanTraverser[List[Plan.Error]] { | ||
protected def foldOver(plan: Plan[Plan.Error, Fallible], accumulator: List[Plan.Error]): List[Plan.Error] = | ||
plan match { | ||
case error: Plan.Error => error :: accumulator | ||
case other => accumulator | ||
} | ||
val errors = recurse(plan :: Nil, Nil) | ||
} | ||
|
||
def run[F <: Fallible](plan: Plan[Plan.Error, F]): Either[NonEmptyList[Plan.Error], Plan[Nothing, F]] = { | ||
// if no errors were accumulated that means there are no Plan.Error nodes which means we operate on a Plan[Nothing] | ||
NonEmptyList.fromList(errors).toLeft(plan.asInstanceOf[Plan[Nothing, F]]) | ||
NonEmptyList | ||
.fromList(ErrorCollector.run(plan, Nil)) | ||
.toLeft(plan.asInstanceOf[Plan[Nothing, F]]) | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
ducktape/src/main/scala/io/github/arainko/ducktape/internal/PlanTraverser.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package io.github.arainko.ducktape.internal | ||
|
||
import scala.annotation.tailrec | ||
|
||
private[ducktape] trait PlanTraverser[A] { | ||
final def run(plan: Plan[Plan.Error, Fallible], initial: A): A = { | ||
@tailrec | ||
def recurse(stack: List[Plan[Plan.Error, Fallible]], accumulator: A): A = | ||
stack match { | ||
case head :: next => | ||
head match { | ||
case plan: Plan.Upcast => | ||
recurse(next, foldOver(plan, accumulator)) | ||
case plan @ Plan.BetweenProducts(_, _, fieldPlans) => | ||
recurse(fieldPlans.values.toList ::: next, foldOver(plan, accumulator)) | ||
case plan @ Plan.BetweenCoproducts(_, _, casePlans) => | ||
recurse(casePlans.toList ::: next, foldOver(plan, accumulator)) | ||
case plan @ Plan.BetweenProductFunction(_, _, argPlans) => | ||
recurse(argPlans.values.toList ::: next, foldOver(plan, accumulator)) | ||
case p @ Plan.BetweenOptions(_, _, plan) => | ||
recurse(plan :: next, foldOver(p, accumulator)) | ||
case p @ Plan.BetweenNonOptionOption(_, _, plan) => | ||
recurse(plan :: next, foldOver(p, accumulator)) | ||
case p @ Plan.BetweenCollections(_, _, plan) => | ||
recurse(plan :: next, foldOver(p, accumulator)) | ||
case plan: Plan.BetweenSingletons => | ||
recurse(next, foldOver(plan, accumulator)) | ||
case plan: Plan.UserDefined[Fallible] => | ||
recurse(next, foldOver(plan, accumulator)) | ||
case plan: Plan.Derived[Fallible] => | ||
recurse(next, foldOver(plan, accumulator)) | ||
case plan: Plan.Configured[Fallible] => | ||
recurse(next, foldOver(plan, accumulator)) | ||
case plan: Plan.BetweenWrappedUnwrapped => | ||
recurse(next, foldOver(plan, accumulator)) | ||
case plan: Plan.BetweenUnwrappedWrapped => | ||
recurse(next, foldOver(plan, accumulator)) | ||
case plan: Plan.Error => | ||
recurse(next, foldOver(plan, accumulator)) | ||
} | ||
case Nil => accumulator | ||
} | ||
|
||
recurse(plan :: Nil, initial) | ||
} | ||
|
||
protected def foldOver(plan: Plan[Plan.Error, Fallible], accumulator: A): A | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.