diff --git a/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplTyped.scala b/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplTyped.scala index a323a653e..ffd8ac45f 100644 --- a/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplTyped.scala +++ b/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplTyped.scala @@ -17,7 +17,7 @@ import org.typelevel.scalaccompat.annotation.unused * @since 4.1.0 * @group filters */ -trait FilterConfig[A] { +sealed trait FilterConfig[A] { private [parsley] def filter(p: Parsley[A])(f: A => Boolean): Parsley[A] private [parsley] def mkError(offset: Int, line: Int, col: Int, caretWidth: Int, x: A): DefuncError // $COVERAGE-OFF$ @@ -32,19 +32,19 @@ trait FilterConfig[A] { * @since 4.1.0 * @group filters */ -trait SpecialisedFilterConfig[A] extends FilterConfig[A] +sealed trait SpecialisedFilterConfig[A] extends FilterConfig[A] /** This subtrait of `FilterConfig` specifies that only filters generating ''vanilla'' errors may be used. * @since 4.1.0 * @group filters */ -trait VanillaFilterConfig[A] extends FilterConfig[A] +sealed trait VanillaFilterConfig[A] extends FilterConfig[A] /** This class ensures that the filter will generate ''specialised'' messages for the given failing parse. * @since 4.1.0 * @group filters */ abstract class SpecialisedMessage[A] extends SpecialisedFilterConfig[A] { self => - @deprecated("filters do not have partial amend semantics, so this does nothing", "4.1.0") def this(@unused fullAmend: Boolean) = this() + private def this(@unused fullAmend: Boolean) = this() /** This method produces the messages for the given value. * @since 4.1.0 * @group badchar @@ -83,7 +83,7 @@ abstract class SpecialisedMessage[A] extends SpecialisedFilterConfig[A] { self = * @group filters */ abstract class Unexpected[A] extends VanillaFilterConfig[A] { self => - @deprecated("filters do not have partial amend semantics, so this does nothing", "4.1.0") def this(@unused fullAmend: Boolean) = this() + private def this(@unused fullAmend: Boolean) = this() /** This method produces the unexpected label for the given value. * @since 4.1.0 * @group badchar @@ -121,7 +121,7 @@ abstract class Unexpected[A] extends VanillaFilterConfig[A] { self => * @group filters */ abstract class Because[A] extends VanillaFilterConfig[A] { self => - @deprecated("filters do not have partial amend semantics, so this does nothing", "4.1.0") def this(@unused fullAmend: Boolean) = this() + private def this(@unused fullAmend: Boolean) = this() /** This method produces the reason for the given value. * @since 4.1.0 * @group badchar @@ -159,7 +159,7 @@ abstract class Because[A] extends VanillaFilterConfig[A] { self => * @group filters */ abstract class UnexpectedBecause[A] extends VanillaFilterConfig[A] { self => - @deprecated("filters do not have partial amend semantics, so this does nothing", "4.1.0") def this(@unused fullAmend: Boolean) = this() + private def this(@unused fullAmend: Boolean) = this() /** This method produces the unexpected label for the given value. * @since 4.1.0 * @group badchar diff --git a/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplUntyped.scala b/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplUntyped.scala index fc1782086..6fd90a66b 100644 --- a/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplUntyped.scala +++ b/parsley/shared/src/main/scala/parsley/token/errors/ConfigImplUntyped.scala @@ -20,7 +20,7 @@ private [parsley] sealed trait ConfigImplUntyped { // TODO: move into internal? // Relaxing Types -private [parsley] trait LabelOps { +private [parsley] sealed trait LabelOps { private [parsley] def asExpectDescs: Iterable[ExpectDesc] private [parsley] def asExpectDescs(otherwise: String): Iterable[ExpectDesc] private [parsley] def asExpectItems(raw: String): Iterable[ExpectItem] @@ -28,31 +28,34 @@ private [parsley] trait LabelOps { } // TODO: reason extraction, maybe tie into errors? -private [parsley] trait ExplainOps - +private [parsley] sealed trait ExplainOps // Constraining Types /** This type can be used to configure ''both'' errors that make labels and those that make reasons. * @since 4.1.0 * @group labels */ -trait LabelWithExplainConfig extends ConfigImplUntyped with LabelOps with ExplainOps { +sealed trait LabelWithExplainConfig extends ConfigImplUntyped with LabelOps with ExplainOps { private [parsley] def orElse(other: LabelWithExplainConfig): LabelWithExplainConfig } /** This type can be used to configure errors that make labels. * @since 4.1.0 * @group labels */ -trait LabelConfig extends LabelWithExplainConfig { +sealed trait LabelConfig extends LabelWithExplainConfig { private [parsley] def orElse(other: LabelConfig): LabelConfig } /** This type can be used to configure errors that make reasons. * @since 4.1.0 * @group labels */ -trait ExplainConfig extends LabelWithExplainConfig +sealed trait ExplainConfig extends LabelWithExplainConfig -private [errors] final class Label private[errors] (val label: String, val labels: String*) extends LabelConfig { +/** This class represents configurations producing labels: labels may not be empty. + * @since 4.1.0 + * @group labels + */ +final class Label(val label: String, val labels: String*) extends LabelConfig { require(label.nonEmpty && labels.forall(_.nonEmpty), "labels cannot be empty strings") private [parsley] final override def apply[A](p: Parsley[A]) = p.label(label, labels: _*) private [parsley] final override def asExpectDescs: Iterable[ExpectDesc] = (label +: labels).map(new ExpectDesc(_)) @@ -65,8 +68,7 @@ private [errors] final class Label private[errors] (val label: String, val label } private [parsley] final override def orElse(config: LabelConfig) = this } -/** This object has a factory for configurations producing labels: labels may not be empty. - * @since 4.1.0 +/** @since 4.1.0 * @group labels */ object Label { @@ -86,7 +88,11 @@ object Hidden extends LabelConfig { private [parsley] final override def orElse(config: LabelConfig) = this } -private [errors] final class Reason private[errors] (val reason: String) extends ExplainConfig { +/** This object has a factory for configurations producing reasons: if the empty string is provided, this equivalent to [[NotConfigured `NotConfigured`]]. + * @since 4.1.0 + * @group labels + */ +final class Reason(val reason: String) extends ExplainConfig { require(reason.nonEmpty, "reasons cannot be empty strings") private [parsley] final override def apply[A](p: Parsley[A]) = p.explain(reason) private [parsley] final override def asExpectDescs = None @@ -98,15 +104,18 @@ private [errors] final class Reason private[errors] (val reason: String) extends case _ => this } } -/** This object has a factory for configurations producing reasons: if the empty string is provided, this equivalent to [[NotConfigured `NotConfigured`]]. - * @since 4.1.0 +/** @since 4.1.0 * @group labels */ object Reason { - def apply(reason: String): ExplainConfig = if (reason.nonEmpty) new Reason(reason) else NotConfigured + def apply(reason: String): ExplainConfig = new Reason(reason) } -private [errors] final class LabelAndReason private[errors] (val reason: String, val label: String, val labels: String*) extends LabelWithExplainConfig { +/** This object has a factory for configurations producing labels and reasons: the reason and labels cannot be empty. + * @since 4.1.0 + * @group labels + */ +final class LabelAndReason(val reason: String, val label: String, val labels: String*) extends LabelWithExplainConfig { require(reason.nonEmpty, "reason cannot be empty strings, use `Label` instead") require(label.nonEmpty && labels.forall(_.nonEmpty), "labels cannot be empty strings") private [parsley] final override def apply[A](p: Parsley[A]) = p.label(label, labels: _*).explain(reason) @@ -115,17 +124,11 @@ private [errors] final class LabelAndReason private[errors] (val reason: String, private [parsley] final override def asExpectItems(@unused raw: String) = asExpectDescs private [parsley] final override def orElse(config: LabelWithExplainConfig) = this } -/** This object has a factory for configurations producing labels and reasons: if the empty label is provided, this equivalent to [[Hidden `Hidden`]] with no - * reason; if the empty reason is provided this is equivalent to [[Label$ `Label`]]. - * @since 4.1.0 +/** @since 4.1.0 * @group labels */ object LabelAndReason { - def apply(label: String, reason: String): LabelWithExplainConfig = { - if (label.isEmpty) Hidden - else if (reason.nonEmpty) new LabelAndReason(reason, label) - else new Label(label) - } + def apply(label: String, reason: String): LabelWithExplainConfig = new LabelAndReason(reason, label) } /** This object specifies that no special labels or reasons should be generated, and default errors should be used instead. diff --git a/parsley/shared/src/main/scala/parsley/token/errors/ErrorConfig.scala b/parsley/shared/src/main/scala/parsley/token/errors/ErrorConfig.scala index dffedfd97..6bb2e43cb 100644 --- a/parsley/shared/src/main/scala/parsley/token/errors/ErrorConfig.scala +++ b/parsley/shared/src/main/scala/parsley/token/errors/ErrorConfig.scala @@ -847,6 +847,7 @@ class ErrorConfig { /** Some possible defaults for the `ErrorConfig`. * + * @group errconfig * @since 4.5.0 */ object ErrorConfig { diff --git a/parsley/shared/src/test/scala/parsley/internal/deepembedding/frontend/VisitorTests.scala b/parsley/shared/src/test/scala/parsley/internal/deepembedding/frontend/VisitorTests.scala index 6216d8da4..caccd1394 100644 --- a/parsley/shared/src/test/scala/parsley/internal/deepembedding/frontend/VisitorTests.scala +++ b/parsley/shared/src/test/scala/parsley/internal/deepembedding/frontend/VisitorTests.scala @@ -15,13 +15,13 @@ import parsley.internal.deepembedding.{ContOps, Sign} import parsley.internal.deepembedding.backend.StrictParsley import parsley.internal.deepembedding.singletons.* import parsley.internal.deepembedding.singletons.token.* -import parsley.internal.errors.{CaretWidth, ExpectDesc, ExpectItem, FlexibleCaret} -import parsley.internal.machine.errors.DefuncError +import parsley.internal.errors.{CaretWidth, FlexibleCaret} import parsley.state.Ref import parsley.token.descriptions.SpaceDesc import parsley.token.descriptions.numeric.PlusSignPresence -import parsley.token.errors.{ErrorConfig, FilterConfig, LabelConfig, LabelWithExplainConfig, SpecialisedFilterConfig} +import parsley.token.errors.{ErrorConfig, BasicFilter, LabelConfig, SpecialisedFilterConfig} import parsley.token.predicate.Basic +import parsley.token.errors.NotConfigured class VisitorTests extends ParsleyTest { sealed trait ConstUnit[+A] @@ -65,25 +65,7 @@ class VisitorTests extends ParsleyTest { } - private val dummyLabelConfig: LabelConfig = new LabelConfig { - override private[parsley] def orElse(other: LabelConfig): LabelConfig = - dontExecute() - - override private[parsley] def orElse(other: LabelWithExplainConfig): LabelWithExplainConfig = - dontExecute() - - override private[parsley] def asExpectDescs: Iterable[ExpectDesc] = - dontExecute() - - override private[parsley] def asExpectDescs(otherwise: String): Iterable[ExpectDesc] = - dontExecute() - - override private[parsley] def asExpectItems(raw: String): Iterable[ExpectItem] = - dontExecute() - - override private[parsley] def apply[A](p: Parsley[A]): Parsley[A] = - dontExecute() - } + private val dummyLabelConfig: LabelConfig = NotConfigured private val dummyCaretWidth: CaretWidth = new FlexibleCaret(0) @@ -92,22 +74,7 @@ class VisitorTests extends ParsleyTest { dontExecute() } - private def dummySFConfig[A](): SpecialisedFilterConfig[A] = new SpecialisedFilterConfig[A] { - override private[parsley] def filter(p: Parsley[A])(f: A => Boolean): Parsley[A] = - dontExecute() - - override private[parsley] def mkError(offset: Int, line: Int, col: Int, caretWidth: Int, x: A): DefuncError = - dontExecute() - - override private[parsley] def injectLeft[B]: FilterConfig[Either[A, B]] = - dontExecute() - - override private[parsley] def injectRight[B]: FilterConfig[Either[B, A]] = - dontExecute() - - override private[parsley] def injectSnd[B]: FilterConfig[(B, A)] = - dontExecute() - } + private def dummySFConfig[A](): SpecialisedFilterConfig[A] = new BasicFilter[A] implicit private class TestVisitorOps[A](p: LazyParsley[A]) { def testV: Assertion = p.visit(testVisitor, ()) shouldBe CUnit diff --git a/project/ParsleySitePlugin.scala b/project/ParsleySitePlugin.scala index 29b6f1a23..45aff9b41 100644 --- a/project/ParsleySitePlugin.scala +++ b/project/ParsleySitePlugin.scala @@ -190,13 +190,13 @@ object redirects { private def redirects(latest: String) = { // TODO: this can be made less brittle, surely can be derived from the above configuration? - val versions = List("latest", "stable", "4.4.x", "4.4", "4.5.x", "4.5", "5.0.x", "5.0") + val versions = List("latest", "stable", "4.4.x", "4.4", "4.5.x", "4.5", /*"5.0.x",*/ "5.0") val versionMappings = List( "latest" -> latest, "stable" -> "4.5", "4.4.x" -> "4.4", "4.5.x" -> "4.5", - "5.0.x" -> "5.0", + //"5.0.x" -> "5.0", ) val versioned = (