summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala1
-rwxr-xr-xsrc/compiler/scala/tools/nsc/Positions.scala (renamed from src/compiler/scala/tools/nsc/interactive/Positions.scala)10
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala23
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala105
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/Parsers.scala79
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala101
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Printers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala15
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala2
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/ContextTrees.scala4
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/Global.scala7
-rwxr-xr-xsrc/compiler/scala/tools/nsc/interactive/RangePositions.scala155
-rwxr-xr-xsrc/compiler/scala/tools/nsc/javac/JavaParsers.scala4
-rwxr-xr-xsrc/compiler/scala/tools/nsc/javac/JavaScanners.scala2
-rw-r--r--src/compiler/scala/tools/nsc/models/SemanticTokens.scala60
-rw-r--r--src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala45
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTable.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala25
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Analyzer.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala21
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala37
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala101
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala18
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala230
-rw-r--r--src/compiler/scala/tools/nsc/util/SourceFile.scala13
-rw-r--r--src/library/scala/Product.scala1
-rw-r--r--test/files/neg/names-defaults-neg.check6
39 files changed, 523 insertions, 607 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index e842c96641..e65469e0a4 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -31,7 +31,6 @@ import backend.jvm.GenJVM
import backend.msil.GenMSIL
import backend.opt.{Inliners, ClosureElimination, DeadCodeElimination}
import backend.icode.analysis._
-import interactive._
class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
with CompilationUnits
diff --git a/src/compiler/scala/tools/nsc/interactive/Positions.scala b/src/compiler/scala/tools/nsc/Positions.scala
index b8be2b1fbb..88c54e6671 100755
--- a/src/compiler/scala/tools/nsc/interactive/Positions.scala
+++ b/src/compiler/scala/tools/nsc/Positions.scala
@@ -1,8 +1,7 @@
package scala.tools.nsc
-package interactive
import ast.Trees
-import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, SyntheticOffsetPosition, WorkScheduler}
+import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler}
import scala.collection.mutable.ListBuffer
trait Positions {
@@ -18,7 +17,12 @@ self: scala.tools.nsc.Global =>
*/
def wrappingPos(trees: List[Tree]): Position = trees.head.pos
- def makeTransparent(pos: Position) = pos
+ /** Ensure that given tree has no positions that overlap with
+ * any of the positions of `others`. This is done by
+ * shortening the range or assinging TransparentPositions
+ * to some of the nodes in `tree`.
+ */
+ def ensureNonOverlapping(tree: Tree, others: List[Tree]) {}
def validatePositions(tree: Tree) {}
}
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 2baf578914..edfca57be6 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -244,7 +244,7 @@ abstract class TreeGen
// var m$: T = null; or, if class member: local var m$: T = _;
def mkModuleVarDef(accessor: Symbol) = {
- val mvar = accessor.owner.newVariable(accessor.pos.toSynthetic, nme.moduleVarName(accessor.name))
+ val mvar = accessor.owner.newVariable(accessor.pos.focus, nme.moduleVarName(accessor.name))
.setInfo(accessor.tpe.finalResultType)
.setFlag(MODULEVAR);
if (mvar.owner.isClass) {
@@ -305,11 +305,11 @@ abstract class TreeGen
if (treeInfo.isPureExpr(expr)) {
within(() => expr);
} else {
- val temp = owner.newValue(expr.pos.toSynthetic, unit.fresh.newName(expr.pos, "ev$"))
- .setFlag(SYNTHETIC).setInfo(expr.tpe);
- atPos(expr.pos) {
- Block(List(ValDef(temp, expr)), within(() => Ident(temp) setType expr.tpe))
- }
+ val temp = owner.newValue(expr.pos.makeTransparent, unit.fresh.newName(expr.pos, "ev$"))
+ .setFlag(SYNTHETIC).setInfo(expr.tpe)
+ val containing = within(() => Ident(temp) setPos temp.pos.focus setType expr.tpe)
+ ensureNonOverlapping(containing, List(expr))
+ Block(List(ValDef(temp, expr)), containing) setPos (containing.pos union expr.pos)
}
def evalOnceAll(exprs: List[Tree], owner: Symbol, unit: CompilationUnit)(within: (List[() => Tree]) => Tree): Tree = {
@@ -319,15 +319,16 @@ abstract class TreeGen
if (treeInfo.isPureExpr(expr)) {
exprs1 += (() => expr)
} else {
- val temp = owner.newValue(expr.pos.toSynthetic, unit.fresh.newName(expr.pos))
+ val temp = owner.newValue(expr.pos.makeTransparent, unit.fresh.newName(expr.pos, "ev$"))
.setFlag(SYNTHETIC).setInfo(expr.tpe)
vdefs += ValDef(temp, expr)
- exprs1 += (() => Ident(temp) setType expr.tpe)
+ exprs1 += (() => Ident(temp) setPos temp.pos.focus setType expr.tpe)
}
}
val prefix = vdefs.toList
- val result = within(exprs1.toList)
- if (prefix.isEmpty) result
- else Block(prefix, result) setPos (prefix.head.pos union result.pos)
+ val containing = within(exprs1.toList)
+ ensureNonOverlapping(containing, exprs)
+ if (prefix.isEmpty) containing
+ else Block(prefix, containing) setPos (prefix.head.pos union containing.pos)
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index c005d0690e..b3f54f453d 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -105,7 +105,7 @@ trait Trees {
}
val id = nodeCount
- //assert(id != 225)
+// assert(id != 14427)
nodeCount += 1
private var rawpos: Position = NoPosition
@@ -118,19 +118,16 @@ trait Trees {
def tpe_=(t: Type) = rawtpe = t
def setPos(pos: Position): this.type = {
- pos match {
- case SyntheticAliasPosition(orig) => assert(orig != this)
- case _ =>
- } // !!!
- rawpos = pos;
+ rawpos = pos
+/*
+ for (c <- this.children)
+ if (c.pos.isOpaqueRange && !pos.includes(c.pos)) {
+ assert(false, "non-enclosing positions in "+this)
+ }
+*/
this
}
- def setOriginal(tree: Tree): this.type = tree.pos match {
- case SyntheticAliasPosition(orig) => setOriginal(orig)
- case _ => setPos(if (tree.pos.isDefined) SyntheticAliasPosition(tree) else tree.pos)
- }
-
def setType(tp: Type): this.type = {
/*assert(kindingIrrelevant(tp) || !kindStar || !tp.isHigherKinded,
tp+" should not be higher-kinded");*/
@@ -177,7 +174,7 @@ trait Trees {
/** The direct child trees of this tree
* EmptyTrees are always omitted. Lists are collapsed.
*/
- def children(): List[Tree] = {
+ def children: List[Tree] = {
def subtrees(x: Any): List[Tree] = x match {
case EmptyTree => List()
case t: Tree => List(t)
@@ -252,15 +249,16 @@ trait Trees {
} else false
}
+ /** Make a copy of this tree, keeping all attributes,
+ * except that all positions are focussed (so nothing
+ * in this tree will be found when searching by position).
+ */
def duplicate: this.type =
(duplicator transform this).asInstanceOf[this.type]
def shallowDuplicate: this.type =
((new ShallowDuplicator(this)) transform this).asInstanceOf[this.type]
- def syntheticDuplicate: this.type =
- (syntheticDuplicator transform this).asInstanceOf[this.type]
-
def copyAttrs(tree: Tree): this.type = {
rawpos = tree.rawpos
tpe = tree.tpe
@@ -297,13 +295,9 @@ trait Trees {
private lazy val duplicator = new Transformer {
override val treeCopy = new StrictTreeCopier
- }
-
- private lazy val syntheticDuplicator = new Transformer {
- override val treeCopy = new StrictTreeCopier
override def transform(t: Tree) = {
val t1 = super.transform(t)
- if (t1 ne t) t1.setOriginal(t)
+ if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus
t1
}
}
@@ -436,7 +430,9 @@ trait Trees {
def ValDef(sym: Symbol, rhs: Tree): ValDef =
atPos(sym.pos) {
- ValDef(Modifiers(sym.flags), sym.name, TypeTree(sym.tpe), rhs) setSymbol sym
+ ValDef(Modifiers(sym.flags), sym.name,
+ TypeTree(sym.tpe) setPos sym.pos.focus,
+ rhs) setSymbol sym
}
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
@@ -473,7 +469,7 @@ trait Trees {
sym.name,
sym.typeParams map TypeDef,
vparamss,
- TypeTree(sym.tpe.finalResultType),
+ TypeTree(sym.tpe.finalResultType) setPos sym.pos.focus,
rhs) setSymbol sym
}
@@ -492,9 +488,7 @@ trait Trees {
/** Abstract type, type parameter, or type alias */
case class TypeDef(mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree)
- extends MemberDef {
- def namePos = pos.offset.map(n => n - name.length).getOrElse(-1)
- }
+ extends MemberDef
/** A TypeDef node which defines given `sym' with given tight hand side `rhs'. */
def TypeDef(sym: Symbol, rhs: Tree): TypeDef =
@@ -603,17 +597,20 @@ trait Trees {
// create parameters for <init> as synthetic trees.
var vparamss1 =
vparamss map (vps => vps.map { vd =>
- atPos(vd) {
+ atPos(vd.pos.focus) {
ValDef(
Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM) | PARAM) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.syntheticDuplicate, vd.rhs.syntheticDuplicate)
+ vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
}})
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val (lvdefs, gvdefs) = List.unzip {
evdefs map {
case vdef @ ValDef(mods, name, tpt, rhs) =>
- val fld = treeCopy.ValDef(vdef.syntheticDuplicate, mods, name, TypeTree() setOriginal tpt, EmptyTree)
+ val fld = treeCopy.ValDef(
+ vdef.duplicate, mods, name,
+ atPos(vdef.pos.focus) { TypeTree() setOriginal tpt setPos tpt.pos.focus }, // atPos in case
+ EmptyTree)
val local = treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs)
(local, fld)
}
@@ -859,10 +856,11 @@ trait Trees {
case class TypeTree() extends TypTree {
override def symbol = if (tpe == null) null else tpe.typeSymbol
- def original: Tree = pos match {
- case SyntheticAliasPosition(orig) => orig
- case _ => null
- }
+ private var orig: Tree = null // should be EmptyTree?
+
+ def original: Tree = orig
+
+ def setOriginal(tree: Tree): this.type = { orig = tree; setPos(tree.pos); this }
override def isEmpty = (tpe eq null) || tpe == NoType
}
@@ -878,10 +876,6 @@ trait Trees {
case class Annotated(annot: Tree, arg: Tree) extends Tree {
override def isType = arg.isType
override def isTerm = arg.isTerm
- override def setPos(pos: Position) : this.type = {
-// assert(pos.start != 27934, this)
- super.setPos(pos)
- }
}
/** Singleton type, eliminated by RefCheck */
@@ -1706,7 +1700,7 @@ trait Trees {
if (tree.tpe ne null) tree.tpe = typeSubst(tree.tpe)
super.traverse(tree)
}
- override def apply[T <: Tree](tree: T): T = super.apply(tree.syntheticDuplicate)
+ override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
override def toString() = "TreeTypeSubstituter("+from+","+to+")"
}
@@ -1724,7 +1718,7 @@ trait Trees {
if (tree.hasSymbol) subst(from, to)
super.traverse(tree)
}
- override def apply[T <: Tree](tree: T): T = super.apply(tree.syntheticDuplicate)
+ override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
override def toString() = "TreeSymSubstituter("+from+","+to+")"
}
@@ -1754,29 +1748,12 @@ trait Trees {
}
}
- object syntheticMaker extends Traverser {
- override def traverse(t: Tree) {
- if (!t.pos.isSynthetic) {
- t setPos t.pos.toSynthetic
- super.traverse(t)
- }
- }
- }
-
def atPos[T <: Tree](pos: Position)(tree: T): T = {
posAssigner.pos = pos
posAssigner.traverse(tree)
tree
}
- def atPos[T <: Tree](original: Tree)(tree: T): T =
- atPos(SyntheticAliasPosition(original))(tree)
-
- def makeSynthetic[T <: Tree](tree: T): T = {
- syntheticMaker.traverse(tree)
- tree
- }
-
class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
override def traverse(t: Tree) {
f(t)
@@ -1851,23 +1828,5 @@ trait Trees {
def hasSymbol : Boolean
def isTop : Boolean
}
-
- /** A position to be used for synthetic trees that correspond to some original tree
- * @note Trees with synthetic positions may not contain trees with real positions inside them!
- */
- case class SyntheticAliasPosition(original: Tree) extends Position {
- override def isDefined: Boolean = true
- override def isSynthetic: Boolean = true
- override def offset: Option[Int] = original.pos.offset
- override def source: Option[SourceFile] = original.pos.source
- override def start: Int = original.pos.start
- override def point: Int = original.pos.point
- override def end: Int = original.pos.end
- override def underlying = original.pos.underlying
- override def focusStart = original.pos.focusStart
- override def focusPoint = original.pos.focusPoint
- override def focusEnd = original.pos.focusEnd
- override def show = "["+ underlying.show +"]"
- }
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 0c1198cdcf..4f5be7cce0 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -150,7 +150,6 @@ self =>
def o2p(offset: Int): Position
def r2p(start: Int, mid: Int, end: Int): Position
- def t2p(tree: Tree): Position = SyntheticAliasPosition(tree)
//private implicit def p2i(pos: Position) = pos.offset.get
/** whether a non-continuable syntax error has been seen */
@@ -220,7 +219,9 @@ self =>
placeholderTypes = List()
var t = op
if (!placeholderTypes.isEmpty && t.isInstanceOf[AppliedTypeTree]) {
- t = atPos(t.pos) { ExistentialTypeTree(t, placeholderTypes.reverse) }
+ val expos = t.pos
+ ensureNonOverlapping(t, placeholderTypes)
+ t = atPos(expos) { ExistentialTypeTree(t, placeholderTypes.reverse) }
placeholderTypes = List()
}
placeholderTypes = placeholderTypes ::: savedPlaceholderTypes
@@ -342,9 +343,9 @@ self =>
ret
}
- def errorTypeTree = TypeTree().setType(ErrorType).setPos(o2p(in.offset).toSynthetic)
- def errorTermTree = Literal(Constant(null)).setPos(o2p(in.offset).toSynthetic)
- def errorPatternTree = Ident(nme.WILDCARD).setPos(o2p(in.offset).toSynthetic)
+ def errorTypeTree = TypeTree().setType(ErrorType).setPos(o2p(in.offset))
+ def errorTermTree = Literal(Constant(null)).setPos(o2p(in.offset))
+ def errorPatternTree = Ident(nme.WILDCARD).setPos(o2p(in.offset))
/** Check that type parameter is not by name T* */
def checkNotByName(t: Tree) = t match {
@@ -451,13 +452,13 @@ self =>
tree match {
case Ident(name) =>
removeAsPlaceholder(name)
- ValDef(Modifiers(Flags.PARAM), name, TypeTree() setPos o2p(tree.pos.end), EmptyTree)
+ ValDef(Modifiers(Flags.PARAM), name, TypeTree() setPos o2p(tree.pos.endOrPoint), EmptyTree)
case Typed(tree @ Ident(name), tpe) if (tpe.isType) => // get the ident!
removeAsPlaceholder(name)
ValDef(Modifiers(Flags.PARAM), name, tpe, EmptyTree)
case _ =>
syntaxError(tree.pos, "not a legal formal parameter", false)
- ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree setPos o2p(tree.pos.end).toSynthetic, EmptyTree)
+ ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree setPos o2p(tree.pos.endOrPoint), EmptyTree)
}
}
@@ -536,7 +537,7 @@ self =>
leftAssoc && prec == precedence(opstack.head.operator))) {
val opinfo = opstack.head
opstack = opstack.tail
- top = atPos(opinfo.operand.pos.start, opinfo.offset) {
+ top = atPos(opinfo.operand.pos.startOrPoint, opinfo.offset) {
makeBinop(isExpr, opinfo.operand, opinfo.operator, top)
}
}
@@ -560,7 +561,7 @@ self =>
def selector(t: Tree): Tree = {
val point = in.offset
//assert(t.pos.isDefined, t)
- Select(t, ident(false)) setPos r2p(t.pos.start, point, in.lastOffset)
+ Select(t, ident(false)) setPos r2p(t.pos.startOrPoint, point, in.lastOffset)
}
/** Path ::= StableId
@@ -613,7 +614,7 @@ self =>
def selectors(t: Tree, typeOK: Boolean, dotOffset: Int): Tree =
if (typeOK && in.token == TYPE) {
in.nextToken()
- atPos(t.pos.start, dotOffset) { SingletonTypeTree(t) }
+ atPos(t.pos.startOrPoint, dotOffset) { SingletonTypeTree(t) }
} else {
val t1 = selector(t)
if (in.token == DOT) { selectors(t1, typeOK, in.skipToken()) }
@@ -774,7 +775,7 @@ self =>
val op = ident()
val tycon = atPos(opOffset) { Ident(op.toTypeName) }
newLineOptWhenFollowing(isTypeIntroToken)
- def mkOp(t1: Tree) = atPos(t.pos.start, opOffset) { AppliedTypeTree(tycon, List(t, t1)) }
+ def mkOp(t1: Tree) = atPos(t.pos.startOrPoint, opOffset) { AppliedTypeTree(tycon, List(t, t1)) }
if (leftAssoc)
infixTypeRest(mkOp(compoundType(isPattern)), isPattern, InfixMode.LeftOp)
else
@@ -797,7 +798,7 @@ self =>
in.nextToken(); ts += annotType(isPattern)
}
newLineOptWhenFollowedBy(LBRACE)
- atPos(t.pos.start) {
+ atPos(t.pos.startOrPoint) {
if (in.token == LBRACE) {
// Warn if they are attempting to refine Unit; we can't be certain it's
// scala.Unit they're refining because at this point all we have is an
@@ -853,12 +854,12 @@ self =>
val hashOffset = in.skipToken()
val nameOffset = in.offset
val name = ident(false)
- val sel = atPos(t.pos.start, if (name == nme.ERROR) hashOffset else nameOffset) {
+ val sel = atPos(t.pos.startOrPoint, if (name == nme.ERROR) hashOffset else nameOffset) {
SelectFromTypeTree(t, name.toTypeName)
}
simpleTypeRest(sel, isPattern)
} else if (in.token == LBRACKET) {
- simpleTypeRest(atPos(t.pos.start) { AppliedTypeTree(t, typeArgs(isPattern, false)) }, isPattern)
+ simpleTypeRest(atPos(t.pos.startOrPoint) { AppliedTypeTree(t, typeArgs(isPattern, false)) }, isPattern)
} else {
t
}
@@ -1046,7 +1047,7 @@ self =>
if (in.token == EQUALS) {
t match {
case Ident(_) | Select(_, _) | Apply(_, _) =>
- t = atPos(t.pos.start, in.skipToken()) { makeAssign(t, expr()) }
+ t = atPos(t.pos.startOrPoint, in.skipToken()) { makeAssign(t, expr()) }
case _ =>
}
} else if (in.token == COLON) {
@@ -1057,7 +1058,7 @@ self =>
val uscorePos = in.skipToken()
if (isIdent && in.name == nme.STAR) {
in.nextToken()
- t = atPos(t.pos.start, colonPos) {
+ t = atPos(t.pos.startOrPoint, colonPos) {
Typed(t, atPos(uscorePos) { Ident(nme.WILDCARD_STAR.toTypeName) })
}
} else {
@@ -1066,13 +1067,13 @@ self =>
} else if (in.token == AT) {
t = (t /: annotations(false, false)) (makeAnnotated)
} else {
- t = atPos(t.pos.start, colonPos) {
+ t = atPos(t.pos.startOrPoint, colonPos) {
val tpt =
if (location == Local) typ() else infixType(false, InfixMode.FirstOp)
if (isWildcard(t))
(placeholderParams: @unchecked) match {
case (vd @ ValDef(mods, name, _, _)) :: rest =>
- placeholderParams = treeCopy.ValDef(vd, mods, name, tpt.syntheticDuplicate, EmptyTree) :: rest
+ placeholderParams = treeCopy.ValDef(vd, mods, name, tpt.duplicate, EmptyTree) :: rest
}
// this does not correspond to syntax, but is necessary to
// accept closures. We might restrict closures to be between {...} only.
@@ -1080,7 +1081,7 @@ self =>
}
}
} else if (in.token == MATCH) {
- t = atPos(t.pos.start, in.skipToken()) {
+ t = atPos(t.pos.startOrPoint, in.skipToken()) {
Match(stripParens(t), surround(LBRACE, RBRACE)(caseClauses(), Nil))
}
}
@@ -1093,7 +1094,7 @@ self =>
case _ => false
}
if (in.token == ARROW && (location != InTemplate || lhsIsTypedParamList)) {
- t = atPos(t.pos.start, in.skipToken()) {
+ t = atPos(t.pos.startOrPoint, in.skipToken()) {
Function(convertToParams(t), if (location != InBlock) expr() else block())
}
}
@@ -1119,7 +1120,7 @@ self =>
val topinfo = opstack.head
opstack = opstack.tail
val od = stripParens(reduceStack(true, base, topinfo.operand, 0, true))
- return atPos(od.pos.start, topinfo.offset) {
+ return atPos(od.pos.startOrPoint, topinfo.offset) {
Select(od, topinfo.operator.encode)
}
}
@@ -1174,9 +1175,9 @@ self =>
case USCORE =>
val start = in.offset
val pname = freshName(o2p(start), "x$")
- val id = atPos(start) (Ident(pname))
in.nextToken()
- val param = atPos(t2p(id)){ makeSyntheticParam(pname) }
+ val id = atPos(start) (Ident(pname))
+ val param = atPos(id.pos.focus){ makeSyntheticParam(pname) }
placeholderParams = param :: placeholderParams
id
case LPAREN =>
@@ -1213,7 +1214,7 @@ self =>
val t1 = stripParens(t)
t1 match {
case Ident(_) | Select(_, _) =>
- val tapp = atPos(t1.pos.start, in.offset) {
+ val tapp = atPos(t1.pos.startOrPoint, in.offset) {
TypeApply(t1, typeArgs(false, true))
}
simpleExprRest(tapp, true)
@@ -1221,7 +1222,7 @@ self =>
t1
}
case LPAREN | LBRACE if (canApply) =>
- val app = atPos(t.pos.start, in.offset) {
+ val app = atPos(t.pos.startOrPoint, in.offset) {
// look for anonymous function application like (f _)(x) and
// translate to (f _).apply(x), bug #460
val sel = t match {
@@ -1234,7 +1235,7 @@ self =>
}
simpleExprRest(app, true)
case USCORE =>
- atPos(t.pos.start, in.skipToken()) {
+ atPos(t.pos.startOrPoint, in.skipToken()) {
Typed(stripParens(t), Function(List(), EmptyTree))
}
case _ =>
@@ -1360,7 +1361,7 @@ self =>
if (in.token == IF) enums += makeFilter(in.offset, guard())
}
- def makeFilter(start: Int, tree: Tree) = Filter(r2p(start, tree.pos.point, tree.pos.end), tree)
+ def makeFilter(start: Int, tree: Tree) = Filter(r2p(start, tree.pos.point, tree.pos.endOrPoint), tree)
/* -------- PATTERNS ------------------------------------------- */
@@ -1398,7 +1399,7 @@ self =>
val p = pattern2(seqOK)
p match {
case Ident(name) if (treeInfo.isVarPattern(p) && in.token == COLON) =>
- atPos(p.pos.start, in.skipToken()) { Typed(p, compoundType(true)) }
+ atPos(p.pos.startOrPoint, in.skipToken()) { Typed(p, compoundType(true)) }
case _ =>
p
}
@@ -1419,7 +1420,7 @@ self =>
pattern3(seqOK)
} else if (treeInfo.isVarPattern(p)) {
in.nextToken()
- atPos(p.pos.start) { Bind(name, pattern3(seqOK)) }
+ atPos(p.pos.startOrPoint) { Bind(name, pattern3(seqOK)) }
} else {
p
}
@@ -1438,7 +1439,7 @@ self =>
val base = opstack
var top = simplePattern(seqOK)
if (seqOK && isIdent && in.name == STAR)
- return atPos(top.pos.start, in.skipToken())(Star(stripParens(top)))
+ return atPos(top.pos.startOrPoint, in.skipToken())(Star(stripParens(top)))
while (isIdent && in.name != BAR) {
top = reduceStack(
@@ -1498,7 +1499,7 @@ self =>
else t
case USCORE =>
in.nextToken()
- atPos(start) { Ident(nme.WILDCARD) }
+ atPos(start, start) { Ident(nme.WILDCARD) }
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL =>
atPos(start) { literal(false) }
@@ -1762,7 +1763,7 @@ self =>
val t = typ()
if (isIdent && in.name == STAR) {
in.nextToken()
- atPos(t.pos.start, t.pos.point) {
+ atPos(t.pos.startOrPoint, t.pos.point) {
AppliedTypeTree(
rootScalaDot(nme.REPEATED_PARAM_CLASS_NAME.toTypeName), List(t))
}
@@ -1834,7 +1835,7 @@ self =>
def bound(tok: Int, default: Name): Tree =
if (in.token == tok) { in.nextToken(); typ() }
- else atPos(o2p(in.lastOffset).toSynthetic) { rootScalaDot(default.toTypeName) }
+ else atPos(o2p(in.lastOffset)) { rootScalaDot(default.toTypeName) }
/* -------- DEFS ------------------------------------------- */
@@ -2008,7 +2009,7 @@ self =>
}
trees
}
- (lhs.toList.init flatMap (mkDefs(_, tp.syntheticDuplicate, rhs.syntheticDuplicate))) ::: mkDefs(lhs.last, tp, rhs)
+ (lhs.toList.init flatMap (mkDefs(_, tp.duplicate, rhs.duplicate))) ::: mkDefs(lhs.last, tp, rhs)
}
/** VarDef ::= PatDef
@@ -2047,7 +2048,7 @@ self =>
val start = in.skipToken()
if (in.token == THIS) {
atPos(start, in.skipToken()) {
- val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (_.syntheticDuplicate), false)
+ val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (_.duplicate), false)
newLineOptWhenFollowedBy(LBRACE)
val rhs = if (in.token == LBRACE) {
atPos(in.offset) { constrBlock(vparamss) }
@@ -2184,7 +2185,7 @@ self =>
val implicitViewBuf = new ListBuffer[Tree]
val tparams = typeParamClauseOpt(name, implicitViewBuf)
implicitClassViews = implicitViewBuf.toList
- val tstart = (in.offset::implicitClassViews.map(_.pos.start)).min
+ val tstart = (in.offset::implicitClassViews.map(_.pos.startOrPoint)).min
if (!implicitClassViews.isEmpty && mods.hasFlag(Flags.TRAIT)) {
syntaxError("traits cannot have type parameters with <% bounds", false)
implicitClassViews = List()
@@ -2301,7 +2302,7 @@ self =>
if (mods.hasFlag(Flags.CASE)) parents = parents ::: List(productConstr)
val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart
atPos(tstart0) {
- Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart).toSynthetic)
+ Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart))
}
}
@@ -2362,7 +2363,7 @@ self =>
def makePackageObject(start: Int, objDef: ModuleDef): PackageDef = objDef match {
case ModuleDef(mods, name, impl) =>
makePackaging(
- start, atPos(o2p(objDef.pos.start)){ Ident(name) }, List(ModuleDef(mods, nme.PACKAGEkw, impl)))
+ start, atPos(o2p(objDef.pos.startOrPoint)){ Ident(name) }, List(ModuleDef(mods, nme.PACKAGEkw, impl)))
}
/** Packaging ::= package QualId [nl] `{' TopStatSeq `}'
@@ -2520,7 +2521,7 @@ self =>
stats ++= localDef
if (in.token == RBRACE || in.token == CASE) {
syntaxError("block must end in result expression, not in definition", false)
- stats += Literal(()).setPos(o2p(in.offset).toSynthetic)
+ stats += Literal(()).setPos(o2p(in.offset))
} else acceptStatSep()
} else if (isStatSep) {
in.nextToken()
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
index d8f43cae2b..100ba462a4 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
@@ -24,11 +24,8 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse
unit.body =
if (unit.source.file.name.endsWith(".java")) new JavaUnitParser(unit).parse()
else if (!global.reporter.incompleteHandled) new UnitParser(unit).smartParse()
- else {
- val result = new UnitParser(unit).parse()
- if (global.settings.Yrangepos.value) global.validatePositions(unit.body)
- result
- }
+ else new UnitParser(unit).parse()
+ if (global.settings.Yrangepos.value) global.validatePositions(unit.body)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index fe06b663b2..fc18cfb195 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -9,7 +9,7 @@ package ast.parser
import symtab.Flags._
import scala.collection.mutable.ListBuffer
-import scala.tools.nsc.util.{Position, SyntheticOffsetPosition}
+import scala.tools.nsc.util.Position
/** Methods for building trees, used in the parser. All the trees
* returned by this class must be untyped.
@@ -39,7 +39,7 @@ abstract class TreeBuilder {
private object patvarTransformer extends Transformer {
override def transform(tree: Tree): Tree = tree match {
case Ident(name) if (treeInfo.isVarPattern(tree) && name != nme.WILDCARD) =>
- atPos(tree.pos)(Bind(name, atPos(tree) (Ident(nme.WILDCARD))))
+ atPos(tree.pos)(Bind(name, atPos(tree.pos.focus) (Ident(nme.WILDCARD))))
case Typed(id @ Ident(name), tpt) if (treeInfo.isVarPattern(id) && name != nme.WILDCARD) =>
atPos(tree.pos.withPoint(id.pos.point)) {
Bind(name, atPos(tree.pos.withStart(tree.pos.point)) {
@@ -61,40 +61,47 @@ abstract class TreeBuilder {
}
}
- /** Traverse pattern and collect all variable names with their types in buffer */
+ /** Traverse pattern and collect all variable names with their types in buffer
+ * The variables keep their positions; whereas the pattern is converted to be synthetic
+ * for all nodes that contain a variable position.
+ */
private object getvarTraverser extends Traverser {
val buf = new ListBuffer[(Name, Tree, Position)]
def init: Traverser = { buf.clear; this }
- override def traverse(tree: Tree): Unit = tree match {
- case Bind(name, Typed(tree1, tpt)) =>
- if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
- buf += ((name, if (treeInfo.mayBeTypePat(tpt)) TypeTree() else tpt, tree.pos))
- }
- traverse(tree1)
- case Bind(name, tree1) =>
- if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
- // can assume only name range as position, as otherwise might overlap
- // with binds embedded in pattern tree1
- val start = tree.pos.start
- val end = start + name.decode.length
-
- // if the name range does overlap the bind we assume it is
- // a fresh name (ie. generated from for(... ; (a, b) <- (1, 2) ...))
- // make it transparent
- val namePos0 = r2p(start, start, end)
- val namePos = if (namePos0 overlaps tree.pos) makeTransparent(namePos0) else namePos0
- buf += ((name, TypeTree(), namePos))
- }
- traverse(tree1)
- case _ =>
- super.traverse(tree)
+ def namePos(tree: Tree, name: Name): Position =
+ if (!tree.pos.isRange || name.toString.contains('$')) tree.pos.focus
+ else {
+ val start = tree.pos.start
+ val end = start + name.decode.length
+ r2p(start, start, end)
+ }
+ override def traverse(tree: Tree): Unit = {
+ val bl = buf.length
+ tree match {
+ case Bind(name, Typed(tree1, tpt)) =>
+ if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
+ buf += ((name, if (treeInfo.mayBeTypePat(tpt)) TypeTree() else tpt.duplicate, namePos(tree, name)))
+ }
+ traverse(tree1)
+ case Bind(name, tree1) =>
+ if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
+ // can assume only name range as position, as otherwise might overlap
+ // with binds embedded in pattern tree1
+ buf += ((name, TypeTree(), namePos(tree, name)))
+ //println("found var "+name+" at "+namePos.show) //DEBUG
+ }
+ traverse(tree1)
+ case _ =>
+ super.traverse(tree)
+ }
+ if (buf.length > bl) tree setPos tree.pos.makeTransparent
}
}
/** Returns list of all pattern variables, possibly with their types,
* without duplicates
*/
- private def getVariables(tree: Tree): List[(Name, Tree,Position)] = {
+ private def getVariables(tree: Tree): List[(Name, Tree, Position)] = {
getvarTraverser.init.traverse(tree)
getvarTraverser.buf.toList
}
@@ -158,7 +165,7 @@ abstract class TreeBuilder {
/** Create positioned tree representing an object creation <new parents { stats }
* @param npos the position of the new
- * @param cpos the position of the anonymous class startig with parents
+ * @param cpos the position of the anonymous class starting with parents
*/
def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], argss: List[List[Tree]],
npos: Position, cpos: Position): Tree =
@@ -174,11 +181,11 @@ abstract class TreeBuilder {
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
- Template(parents, self, NoMods, List(Nil), argss, stats, cpos.toSynthetic))
+ Template(parents, self, NoMods, List(Nil), argss, stats, cpos.focus))
}),
atPos(npos) {
New(
- Ident(x) setPos npos.toSynthetic,
+ Ident(x) setPos npos.focus,
List(Nil))
}
)
@@ -200,7 +207,7 @@ abstract class TreeBuilder {
/** Create tree representing a while loop */
def makeWhile(lname: Name, cond: Tree, body: Tree): Tree = {
- val continu = atPos(o2p(body.pos.end)) { Apply(Ident(lname), Nil) }
+ val continu = atPos(o2p(body.pos.endOrPoint)) { Apply(Ident(lname), Nil) }
val rhs = If(cond, Block(List(body), continu), Literal(()))
LabelDef(lname, Nil, rhs)
}
@@ -234,7 +241,7 @@ abstract class TreeBuilder {
List(
makeVisitor(
List(
- CaseDef(pat1.syntheticDuplicate, EmptyTree, Literal(true)),
+ CaseDef(pat1.duplicate, EmptyTree, Literal(true)),
CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))),
false,
nme.CHECK_IF_REFUTABLE_STRING
@@ -310,7 +317,7 @@ abstract class TreeBuilder {
* the limits given by pat and body.
*/
def makeClosure(pos: Position, pat: Tree, body: Tree): Tree = {
- def splitpos = makeTransparent(wrappingPos(List(pat, body)).withPoint(pos.point))
+ def splitpos = wrappingPos(List(pat, body)).withPoint(pos.point).makeTransparent
matchVarPattern(pat) match {
case Some((name, tpt)) =>
Function(
@@ -345,12 +352,12 @@ abstract class TreeBuilder {
/** A reference to the name bound in Bind `pat`.
*/
def makeValue(pat: Tree): Tree = pat match {
- case Bind(name, _) => Ident(name) setPos pat.pos.toSynthetic
+ case Bind(name, _) => Ident(name) setPos pat.pos.focus
}
/** The position of the closure that starts with generator at position `genpos`.
*/
- def closurePos(genpos: Position) = r2p(genpos.start, genpos.point, body.pos.end)
+ def closurePos(genpos: Position) = r2p(genpos.startOrPoint, genpos.point, body.pos.endOrPoint)
// val result =
enums match {
@@ -361,7 +368,7 @@ abstract class TreeBuilder {
makeFor(mapName, flatMapName, rest, body))
case ValFrom(pos, pat, rhs) :: Filter(_, test) :: rest =>
makeFor(mapName, flatMapName,
- ValFrom(pos, pat, makeCombination(rhs.pos union test.pos, nme.filter, rhs, pat.syntheticDuplicate, test)) :: rest,
+ ValFrom(pos, pat, makeCombination(rhs.pos union test.pos, nme.filter, rhs, pat.duplicate, test)) :: rest,
body)
case ValFrom(pos, pat, rhs) :: rest =>
val valeqs = rest.take(definitions.MaxTupleArity - 1).takeWhile(_.isInstanceOf[ValEq]);
@@ -376,8 +383,8 @@ abstract class TreeBuilder {
val rhs1 = makeForYield(
List(ValFrom(pos, defpat1, rhs)),
Block(pdefs, atPos(wrappingPos(ids)) { makeTupleTerm(ids, true) }) setPos wrappingPos(pdefs))
- val allpats = (pat :: pats) map (_.syntheticDuplicate)
- val vfrom1 = ValFrom(r2p(pos.start, pos.point, rhs1.pos.end), atPos(wrappingPos(allpats)) { makeTuple(allpats, false) } , rhs1)
+ val allpats = (pat :: pats) map (_.duplicate)
+ val vfrom1 = ValFrom(r2p(pos.startOrPoint, pos.point, rhs1.pos.endOrPoint), atPos(wrappingPos(allpats)) { makeTuple(allpats, false) } , rhs1)
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
case _ =>
EmptyTree //may happen for erroneous input
@@ -428,8 +435,9 @@ abstract class TreeBuilder {
def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean): Tree =
makeVisitor(cases, checkExhaustive, "x$")
- private def makeUnchecked(expr: Tree): Tree =
+ private def makeUnchecked(expr: Tree): Tree = atPos(expr.pos) {
Annotated(New(scalaDot(definitions.UncheckedClass.name), List(Nil)), expr)
+ }
/** Create visitor <x => x match cases> */
def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean, prefix: String): Tree = {
@@ -465,25 +473,24 @@ abstract class TreeBuilder {
// val/var x_N = t$._N
val pat1 = patvarTransformer.transform(pat)
val vars = getVariables(pat1)
- val matchExpr = atPos(rhs.pos){
+ val matchExpr = atPos((pat1.pos union rhs.pos).makeTransparent) {
Match(
makeUnchecked(rhs),
List(
- makeSynthetic(
- atPos(rhs.pos) {
- CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
- })))
-
+ atPos(pat1.pos) {
+ CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
+ }
+ ))
}
vars match {
case List((vname, tpt, pos)) =>
- List(atPos(pat.pos union rhs.pos) {
+ List(atPos(pat.pos union pos union rhs.pos) {
ValDef(mods, vname, tpt, matchExpr)
})
case _ =>
val tmp = freshName()
val firstDef =
- atPos(rhs.pos) {
+ atPos(matchExpr.pos) {
ValDef(Modifiers(PRIVATE | LOCAL | SYNTHETIC | (mods.flags & LAZY)),
tmp, TypeTree(), matchExpr)
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index bee6674fd1..aa18d5226d 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -199,7 +199,7 @@ abstract class GenICode extends SubComponent {
private def genLoad(tree: Tree, ctx: Context, expectedType: TypeKind): Context = {
var generatedType = expectedType
if (settings.debug.value)
- log("at line: " + (tree.pos).line.map(_.toString).getOrElse(tree.pos.toString))
+ log("at line: " + (if (tree.pos.isDefined) tree.pos.line else tree.pos))
/**
* Generate code for primitive arithmetic operations.
@@ -1427,10 +1427,10 @@ abstract class GenICode extends SubComponent {
case None =>
val local = ctx.makeLocal(l.pos, definitions.AnyRefClass.typeConstructor, eqEqTempName.toString)
//assert(!l.pos.source.isEmpty, "bad position, unit = "+unit+", tree = "+l+", pos = "+l.pos.source)
- assert(l.pos.source.get == unit.source)
- assert(r.pos.source.get == unit.source)
- local.start = (l.pos).line.get
- local.end = (r.pos).line.get
+ assert(l.pos.source == unit.source)
+ assert(r.pos.source == unit.source)
+ local.start = (l.pos).line
+ local.end = (r.pos).line
local
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
index 812d77f4ff..1dd51a3741 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
@@ -129,7 +129,7 @@ trait Printers { self: ICodes =>
// if (settings.Xdce.value)
// print(if (i.useful) " " else " * ");
if (settings.debug.value)
- print(i.pos.line.map(_.toString).getOrElse(""))
+ if (i.pos.isDefined) print(i.pos.line.toString)
println(i.toString())
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 2184b554f8..cf9be28042 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -1269,9 +1269,9 @@ abstract class GenJVM extends SubComponent {
// assert(instr.pos.source.isEmpty || instr.pos.source.get == (clasz.cunit.source), "sources don't match")
// val crtLine = instr.pos.line.get(lastLineNr);
val crtLine = try {
- (instr.pos).line.get
+ (instr.pos).line
} catch {
- case _: NoSuchElementException =>
+ case _: UnsupportedOperationException =>
log("Warning: wrong position in: " + method)
lastLineNr
}
@@ -1439,7 +1439,7 @@ abstract class GenJVM extends SubComponent {
log("Converting from: " + src + " to: " + dst);
if (dst == BOOL) {
Console.println("Illegal conversion at: " + clasz +
- " at: " + pos.source.get + ":" + pos.line.getOrElse(-1));
+ " at: " + pos.source + ":" + pos.line);
} else
jcode.emitT2T(javaType(src), javaType(dst));
diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
index 58e1e598bc..cbfa4161bd 100644
--- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
+++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala
@@ -504,10 +504,7 @@ abstract class GenMSIL extends SubComponent {
}
}
- val line = (sym.pos).line match {
- case Some(l) => l
- case None => 0
- }
+ val line = sym.pos.line
tBuilder.setPosition(line, iclass.cunit.source.file.name)
if (isTopLevelModule(sym)) {
@@ -1217,12 +1214,7 @@ abstract class GenMSIL extends SubComponent {
needAdditionalRet = false
- val currentLineNr = (instr.pos).line match {
- case Some(line) => line
- case None =>
- log("Warning: wrong position in: " + method)
- lastLineNr
- } // if getting line number fails
+ val currentLineNr = instr.pos.line
if (currentLineNr != lastLineNr) {
mcode.setPosition(currentLineNr)
@@ -1677,8 +1669,7 @@ abstract class GenMSIL extends SubComponent {
case DOUBLE => mcode.Emit(OpCodes.Conv_R8)
case _ =>
Console.println("Illegal conversion at: " + clasz +
- " at: " + pos.source.get + ":" +
- pos.line.get)
+ " at: " + pos.source + ":" + pos.line)
}
case ArrayLength(_) =>
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 4fda69a66e..d46b5b4b89 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -42,7 +42,7 @@ trait CompilerControl { self: Global =>
}
/** The compilation unit corresponding to a position */
- def unitOf(pos: Position): RichCompilationUnit = unitOf(pos.source.get)
+ def unitOf(pos: Position): RichCompilationUnit = unitOf(pos.source)
/** Remove the CompilationUnit corresponding to the given SourceFile
* from consideration for recompilation.
diff --git a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala
index f90434b4bc..70557ac5c6 100755
--- a/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ContextTrees.scala
@@ -56,7 +56,7 @@ trait ContextTrees { self: Global =>
*/
def addContext(contexts: Contexts, context: Context) {
val cpos = context.tree.pos
- if (isTransparent(cpos))
+ if (cpos.isTransparent)
for (t <- context.tree.children flatMap solidDescendants)
addContext(contexts, context, t.pos)
else
@@ -68,7 +68,7 @@ trait ContextTrees { self: Global =>
*/
def addContext(contexts: Contexts, context: Context, cpos: Position) {
try {
- if (!cpos.isDefined || cpos.isSynthetic) {}
+ if (!cpos.isRange) {}
else if (contexts.isEmpty) contexts += new ContextTree(cpos, context)
else {
val hi = contexts.length - 1
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 2f74e1635f..1b77d612cb 100755
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -24,6 +24,8 @@ self =>
import definitions._
+ settings.Xprintpos.value = true
+
override def onlyPresentation = true
/** A list indicating in which order some units should be typechecked.
@@ -67,8 +69,7 @@ self =>
}
if (activeLocks == 0) {
if (context.unit != null &&
- !result.pos.isSynthetic &&
- !isTransparent(result.pos) &&
+ result.pos.isOpaqueRange &&
(result.pos includes context.unit.targetPos)) {
integrateNew()
var located = new Locator(context.unit.targetPos) locateIn result
@@ -368,7 +369,7 @@ self =>
class TreeReplacer(from: Tree, to: Tree) extends Transformer {
override def transform(t: Tree): Tree = {
if (t == from) to
- else if ((t.pos includes from.pos) || isTransparent(t.pos)) super.transform(t)
+ else if ((t.pos includes from.pos) || t.pos.isTransparent) super.transform(t)
else t
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 527efae4b5..4f0d8edfa5 100755
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -2,7 +2,7 @@ package scala.tools.nsc
package interactive
import ast.Trees
-import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, SyntheticOffsetPosition, WorkScheduler}
+import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler}
import scala.collection.mutable.ListBuffer
/** Handling range positions
@@ -29,50 +29,40 @@ self: scala.tools.nsc.Global =>
def isFree = tree == EmptyTree
}
- class TransparentPosition(source0: SourceFile, start: Int, point: Int, end: Int) extends RangePosition(source0, start, point, end) {
- override def show = "<"+super.show+">"
- }
-
- def isTransparent(pos: Position) = pos.isInstanceOf[TransparentPosition]
-
- def isRange(pos: Position) = pos.isInstanceOf[RangePosition] && !isTransparent(pos)
-
- protected var splitAllowed = false
-
override def rangePos(source: SourceFile, start: Int, point: Int, end: Int) =
new RangePosition(source, start, point, end)
- /** A position that wraps the non-empty set of trees.
+ /** A position that wraps a set of trees.
+ * The point of the wrapping position is the point of the default position.
+ * If some of the trees are ranges, returns a range position enclosing all ranges
+ * Otherwise returns default position.
+ */
+ def wrappingPos(default: Position, trees: List[Tree]): Position = {
+ val ranged = trees filter (_.pos.isRange)
+ if (ranged.isEmpty) default.focus
+ else new RangePosition(default.source, (ranged map (_.pos.start)).min, default.point, (ranged map (_.pos.end)).max)
+ }
+
+ /** A position that wraps a non-empty set of trees.
* The point of the wrapping position is the point of the first trees' position.
- * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees
- * Otherwise returns a synthetic offset position to point.
+ * If some of the trees are ranges, returns a range position enclosing all ranges
+ * Otherwise returns first tree's position.
*/
override def wrappingPos(trees: List[Tree]): Position = {
val headpos = trees.head.pos
- if (headpos.isDefined) {
- val source = headpos.source.get
- val point = headpos.point
- val nonsynthetic = trees filter (t => t.pos.isDefined && !t.pos.isSynthetic)
- if (nonsynthetic.isEmpty)
- new SyntheticOffsetPosition(source, point)
- else
- new RangePosition(source, (nonsynthetic map (_.pos.start)).min, point, (nonsynthetic map (_.pos.end)).max)
- } else {
- headpos
- }
+ if (headpos.isDefined) wrappingPos(headpos, trees) else headpos
}
- override def makeTransparent(pos: Position) = pos match {
- case rp: RangePosition if (!rp.isSynthetic) =>
- new TransparentPosition(rp.source.get, rp.start, rp.point, rp.end)
- case _ =>
- pos
- }
+/*
+ override def integratePos(tree: Tree, pos: Position) =
+ if (pos.isSynthetic && !tree.pos.isSynthetic) tree.syntheticDuplicate
+ else tree
+*/
// -------------- ensuring no overlaps -------------------------------
def solidDescendants(tree: Tree): List[Tree] =
- if (isTransparent(tree.pos)) tree.children flatMap solidDescendants
+ if (tree.pos.isTransparent) tree.children flatMap solidDescendants
else List(tree)
/** A free range from `lo` to `hi` */
@@ -95,7 +85,7 @@ self: scala.tools.nsc.Global =>
assert(conflicting.nonEmpty)
rs
case r :: rs1 =>
- assert(!isTransparent(t.pos))
+ assert(!t.pos.isTransparent)
if (r.isFree && (r.pos includes t.pos)) {
// println("subdividing "+r+"/"+t.pos)
maybeFree(t.pos.end, r.pos.end) ::: List(Range(t.pos, t)) ::: maybeFree(r.pos.start, t.pos.start) ::: rs1
@@ -110,67 +100,31 @@ self: scala.tools.nsc.Global =>
if (ts.head == t) replacement ::: ts.tail
else ts.head :: replace(ts.tail, t, replacement)
- /** Ensure that given list of trees has mutually non-overlapping positions,
- * by assinging TransparentPositions to some of them, if necessary
+ /** Ensure that given tree has no positions that overlap with
+ * any of the positions of `others`. This is done by
+ * shortening the range or assinging TransparentPositions
+ * to some of the nodes in `tree`.
*/
- def ensureNonOverlapping(cts: List[Tree]): Unit = {
-
- def isSplittable(node: Tree) = node match {
- case Function(_, _) | CaseDef(_, _, _) | Match(_, _) => true
- case _ => false
- }
-
- /** Do a pass over all child trees `cts`, where `ranges` reflects positions previously
- * encountered. If there are overlaps, break up one node by making its position a TransparentPosition
- * and do another pass of `ensureOverlapping`.
- * @param ranges The current list of non-overlapping ranges,
- * both occupied and free, sorted from later to earlier.
- * No TransparentPositions allowed here!
- * @param trees The list of trees to insert in ranges.
- */
- def iterate(ranges: List[Range], trees: List[Tree]): Unit = trees match {
- case List() =>
- ;
- case tree :: trees1 =>
- if (isTransparent(tree.pos))
- iterate(ranges, solidDescendants(tree) ::: trees1)
- else if (!tree.pos.isDefined || tree.pos.isSynthetic)
- iterate(ranges, trees1)
- else {
- val conflicting = new ListBuffer[Tree]
- val ranges1 = insert(ranges, tree, conflicting)
-// println("inserted "+tree+"; ranges = "+ranges1)
- if (conflicting.isEmpty) {
- iterate(ranges1, trees1)
- } else {
- val splitNode =
- if (conflicting.size == 1 && (conflicting.head.pos includes tree.pos)) {
- //println("*** splitting \n"+conflicting.head+"\n--- because it conflicts with ---\n"+tree)
- //println(tree.id)
- conflicting.head
- } else {
- //println("*** splitting \n"+tree+"\n--- because it conflicts with trees in ---\n"+conflicting)
- //println(tree.id)
- tree
- }
- //throw new Error()//debug
-
-// println("splitting "+splitNode)
- splitNode setPos new TransparentPosition(splitNode.pos.source.get, splitNode.pos.start, splitNode.pos.point, splitNode.pos.end)
- ensureNonOverlapping(replace(cts, splitNode, solidDescendants(splitNode)))
- }
- }
+ override def ensureNonOverlapping(tree: Tree, others: List[Tree]) {
+ def isOverlapping(pos: Position) =
+ pos.isRange && (others exists (pos overlaps _.pos))
+ if (isOverlapping(tree.pos)) {
+ val children = tree.children
+ children foreach (ensureNonOverlapping(_, others))
+ if (tree.pos.isOpaqueRange) {
+ val wpos = wrappingPos(tree.pos.focus, children)
+ tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos)
+ }
}
-// println("ensure non overlap "+cts)
- if (phase.id <= currentRun.typerPhase.id)
- iterate(List(maxFree), cts)
}
- /** Does given list of trees have mutually non-overlapping positions? */
+ /** Does given list of trees have mutually non-overlapping positions?
+ * pre: None of the trees is transparent
+ */
def findOverlapping(cts: List[Tree]): List[(Tree, Tree)] = {
var ranges = List(maxFree)
for (ct <- cts) {
- if (ct.pos.isDefined && !ct.pos.isSynthetic) {
+ if (ct.pos.isOpaqueRange) {
val conflicting = new ListBuffer[Tree]
ranges = insert(ranges, ct, conflicting)
if (conflicting.nonEmpty) return conflicting.toList map (t => (t, ct))
@@ -189,20 +143,17 @@ self: scala.tools.nsc.Global =>
* @param trees The children to position. All children must be positionable.
*/
private def setChildrenPos(pos: Position, trees: List[Tree]): Unit = try {
- var remainingRange = pos
for (tree <- trees) {
if (!tree.isEmpty && tree.pos == NoPosition) {
- val children = tree.children filter (c => !c.isEmpty && !c.pos.isSynthetic)
+ val children = tree.children
if (children.isEmpty) {
- tree setPos new OffsetPosition(pos.source.get, remainingRange.start)
+ tree setPos pos.focus
} else {
- setChildrenPos(remainingRange, children)
- tree setPos wrappingPos(children)
+ setChildrenPos(pos, children)
+ tree setPos wrappingPos(pos, children)
}
- remainingRange = new RangePosition(pos.source.get, tree.pos.end, pos.point, pos.end)
}
}
- ensureNonOverlapping(trees)
} catch {
case ex: Exception =>
println("error while set children pos "+pos+" of "+trees)
@@ -213,7 +164,7 @@ self: scala.tools.nsc.Global =>
* This means: Set position of a node and position all its unpositioned children.
*/
override def atPos[T <: Tree](pos: Position)(tree: T): T =
- if (isRange(pos)) {
+ if (pos.isOpaqueRange) {
if (!tree.isEmpty && tree.pos == NoPosition) {
tree.setPos(pos)
val children = tree.children
@@ -231,11 +182,7 @@ self: scala.tools.nsc.Global =>
override def validatePositions(tree: Tree) {
def reportTree(prefix : String, tree : Tree) {
- val source = tree.pos.source match {
- case Some(sf) => " in file "+sf
- case None => ""
- }
-
+ val source = if (tree.pos.isDefined) tree.pos.source else ""
inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source)
inform("")
inform(tree.toString)
@@ -258,8 +205,8 @@ self: scala.tools.nsc.Global =>
if (!tree.isEmpty) {
if (!tree.pos.isDefined)
error("Unpositioned tree ["+tree.id+"]") { reportTree("Unpositioned", tree) }
- if (!tree.pos.isSynthetic) {
- if (encltree.pos.isSynthetic)
+ if (tree.pos.isRange) {
+ if (!encltree.pos.isRange)
error("Synthetic tree ["+encltree.id+"] contains nonsynthetic tree ["+tree.id+"]") {
reportTree("Enclosing", encltree)
reportTree("Enclosed", tree)
@@ -306,8 +253,8 @@ self: scala.tools.nsc.Global =>
this.last
}
override def traverse(t: Tree) {
- if (!t.pos.isSynthetic && (t.pos includes pos)) {
- if (!isTransparent(t.pos)) last = t
+ if (t.pos includes pos) {
+ if (!t.pos.isTransparent) last = t
super.traverse(t)
}
}
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 1e6e5b297c..a9747325e0 100755
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -24,7 +24,7 @@ trait JavaParsers extends JavaScanners {
class JavaUnitParser(val unit: global.CompilationUnit) extends JavaParser {
val in = new JavaUnitScanner(unit)
def freshName(pos : Position, prefix : String) = unit.fresh.newName(pos, prefix)
- implicit def i2p(offset : Int) : Position = new OffsetPosition(unit.source,offset)
+ implicit def i2p(offset : Int) : Position = new OffsetPosition(unit.source, offset)
def warning(pos : Int, msg : String) : Unit = unit.warning(pos, msg)
def syntaxError(pos: Int, msg: String) : Unit = unit.error(pos, msg)
}
@@ -35,7 +35,7 @@ trait JavaParsers extends JavaScanners {
protected def posToReport: Int = in.currentPos
protected def freshName(pos : Position, prefix : String): Name
protected implicit def i2p(offset : Int) : Position
- private implicit def p2i(pos : Position): Int = pos.offset.getOrElse(-1)
+ private implicit def p2i(pos : Position): Int = if (pos.isDefined) pos.point else -1
/** The simple name of the package of the currently parsed file */
private var thisPackageName: Name = nme.EMPTY
diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
index ab6de92b7a..50c166c38e 100755
--- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
@@ -975,7 +975,7 @@ trait JavaScanners {
def error (pos: Int, msg: String) = unit. error(pos, msg)
def incompleteInputError(pos: Int, msg: String) = unit.incompleteInputError(pos, msg)
def deprecationWarning(pos: Int, msg: String) = unit.deprecationWarning(pos, msg)
- implicit def p2g(pos: Position): Int = pos.offset.getOrElse(-1)
+ implicit def p2g(pos: Position): Int = if (pos.isDefined) pos.point else -1
implicit def g2p(pos: Int): Position = new OffsetPosition(unit.source, pos)
}
}
diff --git a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala
index b9e4046a41..6c76968149 100644
--- a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala
+++ b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala
@@ -204,12 +204,12 @@ class SemanticTokens(val compiler: Global) {
val map = new scala.collection.mutable.LinkedHashMap[Int,Symbol]
map.clear // populate the map.
class visitor extends walker.Visitor {
- def contains(pos : Position) = map.contains(pos.offset.get)
- def apply(pos : Position) = map(pos.offset.get)
- def update(pos : Position, sym : Symbol) : Unit = if (pos.offset.isDefined) {
- val offset = pos.offset.get
+ def contains(pos : Position) = map.contains(pos.point)
+ def apply(pos : Position) = map(pos.point)
+ def update(pos : Position, sym : Symbol) : Unit = if (pos.isDefined) {
+ val offset = pos.point
map(offset) = sym
- val isDef = pos.offset == sym.pos.offset
+ val isDef = pos.point == sym.pos.point
list.put(offset, (if (isDef) new Def(sym) else new Use(sym, NoType)));
}
}
@@ -224,10 +224,10 @@ class SemanticTokens(val compiler: Global) {
def build(tree0: Tree): Unit = try {
/* if (tree0.pos != NoPosition) */ tree0 match {
case tree: ImplDef =>
- val pos = eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.offset.get)
+ val pos = eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.point)
if (pos == -1) {
- } else buildDef(tree.symbol, eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.offset.get));
+ } else buildDef(tree.symbol, eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.point));
tree match {
case cdef: ClassDef => build(cdef.tparams)
case _ => ;
@@ -242,7 +242,7 @@ class SemanticTokens(val compiler: Global) {
// todo: review whether this is correct, or whether abstract getters should be included.
{
val pos : Int = if (tree.name.toString().equals("<init>")) -1 else
- eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.offset.get);
+ eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.point);
if (false) Console.err.println("VALDEF: tree=" + tree + " sym=" + tree.symbol + " pos0=" +
tree.symbol.pos + " alias=" + tree.symbol.alias + " pos1=" +
pos + " pos2=" + tree.pos.dbgString + " " + tree.symbol.hasFlag(Flags.SYNTHETIC));
@@ -256,8 +256,8 @@ class SemanticTokens(val compiler: Global) {
build(ddef.tparams);
for (l0 <- ddef.vparamss; arg <- l0) {
- val pos0 : Int = if (!unit.source.beginsWith(arg.pos.offset.get, "val ")) arg.pos.offset.get;
- else unit.source.skipWhitespace(arg.pos.offset.get + ("val ").length());
+ val pos0 : Int = if (!unit.source.beginsWith(arg.pos.point, "val ")) arg.pos.point;
+ else unit.source.skipWhitespace(arg.pos.point + ("val ").length());
buildDef(arg.symbol, pos0);
build(arg.tpt);
}
@@ -281,7 +281,7 @@ class SemanticTokens(val compiler: Global) {
case tree: PackageDef =>
//Console.err.println("PACKAGE: " + tree.name);
if (false) {
- val pos = eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.offset.getOrElse(-1))
+ val pos = eatKeywords(unit.source.asInstanceOf[BatchSourceFile], tree.pos.pointOrElse(-1))
if (pos != -1)
buildDef(tree.symbol, pos)
}
@@ -290,13 +290,13 @@ class SemanticTokens(val compiler: Global) {
for (arg <- tree.vparams if arg.pos != NoPosition) {
val name = arg.name.toString().trim()
val pos: Int =
- if (unit.source.beginsWith(arg.pos.offset.getOrElse(-1), "val "))
- unit.source.skipWhitespace(arg.pos.offset.getOrElse(-1) + ("val ").length())
- else if (unit.source.asInstanceOf[BatchSourceFile].content(arg.pos.offset.get) == ':') {
- var posx : Int = arg.pos.offset.get
+ if (unit.source.beginsWith(arg.pos.pointOrElse(-1), "val "))
+ unit.source.skipWhitespace(arg.pos.pointOrElse(-1) + ("val ").length())
+ else if (unit.source.asInstanceOf[BatchSourceFile].content(arg.pos.point) == ':') {
+ var posx : Int = arg.pos.point
while (unit.source.asInstanceOf[BatchSourceFile].content(posx - 1).isWhitespace) posx = posx - 1
posx - name.length()
- } else arg.pos.offset.get
+ } else arg.pos.point
buildDef(arg.symbol, pos)
build(arg.tpt)
}
@@ -314,13 +314,13 @@ class SemanticTokens(val compiler: Global) {
def buildT( tree : Tree, tpe : Type) : Unit = if (tree.pos != NoPosition) tpe match {
case tpe0 : TypeRef => tree match {
case apt : AppliedTypeTree =>
- buildUse(tpe.typeSymbol, apt.tpt.pos.offset.getOrElse(-1), tpe0);
+ buildUse(tpe.typeSymbol, apt.tpt.pos.pointOrElse(-1), tpe0);
//Console.err.println("APT: " + treex + " vs. " + treex.original);
//Console.err.println("APT: " + treex.pos + " vs. " + treex.original.pos + " " + unit.source.dbg(treex.original.pos));
//Console.err.println("APT: " + apt.tpt + " sym0=" + apt.tpt.symbol + " sym1=" + tpe0.sym + " apt.args=" + apt.args + " tpe0.args=" + tpe0.args);
buildTs (apt.args, tpe0.args);
- case ident : Ident => buildUse(tpe0.sym, ident.pos.offset.getOrElse(-1), tpe0);
+ case ident : Ident => buildUse(tpe0.sym, ident.pos.pointOrElse(-1), tpe0);
case select : Select =>
if (select.symbol == NoSymbol)
try {
@@ -336,10 +336,10 @@ class SemanticTokens(val compiler: Global) {
case tpt : TypeTree =>
if (tpt.symbol ne null) {
Console.err.println("SYM0 " + tpt.symbol + " " + (tpt.pos).dbgString);
- buildUse(tpt.symbol, tpt.pos.offset.getOrElse(-1), tpe0);
+ buildUse(tpt.symbol, tpt.pos.pointOrElse(-1), tpe0);
} else if (tpe0.typeSymbol ne null) {
//Console.err.println("TYPE_SYM1 " + tpe0.symbol + " " + unit.source.dbg(tpt.pos));
- buildUse(tpe0.typeSymbol, tpt.pos.offset.getOrElse(-1), tpe0);
+ buildUse(tpe0.typeSymbol, tpt.pos.pointOrElse(-1), tpe0);
} else {
Console.err.println("UNKNOWN TPT0: " + (tpt.pos).dbgString + " tpt=" + tpt + " " + tpt.symbol + " tpe0="+ tpe0 + " " + tpe0.typeSymbol + " tpe0.args=" + tpe0.args);
}
@@ -385,7 +385,7 @@ class SemanticTokens(val compiler: Global) {
if (false) Console.err.println("UNKNOWN TPE10: " + tpe0 + " " + tree + " " + tree.getClass() + " " + (tree.pos).dbgString);
}
case tpe0 : SingleType => tree match {
- case ident : Ident => buildUse(tpe0.sym, ident.pos.offset.getOrElse(-1), tpe0);
+ case ident : Ident => buildUse(tpe0.sym, ident.pos.pointOrElse(-1), tpe0);
case select : Select =>
buildUse(tpe0.termSymbol, selectPos(select), tpe0);
//Console.err.println("QUALIFIER-0: " + select.qualifier + " " + unit.source.dbg(select.qualifier.pos) + " " + tpe0.prefix + " " + tpe0.prefix.getClass() + " " + tpe0.prefix.getClass().getSuperclass() +" " + tpe0.prefix.widen + " " + tpe0.prefix.toLongString);
@@ -419,16 +419,16 @@ class SemanticTokens(val compiler: Global) {
case tree: AbsTypeDef =>
//Console.err.println("ABS: " + tree.symbol + " " + unit.source.dbg(tree.namePos) + " " + tree.pos.dbgString);
buildDef(tree.symbol, tree.namePos)
- buildDef(tree.symbol, tree.pos.offset.getOrElse(-1))
+ buildDef(tree.symbol, tree.pos.pointOrElse(-1))
build(tree.tparams); //@M
build(tree.lo)
build(tree.hi)
*/
case tree: Bind =>
- buildDef(tree.symbol, tree.pos.offset.getOrElse(-1))
+ buildDef(tree.symbol, tree.pos.pointOrElse(-1))
build(tree.body)
case tree: Ident =>
- buildUse(tree.symbol, tree.pos.offset.getOrElse(-1), tree.tpe)
+ buildUse(tree.symbol, tree.pos.pointOrElse(-1), tree.tpe)
case tree: Select =>
try {
build(tree.qualifier)
@@ -436,7 +436,7 @@ class SemanticTokens(val compiler: Global) {
case e : Error => Console.err.println("SELECTQ: " + tree + " " + tree.qualifier + " " + (tree.qualifier.pos).dbgString); throw e;
}
try {
- if (tree.pos.offset.isDefined && tree.pos.offset.get >= unit.source.length) {
+ if (tree.pos.isDefined && tree.pos.point >= unit.source.length) {
if (false) Console.err.println("BAD_SELECT_QUALIFIER " + tree + " @ " + (tree.pos).dbgString);
} else {
@@ -490,11 +490,11 @@ class SemanticTokens(val compiler: Global) {
case tree : Alternative => build(tree.trees);
case tree : This =>
- if (tree.symbol ne null) buildUse(tree.symbol, tree.pos.offset.getOrElse(-1), tree.tpe);
+ if (tree.symbol ne null) buildUse(tree.symbol, tree.pos.pointOrElse(-1), tree.tpe);
//Thread.dumpStack();
case tree : TypeDef =>
//Console.err.println("ALIAS: " + tree);
- build(tree.rhs); build(tree.tparams); buildDef(tree.symbol, tree.pos.offset.getOrElse(-1));
+ build(tree.rhs); build(tree.tparams); buildDef(tree.symbol, tree.pos.pointOrElse(-1));
case tree : DocDef => build(tree.definition);
case tree: Import => build(tree.expr)
case tree: AppliedTypeTree => ;
@@ -550,7 +550,7 @@ class SemanticTokens(val compiler: Global) {
def selectPos(tree: Select): Int = if (tree.pos == NoPosition) -1 else {
val buf = unit.source.asInstanceOf[BatchSourceFile].content
- if (tree.pos.offset.get >= buf.length) {
+ if (tree.pos.point >= buf.length) {
if (false) {
Console.err.println("" + tree + "@" + tree.pos + " not in " +
unit.source.file.name + "[" + buf.length + "]");
@@ -561,13 +561,13 @@ class SemanticTokens(val compiler: Global) {
}
val pos : Int =
- if (buf(tree.pos.offset.get) != '.') tree.pos.offset.get
+ if (buf(tree.pos.point) != '.') tree.pos.point
else {
def f(x : Int) : Int = {
if (buf(x).isWhitespace) f(x + 1)
else x
}
- f(tree.pos.offset.get + 1)
+ f(tree.pos.point + 1)
}
pos
};
diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
index aed42ca406..941b698b2a 100644
--- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala
@@ -53,7 +53,7 @@ abstract class AbstractReporter extends Reporter {
private def testAndLog(pos: Position, severity: Severity): Boolean = {
if (pos eq null) return false
if (pos.offset.isEmpty) return false
- val fpos = pos.focusPoint
+ val fpos = pos.focus
if ((positions contains fpos) && positions(fpos) >= severity) return true
positions += (fpos -> severity)
false
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index 4ee4a4fccc..ca7b264d22 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -49,27 +49,20 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
/** Prints the message with the given position indication. */
def printMessage(posIn: Position, msg: String) {
- if (posIn ne null) {
- val pos = posIn.inUltimateSource(posIn.source.getOrElse(null))
- val buf = new StringBuilder(msg)
- if (!pos.source.isEmpty) {
- buf.insert(0, " ")
- buf.insert(0, pos.line.map(ln => ":" + pos.line.get + ":").getOrElse(":"))
- }
- //println(getSource.file)
- pos match {
- case FakePos(msg) =>
- buf.insert(0, msg + " ")
- case _ if !pos.source.isEmpty =>
- val file = pos.source.get.file
- buf.insert(0, if (shortname) file.name else file.path)
- case _ =>
- }
- printMessage(buf.toString())
- if (!pos.line.isEmpty)
+ val pos = if (posIn eq null) NoPosition
+ else if (posIn.isDefined) posIn.inUltimateSource(posIn.source)
+ else posIn
+ pos match {
+ case FakePos(fmsg) =>
+ printMessage(fmsg+" "+msg)
+ case NoPosition =>
+ printMessage(msg)
+ case _ =>
+ val buf = new StringBuilder(msg)
+ val file = pos.source.file
+ printMessage((if (shortname) file.name else file.path)+":"+pos.line+": "+msg)
printSourceLine(pos)
- } else
- printMessage(msg)
+ }
}
def print(pos: Position, msg: String, severity: Severity) {
@@ -88,16 +81,8 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
*
* @param pos ...
*/
- def printColumnMarker(pos: Position) = if (!pos.column.isEmpty) {
- val buffer = new StringBuilder(pos.column.get)
- var i = 1
- while (i < pos.column.get) {
- buffer.append(' ')
- i += 1
- }
- if (pos.column.get > 0) buffer.append('^')
- printMessage(buffer.toString())
- }
+ def printColumnMarker(pos: Position) =
+ if (pos.isDefined) { printMessage(" " * (pos.column - 1) + "^") }
/** Prints the number of errors and warnings if their are non-zero. */
def printSummary() {
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
index 3ecd8f2a6e..9e42db2fce 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
@@ -120,4 +120,6 @@ abstract class SymbolTable extends Names
/** The phase which has given index as identifier */
val phaseWithId: Array[Phase]
+
+ def ensureNonOverlapping(tree: Tree, others: List[Tree])
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 05c0614620..364ed5432d 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -248,7 +248,7 @@ trait Symbols {
var cnt = 0
def freshName() = { cnt += 1; newTermName("x$" + cnt) }
def param(tp: Type) =
- newValueParameter(owner.pos, freshName()).setFlag(SYNTHETIC).setInfo(tp)
+ newValueParameter(owner.pos.focus, freshName()).setFlag(SYNTHETIC).setInfo(tp)
argtypess map (_.map(param))
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index f8188246f8..5375f77569 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -2553,7 +2553,6 @@ A type's typeSymbol should never be inspected directly.
newAnnots
}
-
def mapOver(annot: AnnotationInfo): Option[AnnotationInfo] = {
val AnnotationInfo(atp, args, assocs) = annot
@@ -2827,6 +2826,7 @@ A type's typeSymbol should never be inspected directly.
/** A base class to compute all substitutions */
abstract class SubstMap[T](from: List[Symbol], to: List[T]) extends TypeMap {
+
/** Are `sym' and `sym1' the same.
* Can be tuned by subclasses.
*/
@@ -2953,20 +2953,16 @@ A type's typeSymbol should never be inspected directly.
object trans extends TypeMapTransformer {
override def transform(tree: Tree) =
tree match {
- case tree@Ident(_) if from contains tree.symbol =>
+ case Ident(name) if from contains tree.symbol =>
val totpe = to(from.indexOf(tree.symbol))
- if (!totpe.isStable) {
- giveup()
- } else {
- tree.duplicate.setType(totpe)
- }
+ if (!totpe.isStable) giveup()
+ else Ident(name).setPos(tree.pos).setSymbol(tree.symbol).setType(totpe)
case _ => super.transform(tree)
}
}
trans.transform(tree)
- }
-
+ }
}
@@ -3039,7 +3035,7 @@ A type's typeSymbol should never be inspected directly.
object treeTrans extends TypeMapTransformer {
override def transform(tree: Tree): Tree =
tree match {
- case tree@Ident(name) =>
+ case Ident(name) =>
tree.tpe.withoutAnnotations match {
case DeBruijnIndex(level, pid) =>
if (level == 1) {
@@ -3052,9 +3048,12 @@ A type's typeSymbol should never be inspected directly.
setType typeRef(NoPrefix, sym, Nil))
}
} else
- tree.duplicate.setType(
- DeBruijnIndex(level-1, pid))
- case _ => super.transform(tree)
+ Ident(name)
+ .setPos(tree.pos)
+ .setSymbol(tree.symbol)
+ .setType(DeBruijnIndex(level-1, pid))
+ case _ =>
+ super.transform(tree)
}
case _ => super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 1fa2ba58d2..806b054ee6 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -711,7 +711,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
sym1 + ":" + atRefc(tpe1.toString) +
(if (sym1.owner == root) "" else sym1.locationString) + " and\n" +
sym2 + ":" + atRefc(tpe2.toString) +
- (if (sym2.owner == root) " at line " + (sym2.pos).line.get else sym2.locationString) +
+ (if (sym2.owner == root) " at line " + (sym2.pos).line else sym2.locationString) +
"\nhave same type" +
(if (atRefc(tpe1 =:= tpe2)) "" else " after erasure: " + atPhase(phase.next)(sym1.tpe)))
sym1.setInfo(ErrorType)
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index c02d2cd27d..71caf89010 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -630,7 +630,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def mkCheckedAccessor(clazz: Symbol, retVal: Tree, offset: Int, pos: Position): Tree = {
val bitmapSym = bitmapFor(clazz, offset)
val mask = LIT(1 << (offset % FLAGS_PER_WORD))
- val msg = "Uninitialized field: " + unit.source + ": " + pos.line.get
+ val msg = "Uninitialized field: " + unit.source + ": " + pos.line
val result =
IF (mkTest(clazz, mask, bitmapSym, false)) .
THEN (retVal) .
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 3306b1f63a..b96ce58370 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -362,7 +362,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
localTyper.typed {
atPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, fun.pos.toSynthetic)),
+ List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, fun.pos)),
Typed(
New(TypeTree(anonClass.tpe), List(List())),
TypeTree(fun.tpe)))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
index a7b00894dd..acef0154b2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
@@ -55,6 +55,7 @@ trait Analyzer extends AnyRef
def apply(unit: CompilationUnit) {
try {
unit.body = newTyper(rootContext(unit)).typed(unit.body)
+ if (global.settings.Yrangepos.value) global.validatePositions(unit.body)
for (workItem <- unit.toCheck) workItem()
} finally {
unit.toCheck.clear()
diff --git a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala
index 2714e72640..caa1e027d5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/DeVirtualize.scala
@@ -405,7 +405,7 @@ abstract class DeVirtualize extends InfoTransform with TypingTransformers {
}
}
atPos(clazz.pos) {
- ClassDef(cclazz, Modifiers(0), vparamss, List(List()), pfields ::: overrideBridges, clazz.pos.toSynthetic)
+ ClassDef(cclazz, Modifiers(0), vparamss, List(List()), pfields ::: overrideBridges, clazz.pos.focus)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
index 118e06bf6a..314aee531c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala
@@ -76,8 +76,10 @@ trait EtaExpansion { self: Analyzer =>
if (treeInfo.isPureExpr(tree)) tree
else {
val vname: Name = freshName(tree.pos, 0)
- defs += atPos(tree.pos)(ValDef(Modifiers(SYNTHETIC), vname, TypeTree(), tree))
- Ident(vname) setPos tree.pos.toSynthetic
+ defs += atPos(tree.pos) {
+ ValDef(Modifiers(SYNTHETIC), vname, TypeTree(), tree)
+ }
+ Ident(vname) setPos tree.pos.focus
}
val tree1 = tree match {
// a partial application using named arguments has the following form:
@@ -99,7 +101,7 @@ trait EtaExpansion { self: Analyzer =>
case Ident(name) =>
tree
}
- if (tree1 ne tree) tree1 setPos makeTransparent(tree1.pos)
+ if (tree1 ne tree) tree1 setPos tree1.pos.makeTransparent
tree1
}
@@ -114,8 +116,9 @@ trait EtaExpansion { self: Analyzer =>
tree
case MethodType(paramSyms, restpe) =>
val params = paramSyms map (sym =>
- ValDef(Modifiers(SYNTHETIC | PARAM), sym.name, TypeTree(sym.tpe), EmptyTree))
- atPos(makeTransparent(tree.pos)) {
+ ValDef(Modifiers(SYNTHETIC | PARAM),
+ sym.name, TypeTree(sym.tpe) , EmptyTree))
+ atPos(tree.pos.makeTransparent) {
Function(params, expand(Apply(tree, params map gen.paramToArg), restpe))
}
case _ =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index ee640ef749..9295ba261d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -130,6 +130,8 @@ self: Analyzer =>
class ImplicitSearch(tree: Tree, pt: Type, isView: Boolean, context0: Context)
extends Typer(context0) {
+ assert(tree.isEmpty || tree.pos.isDefined)
+
import infer._
/** Is implicit info `info1` better than implicit info `info2`?
@@ -293,7 +295,7 @@ self: Analyzer =>
isCompatible(depoly(info.tpe), wildPt) &&
isStable(info.pre)) {
- val itree = atPos(tree) {
+ val itree = atPos(tree.pos.focus) {
if (info.pre == NoPrefix) Ident(info.name)
else Select(gen.mkAttributedQualifier(info.pre), info.name)
}
@@ -307,8 +309,9 @@ self: Analyzer =>
val itree1 =
if (isView)
typed1(
- Apply(itree, List(Ident("<argument>").setType(approximate(pt.typeArgs.head)))),
- EXPRmode, approximate(pt.typeArgs.tail.head))
+ atPos(itree.pos) (
+ Apply(itree, List(Ident("<argument>").setType(approximate(pt.typeArgs.head))))),
+ EXPRmode, approximate(pt.typeArgs.tail.head))
else
typed1(itree, EXPRmode, wildPt)
@@ -338,6 +341,7 @@ self: Analyzer =>
// to methTypeArgs
val result = new SearchResult(itree2, subst)
if (traceImplicits) println("RESULT = "+result)
+ // println("RESULT = "+itree+"///"+itree1+"///"+itree2)//DEBUG
result
} else {
if (traceImplicits) println("incompatible???")
@@ -595,7 +599,7 @@ self: Analyzer =>
def manifestFactoryCall(constructor: String, args: Tree*): Tree =
if (args contains EmptyTree) EmptyTree
else
- typed(atPos(tree) {
+ typed(atPos(tree.pos.focus) {
Apply(
TypeApply(
Select(gen.mkAttributedRef(ManifestModule), constructor),
@@ -657,9 +661,14 @@ self: Analyzer =>
* but keep within sizeLimit entries
*/
def cacheResult(key: AnyRef): SearchResult = implicitsCache get key match {
- case Some(r) =>
+ case Some(sr: SearchResult) =>
hits += 1
- r
+ if (sr == SearchFailure) sr
+ else {
+ val result = new SearchResult(sr.tree.duplicate, sr.subst)
+ for (t <- result.tree) t.setPos(tree.pos.focus)
+ result
+ }
case None =>
misses += 1
val r = searchImplicit(implicitsOfExpectedType, false)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 0bc9d4d0f6..e5e0774ade 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -161,8 +161,10 @@ trait Namers { self: Analyzer =>
else m.owner.isClass && context.scope == m.owner.info.decls
}
+ /** Enter symbol into context's scope and return symbol itself */
def enterInScope(sym: Symbol): Symbol = enterInScope(sym, context.scope)
+ /** Enter symbol into given scope and return symbol itself */
def enterInScope(sym: Symbol, scope: Scope): Symbol = {
// allow for overloaded methods
if (!(sym.isSourceMethod && sym.owner.isClass && !sym.owner.isPackageClass)) {
@@ -386,7 +388,9 @@ trait Namers { self: Analyzer =>
setInfo(setter)(namerOf(setter).setterTypeCompleter(vd))
}
tree.symbol =
- if (!mods.hasFlag(DEFERRED)) {
+ if (mods.hasFlag(DEFERRED)) {
+ getter setPos tree.pos // unfocus getter position, because there won't be a separate value
+ } else {
var vsym =
if (!context.owner.isClass) {
assert((mods.flags & LAZY) != 0) // if not a field, it has to be a lazy val
@@ -396,12 +400,12 @@ trait Namers { self: Analyzer =>
.setFlag(mods.flags & FieldFlags | PRIVATE | LOCAL |
(if (mods.hasFlag(LAZY)) MUTABLE else 0))
}
- vsym = enterInScope(vsym).asInstanceOf[TermSymbol]
+ enterInScope(vsym)
setInfo(vsym)(namerOf(vsym).typeCompleter(tree))
if ((mods.flags & LAZY) != 0)
vsym.setLazyAccessor(getter)
vsym
- } else getter
+ }
addBeanGetterSetter(vd, getter)
}
case DefDef(mods, nme.CONSTRUCTOR, tparams, _, _, _) =>
@@ -450,7 +454,7 @@ trait Namers { self: Analyzer =>
}
def enterAliasMethod(tree: Tree, name: Name, flags: Long, mods: Modifiers): TermSymbol =
- enterNewMethod(tree, name, flags, mods, SyntheticAliasPosition(tree))
+ enterNewMethod(tree, name, flags, mods, tree.pos.focus)
private def addBeanGetterSetter(vd: ValDef, getter: Symbol) {
def isAnn(ann: Tree, demand: String) = ann match {
@@ -478,9 +482,9 @@ trait Namers { self: Analyzer =>
val getterName = if (hasBoolBP) "is" + beanName
else "get" + beanName
val getterMods = Modifiers(flags, mods.privateWithin,
- mods.annotations map (_.syntheticDuplicate))
- val beanGetterDef = atPos(vd.pos) {
- DefDef(getterMods, getterName, Nil, List(Nil), tpt.syntheticDuplicate,
+ mods.annotations map (_.duplicate))
+ val beanGetterDef = atPos(vd.pos.focus) {
+ DefDef(getterMods, getterName, Nil, List(Nil), tpt.duplicate,
if (mods hasFlag DEFERRED) EmptyTree
else Select(This(getter.owner.name), name)) }
enterSyntheticSym(beanGetterDef)
@@ -491,14 +495,13 @@ trait Namers { self: Analyzer =>
// create and enter the symbol here, add the tree in Typer.addGettterSetter.
val setterName = "set" + beanName
val setter = enterAliasMethod(vd, setterName, flags, mods)
- .setPos(SyntheticAliasPosition(vd))
+ .setPos(vd.pos.focus)
setInfo(setter)(namerOf(setter).setterTypeCompleter(vd))
}
}
}
}
-
// --- Lazy Type Assignment --------------------------------------------------
def typeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>
@@ -746,7 +749,7 @@ trait Namers { self: Analyzer =>
if (tpt.isEmpty && meth.name == nme.CONSTRUCTOR) {
tpt.tpe = context.enclClass.owner.tpe
- tpt setPos meth.pos
+ tpt setPos meth.pos.focus
}
if (onlyPresentation && methodArgumentNames != null)
@@ -872,7 +875,7 @@ trait Namers { self: Analyzer =>
for (vparam <- vparams) {
if (vparam.tpt.isEmpty) {
vparam.tpt.tpe = pfs.head
- vparam.tpt setPos vparam.pos
+ vparam.tpt setPos vparam.pos.focus
vparam.symbol setInfo pfs.head
}
pfs = pfs.tail
@@ -925,6 +928,8 @@ trait Namers { self: Analyzer =>
var posCounter = 1
+ // Martin to Lukas: this needs to be reviewed in light of range positions.
+
// for each value parameter, create the getter method if it has a default argument. previous
// denotes the parameter lists which are on the left side of the current one. these get added
// to the default getter. Example: "def foo(a: Int)(b: Int = a)" gives "foo$default$1(a: Int) = a"
@@ -944,7 +949,7 @@ trait Namers { self: Analyzer =>
var deftParams = tparams map copyUntyped[TypeDef]
val defvParamss = previous map (_.map(p => {
// in the default getter, remove the default parameter
- val p1 = atPos(p.pos) { ValDef(p.mods &~ DEFAULTPARAM, p.name, p.tpt.syntheticDuplicate, EmptyTree) }
+ val p1 = atPos(p.pos.focus) { ValDef(p.mods &~ DEFAULTPARAM, p.name, p.tpt.duplicate, EmptyTree) }
UnTyper.traverse(p1)
p1
}))
@@ -991,9 +996,9 @@ trait Namers { self: Analyzer =>
}
val defTpt = subst(copyUntyped(vparam.tpt))
- val defRhs = copyUntyped(vparam.rhs)
+ val defRhs = copyUntyped(vparam.rhs)// this should not be synthetic?
- val defaultTree = atPos(vparam.pos) {
+ val defaultTree = atPos(vparam.pos.focus) {
DefDef(
Modifiers(meth.flags & (PRIVATE | PROTECTED | FINAL)) | SYNTHETIC | DEFAULTPARAM | oflag,
name, deftParams, defvParamss, defTpt, defRhs)
@@ -1020,7 +1025,7 @@ trait Namers { self: Analyzer =>
val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol))
// compute result type from rhs
tpt.tpe = widenIfNotFinal(meth, typer.computeType(rhs, pt), pt)
- tpt setPos meth.pos
+ tpt setPos meth.pos.focus
tpt.tpe
} else typer.typedType(tpt).tpe)
}
@@ -1129,7 +1134,7 @@ trait Namers { self: Analyzer =>
sym,
newTyper(typer1.context.make(vdef, sym)).computeType(rhs, WildcardType),
WildcardType)
- tpt setOriginal vdef
+ tpt setPos vdef.pos.focus
tpt.tpe
}
} else typer1.typedType(tpt).tpe
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 830503d37a..8760cd85dc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -327,8 +327,10 @@ trait NamesDefaults { self: Analyzer =>
else TypeApply(default1, targs.map(_.duplicate)).setPos(pos)
val default2 = (default1 /: previousArgss)((tree, args) =>
Apply(tree, args.map(_.duplicate)).setPos(pos))
- if (positional) default2
- else atPos(pos) { AssignOrNamedArg(Ident(p.name), default2) }
+ atPos(pos) {
+ if (positional) default2
+ else AssignOrNamedArg(Ident(p.name), default2)
+ }
})
(givenArgs ::: defaultArgs, Nil)
} else (givenArgs, missing filter (! _.hasFlag(DEFAULTPARAM)))
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 23f90b1b8e..07914fbc27 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -67,7 +67,7 @@ trait SyntheticMethods extends ast.TreeDSL {
newSyntheticMethod(name, flags | OVERRIDE, tpeCons)
def newSyntheticMethod(name: Name, flags: Int, tpeCons: Symbol => Type) = {
- val method = clazz.newMethod(clazz.pos.toSynthetic, name) setFlag (flags | SYNTHETICMETH)
+ val method = clazz.newMethod(clazz.pos.focus, name) setFlag (flags | SYNTHETICMETH)
method setInfo tpeCons(method)
clazz.info.decls.enter(method).asInstanceOf[TermSymbol]
}
@@ -169,7 +169,7 @@ trait SyntheticMethods extends ast.TreeDSL {
// returns (Apply, Bind)
def makeTrees(acc: Symbol, cpt: Type): (Tree, Bind) = {
- val varName = context.unit.fresh.newName(clazz.pos.toSynthetic, acc.name + "$")
+ val varName = context.unit.fresh.newName(clazz.pos.focus, acc.name + "$")
val (eqMethod, binding) =
if (cpt.isVarargs) (nme.sameElements, Star(WILD()))
else (nme.EQ , WILD() )
@@ -215,7 +215,7 @@ trait SyntheticMethods extends ast.TreeDSL {
def newAccessorMethod(tree: Tree): Tree = tree match {
case DefDef(_, _, _, _, _, rhs) =>
var newAcc = tree.symbol.cloneSymbol
- newAcc.name = context.unit.fresh.newName(tree.symbol.pos.toSynthetic, tree.symbol.name + "$")
+ newAcc.name = context.unit.fresh.newName(tree.symbol.pos.focus, tree.symbol.name + "$")
newAcc setFlag SYNTHETIC resetFlag (ACCESSOR | PARAMACCESSOR | PRIVATE)
newAcc = newAcc.owner.info.decls enter newAcc
val result = typer typed { DEF(newAcc) === rhs.duplicate }
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6ef2f61deb..0b50b0b94d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -301,7 +301,7 @@ trait Typers { self: Analyzer =>
case t => t
}
"\n Note that "+tree.symbol+" is not stable because its type, "+tree.tpe+", is volatile."
- } else ""))
+ } else ""))
/** Would tree be a stable (i.e. a pure expression) if the type
* of its symbol was not volatile?
@@ -767,7 +767,7 @@ trait Typers { self: Analyzer =>
val tparams1 = cloneSymbols(tparams)
val tree1 = if (tree.isType) tree
else TypeApply(tree, tparams1 map (tparam =>
- TypeTree(tparam.tpe) setOriginal tree)) setPos tree.pos
+ TypeTree(tparam.tpe) setPos tree.pos.focus)) setPos tree.pos
context.undetparams = context.undetparams ::: tparams1
adapt(tree1 setType restpe.substSym(tparams, tparams1), mode, pt)
case mt: ImplicitMethodType if ((mode & (EXPRmode | FUNmode | LHSmode)) == EXPRmode) => // (4.1)
@@ -1018,7 +1018,7 @@ trait Typers { self: Analyzer =>
val supertpt1 = typedType(supertpt)
if (!supertpt1.tpe.isError) {
mixins = supertpt1 :: mixins
- supertpt = TypeTree(supertpt1.tpe.parents.head) setOriginal supertpt /* setPos supertpt.pos */
+ supertpt = TypeTree(supertpt1.tpe.parents.head) setPos supertpt.pos.focus
}
}
@@ -1033,26 +1033,26 @@ trait Typers { self: Analyzer =>
// A method to replace a super reference by a New in a supercall
def transformSuperCall(scall: Tree): Tree = (scall: @unchecked) match {
case Apply(fn, args) =>
- treeCopy.Apply(scall, transformSuperCall(fn), args map (_.syntheticDuplicate))
+ treeCopy.Apply(scall, transformSuperCall(fn), args map (_.duplicate))
case Select(Super(_, _), nme.CONSTRUCTOR) =>
treeCopy.Select(
scall,
- New(TypeTree(supertpe) setOriginal supertpt) setType supertpe setPos supertpt.pos,
+ atPos(supertpt.pos.focus)(New(TypeTree(supertpe)) setType supertpe),
nme.CONSTRUCTOR)
}
treeInfo.firstConstructor(templ.body) match {
case constr @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
// Convert constructor body to block in environment and typecheck it
- val cstats1: List[Tree] = cstats map (_.syntheticDuplicate)
+ val cstats1: List[Tree] = cstats map (_.duplicate)
val scall = if (cstats.isEmpty) EmptyTree else cstats.last
val cbody1 = scall match {
case Apply(_, _) =>
treeCopy.Block(cbody, cstats1.init,
- if (supertparams.isEmpty) cunit.syntheticDuplicate
+ if (supertparams.isEmpty) cunit.duplicate
else transformSuperCall(scall))
case _ =>
- treeCopy.Block(cbody, cstats1, cunit.syntheticDuplicate)
+ treeCopy.Block(cbody, cstats1, cunit.duplicate)
}
val outercontext = context.outer
@@ -1060,14 +1060,14 @@ trait Typers { self: Analyzer =>
val cscope = outercontext.makeNewScope(constr, outercontext.owner)(ParentTypesScopeKind(clazz))
val cbody2 = newTyper(cscope) // called both during completion AND typing.
.typePrimaryConstrBody(clazz,
- cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.syntheticDuplicate)))
+ cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.duplicate)))
scall match {
case Apply(_, _) =>
val sarg = treeInfo.firstArgument(scall)
if (sarg != EmptyTree && supertpe.typeSymbol != firstParent)
error(sarg.pos, firstParent+" is a trait; does not take constructor arguments")
- if (!supertparams.isEmpty) supertpt = TypeTree(cbody2.tpe) setPos supertpt.pos
+ if (!supertparams.isEmpty) supertpt = TypeTree(cbody2.tpe) setPos supertpt.pos.focus
case _ =>
if (!supertparams.isEmpty) error(supertpt.pos, "missing type arguments")
}
@@ -1238,10 +1238,10 @@ trait Typers { self: Analyzer =>
*/
def addGetterSetter(stat: Tree): List[Tree] = stat match {
case ValDef(mods, name, tpt, rhs)
- if (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL)
- && !stat.symbol.isModuleVar =>
+ if (mods.flags & (PRIVATE | LOCAL)) != (PRIVATE | LOCAL) && !stat.symbol.isModuleVar =>
+ val isDeferred = mods hasFlag DEFERRED
val value = stat.symbol
- val getter = if ((mods hasFlag DEFERRED)) value else value.getter(value.owner)
+ val getter = if (isDeferred) value else value.getter(value.owner)
assert(getter != NoSymbol, stat)
if (getter hasFlag OVERLOADED)
error(getter.pos, getter+" is defined twice")
@@ -1252,20 +1252,22 @@ trait Typers { self: Analyzer =>
if (value.hasFlag(LAZY)) List(stat)
else {
val vdef = treeCopy.ValDef(stat, mods | PRIVATE | LOCAL, nme.getterToLocal(name), tpt, rhs)
- val getterDef: DefDef = atPos(vdef) {
- val result = DefDef(getter,
- if (mods hasFlag DEFERRED) EmptyTree
- else typed(
- atPos(vdef) { gen.mkCheckInit(Select(This(value.owner), value)) },
- EXPRmode, value.tpe))
- result.tpt.asInstanceOf[TypeTree] setOriginal tpt /* setPos tpt.pos */
- checkNoEscaping.privates(getter, result.tpt)
- treeCopy.DefDef(result, result.mods, result.name,
- result.tparams, result.vparamss, result.tpt, result.rhs)
+ val getterDef: DefDef = atPos(vdef.pos.focus) {
+ if (isDeferred) {
+ val r = DefDef(getter, EmptyTree)
+ r.tpt.asInstanceOf[TypeTree].setOriginal(tpt) // keep type tree of original abstract field
+ r
+ } else {
+ val rhs = gen.mkCheckInit(Select(This(value.owner), value))
+ val r = DefDef(getter, typed(rhs, EXPRmode, value.tpe))
+ r.tpt.setPos(tpt.pos.focus)
+ r
+ }
}
+ checkNoEscaping.privates(getter, getterDef.tpt)
def setterDef(setter: Symbol): DefDef = {
setter.setAnnotations(value.annotations)
- val result = atPos(vdef)(
+ val result = atPos(vdef.pos.focus)(
DefDef(setter,
if ((mods hasFlag DEFERRED) || (setter hasFlag OVERLOADED))
EmptyTree
@@ -1705,6 +1707,7 @@ trait Typers { self: Analyzer =>
else ""))
ErrorType
}
+ if (!vparam.tpt.pos.isDefined) vparam.tpt setPos vparam.pos.focus
}
enterSym(context, vparam)
if (context.retyping) context.scope enter vparam.symbol
@@ -1748,7 +1751,7 @@ trait Typers { self: Analyzer =>
def typedStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
val inBlock = exprOwner == context.owner
def includesTargetPos(tree: Tree) =
- !tree.pos.isSynthetic && context.unit != null && (tree.pos includes context.unit.targetPos)
+ tree.pos.isRange && context.unit != null && (tree.pos includes context.unit.targetPos)
val localTarget = stats exists includesTargetPos
def typedStat(stat: Tree): Tree = {
if (context.owner.isRefinementClass && !treeInfo.isDeclaration(stat))
@@ -1982,7 +1985,7 @@ trait Typers { self: Analyzer =>
*/
def tryTupleApply: Option[Tree] = {
// if 1 formal, 1 arg (a tuple), otherwise unmodified args
- val tupleArgs = actualArgs(tree.pos, args, formals.length)
+ val tupleArgs = actualArgs(tree.pos.makeTransparent, args, formals.length)
if (tupleArgs.length != args.length) {
// expected one argument, but got 0 or >1 ==> try applying to tuple
@@ -2046,7 +2049,7 @@ trait Typers { self: Analyzer =>
true
case _ => false
}
- val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos)
+ val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos.focus)
if (allArgs.length == formals.length) {
// useful when a default doesn't match parameter type, e.g. def f[T](x:T="a"); f[Int]()
context.diagnostic = "Error occured in an application involving default arguments." :: context.diagnostic
@@ -2400,7 +2403,7 @@ trait Typers { self: Analyzer =>
// and then stripping the "self =>" and substituting
// in the supplied selfsym.
val funcparm = ValDef(NoMods, nme.self, TypeTree(selfsym.info), EmptyTree)
- val func = Function(List(funcparm), ann.syntheticDuplicate)
+ val func = Function(List(funcparm), ann.duplicate)
// The .duplicate of annot.constr
// deals with problems that
// accur if this annotation is
@@ -2732,7 +2735,7 @@ trait Typers { self: Analyzer =>
ann.tpe = arg1.tpe.withAnnotation(annotInfo)
}
val atype = ann.tpe
- Typed(arg1, TypeTree(atype) setOriginal tree) setPos tree.pos setType atype
+ Typed(arg1, TypeTree(atype) setOriginal tree setPos tree.pos.focus) setPos tree.pos setType atype
}
}
@@ -2857,7 +2860,7 @@ trait Typers { self: Analyzer =>
if (tpt1.hasSymbol && !tpt1.symbol.typeParams.isEmpty) {
context.undetparams = cloneSymbols(tpt1.symbol.typeParams)
tpt1 = TypeTree()
- .setOriginal(tpt1) /* .setPos(tpt1.pos) */
+ .setOriginal(tpt1)
.setType(appliedType(tpt1.tpe, context.undetparams map (_.tpe)))
}
/** If current tree <tree> appears in <val x(: T)? = <tree>>
@@ -2972,7 +2975,7 @@ trait Typers { self: Analyzer =>
setError(tree)
case _ =>
errorTree(tree, treeSymTypeMsg(fun)+" does not take type parameters.")
- }
+ }
/**
* @param args ...
@@ -3065,7 +3068,7 @@ trait Typers { self: Analyzer =>
if (fun2.symbol == Array_apply) {
val checked = gen.mkCheckInit(res)
// this check is needed to avoid infinite recursion in Duplicators
- // (calling typed1 more than once for the same tree
+ // (calling typed1 more than once for the same tree)
if (checked ne res) typed { atPos(tree.pos)(checked) }
else res
} else res
@@ -3102,12 +3105,14 @@ trait Typers { self: Analyzer =>
def mkAssign(vble: Tree): Tree =
Assign(
vble,
- Apply(Select(vble.syntheticDuplicate, prefix) setPos fun.pos, args) setPos tree.pos
+ Apply(
+ Select(vble.duplicate, prefix) setPos fun.pos.focus, args) setPos tree.pos.makeTransparent
) setPos tree.pos
val tree1 = qual match {
case Select(qualqual, vname) =>
gen.evalOnce(qualqual, context.owner, context.unit) { qq =>
- mkAssign(Select(qq(), vname) setPos qual.pos)
+ val qq1 = qq()
+ mkAssign(Select(qq1, vname) setPos qq1.pos)
}
case Apply(Select(table, nme.apply), indices) =>
gen.evalOnceAll(table :: indices, context.owner, context.unit) { ts =>
@@ -3228,8 +3233,8 @@ trait Typers { self: Analyzer =>
qual.tpe.widen+" does not have a constructor"
else
decode(name)+" is not a member of "+qual.tpe.widen +
- (if ((context.unit ne null) &&
- ((for(a <- qual.pos.line; b <- tree.pos.line) yield a < b).getOrElse(false)))
+ (if ((context.unit ne null) && // Martin: why is this condition needed?
+ qual.pos.isDefined && tree.pos.isDefined && qual.pos.line < tree.pos.line)
"\npossible cause: maybe a semicolon is missing before `"+decode(name)+"'?"
else ""))
}
@@ -3383,7 +3388,7 @@ trait Typers { self: Analyzer =>
imports1 = imports1.tail
}
defSym = impSym
- qual = atPos(tree.pos.focusStart)(resetPos(imports.head.qual.syntheticDuplicate))
+ qual = atPos(tree.pos.focusStart)(resetPos(imports.head.qual.duplicate))
pre = qual.tpe
} else {
if (settings.debug.value) {
@@ -3710,16 +3715,14 @@ trait Typers { self: Analyzer =>
case etpt @ ExistentialTypeTree(_, _) =>
newTyper(context.makeNewScope(tree, context.owner)).typedExistentialTypeTree(etpt, mode)
- case TypeTree() =>
- tree.pos match {
- case SyntheticAliasPosition(original) =>
- tree setType typedType(original, mode).tpe
- case _ =>
- // we should get here only when something before failed
- // and we try again (@see tryTypedApply). In that case we can assign
- // whatever type to tree; we just have to survive until a real error message is issued.
- tree setType AnyClass.tpe
- }
+ case tpt @ TypeTree() =>
+ if (tpt.original != null)
+ tree setType typedType(tpt.original, mode).tpe
+ else
+ // we should get here only when something before failed
+ // and we try again (@see tryTypedApply). In that case we can assign
+ // whatever type to tree; we just have to survive until a real error message is issued.
+ tree setType AnyClass.tpe
case _ =>
throw new Error("unexpected tree: " + tree.getClass + "\n" + tree)//debug
}
@@ -3731,7 +3734,7 @@ trait Typers { self: Analyzer =>
* @param pt ...
* @return ...
*/
- def typed(tree: Tree, mode: Int, pt: Type): Tree = {
+ def typed(tree: Tree, mode: Int, pt: Type): Tree = {
def dropExistential(tp: Type): Type = tp match {
case ExistentialType(tparams, tpe) =>
@@ -3776,9 +3779,11 @@ trait Typers { self: Analyzer =>
(context.unit.source ne null) && (tree ne null))
logError("AT: " + (tree.pos).dbgString, ex);
throw(ex)
+/*
case ex: java.lang.Error =>
Console.println("exception when typing "+tree+", pt = "+pt)
throw ex
+*/ //debug
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 74c51405e4..7944e940ef 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -23,7 +23,7 @@ trait Unapplies extends ast.TreeDSL
private def isVarargs(vd: ValDef) = treeInfo isRepeatedParamType vd.tpt
private def isByName(vd: ValDef) = treeInfo isByNameParamType vd.tpt
- private def toIdent(x: DefTree) = Ident(x.name)
+ private def toIdent(x: DefTree) = Ident(x.name) setPos x.pos.focus
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
@@ -94,12 +94,12 @@ trait Unapplies extends ast.TreeDSL
}
def copyUntyped[T <: Tree](tree: T): T =
- applyAndReturn[T](UnTyper traverse _)(tree.syntheticDuplicate)
+ applyAndReturn[T](UnTyper traverse _)(tree.duplicate)
def copyUntypedInvariant(td: TypeDef): TypeDef =
applyAndReturn[TypeDef](UnTyper traverse _)(
treeCopy.TypeDef(td, td.mods &~ (COVARIANT | CONTRAVARIANT), td.name,
- td.tparams map (_.syntheticDuplicate), td.rhs.syntheticDuplicate)
+ td.tparams, td.rhs).duplicate
)
private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = {
@@ -135,11 +135,11 @@ trait Unapplies extends ast.TreeDSL
companionModuleDef(cdef, parents ::: List(gen.scalaScalaObjectConstr))
}
- def companionModuleDef(cdef: ClassDef, parents: List[Tree]): ModuleDef = atPos(cdef) {
+ def companionModuleDef(cdef: ClassDef, parents: List[Tree]): ModuleDef = atPos(cdef.pos.focus) {
ModuleDef(
Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
cdef.name.toTermName,
- Template(parents, emptyValDef, NoMods, Nil, List(Nil), Nil, cdef.impl.pos.toSynthetic))
+ Template(parents, emptyValDef, NoMods, Nil, List(Nil), Nil, cdef.impl.pos.focus))
}
private val caseMods = Modifiers(SYNTHETIC | CASE)
@@ -149,7 +149,7 @@ trait Unapplies extends ast.TreeDSL
def caseModuleApplyMeth(cdef: ClassDef): DefDef = {
val tparams = cdef.tparams map copyUntypedInvariant
val cparamss = constrParamss(cdef)
- atPos(cdef.pos)(
+ atPos(cdef.pos.focus)(
DefDef(caseMods, nme.apply, tparams, cparamss, classType(cdef, tparams),
New(classType(cdef, tparams), cparamss map (_ map gen.paramToArg)))
)
@@ -166,7 +166,7 @@ trait Unapplies extends ast.TreeDSL
}
val cparams = List(ValDef(Modifiers(PARAM | SYNTHETIC), paramName, classType(cdef, tparams), EmptyTree))
- atPos(cdef.pos)(
+ atPos(cdef.pos.focus)(
DefDef(caseMods, method, tparams, List(cparams), TypeTree(),
caseClassUnapplyReturnValue(paramName, cdef.symbol))
)
@@ -184,12 +184,12 @@ trait Unapplies extends ast.TreeDSL
// not good enough to just duplicated the (untyped) tpt tree; the parameter types are removed here
// and re-added in ``finishWith'' in the namer.
def paramWithDefault(vd: ValDef) =
- treeCopy.ValDef(vd, vd.mods | DEFAULTPARAM, vd.name, TypeTree() setOriginal vd.tpt, toIdent(vd))
+ treeCopy.ValDef(vd, vd.mods | DEFAULTPARAM, vd.name, atPos(vd.pos.focus)(TypeTree() setOriginal vd.tpt), toIdent(vd))
val paramss = cparamss map (_ map paramWithDefault)
val classTpe = classType(cdef, tparams)
- Some(atPos(cdef.pos)(
+ Some(atPos(cdef.pos.focus)(
DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, paramss, classTpe,
New(classTpe, paramss map (_ map toIdent)))
))
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 71de35d29e..a63454fd44 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -8,49 +8,61 @@ package scala.tools.nsc
package util
object Position {
- // a static field
- private val tabInc = 8
+ val tabInc = 8
}
trait Position {
- import Position.tabInc
-
- /** An optional value containing the point of this position as an offset in a source file,
- * or None if not defined
- */
- def offset: Option[Int] = None
/** An optional value containing the source file referred to by this position, or
* None if not defined.
*/
- def source: Option[SourceFile] = None
+ def source: SourceFile = throw new UnsupportedOperationException("Position.source")
/** Is this position neither a NoPosition nor a FakePosition?
* If isDefined is true, offset and source are both defined.
*/
def isDefined: Boolean = false
- /** Is this position a synthetic position? */
- def isSynthetic: Boolean = false
+ /** Is this position a transparent position? */
+ def isTransparent: Boolean = false
+
+ /** Is this position a range position? */
+ def isRange: Boolean = false
+
+ /** Is this position a non-transparent range position? */
+ def isOpaqueRange: Boolean = false
+
+ /** if opaque range, make this position transparent */
+ def makeTransparent: Position = this
- /** if possible, make this position a synthetic one */
- def toSynthetic: Position = this
+ /** The start of the position's range, error if not a range position */
+ def start: Int = throw new UnsupportedOperationException("Position.start")
- /** The start of the position's range */
- def start: Int = point
+ /** The start of the position's range, or point if not a range position */
+ def startOrPoint: Int = point
/** The point (where the ^ is) of the position */
- def point: Int = offset.get
+ def point: Int = throw new UnsupportedOperationException("Position.point")
- /** The end of the position's range */
- def end: Int = point
+ /** The point (where the ^ is) of the position, or else `default' if undefined */
+ def pointOrElse(default: Int): Int = default
- def startOrElse(d: Int) = offset.getOrElse(d)
- def pointOrElse(d: Int) = offset.getOrElse(d)
- def endOrElse(d: Int) = offset.getOrElse(d)
+ /** The end of the position's range, error if not a range position */
+ def end: Int = throw new UnsupportedOperationException("Position.end")
+ /** The end of the position's range, or point if not a range position */
+ def endOrPoint: Int = point
+
+ @deprecated("use point instead")
+ def offset: Option[Int] = if (isDefined) Some(point) else None
+
+ /** The same position with a different start value (if a range) */
def withStart(off: Int) = this
+
+ /** The same position with a different end value (if a range) */
def withEnd(off: Int) = this
+
+ /** The same position with a different point value (if a range or offset) */
def withPoint(off: Int) = this
/** If this is a range, the union with the other range, with the point of this position.
@@ -58,11 +70,6 @@ trait Position {
*/
def union(pos: Position) = this
- /** The underlying position; for a SyntheticAliasPosition this is the underlying position
- * of the aliased tree.
- */
- def underlying = this
-
/** If this is a range position, the offset position of its start.
* Otherwise the position itself
*/
@@ -71,7 +78,7 @@ trait Position {
/** If this is a range position, the offset position of its point.
* Otherwise the position itself
*/
- def focusPoint = this
+ def focus = this
/** If this is a range position, the offset position of its end.
* Otherwise the position itself
@@ -79,72 +86,51 @@ trait Position {
def focusEnd = this
/** Does this position include the given position `pos`.
- * This holds if both positions are defined, and the range [start..end] of this position
+ * This holds this is a range position and its range [start..end]
* is the same or covers the range of the given position.
*/
- def includes(pos: Position) =
- isDefined && pos.isDefined && start <= pos.start && pos.end <= end
+ def includes(pos: Position) = false
/** Does this position properly include the given position `pos` ("properly" meaning their
* ranges are not the same)?
*/
def properlyIncludes(pos: Position) =
- includes(pos) && (start < pos.start || pos.end < end)
+ includes(pos) && (start < pos.startOrPoint || pos.endOrPoint < end)
/** Does this position precede that position?
* This holds if both positions are defined and the end point of this position
* is not larger than the start point of the given position.
*/
def precedes(pos: Position) =
- isDefined && pos.isDefined && end <= pos.start
+ isDefined && pos.isDefined && endOrPoint <= pos.startOrPoint
/** Does this position properly precede the given position `pos` ("properly" meaning their ranges
* do not share a common point).
*/
def properlyPrecedes(pos: Position) =
- precedes(pos) && start < pos.end
+ isDefined && pos.isDefined && startOrPoint < pos.endOrPoint
/** Does this position overlap with that position?
- * This holds if both positions are defined and there is an interval of
+ * This holds if both positions are ranges and there is an interval of
* non-zero length that is shared by both position ranges.
*/
def overlaps(pos: Position) =
- isDefined && pos.isDefined &&
- (pos.start < end && start < pos.end) || (start < pos.end && pos.start < end)
+ isRange && pos.isRange &&
+ ((pos.start < end && start < pos.end) || (start < pos.end && pos.start < end))
/** Does this position cover the same range as that position?
+ * Holds only if both position are ranges
*/
def sameRange(pos: Position) =
- isDefined && pos.isDefined && start == pos.start && end == pos.end
-
- def line: Option[Int] =
- if (offset.isEmpty || source.isEmpty) None
- else Some(source.get.offsetToLine(offset.get) + 1)
-
- def column: Option[Int] =
- if (offset.isEmpty || source.isEmpty)
- None
- else {
- var column = 1
- // find beginning offset for line
- val line = source.get.offsetToLine(offset.get)
- var coffset = source.get.lineToOffset(line)
- var continue = true
- while (continue) {
- if (coffset == offset.getOrElse(-1)) continue = false
- else if (source.get.asInstanceOf[BatchSourceFile].content(coffset) == '\t')
- column = ((column - 1) / tabInc * tabInc) + tabInc + 1
- else column += 1
- coffset += 1
- }
- Some(column)
- }
+ isRange && pos.isRange && start == pos.start && end == pos.end
+
+ def line: Int = throw new UnsupportedOperationException("Position.line")
+
+ def column: Int = throw new UnsupportedOperationException("Position.column")
- def lineContent: String = {
- val line = this.line
- if (!line.isEmpty) source.get.lineToString(line.get - 1)
+ def lineContent: String =
+ if (isDefined) source.lineToString(line - 1)
else "NO_LINE"
- }
/** Map this position to a position in an original source
* file. If the SourceFile is a normal SourceFile, simply
@@ -153,77 +139,89 @@ trait Position {
def inUltimateSource(source : SourceFile) =
if (source == null) this else source.positionInUltimateSource(this)
- def dbgString = {
- (if (source.isEmpty) "" else "source-" + source.get.path) +
- (if (line.isEmpty) "" else "line-" + line.get) +
- (if (offset.isEmpty) ""
- else if (offset.get >= source.get.length) "out-of-bounds-" + offset.get
- else {
- val ret = "offset=" + offset.get;
- var add = "";
- /*
- while (offset.get + add.length < source.get.length &&
- add.length < 10) add = add + source.get.content(offset.get + add.length());
- */
- ret + " c[0..9]=\"" + add + "\"";
- })
- }
+ def dbgString = toString
def show: String = "["+toString+"]"
}
-case object NoPosition extends Position
+case object NoPosition extends Position {
+ override def dbgString = toString
+}
+
case class FakePos(msg: String) extends Position {
- override def toString=msg
+ override def toString = msg
}
-case class OffsetPosition(source0: SourceFile, offset0: Int) extends Position {
- override def source = Some(source0)
- override def offset = Some(offset0)
- override def withPoint(off: Int) = new OffsetPosition(source0, off)
+class OffsetPosition(override val source: SourceFile, override val point: Int) extends Position {
override def isDefined = true
- override def toSynthetic: Position = new SyntheticOffsetPosition(source0, offset0)
+ override def pointOrElse(default: Int): Int = point
+ override def withPoint(off: Int) = new OffsetPosition(source, off)
+
+ override def line: Int = source.offsetToLine(point) + 1
+
+ override def column: Int = {
+ var idx = source.lineToOffset(source.offsetToLine(point))
+ var col = 0
+ while (idx != point) {
+ col += (if (source.content(idx) == '\t') Position.tabInc - col % Position.tabInc else 1)
+ idx += 1
+ }
+ col + 1
+ }
+
+ override def union(pos: Position) =
+ if (pos.isRange) pos else this
+
override def equals(that : Any) = that match {
- case that : OffsetPosition => offset0 == that.offset0 && source0.file == that.source0.file
- case that => false
+ case that : OffsetPosition => point == that.point && source.file == that.source.file
+ case that => false
}
- override def hashCode = offset0 * 37 + source0.file.hashCode
+ override def hashCode = point * 37 + source.file.hashCode
+
+ override def dbgString =
+ "source-"+source.path+
+ ",line-"+line+
+ (if (point >= source.length) ",out-of-bounds-"+point
+ else ",offset="+point)
+
override def show = "["+point+"]"
}
-class SyntheticOffsetPosition(source0: SourceFile, offset0: Int) extends OffsetPosition(source0, offset0) {
- override def isSynthetic = true
- override def toSynthetic = this
- override def withPoint(off: Int) = new SyntheticOffsetPosition(source0, off)
- override def show = "<["+point+"]>"
-/*
+/** new for position ranges */
+class RangePosition(source: SourceFile, override val start: Int, point: Int, override val end: Int)
+extends OffsetPosition(source, point) {
+ if (start > end) assert(false, "bad position: "+show)
+ override def isRange: Boolean = true
+ override def isOpaqueRange: Boolean = true
+ override def startOrPoint: Int = start
+ override def endOrPoint: Int = end
+ override def withStart(off: Int) = new RangePosition(source, off, point, end)
+ override def withEnd(off: Int) = new RangePosition(source, start, point, off)
+ override def withPoint(off: Int) = new RangePosition(source, start, off, end)
+ override def focusStart = new OffsetPosition(source, start)
+ override def focus = {
+ if (focusCache eq NoPosition) focusCache = new OffsetPosition(source, point)
+ focusCache
+ }
+ override def focusEnd = new OffsetPosition(source, end)
+ override def makeTransparent = new TransparentPosition(source, start, point, end)
+ override def includes(pos: Position) = pos.isDefined && start <= pos.startOrPoint && pos.endOrPoint <= end
override def union(pos: Position) =
- if (pos.isDefined && !pos.isSynthetic) pos
- else this
-*/
+ if (pos.isRange) new RangePosition(source, start min pos.start, point, end max pos.end) else this
+ override def toString = "RangePosition("+source+", "+start+", "+point+", "+end+")"
+ override def show = "["+start+":"+end+"]"
+ private var focusCache: Position = NoPosition
}
-/** new for position ranges */
-class RangePosition(source0: SourceFile, override val start: Int, override val point: Int, override val end: Int)
-extends OffsetPosition(source0, point) {
- override def isDefined = true
- override def startOrElse(d: Int) = start
- override def pointOrElse(d: Int) = point
- override def withStart(off: Int) = new RangePosition(source0, off, point, end)
- override def withEnd(off: Int) = new RangePosition(source0, start, point, off)
- override def withPoint(off: Int) = new RangePosition(source0, start, off, end)
- override def endOrElse(d: Int) = end
- override def focusStart = OffsetPosition(source0, start)
- override def focusPoint = OffsetPosition(source0, point)
- override def focusEnd = OffsetPosition(source0, end)
- override def toString = "RangePosition("+source0+", "+start+", "+point+", "+end+")"
- override def show = "["+start+":"+end+"]"
- override def union(pos: Position) =
- if (pos.isDefined && !pos.isSynthetic) new RangePosition(source0, start min pos.start, point, end max pos.end)
- else this
+class TransparentPosition(source: SourceFile, start: Int, point: Int, end: Int) extends RangePosition(source, start, point, end) {
+ override def isOpaqueRange: Boolean = false
+ override def isTransparent = true
+ override def makeTransparent = this
+ override def show = "<"+start+":"+end+">"
}
+
diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala
index 3744262be6..2d8d963ca3 100644
--- a/src/compiler/scala/tools/nsc/util/SourceFile.scala
+++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala
@@ -82,16 +82,16 @@ class BatchSourceFile(val file : AbstractFile, val content: Array[Char]) extends
def underlyingLength = length
def start = 0
- override def identifier(pos: Position, compiler: Global) = pos match {
- case OffsetPosition(source, offset) if source == this && offset != -1 =>
+ override def identifier(pos: Position, compiler: Global) =
+ if (pos.isDefined && pos.source == this && pos.point != -1) {
def isOK(c: Char) = {
import compiler.syntaxAnalyzer.{ isOperatorPart, isIdentifierPart }
isIdentifierPart(c) || isOperatorPart(c)
}
- Some(new String(content drop offset takeWhile isOK))
- case _ =>
+ Some(new String(content drop pos.point takeWhile isOK))
+ } else {
super.identifier(pos, compiler)
- }
+ }
def isLineBreak(idx: Int) =
if (idx >= length) false else content(idx) match {
@@ -112,6 +112,9 @@ class BatchSourceFile(val file : AbstractFile, val content: Array[Char]) extends
private var lastLine = 0
+ /** Convert offset to line in this source file
+ * Lines are numbered from 0
+ */
def offsetToLine(offset: Int): Int = {
val lines = lineIndices
def findLine(lo: Int, hi: Int, mid: Int): Int =
diff --git a/src/library/scala/Product.scala b/src/library/scala/Product.scala
index bae88f52d7..85c562fee8 100644
--- a/src/library/scala/Product.scala
+++ b/src/library/scala/Product.scala
@@ -32,6 +32,7 @@ trait Product extends AnyRef {
*/
def productArity: Int
+ /** An iterator that returns all fields of this product */
def productIterator: Iterator[Any] = new Iterator[Any] {
private var c: Int = 0
private val cmax = productArity
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index a6200419ce..d8eb03fbaf 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -93,10 +93,6 @@ List[Int]'s type parameters do not match type T's expected parameters: class Lis
Error occured in an application involving default arguments.
test4()
^
-error: type mismatch;
- found : List[Int]
- required: List[List[scala.List[List[X forSome { type X }]]]]
-Error occured in an application involving default arguments.
names-defaults-neg.scala:80: error: type mismatch;
found : List[Int]
required: scala.List[scala.List[?]]
@@ -117,4 +113,4 @@ names-defaults-neg.scala:105: error: multiple overloaded alternatives of method
names-defaults-neg.scala:108: error: multiple overloaded alternatives of method bar define default arguments
def bar(i: Int = 129083) = i
^
-29 errors found
+28 errors found