@@ -1045,6 +1045,9 @@ object Parsers {
10451045 if in.token == MATCH then matchClause(t) else Select (t, ident())
10461046 }
10471047
1048+ def idSelector (t : Tree ): Tree =
1049+ atSpan(startOffset(t), in.offset) { Select (t, ident()) }
1050+
10481051 /** Selectors ::= id { `.' id }
10491052 *
10501053 * Accept `.' separated identifiers acting as a selectors on given tree `t`.
@@ -1066,59 +1069,53 @@ object Parsers {
10661069 if (in.token == DOT ) { in.nextToken(); selectors(t, finish) }
10671070 else t
10681071
1072+ def dotSelections (t : Tree ): Tree =
1073+ if (in.token == DOT ) { in.nextToken(); dotSelections(t) }
1074+ else t
1075+
10691076 private val id : Tree => Tree = x => x
10701077
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
10781081 */
1079- def path ( thisOK : Boolean , finish : Tree => Tree = id ): Tree = {
1082+ def simpleRef ( ): Tree =
10801083 val start = in.offset
1081- def handleThis (qual : Ident ) = {
1084+
1085+ def handleThis (qual : Ident ) =
10821086 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 ) =
10881090 in.nextToken()
10891091 val mix = mixinQualifierOpt()
10901092 val t = atSpan(start) { Super (This (qual), mix) }
10911093 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
10971099 val t = termIdent()
1098- if ( in.token == DOT ) {
1100+ if in.token == DOT then
10991101 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
11051110 else t
1106- }
1107- }
1111+ end simpleRef
11081112
11091113 /** MixinQualifier ::= `[' id `]'
11101114 */
11111115 def mixinQualifierOpt (): Ident =
11121116 if (in.token == LBRACKET ) inBrackets(atSpan(in.offset) { typeIdent() })
11131117 else EmptyTypeIdent
11141118
1115- /** StableId ::= id
1116- * | Path `.' id
1117- * | [id '.'] super [`[' id `]']`.' id
1118- */
1119- def stableId (): Tree =
1120- path(thisOK = false )
1121-
11221119 /** QualId ::= id {`.' id}
11231120 */
11241121 def qualId (): Tree = dotSelectors(termIdent())
@@ -1577,8 +1574,8 @@ object Parsers {
15771574
15781575 /** SimpleType ::= SimpleType TypeArgs
15791576 * | SimpleType `#' id
1580- * | StableId
1581- * | Path `.' type
1577+ * | Singleton `.' id
1578+ * | Singleton `.' type
15821579 * | `(' ArgTypes `)'
15831580 * | `_' TypeBounds
15841581 * | Refinement
@@ -1613,18 +1610,22 @@ object Parsers {
16131610 }
16141611 else if (isSplice)
16151612 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())
16201615 }
16211616
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
16241622 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)
16281629
16291630 private def simpleTypeRest (t : Tree ): Tree = in.token match {
16301631 case HASH => simpleTypeRest(typeProjection(t))
@@ -2207,7 +2208,7 @@ object Parsers {
22072208 * | SimpleExpr1 [`_`]
22082209 * SimpleExpr1 ::= literal
22092210 * | xmlLiteral
2210- * | Path
2211+ * | SimpleRef
22112212 * | `(` [ExprsInParens] `)`
22122213 * | SimpleExpr `.` id
22132214 * | SimpleExpr `.` MatchClause
@@ -2223,9 +2224,9 @@ object Parsers {
22232224 xmlLiteral()
22242225 case IDENTIFIER =>
22252226 if (isSplice) splice(isType = false )
2226- else path(thisOK = true )
2227+ else simpleRef( )
22272228 case BACKQUOTED_IDENT | THIS | SUPER =>
2228- path(thisOK = true )
2229+ simpleRef( )
22292230 case USCORE =>
22302231 val start = in.skipToken()
22312232 val pname = WildcardParamName .fresh()
@@ -2658,17 +2659,16 @@ object Parsers {
26582659 * | XmlPattern
26592660 * | `(' [Patterns] `)'
26602661 * | SimplePattern1 [TypeArgs] [ArgumentPatterns]
2661- * SimplePattern1 ::= Path
2662+ * SimplePattern1 ::= SimpleRef
26622663 * | SimplePattern1 `.' id
26632664 * PatVar ::= id
26642665 * | `_'
26652666 */
26662667 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
26692670 case id @ Ident (nme.raw.MINUS ) if isNumericLit => literal(startOffset(id))
26702671 case t => simplePatternRest(t)
2671- }
26722672 case USCORE =>
26732673 val wildIdent = wildcardIdent()
26742674
@@ -2694,14 +2694,17 @@ object Parsers {
26942694 }
26952695 }
26962696
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
27052708
27062709 /** Patterns ::= Pattern [`,' Pattern]
27072710 */
@@ -3088,7 +3091,7 @@ object Parsers {
30883091 ctx.compilationUnit.sourceVersion = Some (SourceVersion .valueOf(imported.toString))
30893092 Import (tree, selectors)
30903093
3091- /** ImportExpr ::= StableId ‘.’ ImportSpec
3094+ /** ImportExpr ::= SimpleRef {‘.’ id} ‘.’ ImportSpec
30923095 * ImportSpec ::= id
30933096 * | ‘_’
30943097 * | ‘{’ ImportSelectors) ‘}’
@@ -3135,26 +3138,24 @@ object Parsers {
31353138 Nil
31363139 selector :: rest
31373140
3138- val handleImport : Tree => Tree = tree =>
3141+ def importSelection (qual : Tree ): Tree =
3142+ accept(DOT )
31393143 in.token match
31403144 case USCORE =>
3141- mkTree(tree , ImportSelector (wildcardSelectorId()) :: Nil )
3145+ mkTree(qual , ImportSelector (wildcardSelectorId()) :: Nil )
31423146 case LBRACE =>
3143- mkTree(tree , inBraces(importSelectors(idOK = true )))
3147+ mkTree(qual , inBraces(importSelectors(idOK = true )))
31443148 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())
31583159 }
31593160
31603161 def posMods (start : Int , mods : Modifiers ): Modifiers = {
0 commit comments