aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2017-02-05 12:47:05 +0100
committerGuillaume Martres <smarter@ubuntu.com>2017-02-05 17:50:05 +0100
commitac868319ecf75bcffe6000a41379c5c12e92e62e (patch)
tree4fcef8e1a93bde01abb8fe4ccc4c7e44e28f60f4 /compiler/src/dotty/tools
parentda7d7231b7f21fe1085abc569eb783590074a359 (diff)
downloaddotty-ac868319ecf75bcffe6000a41379c5c12e92e62e.tar.gz
dotty-ac868319ecf75bcffe6000a41379c5c12e92e62e.tar.bz2
dotty-ac868319ecf75bcffe6000a41379c5c12e92e62e.zip
Represent untyped operators as Ident instead of Name
This has two advantages: - We can distinguish BackquotedIdent from Ident, allowing the user to use a defined "type `&`", see testcase. - We get better positions for the operators. This is useful in IDEs, for example to get the type at point.
Diffstat (limited to 'compiler/src/dotty/tools')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala24
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Trees.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/ast/untpd.scala20
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala26
-rw-r--r--compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala4
9 files changed, 44 insertions, 43 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index 2e471e046..3835355e3 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -353,7 +353,7 @@ object desugar {
for (i <- 0 until arity if nme.selectorName(i) `ne` caseParams(i).name)
yield syntheticProperty(nme.selectorName(i), Select(This(EmptyTypeIdent), caseParams(i).name))
def isRepeated(tree: Tree): Boolean = tree match {
- case PostfixOp(_, nme.raw.STAR) => true
+ case PostfixOp(_, Ident(nme.raw.STAR)) => true
case ByNameTypeTree(tree1) => isRepeated(tree1)
case _ => false
}
@@ -739,23 +739,23 @@ object desugar {
/** Translate infix operation expression left op right
*/
- def makeBinop(left: Tree, op: Name, right: Tree): Tree = {
+ def makeBinop(left: Tree, op: Ident, right: Tree): Tree = {
def assignToNamedArg(arg: Tree) = arg match {
case Assign(Ident(name), rhs) => cpy.NamedArg(arg)(name, rhs)
case _ => arg
}
- if (isLeftAssoc(op)) {
+ if (isLeftAssoc(op.name)) {
val args: List[Tree] = right match {
case Parens(arg) => assignToNamedArg(arg) :: Nil
case Tuple(args) => args mapConserve assignToNamedArg
case _ => right :: Nil
}
- Apply(Select(left, op), args)
+ Apply(Select(left, op.name), args)
} else {
val x = ctx.freshName().toTermName
new InfixOpBlock(
ValDef(x, TypeTree(), left).withMods(synthetic),
- Apply(Select(right, op), Ident(x)))
+ Apply(Select(right, op.name), Ident(x)))
}
}
@@ -956,25 +956,25 @@ object desugar {
Apply(Select(Apply(Ident(nme.StringContext), strs), id), elems)
case InfixOp(l, op, r) =>
if (ctx.mode is Mode.Type)
- if (op == tpnme.raw.AMP) AndTypeTree(l, r) // l & r
- else if (op == tpnme.raw.BAR) OrTypeTree(l, r) // l | r
- else AppliedTypeTree(Ident(op), l :: r :: Nil) // op[l, r]
+ if (!op.isBackquoted && op.name == tpnme.raw.AMP) AndTypeTree(l, r) // l & r
+ else if (!op.isBackquoted && op.name == tpnme.raw.BAR) OrTypeTree(l, r) // l | r
+ else AppliedTypeTree(op, l :: r :: Nil) // op[l, r]
else if (ctx.mode is Mode.Pattern)
- Apply(Ident(op), l :: r :: Nil) // op(l, r)
+ Apply(op, l :: r :: Nil) // op(l, r)
else // l.op(r), or val x = r; l.op(x), plus handle named args specially
makeBinop(l, op, r)
case PostfixOp(t, op) =>
- if ((ctx.mode is Mode.Type) && op == nme.raw.STAR) {
+ if ((ctx.mode is Mode.Type) && !op.isBackquoted && op.name == nme.raw.STAR) {
val seqType = if (ctx.compilationUnit.isJava) defn.ArrayType else defn.SeqType
Annotated(
AppliedTypeTree(ref(seqType), t),
New(ref(defn.RepeatedAnnotType), Nil :: Nil))
} else {
assert(ctx.mode.isExpr || ctx.reporter.hasErrors, ctx.mode)
- Select(t, op)
+ Select(t, op.name)
}
case PrefixOp(op, t) =>
- Select(t, nme.UNARY_PREFIX ++ op)
+ Select(t, nme.UNARY_PREFIX ++ op.name)
case Parens(t) =>
t
case Tuple(ts) =>
diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala
index 6dc2c9a13..7ab8de39f 100644
--- a/compiler/src/dotty/tools/dotc/ast/Trees.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala
@@ -334,10 +334,15 @@ object Trees {
extends RefTree[T] {
type ThisTree[-T >: Untyped] = Ident[T]
def qualifier: Tree[T] = genericEmptyTree
+
+ /** Is this a `BackquotedIdent` ? */
+ def isBackquoted: Boolean = false
}
class BackquotedIdent[-T >: Untyped] private[ast] (name: Name)
extends Ident[T](name) {
+ override def isBackquoted: Boolean = true
+
override def toString = s"BackquotedIdent($name)"
}
diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala
index 37dc32c0e..99bc3240f 100644
--- a/compiler/src/dotty/tools/dotc/ast/untpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala
@@ -15,9 +15,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
// ----- Tree cases that exist in untyped form only ------------------
trait OpTree extends Tree {
- def op: Name
- override def isTerm = op.isTermName
- override def isType = op.isTypeName
+ def op: Ident
+ override def isTerm = op.name.isTermName
+ override def isType = op.name.isTypeName
}
/** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice
@@ -66,9 +66,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
*/
class WildcardFunction(placeholderParams: List[ValDef], body: Tree) extends Function(placeholderParams, body)
- case class InfixOp(left: Tree, op: Name, right: Tree) extends OpTree
- case class PostfixOp(od: Tree, op: Name) extends OpTree
- case class PrefixOp(op: Name, od: Tree) extends OpTree
+ case class InfixOp(left: Tree, op: Ident, right: Tree) extends OpTree
+ case class PostfixOp(od: Tree, op: Ident) extends OpTree
+ case class PrefixOp(op: Ident, od: Tree) extends OpTree
case class Parens(t: Tree) extends ProxyTree {
def forwardTo = t
}
@@ -357,7 +357,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
* parameter, the reference will be a repeated argument.
*/
def refOfDef(tree: MemberDef)(implicit ctx: Context) = tree match {
- case ValDef(_, PostfixOp(_, nme.raw.STAR), _) => repeated(Ident(tree.name))
+ case ValDef(_, PostfixOp(_, Ident(nme.raw.STAR)), _) => repeated(Ident(tree.name))
case _ => Ident(tree.name)
}
@@ -409,15 +409,15 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case tree: Function if (args eq tree.args) && (body eq tree.body) => tree
case _ => untpd.Function(args, body).withPos(tree.pos)
}
- def InfixOp(tree: Tree)(left: Tree, op: Name, right: Tree) = tree match {
+ def InfixOp(tree: Tree)(left: Tree, op: Ident, right: Tree) = tree match {
case tree: InfixOp if (left eq tree.left) && (op eq tree.op) && (right eq tree.right) => tree
case _ => untpd.InfixOp(left, op, right).withPos(tree.pos)
}
- def PostfixOp(tree: Tree)(od: Tree, op: Name) = tree match {
+ def PostfixOp(tree: Tree)(od: Tree, op: Ident) = tree match {
case tree: PostfixOp if (od eq tree.od) && (op eq tree.op) => tree
case _ => untpd.PostfixOp(od, op).withPos(tree.pos)
}
- def PrefixOp(tree: Tree)(op: Name, od: Tree) = tree match {
+ def PrefixOp(tree: Tree)(op: Ident, od: Tree) = tree match {
case tree: PrefixOp if (op eq tree.op) && (od eq tree.od) => tree
case _ => untpd.PrefixOp(op, od).withPos(tree.pos)
}
diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
index 92ab10db9..d35594823 100644
--- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
@@ -448,7 +448,7 @@ object JavaParsers {
if (in.token == DOTDOTDOT) {
in.nextToken()
t = atPos(t.pos.start) {
- PostfixOp(t, nme.raw.STAR)
+ PostfixOp(t, Ident(nme.raw.STAR))
}
}
atPos(start, in.offset) {
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index f62093db0..5ed4fbdd7 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -30,7 +30,7 @@ object Parsers {
import reporting.diagnostic.Message
import reporting.diagnostic.messages._
- case class OpInfo(operand: Tree, operator: Name, offset: Offset)
+ case class OpInfo(operand: Tree, operator: Ident, offset: Offset)
class ParensCounters {
private var parCounts = new Array[Int](lastParen - firstParen)
@@ -414,18 +414,17 @@ object Parsers {
"left- and right-associative operators with same precedence may not be mixed", offset)
def reduceStack(base: List[OpInfo], top: Tree, prec: Int, leftAssoc: Boolean): Tree = {
- if (opStack != base && precedence(opStack.head.operator) == prec)
- checkAssoc(opStack.head.offset, opStack.head.operator, leftAssoc)
+ if (opStack != base && precedence(opStack.head.operator.name) == prec)
+ checkAssoc(opStack.head.offset, opStack.head.operator.name, leftAssoc)
def recur(top: Tree): Tree = {
if (opStack == base) top
else {
val opInfo = opStack.head
- val opPrec = precedence(opInfo.operator)
+ val opPrec = precedence(opInfo.operator.name)
if (prec < opPrec || leftAssoc && prec == opPrec) {
opStack = opStack.tail
recur {
- val opPos = Position(opInfo.offset, opInfo.offset + opInfo.operator.length, opInfo.offset)
- atPos(opPos union opInfo.operand.pos union top.pos) {
+ atPos(opInfo.operator.pos union opInfo.operand.pos union top.pos) {
InfixOp(opInfo.operand, opInfo.operator, top)
}
}
@@ -449,10 +448,9 @@ object Parsers {
val base = opStack
var top = first
while (isIdent && in.name != notAnOperator) {
- val op = if (isType) in.name.toTypeName else in.name
- top = reduceStack(base, top, precedence(op), isLeftAssoc(op))
+ val op = if (isType) typeIdent() else termIdent()
+ top = reduceStack(base, top, precedence(op.name), isLeftAssoc(op.name))
opStack = OpInfo(top, op, in.offset) :: opStack
- ident()
newLineOptWhenFollowing(canStartOperand)
if (maybePostfix && !canStartOperand(in.token)) {
val topInfo = opStack.head
@@ -870,7 +868,7 @@ object Parsers {
val t = toplevelTyp()
if (isIdent(nme.raw.STAR)) {
in.nextToken()
- atPos(startOffset(t)) { PostfixOp(t, nme.raw.STAR) }
+ atPos(startOffset(t)) { PostfixOp(t, Ident(nme.raw.STAR)) }
} else t
}
@@ -1189,11 +1187,11 @@ object Parsers {
val prefixExpr = () =>
if (isIdent && nme.raw.isUnary(in.name)) {
val start = in.offset
- val name = ident()
- if (name == nme.raw.MINUS && isNumericLit)
+ val op = termIdent()
+ if (op.name == nme.raw.MINUS && isNumericLit)
simpleExprRest(literal(start), canApply = true)
else
- atPos(start) { PrefixOp(name, simpleExpr()) }
+ atPos(start) { PrefixOp(op, simpleExpr()) }
}
else simpleExpr()
@@ -1260,7 +1258,7 @@ object Parsers {
val app = atPos(startOffset(t), in.offset) { Apply(t, argumentExprs()) }
simpleExprRest(app, canApply = true)
case USCORE =>
- atPos(startOffset(t), in.skipToken()) { PostfixOp(t, nme.WILDCARD) }
+ atPos(startOffset(t), in.skipToken()) { PostfixOp(t, Ident(nme.WILDCARD)) }
case _ =>
t
}
diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 7f124563d..5b75df6b2 100644
--- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -516,7 +516,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
argsText ~ " => " ~ toText(body)
}
case InfixOp(l, op, r) =>
- val opPrec = parsing.precedence(op)
+ val opPrec = parsing.precedence(op.name)
changePrec(opPrec) { toText(l) ~ " " ~ toText(op) ~ " " ~ toText(r) }
case PostfixOp(l, op) =>
changePrec(InfixPrec) { toText(l) ~ " " ~ toText(op) }
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index 181dfccd9..7c49e68dd 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -1077,8 +1077,6 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {
trait MatchTranslator extends TreeMakers with ScalacPatternExpanders {
- def isBackquoted(x: Ident) = x.isInstanceOf[BackquotedIdent]
-
def isVarPattern(pat: Tree): Boolean = pat match {
case x: BackquotedIdent => false
case x: Ident => x.name.isVariableName
diff --git a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
index c390ae808..e7e7ece78 100644
--- a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -144,7 +144,7 @@ object EtaExpansion {
ids = ids.init :+ repeated(ids.last)
var body: Tree = Apply(lifted, ids)
mt.resultType match {
- case rt: MethodType if !rt.isImplicit => body = PostfixOp(body, nme.WILDCARD)
+ case rt: MethodType if !rt.isImplicit => body = PostfixOp(body, Ident(nme.WILDCARD))
case _ =>
}
val fn = untpd.Function(params, body)
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 59df98a93..5ea36986f 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -1440,7 +1440,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedAsFunction(tree: untpd.PostfixOp, pt: Type)(implicit ctx: Context): Tree = {
- val untpd.PostfixOp(qual, nme.WILDCARD) = tree
+ val untpd.PostfixOp(qual, Ident(nme.WILDCARD)) = tree
val pt1 = if (defn.isFunctionType(pt)) pt else AnyFunctionProto
var res = typed(qual, pt1)
if (pt1.eq(AnyFunctionProto) && !defn.isFunctionClass(res.tpe.classSymbol)) {
@@ -1541,7 +1541,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case tree: untpd.Annotated => typedAnnotated(tree, pt)
case tree: untpd.TypedSplice => typedTypedSplice(tree)
case tree: untpd.UnApply => typedUnApply(tree, pt)
- case tree @ untpd.PostfixOp(qual, nme.WILDCARD) => typedAsFunction(tree, pt)
+ case tree @ untpd.PostfixOp(qual, Ident(nme.WILDCARD)) => typedAsFunction(tree, pt)
case untpd.EmptyTree => tpd.EmptyTree
case _ => typedUnadapted(desugar(tree), pt)
}