Skip to content

Commit ddde226

Browse files
committed
Parse type/singleton applications
1 parent 6aa95a3 commit ddde226

File tree

3 files changed

+51
-19
lines changed

3 files changed

+51
-19
lines changed

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

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,9 @@ object Parsers {
192192

193193
def isIdent = in.isIdent
194194
def isIdent(name: Name) = in.isIdent(name)
195-
def isSimpleLiteral = simpleLiteralTokens contains in.token
195+
def isSimpleLiteral =
196+
simpleLiteralTokens.contains(in.token)
197+
|| isIdent(nme.raw.MINUS) && numericLitTokens.contains(in.lookahead.token)
196198
def isLiteral = literalTokens contains in.token
197199
def isNumericLit = numericLitTokens contains in.token
198200
def isTemplateIntro = templateIntroTokens contains in.token
@@ -1100,18 +1102,42 @@ object Parsers {
11001102
*/
11011103
def qualId(): Tree = dotSelectors(termIdent())
11021104

1103-
/** SimpleExpr ::= literal
1104-
* | 'id | 'this | 'true | 'false | 'null
1105-
* | null
1105+
/** Singleton ::= SimpleRef
1106+
* | SimpleLiteral
1107+
* | Singleton ‘.’ id
1108+
*/
1109+
def singleton(): Tree =
1110+
if isSimpleLiteral then simpleLiteral()
1111+
else dotSelectors(simpleRef())
1112+
1113+
/** SimpleLiteral ::= [‘-’] integerLiteral
1114+
* | [‘-’] floatingPointLiteral
1115+
* | booleanLiteral
1116+
* | characterLiteral
1117+
* | stringLiteral
1118+
*/
1119+
def simpleLiteral(): Tree =
1120+
if isIdent(nme.raw.MINUS) then
1121+
val start = in.offset
1122+
in.nextToken()
1123+
literal(negOffset = start, inTypeOrSingleton = true)
1124+
else
1125+
literal(inTypeOrSingleton = true)
1126+
1127+
/** Literal ::= SimpleLiteral
1128+
* | processedStringLiteral
1129+
* | symbolLiteral
1130+
* | ‘null’
1131+
*
11061132
* @param negOffset The offset of a preceding `-' sign, if any.
1107-
* If the literal is not negated, negOffset = in.offset.
1133+
* If the literal is not negated, negOffset == in.offset.
11081134
*/
1109-
def literal(negOffset: Int = in.offset, inPattern: Boolean = false, inType: Boolean = false, inStringInterpolation: Boolean = false): Tree = {
1135+
def literal(negOffset: Int = in.offset, inPattern: Boolean = false, inTypeOrSingleton: Boolean = false, inStringInterpolation: Boolean = false): Tree = {
11101136
def literalOf(token: Token): Tree = {
11111137
val isNegated = negOffset < in.offset
11121138
def digits0 = in.removeNumberSeparators(in.strVal)
11131139
def digits = if (isNegated) "-" + digits0 else digits0
1114-
if (!inType)
1140+
if !inTypeOrSingleton then
11151141
token match {
11161142
case INTLIT => return Number(digits, NumberKind.Whole(in.base))
11171143
case DECILIT => return Number(digits, NumberKind.Decimal)
@@ -1554,15 +1580,12 @@ object Parsers {
15541580

15551581
/** SimpleType ::= SimpleLiteral
15561582
* | ‘?’ SubtypeBounds
1557-
* | SimpleType1
1583+
* | SimpleType1 { ‘(’ Singletons ‘)’ }
1584+
* Singletons ::= Singleton {‘,’ Singleton}
15581585
*/
15591586
def simpleType(): Tree =
15601587
if isSimpleLiteral then
1561-
SingletonTypeTree(literal(inType = true))
1562-
else if isIdent(nme.raw.MINUS) && numericLitTokens.contains(in.lookahead.token) then
1563-
val start = in.offset
1564-
in.nextToken()
1565-
SingletonTypeTree(literal(negOffset = start, inType = true))
1588+
SingletonTypeTree(simpleLiteral())
15661589
else if in.token == USCORE then
15671590
if sourceVersion.isAtLeast(`3.1`) then
15681591
deprecationWarning(em"`_` is deprecated for wildcard arguments of types: use `?` instead")
@@ -1575,7 +1598,11 @@ object Parsers {
15751598
else if isIdent(nme.*) && ctx.settings.YkindProjector.value then
15761599
typeIdent()
15771600
else
1578-
simpleType1()
1601+
def singletonArgs(t: Tree): Tree =
1602+
if in.token == LPAREN
1603+
then singletonArgs(AppliedTypeTree(t, inParens(commaSeparated(singleton))))
1604+
else t
1605+
singletonArgs(simpleType1())
15791606

15801607
/** SimpleType1 ::= id
15811608
* | Singleton `.' id

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,11 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
477477
changePrec(OrTypePrec) { toText(args(0)) ~ " | " ~ atPrec(OrTypePrec + 1) { toText(args(1)) } }
478478
else if (tpt.symbol == defn.andType && args.length == 2)
479479
changePrec(AndTypePrec) { toText(args(0)) ~ " & " ~ atPrec(AndTypePrec + 1) { toText(args(1)) } }
480-
else
481-
toTextLocal(tpt) ~ "[" ~ Text(args map argText, ", ") ~ "]"
480+
else args match
481+
case arg :: _ if arg.isTerm =>
482+
toTextLocal(tpt) ~ "(" ~ Text(args.map(argText), ", ") ~ ")"
483+
case _ =>
484+
toTextLocal(tpt) ~ "[" ~ Text(args.map(argText), ", ") ~ "]"
482485
case LambdaTypeTree(tparams, body) =>
483486
changePrec(GlobalPrec) {
484487
tparamsText(tparams) ~ " =>> " ~ toText(body)

docs/docs/internals/syntax.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,15 @@ ClassQualifier ::= ‘[’ id ‘]’
139139
```ebnf
140140
Type ::= FunType
141141
| HkTypeParamClause ‘=>>’ Type TypeLambda(ps, t)
142+
| ‘(’ TypedFunParams ‘)’ ‘=>>’ Type TypeLambda(ps, t)
142143
| MatchType
143144
| InfixType
144145
FunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type Function(ts, t)
145146
| HKTypeParamClause '=>' Type PolyFunction(ps, t)
146147
FunArgTypes ::= InfixType
147148
| ‘(’ [ FunArgType {‘,’ FunArgType } ] ‘)’
148-
| ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’
149+
| ‘(’ TypedFunParams ‘)’
150+
TypedFunParams ::= TypedFunParam {‘,’ TypedFunParam }
149151
TypedFunParam ::= id ‘:’ Type
150152
MatchType ::= InfixType `match` ‘{’ TypeCaseClauses ‘}’
151153
InfixType ::= RefinedType {id [nl] RefinedType} InfixOp(t1, op, t2)
@@ -155,8 +157,7 @@ AnnotType ::= SimpleType {Annotation}
155157
156158
SimpleType ::= SimpleLiteral SingletonTypeTree(l)
157159
| ‘?’ SubtypeBounds
158-
| SimpleType ‘(’ Singletons ‘)’
159-
| SimpleType1
160+
| SimpleType1 { ‘(’ Singletons ‘)’ }
160161
SimpleType1 ::= id Ident(name)
161162
| Singleton ‘.’ id Select(t, name)
162163
| Singleton ‘.’ ‘type’ SingletonTypeTree(p)
@@ -166,6 +167,7 @@ SimpleType1 ::= id
166167
| SimpleType1 TypeArgs AppliedTypeTree(t, args)
167168
| SimpleType1 ‘#’ id Select(t, name)
168169
Singleton ::= SimpleRef
170+
| SimpleLiteral
169171
| Singleton ‘.’ id
170172
-- not yet | Singleton ‘(’ Singletons ‘)’
171173
-- not yet | Singleton ‘[’ ArgTypes ‘]’

0 commit comments

Comments
 (0)