Skip to content

Commit

Permalink
Merge commit '35c6f5d026' into 2.13.x
Browse files Browse the repository at this point in the history
  • Loading branch information
lrytz committed Jun 9, 2022
2 parents 09c4cd5 + 35c6f5d commit eb014d8
Show file tree
Hide file tree
Showing 24 changed files with 212 additions and 159 deletions.
2 changes: 0 additions & 2 deletions src/compiler/scala/tools/nsc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
}
}

class PostfixSelect(qual: Tree, name: Name) extends Select(qual, name)

/** emitted by typer, eliminated by refchecks */
case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree {
override def transform(transformer: ApiTransformer): Tree =
Expand Down
11 changes: 5 additions & 6 deletions src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ trait MarkupParsers {
xTakeUntil(handle.charData, () => r2p(start, mid, curOffset), "]]>")
}

def xUnparsed: Tree = {
val start = curOffset
def xUnparsed(start: Int): Tree = {
xTakeUntil(handle.unparsed, () => r2p(start, start, curOffset), "</xml:unparsed>")
}

Expand Down Expand Up @@ -305,7 +304,7 @@ trait MarkupParsers {
* | xmlTag1 '/' '>'
*/
def element: Tree = {
val start = curOffset
val start = curOffset - 1 // include <
val (qname, attrMap) = xTag(())
if (ch == '/') { // empty element
xToken("/>")
Expand All @@ -314,7 +313,7 @@ trait MarkupParsers {
else { // handle content
xToken('>')
if (qname == "xml:unparsed")
return xUnparsed
return xUnparsed(start)

debugLastStartElement.push((start, qname))
val ts = content
Expand Down Expand Up @@ -382,7 +381,7 @@ trait MarkupParsers {
handle.isPattern = false

val ts = new ArrayBuffer[Tree]
val start = curOffset
val start = curOffset - 1 // include <
content_LT(ts)

// parse more XML?
Expand Down Expand Up @@ -446,7 +445,7 @@ trait MarkupParsers {
* | Name [S] '/' '>'
*/
def xPattern: Tree = {
val start = curOffset
val start = curOffset - 1 // include <
val qname = xName
debugLastStartElement.push((start, qname))
xSpaceOpt()
Expand Down
55 changes: 31 additions & 24 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ self =>
case _ => right :: Nil
}
def mkApply(fun: Tree, args: List[Tree]) = {
val apply = Apply(fun, args)
val apply = Apply(fun, args).updateAttachment(InfixAttachment)
if (isMultiarg) apply.updateAttachment(MultiargInfixAttachment)
apply
}
Expand Down Expand Up @@ -1301,12 +1301,12 @@ self =>

def identOrMacro(): Name = if (isMacro) rawIdent() else ident()

def selector(t0: Tree): Tree = {
def selector(start: Offset, t0: Tree): Tree = {
val t = stripParens(t0)
val point = if (isIdent) in.offset else in.lastOffset //scala/bug#8459
//assert(t.pos.isDefined, t)
if (t != EmptyTree)
Select(t, ident(skipIt = false)) setPos r2p(t0.pos.start, point, in.lastOffset)
Select(t, ident(skipIt = false)) setPos r2p(start, point, in.lastOffset)
else
errorTermTree // has already been reported
}
Expand All @@ -1324,14 +1324,14 @@ self =>
in.nextToken()
t = atPos(start) { This(tpnme.EMPTY) }
if (!thisOK || in.token == DOT) {
t = selectors(t, typeOK, accept(DOT))
t = selectors(start, t, typeOK, accept(DOT))
}
} else if (in.token == SUPER) {
in.nextToken()
t = atPos(start) { Super(This(tpnme.EMPTY), mixinQualifierOpt()) }
accept(DOT)
t = selector(t)
if (in.token == DOT) t = selectors(t, typeOK, in.skipToken())
t = selector(start, t)
if (in.token == DOT) t = selectors(start, t, typeOK, in.skipToken())
} else {
val tok = in.token
val name = ident()
Expand All @@ -1345,31 +1345,31 @@ self =>
in.nextToken()
t = atPos(start) { This(name.toTypeName) }
if (!thisOK || in.token == DOT)
t = selectors(t, typeOK, accept(DOT))
t = selectors(start, t, typeOK, accept(DOT))
} else if (in.token == SUPER) {
in.nextToken()
t = atPos(start) { Super(This(name.toTypeName), mixinQualifierOpt()) }
accept(DOT)
t = selector(t)
if (in.token == DOT) t = selectors(t, typeOK, in.skipToken())
t = selector(start, t)
if (in.token == DOT) t = selectors(start, t, typeOK, in.skipToken())
} else {
if (name == nme.ROOTPKG) t.updateAttachment(RootSelection)
t = selectors(t, typeOK, dotOffset)
t = selectors(start, t, typeOK, dotOffset)
}
}
}
t
}

@tailrec
final def selectors(t: Tree, typeOK: Boolean, dotOffset: Offset): Tree =
final def selectors(start: Offset, t: Tree, typeOK: Boolean, dotOffset: Offset): Tree =
if (typeOK && in.token == TYPE) {
in.nextToken()
atPos(t.pos.start, dotOffset) { SingletonTypeTree(t) }
}
else {
val t1 = selector(t)
if (in.token == DOT) { selectors(t1, typeOK, in.skipToken()) }
val t1 = selector(start, t)
if (in.token == DOT) { selectors(start, t1, typeOK, in.skipToken()) }
else t1
}

Expand Down Expand Up @@ -1399,7 +1399,7 @@ self =>
val id = atPos(start) { Ident(ident()) }
if (in.token == DOT) {
if (id.name == nme.ROOTPKG) id.updateAttachment(RootSelection)
selectors(id, typeOK = false, in.skipToken())
selectors(start, id, typeOK = false, in.skipToken())
}
else id
}
Expand Down Expand Up @@ -1813,20 +1813,21 @@ self =>
* }}}
*/
def prefixExpr(): Tree =
if (isUnaryOp)
atPos(in.offset) {
if (isUnaryOp) {
val start = in.offset
atPos(start) {
if (lookingAhead(isExprIntro)) {
val namePos = in.offset
val uname = nme.toUnaryName(rawIdent().toTermName)
if (uname == nme.UNARY_- && isNumericLit)
// start at the -, not the number
simpleExprRest(literal(isNegated = true, start = namePos), canApply = true)
simpleExprRest(start, literal(isNegated = true, start = namePos), canApply = true)
else
Select(stripParens(simpleExpr()), uname)
}
else simpleExpr()
}
else simpleExpr()
} else simpleExpr()

def xmlLiteral(): Tree

Expand All @@ -1845,6 +1846,7 @@ self =>
*/
def simpleExpr(): Tree = {
var canApply = true
val start = in.offset
val t =
if (isLiteral) literal()
else in.token match {
Expand All @@ -1870,16 +1872,16 @@ self =>
case _ =>
syntaxErrorOrIncompleteAnd("illegal start of simple expression", skipIt = true)(errorTermTree)
}
simpleExprRest(t, canApply = canApply)
simpleExprRest(start, t, canApply = canApply)
}

@tailrec
final def simpleExprRest(t: Tree, canApply: Boolean): Tree = {
final def simpleExprRest(start: Offset, t: Tree, canApply: Boolean): Tree = {
if (canApply) newLineOptWhenFollowedBy(LBRACE)
in.token match {
case DOT =>
in.nextToken()
simpleExprRest(selector(t), canApply = true)
simpleExprRest(start, selector(start, t), canApply = true)
case LBRACKET =>
val t1 = stripParens(t)
t1 match {
Expand All @@ -1888,7 +1890,7 @@ self =>
while (in.token == LBRACKET)
app = atPos(t.pos.start, in.offset)(TypeApply(app, exprTypeArgs()))

simpleExprRest(app, canApply = true)
simpleExprRest(start, app, canApply = true)
case _ =>
t1
}
Expand All @@ -1904,7 +1906,7 @@ self =>
}
Apply(sel, argumentExprs())
}
simpleExprRest(app, canApply = true)
simpleExprRest(start, app, canApply = true)
case USCORE =>
atPos(t.pos.start, in.skipToken()) { MethodValue(stripParens(t)) }
case _ =>
Expand Down Expand Up @@ -1938,9 +1940,14 @@ self =>
* }}}
*/
def blockExpr(): Tree = atPos(in.offset) {
val start = in.offset
inBraces {
if (in.token == CASE) Match(EmptyTree, caseClauses())
else block()
} match {
case b: Block if b.pos == NoPosition =>
b.setPos(r2p(start, start, in.lastOffset))
case t => t
}
}

Expand Down Expand Up @@ -2661,7 +2668,7 @@ self =>
in.nextToken()
val t = atPos(start)(This(name))
accept(DOT)
val result = selector(t)
val result = selector(start, t)
accept(DOT)
result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
val buffer = ValDef(NoMods, _buf, TypeTree(), New(_scala_xml_NodeBuffer, ListOfNil))
val applies = args filterNot isEmptyText map (t => Apply(Select(Ident(_buf), _plus), List(t)))

atPos(pos)( Block(buffer :: applies.toList, Ident(_buf)) )
atPos(pos)( gen.mkBlock(buffer :: applies.toList ::: List(Ident(_buf))) )
}

