Skip to content

Commit

Permalink
Fixed missing label for Reason'd symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mie6 committed Feb 1, 2024
1 parent 0a9443d commit fed3381
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 22 deletions.
3 changes: 0 additions & 3 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ exclude_patterns:
- "**/ap.scala"
- "**/lift.scala"
- "**/generic.scala"
- "**/genericbridges.scala"
- "**/implicits/zipped.scala"
- "**/implicits/lift.scala"
- "**/syntax/zipped.scala"
- "**/syntax/lift.scala"
plugins:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ package parsley
* Automatic conversion to `Parsley[Unit]` is also supported within this package.
*
*/
package object implicits
package object syntax
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import parsley.token.errors.LabelWithExplainConfig
import parsley.token.predicate

import parsley.internal.collection.immutable.Trie
import parsley.internal.errors.ExpectDesc
import parsley.internal.errors.{ExpectDesc, ExpectItem}
import parsley.internal.machine.Context
import parsley.internal.machine.XAssert._
import parsley.internal.machine.instructions.Instr

private [token] abstract class Specific extends Instr {
protected val specific: String
protected val caseSensitive: Boolean
protected val expected: Iterable[ExpectDesc]
protected val expected: Iterable[ExpectItem]
protected val reason: Option[String]
private [this] final val strsz = specific.length
private [this] final val numCodePoints = specific.codePointCount(0, strsz)
Expand Down Expand Up @@ -66,13 +66,13 @@ private [token] abstract class Specific extends Instr {
}

private [internal] final class SoftKeyword(protected val specific: String, letter: CharPredicate, protected val caseSensitive: Boolean,
protected val expected: Iterable[ExpectDesc], protected val reason: Option[String],
protected val expected: Iterable[ExpectItem], protected val reason: Option[String],
expectedEnd: Iterable[ExpectDesc]) extends Specific {
def this(specific: String, letter: predicate.CharPredicate, caseSensitive: Boolean, expected: LabelWithExplainConfig, expectedEnd: String) = {
this(if (caseSensitive) specific else specific.toLowerCase,
letter.asInternalPredicate,
caseSensitive,
expected.asExpectDescs, expected.asReason, Some(new ExpectDesc(expectedEnd)))
expected.asExpectItems(specific), expected.asReason, Some(new ExpectDesc(expectedEnd)))
}

protected def postprocess(ctx: Context): Unit = {
Expand All @@ -92,10 +92,10 @@ private [internal] final class SoftKeyword(protected val specific: String, lette
}

private [internal] final class SoftOperator(protected val specific: String, letter: CharPredicate, ops: Trie[Unit],
protected val expected: Iterable[ExpectDesc], protected val reason: Option[String],
protected val expected: Iterable[ExpectItem], protected val reason: Option[String],
expectedEnd: Iterable[ExpectDesc]) extends Specific {
def this(specific: String, letter: predicate.CharPredicate, ops: Trie[Unit], expected: LabelWithExplainConfig, expectedEnd: String) = {
this(specific, letter.asInternalPredicate, ops, expected.asExpectDescs, expected.asReason, Some(new ExpectDesc(expectedEnd)))
this(specific, letter.asInternalPredicate, ops, expected.asExpectItems(specific), expected.asReason, Some(new ExpectDesc(expectedEnd)))
}
protected val caseSensitive = true
private val ends = ops.suffixes(specific)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ sealed trait LabelConfig extends LabelWithExplainConfig {
*/
sealed trait ExplainConfig extends LabelWithExplainConfig

private [parsley] sealed trait Labeller {
private [parsley] def config(name: String): LabelConfig
}

/** This class represents configurations producing labels: labels may not be empty.
* @since 4.1.0
* @group labels
Expand All @@ -73,8 +77,9 @@ final class Label(val label: String, val labels: String*) extends LabelConfig {
/** @since 4.1.0
* @group labels
*/
object Label {
object Label extends Labeller {
def apply(label: String, labels: String*): LabelConfig = new Label(label, labels: _*)
private [parsley] final def config(name: String) = new Label(name)
}

/** This object configures labels by stating that it must be hidden.
Expand Down Expand Up @@ -140,12 +145,13 @@ object LabelAndReason {
* @since 4.1.0
* @group labels
*/
object NotConfigured extends LabelConfig with ExplainConfig with LabelWithExplainConfig {
object NotConfigured extends LabelConfig with ExplainConfig with LabelWithExplainConfig with Labeller {
private [parsley] final override def apply[A](p: Parsley[A]) = p
private [parsley] final override def asExpectDescs = None
private [parsley] final override def asExpectDescs(otherwise: String) = Some(new ExpectDesc(otherwise))
private [parsley] final override def asExpectItems(raw: String) = Some(new ExpectRaw(raw))
private [parsley] final override def orElse(config: LabelWithExplainConfig) = config
private [parsley] final override def orElse(config: LabelConfig) = config
private [parsley] final override def asReason: Option[String] = None
private [parsley] final def config(name: String) = this
}
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,11 @@ class ErrorConfig {
*/
@deprecated("This will be removed in favour of `labelSymbol` in a future milestone", "5.0.0-M3")
def labelSymbolOperator(symbol: String): LabelWithExplainConfig = Label(symbol)
// To unify, or not to unify
private [parsley] def defaultSymbolKeyword: Labeller = Label
private [parsley] def defaultSymbolOperator: Labeller = Label
// Other?
private [parsley] def defaultSymbolPunctuation: Labeller = NotConfigured
/** How the required end of a given keyword should be specified in an error.
* @since 4.1.0
* @note defaults to "end of symbol"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ private [token] class ConcreteSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc,
}.getOrElse(NotConfigured)
if (symbolDesc.hardKeywords(name)) softKeyword(name)
else if (symbolDesc.hardOperators(name)) softOperator(name)
else err.labelSymbol.getOrElse(name, compatLabel)(atomic(string(name)).void)
else err.labelSymbol.getOrElse(name, compatLabel).orElse(err.defaultSymbolPunctuation.config(name))(atomic(string(name)).void)
}

override def apply(name: Char): Parsley[Unit] = err.labelSymbol.getOrElse(name.toString, NotConfigured)(char(name).void)

override def softKeyword(name: String): Parsley[Unit] = {
require(name.nonEmpty, "Keywords may not be empty strings")
new Parsley(new token.SoftKeyword(name, nameDesc.identifierLetter, symbolDesc.caseSensitive,
err.labelSymbol.getOrElse(name, err.labelSymbolKeyword(name): @nowarn), err.labelSymbolEndOfKeyword(name)))
err.labelSymbol.getOrElse(name, err.labelSymbolKeyword(name): @nowarn).orElse(err.defaultSymbolKeyword.config(name)), err.labelSymbolEndOfKeyword(name)))
}

override def softOperator(name: String): Parsley[Unit] = {
require(name.nonEmpty, "Operators may not be empty strings")
new Parsley(new token.SoftOperator(name, nameDesc.operatorLetter, symbolDesc.hardOperatorsTrie,
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn), err.labelSymbolEndOfOperator(name)))
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn).orElse(err.defaultSymbolOperator.config(name)), err.labelSymbolEndOfOperator(name)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import parsley.character.{char, string, strings}
import parsley.unicode
import parsley.errors.combinator.{ErrorMethods, amend}
import parsley.token.descriptions.{NameDesc, SymbolDesc}
import parsley.token.errors.ErrorConfig
import parsley.token.errors.{ErrorConfig, NotConfigured}

// $COVERAGE-OFF$
private [token] class OriginalSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc, err: ErrorConfig) extends Symbol(err) {
Expand All @@ -21,7 +21,7 @@ private [token] class OriginalSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc,
require(name.nonEmpty, "Symbols may not be empty strings")
if (symbolDesc.hardKeywords(name)) softKeyword(name)
else if (symbolDesc.hardOperators(name)) softOperator(name)
else atomic(string(name)).void
else err.labelSymbol.getOrElse(name, NotConfigured).orElse(err.defaultSymbolPunctuation.config(name))(atomic(string(name)).void)
}

override def apply(name: Char): Parsley[Unit] = char(name).void
Expand All @@ -47,7 +47,7 @@ private [token] class OriginalSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc,
override def softKeyword(name: String): Parsley[Unit] = {
require(name.nonEmpty, "Keywords may not be empty strings")
atomic {
err.labelSymbol.getOrElse(name, err.labelSymbolKeyword(name): @nowarn)(caseString(name)) *>
err.labelSymbol.getOrElse(name, err.labelSymbolKeyword(name): @nowarn).orElse(err.defaultSymbolKeyword.config(name))(caseString(name)) *>
notFollowedBy(identLetter).label(err.labelSymbolEndOfKeyword(name))
}
}
Expand All @@ -60,11 +60,11 @@ private [token] class OriginalSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc,
}.toList
ends match {
case Nil => atomic {
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn)(string(name)) *>
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn).orElse(err.defaultSymbolOperator.config(name))(string(name)) *>
notFollowedBy(opLetter).label(err.labelSymbolEndOfOperator(name))
}
case end::ends => atomic {
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn)(string(name)) *>
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn).orElse(err.defaultSymbolOperator.config(name))(string(name)) *>
notFollowedBy(opLetter <|> strings(end, ends: _*)).label(err.labelSymbolEndOfOperator(name))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package parsley.token.symbol

import Predef.{ArrowAssoc => _, _}

import parsley.{Parsley, ParsleyTest}
import parsley._
import parsley.token.LexemeImpl._

import parsley.token.descriptions._
Expand All @@ -17,7 +17,11 @@ import parsley.character.{spaces, string}
import org.scalactic.source.Position

class SymbolTests extends ParsleyTest {
val errConfig = new ErrorConfig
val errConfig = new ErrorConfig {
override def labelSymbol = Map(
("keyword", parsley.token.errors.Reason("bla bla"))
)
}
def makeSymbol(nameDesc: NameDesc, symDesc: SymbolDesc): Symbol = new LexemeSymbol(new ConcreteSymbol(nameDesc, symDesc, errConfig), spaces, errConfig)

val plainName = NameDesc.plain.copy(identifierLetter = Basic(_.isLetter), operatorLetter = ':')
Expand Down

0 comments on commit fed3381

Please sign in to comment.