@@ -1045,6 +1045,9 @@ object Parsers {
1045
1045
if in.token == MATCH then matchClause(t) else Select (t, ident())
1046
1046
}
1047
1047
1048
+ def idSelector (t : Tree ): Tree =
1049
+ atSpan(startOffset(t), in.offset) { Select (t, ident()) }
1050
+
1048
1051
/** Selectors ::= id { `.' id }
1049
1052
*
1050
1053
* Accept `.' separated identifiers acting as a selectors on given tree `t`.
@@ -1066,59 +1069,53 @@ object Parsers {
1066
1069
if (in.token == DOT ) { in.nextToken(); selectors(t, finish) }
1067
1070
else t
1068
1071
1072
+ def dotSelections (t : Tree ): Tree =
1073
+ if (in.token == DOT ) { in.nextToken(); dotSelections(t) }
1074
+ else t
1075
+
1069
1076
private val id : Tree => Tree = x => x
1070
1077
1071
- /** Path ::= StableId
1072
- * | [id `.'] this
1073
- *
1074
- * @param thisOK If true, the path can end with the keyword `this`.
1075
- * If false, another selection is required after the `this`.
1076
- * @param finish An alternative parse in case the token following a `.' is not an identifier.
1077
- * If the alternative does not apply, its tree argument is returned unchanged.
1078
+ /** SimpleRef ::= id
1079
+ * | [id ‘.’] ‘this’
1080
+ * | [id ‘.’] ‘super’ [ClassQualifier] ‘.’ id
1078
1081
*/
1079
- def path ( thisOK : Boolean , finish : Tree => Tree = id ): Tree = {
1082
+ def simpleRef ( ): Tree =
1080
1083
val start = in.offset
1081
- def handleThis (qual : Ident ) = {
1084
+
1085
+ def handleThis (qual : Ident ) =
1082
1086
in.nextToken()
1083
- val t = atSpan(start) { This (qual) }
1084
- if (! thisOK && in.token != DOT ) syntaxError(DanglingThisInPath (), t.span)
1085
- dotSelectors(t, finish)
1086
- }
1087
- def handleSuper (qual : Ident ) = {
1087
+ atSpan(start) { This (qual) }
1088
+
1089
+ def handleSuper (qual : Ident ) =
1088
1090
in.nextToken()
1089
1091
val mix = mixinQualifierOpt()
1090
1092
val t = atSpan(start) { Super (This (qual), mix) }
1091
1093
accept(DOT )
1092
- dotSelectors(selector(t), finish )
1093
- }
1094
- if ( in.token == THIS ) handleThis(EmptyTypeIdent )
1095
- else if ( in.token == SUPER ) handleSuper(EmptyTypeIdent )
1096
- else {
1094
+ idSelector(t )
1095
+
1096
+ if in.token == THIS then handleThis(EmptyTypeIdent )
1097
+ else if in.token == SUPER then handleSuper(EmptyTypeIdent )
1098
+ else
1097
1099
val t = termIdent()
1098
- if ( in.token == DOT ) {
1100
+ if in.token == DOT then
1099
1101
def qual = cpy.Ident (t)(t.name.toTypeName)
1100
- in.nextToken()
1101
- if (in.token == THIS ) handleThis(qual)
1102
- else if (in.token == SUPER ) handleSuper(qual)
1103
- else selectors(t, finish)
1104
- }
1102
+ in.lookahead.token match
1103
+ case THIS =>
1104
+ in.nextToken()
1105
+ handleThis(qual)
1106
+ case SUPER =>
1107
+ in.nextToken()
1108
+ handleSuper(qual)
1109
+ case _ => t
1105
1110
else t
1106
- }
1107
- }
1111
+ end simpleRef
1108
1112
1109
1113
/** MixinQualifier ::= `[' id `]'
1110
1114
*/
1111
1115
def mixinQualifierOpt (): Ident =
1112
1116
if (in.token == LBRACKET ) inBrackets(atSpan(in.offset) { typeIdent() })
1113
1117
else EmptyTypeIdent
1114
1118
1115
- /** StableId ::= id
1116
- * | Path `.' id
1117
- * | [id '.'] super [`[' id `]']`.' id
1118
- */
1119
- def stableId (): Tree =
1120
- path(thisOK = false )
1121
-
1122
1119
/** QualId ::= id {`.' id}
1123
1120
*/
1124
1121
def qualId (): Tree = dotSelectors(termIdent())
@@ -1577,8 +1574,8 @@ object Parsers {
1577
1574
1578
1575
/** SimpleType ::= SimpleType TypeArgs
1579
1576
* | SimpleType `#' id
1580
- * | StableId
1581
- * | Path `.' type
1577
+ * | Singleton `.' id
1578
+ * | Singleton `.' type
1582
1579
* | `(' ArgTypes `)'
1583
1580
* | `_' TypeBounds
1584
1581
* | Refinement
@@ -1613,18 +1610,22 @@ object Parsers {
1613
1610
}
1614
1611
else if (isSplice)
1615
1612
splice(isType = true )
1616
- else path(thisOK = false , handleSingletonType) match {
1617
- case r @ SingletonTypeTree (_) => r
1618
- case r => convertToTypeId(r)
1619
- }
1613
+ else
1614
+ singletonCompletion(simpleRef())
1620
1615
}
1621
1616
1622
- val handleSingletonType : Tree => Tree = t =>
1623
- if (in.token == TYPE ) {
1617
+ /** Singleton ::= SimpleRef
1618
+ * | Singleton ‘.’ id
1619
+ */
1620
+ def singletonCompletion (t : Tree ): Tree =
1621
+ if in.token == DOT then
1624
1622
in.nextToken()
1625
- atSpan(startOffset(t)) { SingletonTypeTree (t) }
1626
- }
1627
- else t
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)
1628
1629
1629
1630
private def simpleTypeRest (t : Tree ): Tree = in.token match {
1630
1631
case HASH => simpleTypeRest(typeProjection(t))
@@ -2207,7 +2208,7 @@ object Parsers {
2207
2208
* | SimpleExpr1 [`_`]
2208
2209
* SimpleExpr1 ::= literal
2209
2210
* | xmlLiteral
2210
- * | Path
2211
+ * | SimpleRef
2211
2212
* | `(` [ExprsInParens] `)`
2212
2213
* | SimpleExpr `.` id
2213
2214
* | SimpleExpr `.` MatchClause
@@ -2223,9 +2224,9 @@ object Parsers {
2223
2224
xmlLiteral()
2224
2225
case IDENTIFIER =>
2225
2226
if (isSplice) splice(isType = false )
2226
- else path(thisOK = true )
2227
+ else simpleRef( )
2227
2228
case BACKQUOTED_IDENT | THIS | SUPER =>
2228
- path(thisOK = true )
2229
+ simpleRef( )
2229
2230
case USCORE =>
2230
2231
val start = in.skipToken()
2231
2232
val pname = WildcardParamName .fresh()
@@ -2658,17 +2659,16 @@ object Parsers {
2658
2659
* | XmlPattern
2659
2660
* | `(' [Patterns] `)'
2660
2661
* | SimplePattern1 [TypeArgs] [ArgumentPatterns]
2661
- * SimplePattern1 ::= Path
2662
+ * SimplePattern1 ::= SimpleRef
2662
2663
* | SimplePattern1 `.' id
2663
2664
* PatVar ::= id
2664
2665
* | `_'
2665
2666
*/
2666
2667
val simplePattern : () => Tree = () => in.token match {
2667
- case IDENTIFIER | BACKQUOTED_IDENT | THIS =>
2668
- path(thisOK = true ) match {
2668
+ case IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER =>
2669
+ simpleRef( ) match
2669
2670
case id @ Ident (nme.raw.MINUS ) if isNumericLit => literal(startOffset(id))
2670
2671
case t => simplePatternRest(t)
2671
- }
2672
2672
case USCORE =>
2673
2673
val wildIdent = wildcardIdent()
2674
2674
@@ -2694,14 +2694,17 @@ object Parsers {
2694
2694
}
2695
2695
}
2696
2696
2697
- def simplePatternRest (t : Tree ): Tree = {
2698
- var p = t
2699
- if (in.token == LBRACKET )
2700
- p = atSpan(startOffset(t), in.offset) { TypeApply (p, typeArgs(namedOK = false , wildOK = false )) }
2701
- if (in.token == LPAREN )
2702
- p = atSpan(startOffset(t), in.offset) { Apply (p, argumentPatterns()) }
2703
- p
2704
- }
2697
+ def simplePatternRest (t : Tree ): Tree =
2698
+ if in.token == DOT then
2699
+ in.nextToken()
2700
+ simplePatternRest(idSelector(t))
2701
+ else
2702
+ var p = t
2703
+ if (in.token == LBRACKET )
2704
+ p = atSpan(startOffset(t), in.offset) { TypeApply (p, typeArgs(namedOK = false , wildOK = false )) }
2705
+ if (in.token == LPAREN )
2706
+ p = atSpan(startOffset(t), in.offset) { Apply (p, argumentPatterns()) }
2707
+ p
2705
2708
2706
2709
/** Patterns ::= Pattern [`,' Pattern]
2707
2710
*/
@@ -3088,7 +3091,7 @@ object Parsers {
3088
3091
ctx.compilationUnit.sourceVersion = Some (SourceVersion .valueOf(imported.toString))
3089
3092
Import (tree, selectors)
3090
3093
3091
- /** ImportExpr ::= StableId ‘.’ ImportSpec
3094
+ /** ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec
3092
3095
* ImportSpec ::= id
3093
3096
* | ‘_’
3094
3097
* | ‘{’ ImportSelectors) ‘}’
@@ -3135,26 +3138,24 @@ object Parsers {
3135
3138
Nil
3136
3139
selector :: rest
3137
3140
3138
- val handleImport : Tree => Tree = tree =>
3141
+ def importSelection (qual : Tree ): Tree =
3142
+ accept(DOT )
3139
3143
in.token match
3140
3144
case USCORE =>
3141
- mkTree(tree , ImportSelector (wildcardSelectorId()) :: Nil )
3145
+ mkTree(qual , ImportSelector (wildcardSelectorId()) :: Nil )
3142
3146
case LBRACE =>
3143
- mkTree(tree , inBraces(importSelectors(idOK = true )))
3147
+ mkTree(qual , inBraces(importSelectors(idOK = true )))
3144
3148
case _ =>
3145
- tree
3146
-
3147
- () => {
3148
- val p = path(thisOK = false , handleImport)
3149
- p match
3150
- case _ : Import | _ : Export => p
3151
- case sel @ Select (qual, name) =>
3152
- val selector = ImportSelector (atSpan(pointOffset(sel)) { Ident (name) })
3153
- mkTree(qual, selector :: Nil ).withSpan(sel.span)
3154
- case t =>
3155
- accept(DOT )
3156
- mkTree(t, ImportSelector (Ident (nme.WILDCARD )) :: Nil )
3157
- }
3149
+ val start = in.offset
3150
+ val name = ident()
3151
+ if in.token == DOT then
3152
+ importSelection(atSpan(startOffset(qual), start) { Select (qual, name) })
3153
+ else
3154
+ atSpan(startOffset(qual)) {
3155
+ mkTree(qual, ImportSelector (atSpan(start) { Ident (name) }) :: Nil )
3156
+ }
3157
+
3158
+ () => importSelection(simpleRef())
3158
3159
}
3159
3160
3160
3161
def posMods (start : Int , mods : Modifiers ): Modifiers = {
0 commit comments