/** Returns (Some(prefix) | None, rest) based on position of ':' */
Expand Down Expand Up @@ -271,6 +271,6 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
args
)

atPos(pos.makeTransparent)( Block(nsResult, Block(attrResult, body)) )
atPos(pos.makeTransparent)( gen.mkBlock(nsResult :+ gen.mkBlock(attrResult :+ body)) )
}
}
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ abstract class TreeBuilder {

/** Tree for `od op`, start is start0 if od.pos is borked. */
def makePostfixSelect(start: Int, end: Int, od: Tree, op: Name): Tree = {
atPos(r2p(start, end, end + op.length)) { new PostfixSelect(od, op.encode) }
atPos(r2p(start, end, end + op.length)) { Select(od, op.encode) }.updateAttachment(PostfixAttachment)
}

/** Create tree representing a while loop */
Expand Down
9 changes: 6 additions & 3 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -967,8 +967,11 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}

if (!meth.isConstructor && checkCanEtaExpand()) typedEtaExpansion(tree, mode, pt)
else if (arity == 0 && checkCanAutoApply()) adapt(typed(Apply(tree, Nil) setPos tree.pos), mode, pt, original)
else
else if (arity == 0 && checkCanAutoApply()) {
val apply = Apply(tree, Nil) setPos tree.pos
if (tree.hasAttachment[PostfixAttachment.type]) apply.updateAttachment(InfixAttachment)
adapt(typed(apply), mode, pt, original)
} else
if (context.implicitsEnabled) MissingArgsForMethodTpeError(tree, meth) // `context.implicitsEnabled` implies we are not in a pattern
else UnstableTreeError(tree)
}
Expand Down Expand Up @@ -5426,7 +5429,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val qualTyped = checkDead(context, typedQualifier(qual, mode))
val tree1 = typedSelect(tree, qualTyped, name)

