@@ -889,6 +889,16 @@ object Parsers {
889889 val next = in.lookahead.token
890890 next == LBRACKET || next == LPAREN
891891
892+
893+ def followingIsSelfType () =
894+ val lookahead = in.LookaheadScanner ()
895+ lookahead.nextToken()
896+ lookahead.token == COLON
897+ && {
898+ lookahead.nextToken()
899+ canStartTypeTokens(lookahead.token)
900+ }
901+
892902 /** Is current ident a `*`, and is it followed by a `)`, `, )`, `,EOF`? The latter two are not
893903 syntactically valid, but we need to include them here for error recovery. */
894904 def followingIsVararg (): Boolean =
@@ -3901,7 +3911,37 @@ object Parsers {
39013911 stats.toList
39023912 }
39033913
3904- /** TemplateStatSeq ::= [id [`:' Type] `=>'] TemplateStat {semi TemplateStat}
3914+ /** SelfType ::= id [‘:’ InfixType] ‘=>’
3915+ * | ‘this’ ‘:’ InfixType ‘=>’
3916+ */
3917+ def selfType (): ValDef =
3918+ if (in.isIdent || in.token == THIS )
3919+ && (in.lookahead.token == COLON && followingIsSelfType()
3920+ || in.lookahead.token == ARROW )
3921+ then
3922+ atSpan(in.offset) {
3923+ val selfName =
3924+ if in.token == THIS then
3925+ in.nextToken()
3926+ nme.WILDCARD
3927+ else ident()
3928+ val selfTpt =
3929+ if in.token == COLON then
3930+ in.nextToken()
3931+ infixType()
3932+ else
3933+ if selfName == nme.WILDCARD then accept(COLON )
3934+ TypeTree ()
3935+ if in.token == ARROW then
3936+ in.token = SELFARROW // suppresses INDENT insertion after `=>`
3937+ in.nextToken()
3938+ else
3939+ syntaxError(" `=>` expected after self type" )
3940+ makeSelfDef(selfName, selfTpt)
3941+ }
3942+ else EmptyValDef
3943+
3944+ /** TemplateStatSeq ::= [SelfType] TemplateStat {semi TemplateStat}
39053945 * TemplateStat ::= Import
39063946 * | Export
39073947 * | Annotations Modifiers Def
@@ -3913,25 +3953,8 @@ object Parsers {
39133953 * | Annotations Modifiers EnumCase
39143954 */
39153955 def templateStatSeq (): (ValDef , List [Tree ]) = checkNoEscapingPlaceholders {
3916- var self : ValDef = EmptyValDef
39173956 val stats = new ListBuffer [Tree ]
3918- if isExprIntro && ! isDefIntro(modifierTokens) then
3919- val first = expr1()
3920- if in.token == ARROW then
3921- first match {
3922- case Typed (tree @ This (EmptyTypeIdent ), tpt) =>
3923- self = makeSelfDef(nme.WILDCARD , tpt).withSpan(first.span)
3924- case _ =>
3925- val ValDef (name, tpt, _) = convertToParam(first, EmptyModifiers , " self type clause" )
3926- if (name != nme.ERROR )
3927- self = makeSelfDef(name, tpt).withSpan(first.span)
3928- }
3929- in.token = SELFARROW // suppresses INDENT insertion after `=>`
3930- in.nextToken()
3931- else
3932- stats += first
3933- statSepOrEnd(stats)
3934- end if
3957+ val self = selfType()
39353958 while
39363959 var empty = false
39373960 if (in.token == IMPORT )
0 commit comments