Skip to content

Commit fed3381

Browse files
committed
Fixed missing label for Reason'd symbols
1 parent 0a9443d commit fed3381

File tree

8 files changed

+34
-22
lines changed

8 files changed

+34
-22
lines changed

.codeclimate.yml

-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ exclude_patterns:
1717
- "**/ap.scala"
1818
- "**/lift.scala"
1919
- "**/generic.scala"
20-
- "**/genericbridges.scala"
21-
- "**/implicits/zipped.scala"
22-
- "**/implicits/lift.scala"
2320
- "**/syntax/zipped.scala"
2421
- "**/syntax/lift.scala"
2522
plugins:

parsley/shared/src/main/scala-2/parsley/implicits/package.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ package parsley
1212
* Automatic conversion to `Parsley[Unit]` is also supported within this package.
1313
*
1414
*/
15-
package object implicits
15+
package object syntax

parsley/shared/src/main/scala/parsley/internal/machine/instructions/token/SymbolInstrs.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import parsley.token.errors.LabelWithExplainConfig
1111
import parsley.token.predicate
1212

1313
import parsley.internal.collection.immutable.Trie
14-
import parsley.internal.errors.ExpectDesc
14+
import parsley.internal.errors.{ExpectDesc, ExpectItem}
1515
import parsley.internal.machine.Context
1616
import parsley.internal.machine.XAssert._
1717
import parsley.internal.machine.instructions.Instr
1818

