Skip to content

Commit f4b3538

Browse files
committed
Report forbidden modifiers from modifiers
Missing: tests. Had to add to `modifiers` a new `parsedSeparately` parameter, and since its interface is tricky I wrote some documentation.
1 parent 6f2effe commit f4b3538

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,7 @@ object Parsers {
16501650
case PROTECTED => Mod.Protected()
16511651
case SEALED => Mod.Sealed()
16521652
}
1653+
private def flagsOfModToken(tok: Int): FlagSet = modOfToken(tok).flags
16531654

16541655
/** Drop `private' modifier when followed by a qualifier.
16551656
* Contract `abstract' and `override' to ABSOVERRIDE
@@ -1705,7 +1706,14 @@ object Parsers {
17051706
}
17061707
} else mods
17071708

1708-
/** {Annotation} {Modifier}
1709+
/**
1710+
* Extend the start Modifiers by parsing modifier tokens in the allowed BitSet, appearing in any order.
1711+
* Ignore modifier tokens in the parsedSeparately BitSet, so that the caller can parse them after modifier returns
1712+
* (suitable to parse `AllowedModifiers* lazy`).
1713+
* Report modifier tokens that appear neither in allowed nor in parsedSeparately.
1714+
*
1715+
* Grammar:
1716+
* {Annotation} {Modifier}
17091717
* Modifiers ::= {Modifier}
17101718
* LocalModifiers ::= {LocalModifier}
17111719
* AccessModifier ::= (private | protected) [AccessQualifier]
@@ -1714,7 +1722,7 @@ object Parsers {
17141722
* | override
17151723
* LocalModifier ::= abstract | final | sealed | implicit | lazy
17161724
*/
1717-
def modifiers(allowed: BitSet = modifierTokens, start: Modifiers = Modifiers()): Modifiers = {
1725+
def modifiers(allowed: BitSet = modifierTokens, start: Modifiers = Modifiers(), parsedSeparately: BitSet = BitSet.empty): Modifiers = {
17181726
@tailrec
17191727
def loop(mods: Modifiers): Modifiers = {
17201728
if (allowed contains in.token) {
@@ -1725,6 +1733,8 @@ object Parsers {
17251733
in.nextToken()
17261734
loop(mods)
17271735
} else {
1736+
if ((modifierTokens contains in.token) && !(parsedSeparately contains in.token))
1737+
syntaxError(hl"Modifier `${flagsOfModToken(in.token)}' not allowed at this position")
17281738
mods
17291739
}
17301740
}
@@ -2471,7 +2481,7 @@ object Parsers {
24712481
else if (isDefIntro(localModifierTokens))
24722482
if (in.token == IMPLICIT || in.token == ERASED) {
24732483
val start = in.offset
2474-
var imods = modifiers(funArgMods)
2484+
var imods = modifiers(funArgMods, parsedSeparately = BitSet(LAZY))
24752485
if (isBindingIntro) stats += implicitClosure(start, Location.InBlock, imods)
24762486
else stats +++= localDef(start, imods)
24772487
} else {

0 commit comments

Comments
 (0)