@@ -196,7 +196,6 @@ object Parsers {
196196 def isTemplateIntro = templateIntroTokens contains in.token
197197 def isDclIntro = dclIntroTokens contains in.token
198198 def isStatSeqEnd = in.isNestedEnd || in.token == EOF || in.token == RPAREN
199- def isTemplateBodyStart = in.token == WITH || in.isNestedStart
200199 def mustStartStat = mustStartStatTokens contains in.token
201200
202201 /** Is current token a hard or soft modifier (in modifier position or not)? */
@@ -920,39 +919,6 @@ object Parsers {
920919 val next = in.lookahead.token
921920 next == LBRACKET || next == LPAREN
922921
923- /** Does a template start after `with`? This is the case if either
924- * - the next token is `{`
925- * - the `with` is at the end of a line
926- * (except for source = 3.0-migration, when a warning is issued)
927- * - the next tokens is `<ident>` or `this` and the one after it is `:` or `=>`
928- * (i.e. we see the start of a self type)
929- */
930- def followingIsTemplateStart () =
931- val lookahead = in.LookaheadScanner ()
932- lookahead.nextToken()
933- lookahead.token == LBRACE
934- || lookahead.isAfterLineEnd
935- && {
936- if migrateTo3 then
937- warning(
938- em """ In Scala 3, `with` at the end of a line will start definitions,
939- |so it cannot be used in front of a parent constructor anymore.
940- |Place the `with` at the beginning of the next line instead. """ )
941- false
942- else
943- true
944- }
945- || (lookahead.isIdent || lookahead.token == THIS )
946- && {
947- lookahead.nextToken()
948- lookahead.token == COLON
949- && { // needed only as long as we support significant colon at eol
950- lookahead.nextToken()
951- ! lookahead.isAfterLineEnd
952- }
953- || lookahead.token == ARROW
954- }
955-
956922/* --------- OPERAND/OPERATOR STACK --------------------------------------- */
957923
958924 var opStack : List [OpInfo ] = Nil
@@ -1315,14 +1281,14 @@ object Parsers {
13151281 in.sourcePos())
13161282 patch(source, Span (in.offset), " " )
13171283
1318- def possibleTemplateStart (): Unit =
1284+ def possibleTemplateStart (isNew : Boolean = false ): Unit =
13191285 in.observeColonEOL()
1320- if in.token == COLONEOL then
1286+ if in.token == COLONEOL || in.token == WITH then
13211287 if in.lookahead.isIdent(nme.end) then in.token = NEWLINE
13221288 else
13231289 in.nextToken()
13241290 if in.token != INDENT && in.token != LBRACE then
1325- syntaxErrorOrIncomplete(ExpectedTokenButFound ( INDENT , in.token) )
1291+ syntaxErrorOrIncomplete(i " indented definitions expected, ${in} found " )
13261292 else
13271293 newLineOptWhenFollowedBy(LBRACE )
13281294
@@ -2347,11 +2313,13 @@ object Parsers {
23472313 val start = in.skipToken()
23482314 def reposition (t : Tree ) = t.withSpan(Span (start, in.lastOffset))
23492315 possibleTemplateStart()
2350- val parents = if isTemplateBodyStart then Nil else constrApp() :: withConstrApps()
2316+ val parents =
2317+ if in.isNestedStart then Nil
2318+ else constrApp() :: withConstrApps()
23512319 colonAtEOLOpt()
2352- possibleTemplateStart()
2320+ possibleTemplateStart(isNew = true )
23532321 parents match {
2354- case parent :: Nil if ! isTemplateBodyStart =>
2322+ case parent :: Nil if ! in.isNestedStart =>
23552323 reposition(if (parent.isType) ensureApplied(wrapNew(parent)) else parent)
23562324 case _ =>
23572325 New (reposition(templateBodyOpt(emptyConstructor, parents, Nil )))
@@ -3675,7 +3643,21 @@ object Parsers {
36753643 /** `{`with` ConstrApp} but no EOL allowed after `with`.
36763644 */
36773645 def withConstrApps (): List [Tree ] =
3678- if in.token == WITH && ! followingIsTemplateStart() then
3646+ def isTemplateStart =
3647+ val la = in.lookahead
3648+ la.token == LBRACE
3649+ || la.isAfterLineEnd
3650+ && {
3651+ if migrateTo3 then
3652+ warning(
3653+ em """ In Scala 3, `with` at the end of a line will start definitions,
3654+ |so it cannot be used in front of a parent constructor anymore.
3655+ |Place the `with` at the beginning of the next line instead. """ )
3656+ false
3657+ else
3658+ true
3659+ }
3660+ if in.token == WITH && ! isTemplateStart then
36793661 in.nextToken()
36803662 constrApp() :: withConstrApps()
36813663 else Nil
@@ -3719,66 +3701,32 @@ object Parsers {
37193701 template(constr)
37203702 else
37213703 possibleTemplateStart()
3722- if isTemplateBodyStart then
3704+ if in.isNestedStart then
37233705 template(constr)
37243706 else
37253707 checkNextNotIndented()
37263708 Template (constr, Nil , Nil , EmptyValDef , Nil )
37273709
3728- /** TemplateBody ::= [nl | ‘with’] `{' TemplateStatSeq `}'
3729- * | ‘with’ [SelfType] indent TemplateStats outdent
3730- * EnumBody ::= [nl | ‘with’] ‘{’ [SelfType] EnumStats ‘}’
3731- * | ‘with’ [SelfType] indent EnumStats outdent
3710+ /** TemplateBody ::= [nl] `{' TemplateStatSeq `}'
3711+ * EnumBody ::= [nl] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’
37323712 */
37333713 def templateBodyOpt (constr : DefDef , parents : List [Tree ], derived : List [Tree ]): Template =
37343714 val (self, stats) =
3735- if isTemplateBodyStart then
3715+ if in.isNestedStart then
37363716 templateBody()
37373717 else
37383718 checkNextNotIndented()
37393719 (EmptyValDef , Nil )
37403720 Template (constr, parents, derived, self, stats)
37413721
37423722 def templateBody (): (ValDef , List [Tree ]) =
3743- val givenSelf =
3744- if in.token == WITH then
3745- in.nextToken()
3746- selfDefOpt()
3747- else EmptyValDef
3748- val r = inDefScopeBraces(templateStatSeq(givenSelf), rewriteWithColon = true )
3723+ val r = inDefScopeBraces(templateStatSeq(), rewriteWithColon = true )
37493724 if in.token == WITH then
37503725 syntaxError(EarlyDefinitionsNotSupported ())
37513726 in.nextToken()
37523727 template(emptyConstructor)
37533728 r
37543729
3755- /** SelfType ::= id [‘:’ InfixType] ‘=>’
3756- * | ‘this’ ‘:’ InfixType ‘=>’
3757- * Only called immediately after a `with`, in which case it must in turn
3758- * be followed by `INDENT`.
3759- */
3760- def selfDefOpt (): ValDef = atSpan(in.offset) {
3761- val vd =
3762- if in.isIdent then
3763- val selfName = ident()
3764- if in.token == COLON then
3765- in.nextToken()
3766- makeSelfDef(selfName, infixType())
3767- else
3768- makeSelfDef(selfName, TypeTree ())
3769- else if in.token == THIS then
3770- in.nextToken()
3771- accept(COLON )
3772- makeSelfDef(nme.WILDCARD , infixType())
3773- else
3774- EmptyValDef
3775- if ! vd.isEmpty then
3776- accept(ARROW )
3777- if in.token != INDENT then
3778- syntaxErrorOrIncomplete(ExpectedTokenButFound (INDENT , in.token))
3779- vd
3780- }
3781-
37823730 /** with Template, with EOL <indent> interpreted */
37833731 def withTemplate (constr : DefDef , parents : List [Tree ]): Template =
37843732 if in.token != WITH then syntaxError(em " `with` expected " )
@@ -3852,10 +3800,10 @@ object Parsers {
38523800 * EnumStat ::= TemplateStat
38533801 * | Annotations Modifiers EnumCase
38543802 */
3855- def templateStatSeq (givenSelf : ValDef = EmptyValDef ): (ValDef , List [Tree ]) = checkNoEscapingPlaceholders {
3856- var self = givenSelf
3803+ def templateStatSeq (): (ValDef , List [Tree ]) = checkNoEscapingPlaceholders {
3804+ var self : ValDef = EmptyValDef
38573805 val stats = new ListBuffer [Tree ]
3858- if (self.isEmpty && isExprIntro && ! isDefIntro(modifierTokens)) {
3806+ if (isExprIntro && ! isDefIntro(modifierTokens)) {
38593807 val first = expr1()
38603808 if (in.token == ARROW ) {
38613809 first match {
@@ -4008,7 +3956,7 @@ object Parsers {
40083956 possibleTemplateStart()
40093957 if in.token == EOF then
40103958 ts += makePackaging(start, pkg, List ())
4011- else if isTemplateBodyStart then
3959+ else if in.isNestedStart then
40123960 ts += inDefScopeBraces(makePackaging(start, pkg, topStatSeq()), rewriteWithColon = true )
40133961 continue = true
40143962 else
@@ -4046,7 +3994,6 @@ object Parsers {
40463994 }
40473995
40483996 override def templateBody (): (ValDef , List [Thicket ]) = {
4049- if in.token == WITH then in.nextToken()
40503997 skipBraces()
40513998 (EmptyValDef , List (EmptyTree ))
40523999 }
0 commit comments