From 14c5910337e5c8d291ca021c1a87d771d8f69c9d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 30 Jul 2009 17:26:46 +0000 Subject: more fixes for positions --- src/compiler/scala/tools/nsc/Global.scala | 1 - src/compiler/scala/tools/nsc/Positions.scala | 28 ----------------- src/compiler/scala/tools/nsc/ast/Trees.scala | 10 ++++-- .../scala/tools/nsc/ast/parser/Parsers.scala | 8 ++--- .../tools/nsc/ast/parser/SymbolicXMLBuilder.scala | 17 ++++++---- .../scala/tools/nsc/interactive/Global.scala | 2 +- .../tools/nsc/interactive/RangePositions.scala | 3 +- .../scala/tools/nsc/symtab/Positions.scala | 36 ++++++++++++++++++++++ .../scala/tools/nsc/symtab/SymbolTable.scala | 3 +- 9 files changed, 62 insertions(+), 46 deletions(-) delete mode 100755 src/compiler/scala/tools/nsc/Positions.scala create mode 100755 src/compiler/scala/tools/nsc/symtab/Positions.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index e65469e0a4..20053d112b 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -34,7 +34,6 @@ import backend.icode.analysis._ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable with CompilationUnits - with Positions with Plugins with PhaseAssembly { diff --git a/src/compiler/scala/tools/nsc/Positions.scala b/src/compiler/scala/tools/nsc/Positions.scala deleted file mode 100755 index 88c54e6671..0000000000 --- a/src/compiler/scala/tools/nsc/Positions.scala +++ /dev/null @@ -1,28 +0,0 @@ -package scala.tools.nsc - -import ast.Trees -import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler} -import scala.collection.mutable.ListBuffer - -trait Positions { -self: scala.tools.nsc.Global => - - def rangePos(source: SourceFile, start: Int, point: Int, end: Int) = - new OffsetPosition(source, point) - - /** A position that wraps the 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. - */ - def wrappingPos(trees: List[Tree]): Position = trees.head.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/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index b3f54f453d..20aa37e28b 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 != 14427) +// assert(id != 1223) nodeCount += 1 private var rawpos: Position = NoPosition @@ -619,7 +619,8 @@ trait Trees { if (constrMods.isTrait) { if (body forall treeInfo.isInterfaceMember) List() else List( - DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(())))) + atPos(wrappingPos(superPos, lvdefs)) ( + DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(()))))) } else { // convert (implicit ... ) to ()(implicit ... ) if its the only parameter section if (vparamss1.isEmpty || @@ -630,9 +631,12 @@ trait Trees { } val superCall = (superRef /: argss) (Apply) List( - DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(())))) + atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) ( + DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(()))))) } } + // println("typed template, gvdefs = "+gvdefs+", parents = "+parents+", constrs = "+constrs) + constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs)) // remove defaults val vparamss2 = vparamss map (vps => vps map { vd => treeCopy.ValDef(vd, vd.mods &~ DEFAULTPARAM, vd.name, vd.tpt, EmptyTree) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index ef9d678bd7..7ff5aa3dca 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -426,10 +426,10 @@ self => /* ---------- TREE CONSTRUCTION ------------------------------------------- */ def atPos[T <: Tree](offset: Int)(t: T): T = - global.atPos(r2p(offset, offset, in.lastOffset))(t) + global.atPos(r2p(offset, offset, in.lastOffset max offset))(t) def atPos[T <: Tree](start: Int, point: Int)(t: T): T = - global.atPos(r2p(start, point, in.lastOffset))(t) - def atPos[T <: Tree](start: Int, point: Int, end: Int)(t: T): T = + global.atPos(r2p(start, point, in.lastOffset max start))(t) + def atPos[T <: Tree](start: Int, point: Int, end: Int)(t: T): T = // !!! put an { brace here and observe global.atPos(r2p(start, point, end))(t) def atPos[T <: Tree](pos: Position)(t: T): T = global.atPos(pos)(t) @@ -2342,7 +2342,7 @@ self => /** Create a tree representing a packaging */ def makePackaging(start: Int, pkg: Tree, stats: List[Tree]): PackageDef = - atPos(start, pkg.pos.point, in.lastOffset max start) { PackageDef(pkg.asInstanceOf[RefTree], stats) } + atPos(start, pkg.pos.point) { PackageDef(pkg.asInstanceOf[RefTree], stats) } /* pkg match { case id @ Ident(_) => diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index 26735aec65..3f77ca5ae6 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -14,6 +14,11 @@ import util.Position import symtab.Flags.MUTABLE /** This class builds instance of Tree that represent XML. + * + * Note from martin: This needs to have its position info reworked. I don't understand exactly + * what's done here. To make validation pass, I set many positions to be transparent. Not sure this + * is a good idea for navigating XML trees in the IDE< but it's the best I can do right now. If someone + * who understands this part better wants to give it a shot, please do! * * @author Burak Emir * @version 1.0 @@ -202,7 +207,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) case (None, x) => (null, x) } - def mkAttributeTree(pre: String, key: String, value: Tree) = atPos(pos) { + def mkAttributeTree(pre: String, key: String, value: Tree) = atPos(pos.makeTransparent) { // XXX this is where we'd like to put Select(value, nme.toString_) for #1787 // after we resolve the Some(foo) situation. val baseArgs = List(const(key), value, Ident(_md)) @@ -222,9 +227,9 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) case _ => handleUnprefixedAttribute(k, v) } - lazy val scopeDef = atPos(pos)(ValDef(NoMods, _scope, _scala_xml_NamespaceBinding, Ident(_tmpscope))) - lazy val tmpScopeDef = atPos(pos)(ValDef(Modifiers(MUTABLE), _tmpscope, _scala_xml_NamespaceBinding, Ident(_scope))) - lazy val metadataDef = atPos(pos)(ValDef(Modifiers(MUTABLE), _md, _scala_xml_MetaData, _scala_xml_Null)) + lazy val scopeDef = ValDef(NoMods, _scope, _scala_xml_NamespaceBinding, Ident(_tmpscope)) + lazy val tmpScopeDef = ValDef(Modifiers(MUTABLE), _tmpscope, _scala_xml_NamespaceBinding, Ident(_scope)) + lazy val metadataDef = ValDef(Modifiers(MUTABLE), _md, _scala_xml_MetaData, _scala_xml_Null) val makeSymbolicAttrs = if (!attributes.isEmpty) Ident(_md) else _scala_xml_Null val (attrResult, nsResult) = @@ -236,7 +241,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) } val body = mkXML( - pos, + pos.makeTransparent, false, const(pre), const(newlabel), @@ -245,6 +250,6 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) args ) - atPos(pos)( Block(nsResult, Block(attrResult, body)) ) + atPos(pos.makeTransparent)( Block(nsResult, Block(attrResult, body)) ) } } diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 1b77d612cb..a4ba711d95 100755 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -235,7 +235,7 @@ self => /** Parse unit and create a name index. */ def parse(unit: RichCompilationUnit): Unit = { currentTyperRun.compileLate(unit) - validatePositions(unit.body) + if (!reporter.hasErrors) validatePositions(unit.body) //println("parsed: [["+unit.body+"]]") unit.status = JustParsed } diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala index 4f0d8edfa5..294909c83b 100755 --- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala +++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala @@ -2,6 +2,7 @@ package scala.tools.nsc package interactive import ast.Trees +import symtab.Positions import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler} import scala.collection.mutable.ListBuffer @@ -37,7 +38,7 @@ self: scala.tools.nsc.Global => * 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 = { + override 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) diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala new file mode 100755 index 0000000000..e096d3b5e3 --- /dev/null +++ b/src/compiler/scala/tools/nsc/symtab/Positions.scala @@ -0,0 +1,36 @@ +package scala.tools.nsc +package symtab + +import ast.Trees +import scala.tools.nsc.util.{SourceFile, Position, RangePosition, OffsetPosition, NoPosition, WorkScheduler} +import scala.collection.mutable.ListBuffer + +trait Positions { +self: scala.tools.nsc.symtab.SymbolTable => + + def rangePos(source: SourceFile, start: Int, point: Int, end: Int) = + new OffsetPosition(source, point) + + /** 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 = default + + /** A position that wraps the 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. + */ + def wrappingPos(trees: List[Tree]): Position = trees.head.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/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala index 9e42db2fce..e8baaec732 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala @@ -22,6 +22,7 @@ abstract class SymbolTable extends Names with AnnotationInfos with AnnotationCheckers with Trees + with Positions { def settings: Settings def rootLoader: LazyType @@ -120,6 +121,4 @@ abstract class SymbolTable extends Names /** The phase which has given index as identifier */ val phaseWithId: Array[Phase] - - def ensureNonOverlapping(tree: Tree, others: List[Tree]) } -- cgit v1.2.3