Skip to content

Commit 5cbc840

Browse files
committed
Refactor syntax for ConstrApps
Split off the parts of SimpleType that - can be applied to type arguments, or selected with # - can be used in a constructor This gives a bit more precision for type and constructor parsing. It's also a necessary step to be able to add types that are applied to singletons.
1 parent 5fb7c4e commit 5cbc840

File tree

4 files changed

+67
-59
lines changed

4 files changed

+67
-59
lines changed

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

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,61 +1572,62 @@ object Parsers {
15721572
if (isType) TypSplice(expr) else Splice(expr)
15731573
}
15741574

1575-
/** SimpleType ::= SimpleType TypeArgs
1576-
* | SimpleType `#' id
1577-
* | Singleton `.' id
1578-
* | Singleton `.' type
1579-
* | `(' ArgTypes `)'
1580-
* | `_' TypeBounds
1581-
* | Refinement
1582-
* | Literal
1583-
* | ‘$’ ‘{’ Block ‘}’
1575+
/** SimpleType ::= SimpleLiteral
1576+
* | ‘?’ SubtypeBounds
1577+
* | SimpleType1
15841578
*/
1585-
def simpleType(): Tree = simpleTypeRest {
1586-
if (in.token == LPAREN)
1587-
atSpan(in.offset) {
1588-
makeTupleOrParens(inParens(argTypes(namedOK = false, wildOK = true)))
1589-
}
1590-
else if (in.token == LBRACE)
1591-
atSpan(in.offset) { RefinedTypeTree(EmptyTree, refinement()) }
1592-
else if (isSimpleLiteral) { SingletonTypeTree(literal(inType = true)) }
1579+
def simpleType(): Tree =
1580+
if isSimpleLiteral then
1581+
SingletonTypeTree(literal(inType = true))
15931582
else if isIdent(nme.raw.MINUS) && numericLitTokens.contains(in.lookahead.token) then
15941583
val start = in.offset
15951584
in.nextToken()
15961585
SingletonTypeTree(literal(negOffset = start, inType = true))
1597-
else if (in.token == USCORE) {
1586+
else if in.token == USCORE then
15981587
if sourceVersion.isAtLeast(`3.1`) then
15991588
deprecationWarning(em"`_` is deprecated for wildcard arguments of types: use `?` instead")
16001589
patch(source, Span(in.offset, in.offset + 1), "?")
16011590
val start = in.skipToken()
16021591
typeBounds().withSpan(Span(start, in.lastOffset, start))
1603-
}
1604-
else if (isIdent(nme.?)) {
1592+
else if isIdent(nme.?) then
16051593
val start = in.skipToken()
16061594
typeBounds().withSpan(Span(start, in.lastOffset, start))
1607-
}
1608-
else if (isIdent(nme.*) && ctx.settings.YkindProjector.value) {
1595+
else if isIdent(nme.*) && ctx.settings.YkindProjector.value then
16091596
typeIdent()
1610-
}
1597+
else
1598+
simpleType1()
1599+
1600+
/** SimpleType1 ::= id
1601+
* | Singleton `.' id
1602+
* | Singleton `.' type
1603+
* | ‘(’ ArgTypes ‘)’
1604+
* | Refinement
1605+
* | ‘$’ ‘{’ Block ‘}’
1606+
* | SimpleType1 TypeArgs
1607+
* | SimpleType1 `#' id
1608+
*/
1609+
def simpleType1() = simpleTypeRest {
1610+
if in.token == LPAREN then
1611+
atSpan(in.offset) {
1612+
makeTupleOrParens(inParens(argTypes(namedOK = false, wildOK = true)))
1613+
}
1614+
else if in.token == LBRACE then
1615+
atSpan(in.offset) { RefinedTypeTree(EmptyTree, refinement()) }
16111616
else if (isSplice)
16121617
splice(isType = true)
16131618
else
1619+
def singletonCompletion(t: Tree): Tree =
1620+
if in.token == DOT then
1621+
in.nextToken()
1622+
if in.token == TYPE then
1623+
in.nextToken()
1624+
atSpan(startOffset(t)) { SingletonTypeTree(t) }
1625+
else
1626+
singletonCompletion(idSelector(t))
1627+
else convertToTypeId(t)
16141628
singletonCompletion(simpleRef())
16151629
}
16161630

1617-
/** Singleton ::= SimpleRef
1618-
* | Singleton ‘.’ id
1619-
*/
1620-
def singletonCompletion(t: Tree): Tree =
1621-
if in.token == DOT then
1622-
in.nextToken()
1623-
if in.token == TYPE then
1624-
in.nextToken()
1625-
atSpan(startOffset(t)) { SingletonTypeTree(t) }
1626-
else
1627-
singletonCompletion(idSelector(t))
1628-
else convertToTypeId(t)
1629-
16301631
private def simpleTypeRest(t: Tree): Tree = in.token match {
16311632
case HASH => simpleTypeRest(typeProjection(t))
16321633
case LBRACKET => simpleTypeRest(atSpan(startOffset(t)) {
@@ -3630,13 +3631,13 @@ object Parsers {
36303631

36313632
/* -------- TEMPLATES ------------------------------------------- */
36323633

3633-
/** SimpleConstrApp ::= AnnotType {ParArgumentExprs}
3634+
/** ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs}
36343635
*/
3635-
val constrApp: () => Tree = () => {
3636-
val t = rejectWildcardType(annotType(), fallbackTree = Ident(nme.ERROR))
3637-
// Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code
3636+
val constrApp: () => Tree = () =>
3637+
val t = rejectWildcardType(annotTypeRest(simpleType1()),
3638+
fallbackTree = Ident(tpnme.ERROR))
3639+
// Using Ident(tpnme.ERROR) to avoid causing cascade errors on non-user-written code
36383640
if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t
3639-
}
36403641

36413642
/** ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp}
36423643
*/

docs/docs/internals/syntax.md

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,10 @@ Literal ::= SimpleLiteral
128128
QualId ::= id {‘.’ id}
129129
ids ::= id {‘,’ id}
130130
131-
Path ::= StableId
131+
SimpleRef ::= id
132132
| [id ‘.’] ‘this’
133-
StableId ::= id
134-
| Path ‘.’ id
135133
| [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id
134+
136135
ClassQualifier ::= ‘[’ id ‘]’
137136
```
138137

@@ -153,17 +152,25 @@ InfixType ::= RefinedType {id [nl] RefinedType}
153152
RefinedType ::= WithType {[nl | colonEol] Refinement} RefinedTypeTree(t, ds)
154153
WithType ::= AnnotType {‘with’ AnnotType} (deprecated)
155154
AnnotType ::= SimpleType {Annotation} Annotated(t, annot)
156-
SimpleType ::= SimpleType TypeArgs AppliedTypeTree(t, args)
157-
| SimpleType ‘#’ id Select(t, name)
158-
| StableId
159-
| Path ‘.’ ‘type’ SingletonTypeTree(p)
160-
| ‘(’ ArgTypes ‘)’ Tuple(ts)
155+
156+
SimpleType ::= SimpleLiteral SingletonTypeTree(l)
161157
| ‘?’ SubtypeBounds
158+
| SimpleType ‘(’ Singletons ‘)’
159+
| SimpleType1
160+
SimpleType1 ::= id Ident(name)
161+
| Singleton ‘.’ id Select(t, name)
162+
| Singleton ‘.’ ‘type’ SingletonTypeTree(p)
163+
| ‘(’ ArgTypes ‘)’ Tuple(ts)
162164
| Refinement RefinedTypeTree(EmptyTree, refinement)
163-
| SimpleLiteral SingletonTypeTree(l)
164165
| ‘$’ ‘{’ Block ‘}’
165-
ArgTypes ::= Type {‘,’ Type}
166-
| NamedTypeArg {‘,’ NamedTypeArg}
166+
| SimpleType1 TypeArgs AppliedTypeTree(t, args)
167+
| SimpleType1 ‘#’ id Select(t, name)
168+
Singleton ::= SimpleRef
169+
| Singleton ‘.’ id
170+
-- not yet | Singleton ‘(’ Singletons ‘)’
171+
-- not yet | Singleton ‘[’ ArgTypes ‘]’
172+
Singletons ::= Singleton { ‘,’ Singleton }
173+
ArgTypes ::= Types
167174
FunArgType ::= Type
168175
| ‘=>’ Type PrefixOp(=>, t)
169176
ParamType ::= [‘=>’] ParamValueType
@@ -209,7 +216,7 @@ InfixExpr ::= PrefixExpr
209216
| InfixExpr MatchClause
210217
MatchClause ::= ‘match’ ‘{’ CaseClauses ‘}’ Match(expr, cases)
211218
PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr PrefixOp(expr, op)
212-
SimpleExpr ::= Path
219+
SimpleExpr ::= SimpleRef
213220
| Literal
214221
| ‘_’
215222
| BlockExpr
@@ -271,7 +278,7 @@ SimplePattern ::= PatVar
271278
| Quoted
272279
| XmlPattern
273280
| SimplePattern1 [TypeArgs] [ArgumentPatterns]
274-
SimplePattern1 ::= Path
281+
SimplePattern1 ::= SimpleRef
275282
| SimplePattern1 ‘.’ id
276283
PatVar ::= varid
277284
| ‘_’
@@ -335,7 +342,7 @@ AccessQualifier ::= ‘[’ id ‘]’
335342
Annotation ::= ‘@’ SimpleType {ParArgumentExprs} Apply(tpe, args)
336343
337344
Import ::= ‘import’ ImportExpr {‘,’ ImportExpr}
338-
ImportExpr ::= StableId ‘.’ ImportSpec Import(expr, sels)
345+
ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec Import(expr, sels)
339346
ImportSpec ::= id
340347
| ‘_’
341348
| ‘{’ ImportSelectors) ‘}’
@@ -398,7 +405,7 @@ ExtParamClause ::= [DefTypeParamClause] ‘(’ DefParam ‘)’
398405
Template ::= InheritClauses [TemplateBody] Template(constr, parents, self, stats)
399406
InheritClauses ::= [‘extends’ ConstrApps] [‘derives’ QualId {‘,’ QualId}]
400407
ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp}
401-
ConstrApp ::= AnnotType {ParArgumentExprs} Apply(tp, args)
408+
ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs} Apply(tp, args)
402409
ConstrExpr ::= SelfInvocation
403410
| ‘{’ SelfInvocation {semi BlockStat} ‘}’
404411
SelfInvocation ::= ‘this’ ArgumentExprs {ArgumentExprs}

tests/neg/i4373.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ class X5[A >: _ with X5[_]] // error
99
class X6[A >: X6[_] with _] // error
1010

1111
class A1 extends _ // error
12-
class A2 extends _ with _ // error // error
12+
class A2 extends _ with _ // error
1313
class A3 extends Base with _ // error
1414
class A4 extends _ with Base // error
1515

1616
object Test {
1717
type T1 = _ // error
18-
type T2 = _[Int] // error
18+
type T2 = _[Int] // error // error
1919
type T3 = _ { type S } // error
2020
type T4 = [X] =>> _ // error
2121

tests/neg/i4373c.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// ==> 18b253a4a89a84c5674165c6fc3efafad535eee3.scala <==
22
object x0 {
3-
def x1[x2 <:_[ // error // error
3+
def x1[x2 <:_[ // error
44
// error

0 commit comments

Comments
 (0)