1919
private [token] abstract class Specific extends Instr {
2020
protected val specific: String
2121
protected val caseSensitive: Boolean
22-
protected val expected: Iterable[ExpectDesc]
22+
protected val expected: Iterable[ExpectItem]
2323
protected val reason: Option[String]
2424
private [this] final val strsz = specific.length
2525
private [this] final val numCodePoints = specific.codePointCount(0, strsz)
@@ -66,13 +66,13 @@ private [token] abstract class Specific extends Instr {
6666
}
6767

6868
private [internal] final class SoftKeyword(protected val specific: String, letter: CharPredicate, protected val caseSensitive: Boolean,
69-
protected val expected: Iterable[ExpectDesc], protected val reason: Option[String],
69+
protected val expected: Iterable[ExpectItem], protected val reason: Option[String],
7070
expectedEnd: Iterable[ExpectDesc]) extends Specific {
7171
def this(specific: String, letter: predicate.CharPredicate, caseSensitive: Boolean, expected: LabelWithExplainConfig, expectedEnd: String) = {
7272
this(if (caseSensitive) specific else specific.toLowerCase,
7373
letter.asInternalPredicate,
7474
caseSensitive,
75-
expected.asExpectDescs, expected.asReason, Some(new ExpectDesc(expectedEnd)))
75+
expected.asExpectItems(specific), expected.asReason, Some(new ExpectDesc(expectedEnd)))
7676
}
7777

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

9494
private [internal] final class SoftOperator(protected val specific: String, letter: CharPredicate, ops: Trie[Unit],
95-
protected val expected: Iterable[ExpectDesc], protected val reason: Option[String],
95+
protected val expected: Iterable[ExpectItem], protected val reason: Option[String],
9696
expectedEnd: Iterable[ExpectDesc]) extends Specific {
9797
def this(specific: String, letter: predicate.CharPredicate, ops: Trie[Unit], expected: LabelWithExplainConfig, expectedEnd: String) = {
98-
this(specific, letter.asInternalPredicate, ops, expected.asExpectDescs, expected.asReason, Some(new ExpectDesc(expectedEnd)))
98+
this(specific, letter.asInternalPredicate, ops, expected.asExpectItems(specific), expected.asReason, Some(new ExpectDesc(expectedEnd)))
9999
}
100100
protected val caseSensitive = true
101101
private val ends = ops.suffixes(specific)

parsley/shared/src/main/scala/parsley/token/errors/ConfigImplUntyped.scala

+8-2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ sealed trait LabelConfig extends LabelWithExplainConfig {
5252
*/
5353
sealed trait ExplainConfig extends LabelWithExplainConfig
5454

55+
private [parsley] sealed trait Labeller {
56+
private [parsley] def config(name: String): LabelConfig
57+
}
58+
5559
/** This class represents configurations producing labels: labels may not be empty.
5660
* @since 4.1.0
5761
* @group labels
@@ -73,8 +77,9 @@ final class Label(val label: String, val labels: String*) extends LabelConfig {
7377
/** @since 4.1.0
7478
* @group labels
7579
*/
76-
object Label {
80+
object Label extends Labeller {
7781
def apply(label: String, labels: String*): LabelConfig = new Label(label, labels: _*)
82+
private [parsley] final def config(name: String) = new Label(name)
7883
}
7984

8085
/** This object configures labels by stating that it must be hidden.
@@ -140,12 +145,13 @@ object LabelAndReason {
140145
* @since 4.1.0
141146
* @group labels
142147
*/
143-
object NotConfigured extends LabelConfig with ExplainConfig with LabelWithExplainConfig {
148+
object NotConfigured extends LabelConfig with ExplainConfig with LabelWithExplainConfig with Labeller {
144149
private [parsley] final override def apply[A](p: Parsley[A]) = p
145150
private [parsley] final override def asExpectDescs = None
146151
private [parsley] final override def asExpectDescs(otherwise: String) = Some(new ExpectDesc(otherwise))
147152
private [parsley] final override def asExpectItems(raw: String) = Some(new ExpectRaw(raw))
148153
private [parsley] final override def orElse(config: LabelWithExplainConfig) = config
149154
private [parsley] final override def orElse(config: LabelConfig) = config
150155
private [parsley] final override def asReason: Option[String] = None
156+
private [parsley] final def config(name: String) = this
151157
}

parsley/shared/src/main/scala/parsley/token/errors/ErrorConfig.scala

+5
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,11 @@ class ErrorConfig {
842842
*/
843843
@deprecated("This will be removed in favour of `labelSymbol` in a future milestone", "5.0.0-M3")
844844
def labelSymbolOperator(symbol: String): LabelWithExplainConfig = Label(symbol)
845+
// To unify, or not to unify
846+
private [parsley] def defaultSymbolKeyword: Labeller = Label
847+
private [parsley] def defaultSymbolOperator: Labeller = Label
848+
// Other?
849+
private [parsley] def defaultSymbolPunctuation: Labeller = NotConfigured
845850
/** How the required end of a given keyword should be specified in an error.
846851
* @since 4.1.0
847852
* @note defaults to "end of symbol"

parsley/shared/src/main/scala/parsley/token/symbol/ConcreteSymbol.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,20 @@ private [token] class ConcreteSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc,
3030
}.getOrElse(NotConfigured)
3131
if (symbolDesc.hardKeywords(name)) softKeyword(name)
3232
else if (symbolDesc.hardOperators(name)) softOperator(name)
33-
else err.labelSymbol.getOrElse(name, compatLabel)(atomic(string(name)).void)
33+
else err.labelSymbol.getOrElse(name, compatLabel).orElse(err.defaultSymbolPunctuation.config(name))(atomic(string(name)).void)
3434
}
3535

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

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

4444
override def softOperator(name: String): Parsley[Unit] = {
4545
require(name.nonEmpty, "Operators may not be empty strings")
4646
new Parsley(new token.SoftOperator(name, nameDesc.operatorLetter, symbolDesc.hardOperatorsTrie,
47-
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn), err.labelSymbolEndOfOperator(name)))
47+
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn).orElse(err.defaultSymbolOperator.config(name)), err.labelSymbolEndOfOperator(name)))
4848
}
4949
}

parsley/shared/src/test/scala/parsley/token/symbol/OriginalSymbol.scala

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import parsley.character.{char, string, strings}
1212
import parsley.unicode
1313
import parsley.errors.combinator.{ErrorMethods, amend}
1414
import parsley.token.descriptions.{NameDesc, SymbolDesc}
15-
import parsley.token.errors.ErrorConfig
15+
import parsley.token.errors.{ErrorConfig, NotConfigured}
1616

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

2727
override def apply(name: Char): Parsley[Unit] = char(name).void
@@ -47,7 +47,7 @@ private [token] class OriginalSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc,
4747
override def softKeyword(name: String): Parsley[Unit] = {
4848
require(name.nonEmpty, "Keywords may not be empty strings")
4949
atomic {
50-
err.labelSymbol.getOrElse(name, err.labelSymbolKeyword(name): @nowarn)(caseString(name)) *>
50+
err.labelSymbol.getOrElse(name, err.labelSymbolKeyword(name): @nowarn).orElse(err.defaultSymbolKeyword.config(name))(caseString(name)) *>
5151
notFollowedBy(identLetter).label(err.labelSymbolEndOfKeyword(name))
5252
}
5353
}
@@ -60,11 +60,11 @@ private [token] class OriginalSymbol(nameDesc: NameDesc, symbolDesc: SymbolDesc,
6060
}.toList
6161
ends match {
6262
case Nil => atomic {
63-
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn)(string(name)) *>
63+
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn).orElse(err.defaultSymbolOperator.config(name))(string(name)) *>
6464
notFollowedBy(opLetter).label(err.labelSymbolEndOfOperator(name))
6565
}
6666
case end::ends => atomic {
67-
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn)(string(name)) *>
67+
err.labelSymbol.getOrElse(name, err.labelSymbolOperator(name): @nowarn).orElse(err.defaultSymbolOperator.config(name))(string(name)) *>
6868
notFollowedBy(opLetter <|> strings(end, ends: _*)).label(err.labelSymbolEndOfOperator(name))
6969
}
7070
}

parsley/shared/src/test/scala/parsley/token/symbol/SymbolTests.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ package parsley.token.symbol
77

88
import Predef.{ArrowAssoc => _, _}
99

10-
import parsley.{Parsley, ParsleyTest}
10+
import parsley._
1111
import parsley.token.LexemeImpl._
1212

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

1919
class SymbolTests extends ParsleyTest {
20-
val errConfig = new ErrorConfig
20+
val errConfig = new ErrorConfig {
21+
override def labelSymbol = Map(
22+
("keyword", parsley.token.errors.Reason("bla bla"))
23+
)
24+
}
2125
def makeSymbol(nameDesc: NameDesc, symDesc: SymbolDesc): Symbol = new LexemeSymbol(new ConcreteSymbol(nameDesc, symDesc, errConfig), spaces, errConfig)
2226

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

0 commit comments

Comments
 (0)