summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-12-17 14:20:49 -0800
committerPaul Phillips <paulp@improving.org>2013-12-17 14:41:42 -0800
commita1c00ae4b2df051c33384269b6b983746e537aee (patch)
tree912f47b790250c6d28e6cc7c9a101328190e1753 /src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
parentb5ef79f2f8bc010220d2920a890352d96ad84b45 (diff)
downloadscala-a1c00ae4b2df051c33384269b6b983746e537aee.tar.gz
scala-a1c00ae4b2df051c33384269b6b983746e537aee.tar.bz2
scala-a1c00ae4b2df051c33384269b6b983746e537aee.zip
Dotless type application for infix operators.
When you have an aesthetic expresion like def f(xs: Iterator[Int]) = ( xs takeWhile (_ < 1000) map (_ * -1) filter (_ % 2 == 0) flatMap (x => List(x, x)) reduceOption (_ + _) maxBy (_.toString) ) And then for whatever reason you have to perform explicit type application in the midst of that expression, it's aggravating in the extreme that it has (had) to be rewritten in its entirety to accommodate that change. So now you can perform type application in the middle of it. For reasons not entirely clear to me postfix operators are excluded. The discussion as well as the approval for the infix variation of it can be found at: https://groups.google.com/forum/#!msg/scala-language/eJl1wnkEz9M/hR984-lqC5EJ
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser/Parsers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 91db1bb92a..2134058287 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -133,7 +133,7 @@ self =>
val global: Global
import global._
- case class OpInfo(lhs: Tree, operator: TermName, offset: Offset) {
+ case class OpInfo(lhs: Tree, operator: TermName, targs: List[Tree], offset: Offset) {
def precedence = Precedence(operator.toString)
}
@@ -795,10 +795,13 @@ self =>
private def opHead = opstack.head
private def headPrecedence = opHead.precedence
private def popOpInfo(): OpInfo = try opHead finally opstack = opstack.tail
- private def pushOpInfo(top: Tree) {
- val opinfo = OpInfo(top, in.name, in.offset)
- opstack ::= opinfo
+ private def pushOpInfo(top: Tree): Unit = {
+ val name = in.name
+ val offset = in.offset
ident()
+ val targs = if (in.token == LBRACKET) exprTypeArgs() else Nil
+ val opinfo = OpInfo(top, name, targs, offset)
+ opstack ::= opinfo
}
def checkHeadAssoc(leftAssoc: Boolean) = checkAssoc(opHead.offset, opHead.operator, leftAssoc)
@@ -808,6 +811,9 @@ self =>
)
def finishPostfixOp(start: Int, base: List[OpInfo], opinfo: OpInfo): Tree = {
+ if (opinfo.targs.nonEmpty)
+ syntaxError(opinfo.offset, "type application is not allowed for postfix operators")
+
val od = stripParens(reduceExprStack(base, opinfo.lhs))
makePostfixSelect(start, opinfo.offset, od, opinfo.operator)
}
@@ -817,7 +823,7 @@ self =>
val operatorPos: Position = Position.range(rhs.pos.source, offset, offset, offset + operator.length)
val pos = lhs.pos union rhs.pos union operatorPos withPoint offset
- atPos(pos)(makeBinop(isExpr, lhs, operator, rhs, operatorPos))
+ atPos(pos)(makeBinop(isExpr, lhs, operator, rhs, operatorPos, opinfo.targs))
}
def reduceExprStack(base: List[OpInfo], top: Tree): Tree = reduceStack(isExpr = true, base, top)
@@ -1893,9 +1899,9 @@ self =>
def isDelimiter = in.token == RPAREN || in.token == RBRACE
def isCommaOrDelimiter = isComma || isDelimiter
val (isUnderscore, isStar) = opstack match {
- case OpInfo(Ident(nme.WILDCARD), nme.STAR, _) :: _ => (true, true)
- case OpInfo(_, nme.STAR, _) :: _ => (false, true)
- case _ => (false, false)
+ case OpInfo(Ident(nme.WILDCARD), nme.STAR, _, _) :: _ => (true, true)
+ case OpInfo(_, nme.STAR, _, _) :: _ => (false, true)
+ case _ => (false, false)
}
def isSeqPatternClose = isUnderscore && isStar && isSequenceOK && isDelimiter
val preamble = "bad simple pattern:"