if (tree.isInstanceOf[PostfixSelect])
if (tree.hasAttachment[PostfixAttachment.type])
checkFeature(tree.pos, currentRun.runDefinitions.PostfixOpsFeature, name.decode)
val sym = tree1.symbol
if (sym != null && sym.isOnlyRefinementMember && !sym.isMacro)
Expand Down
5 changes: 5 additions & 0 deletions src/reflect/scala/reflect/internal/StdAttachments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ trait StdAttachments {
*/
case object BackquotedIdentifierAttachment extends PlainAttachment

/** Indicates that a selection was postfix (on Select tree) */
case object PostfixAttachment extends PlainAttachment
/** Indicates that a application was infix (on Apply tree) */
case object InfixAttachment extends PlainAttachment

/** A pattern binding exempt from unused warning.
*
* Its host `Ident` has been created from a pattern2 binding, `case x @ p`.
Expand Down
2 changes: 2 additions & 0 deletions src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.SAMFunction
this.DelambdafyTarget
this.BackquotedIdentifierAttachment
this.PostfixAttachment
this.InfixAttachment
this.NoWarnAttachment
this.PatVarDefAttachment
this.ForAttachment
Expand Down
2 changes: 1 addition & 1 deletion src/repl/scala/tools/nsc/interpreter/IMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,7 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
// This is really just trying to make the 100 or so implicits imported
// by default into something readable.
val memberGroups: List[List[Symbol]] = {
val groups = members groupBy (_.tpe.finalResultType) toList
val groups = members.groupBy(_.tpe.finalResultType).toList
val (big, small) = groups partition (_._2.size > 3)
val xss = (
(big sortBy (_._1.toString) map (_._2)) :+
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/t2275a.check
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ t2275a.scala:4: error: in XML literal: in XML content, please use '}}' to expres
^
t2275a.scala:3: error: I encountered a '}' where I didn't expect one, maybe this tag isn't closed <br>
<br>
^
^
t2275a.scala:4: error: ';' expected but 'else' found.
}else{
^
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/t2275b.check
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ t2275b.scala:2: error: in XML literal: in XML content, please use '}}' to expres
^
t2275b.scala:2: error: I encountered a '}' where I didn't expect one, maybe this tag isn't closed <br>
{<br>}xx
^
^
t2275b.scala:3: error: '}' expected but eof found.
}
^
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/t3604.check
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ t3604.scala:3: error: in XML literal: expected closing tag of abbr
^
t3604.scala:3: error: start tag was here: abbr>
<abbr></div>
^
^
2 errors
2 changes: 1 addition & 1 deletion test/files/neg/t3769.check
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ t3769.scala:2: error: in XML literal: expected closing tag of a
^
t3769.scala:2: error: start tag was here: a>
val x = <b> <c><a></c> {"text"} </b>
^
^
2 errors
2 changes: 1 addition & 1 deletion test/files/neg/t4069.check
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ t4069.scala:9: error: in XML literal: in XML content, please use '}}' to express
^
t4069.scala:4: error: I encountered a '}' where I didn't expect one, maybe this tag isn't closed <div>
<div>
^
^
t4069.scala:10: error: '}' expected but eof found.
}
^
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/t5702-neg-ugly-xbrace.check
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ t5702-neg-ugly-xbrace.scala:13: error: in XML literal: in XML content, please us
^
t5702-neg-ugly-xbrace.scala:11: error: I encountered a '}' where I didn't expect one, maybe this tag isn't closed <top>
val <top>{a, z@_*)</top> = xml
^
^
t5702-neg-ugly-xbrace.scala:14: error: illegal start of simple pattern
}
^
Expand Down
2 changes: 1 addition & 1 deletion test/files/neg/xmltruncated7.check
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ xmltruncated7.scala:2: error: in XML literal: in XML content, please use '}}' to
^
xmltruncated7.scala:2: error: I encountered a '}' where I didn't expect one, maybe this tag isn't closed <p>
<p>foo}: </p>
^
^
2 errors
17 changes: 17 additions & 0 deletions test/files/run/infixPostfixAttachments.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
newSource1.scala:15: warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method d,
or remove the empty argument list from its definition (Java-defined methods are exempt).
In Scala 3, an unapplied method like this will be eta-expanded into a function.
def t6 = this d
^
newSource1.scala:16: warning: Auto-application to `()` is deprecated. Supply the empty argument list `()` explicitly to invoke method d,
or remove the empty argument list from its definition (Java-defined methods are exempt).
In Scala 3, an unapplied method like this will be eta-expanded into a function.
def t7 = this.d
^
t1 this.a(0) List(InfixAttachment)
t2 this.b(scala.Tuple2.apply[Int, Int](1, 2)).b(scala.Tuple2.apply[Int, Int](1, 2)).c(1, 2) List(InfixAttachment, MultiargInfixAttachment)
t2 this.b(scala.Tuple2.apply[Int, Int](1, 2)).b(scala.Tuple2.apply[Int, Int](1, 2)) List(InfixAttachment)
t2 this.b(scala.Tuple2.apply[Int, Int](1, 2)) List(InfixAttachment)
t6 this.d() List(InfixAttachment)
t6 this.d List(PostfixAttachment)
t8 this.e List(PostfixAttachment)
Loading

0 comments on commit eb014d8

Please sign in to comment.