diff options
author | Miles Sabin <miles@milessabin.com> | 2009-10-07 22:12:48 +0000 |
---|---|---|
committer | Miles Sabin <miles@milessabin.com> | 2009-10-07 22:12:48 +0000 |
commit | 611e5bd1f93bc04d7a699be376b53f3505b9414a (patch) | |
tree | 3ff4cbc843fcf09c54412655c7462576f137521c /src/compiler | |
parent | a8272bce60fae53d9164fbc7660f61bc56e6b2c0 (diff) | |
download | scala-611e5bd1f93bc04d7a699be376b53f3505b9414a.tar.gz scala-611e5bd1f93bc04d7a699be376b53f3505b9414a.tar.bz2 scala-611e5bd1f93bc04d7a699be376b53f3505b9414a.zip |
Retains Import nodes until the typers phase so ...
Retains Import nodes until the typers phase so that they are available
to interactive compiler clients and other AST users. Adds position
information to imported names and renames.
Diffstat (limited to 'src/compiler')
10 files changed, 79 insertions, 51 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index 48cc5bc61b..9e2966e976 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -614,13 +614,13 @@ class Interpreter(val settings: Settings, out: PrintWriter) private class ImportHandler(imp: Import) extends MemberHandler(imp) { /** Whether this import includes a wildcard import */ - override val importsWildcard = imp.selectors.map(_._1) contains USCOREkw + override val importsWildcard = imp.selectors.map(_.name) contains USCOREkw /** The individual names imported by this statement */ override val importedNames: Seq[Name] = for { - (_, sel) <- imp.selectors - if (sel != null && sel != USCOREkw) - name <- List(sel.toTypeName, sel.toTermName) + sel <- imp.selectors + if (sel.rename != null && sel.rename != USCOREkw) + name <- List(sel.rename.toTypeName, sel.rename.toTermName) } yield name diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index f208cc54fb..275b422d5f 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -195,9 +195,9 @@ abstract class TreePrinters { case Import(expr, selectors) => // Is this selector remapping a name (i.e, {name1 => name2}) - def isNotRemap(s: (Name, Name)) : Boolean = (s._1 == nme.WILDCARD || s._1 == s._2) - def selectorToString(s: (Name, Name)): String = - if (isNotRemap(s)) s._1.toString else s._1.toString + "=>" + s._2.toString + def isNotRemap(s: ImportSelector) : Boolean = (s.name == nme.WILDCARD || s.name == s.rename) + def selectorToString(s: ImportSelector): String = + if (isNotRemap(s)) s.name.toString else s.name.toString + "=>" + s.rename.toString print("import "); print(expr) print(".") diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 19e904700f..f91ff83e37 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -535,12 +535,23 @@ trait Trees { LabelDef(sym.name, params map Ident, rhs) setSymbol sym } + /** Import selector + * + * Representation of an imported name its optional rename and their optional positions + * + * @param name the imported name + * @param namePos its position or -1 if undefined + * @param rename the name the import is renamed to (== name if no renaming) + * @param renamePos the position of the rename or -1 if undefined + */ + case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) + /** Import clause * * @param expr * @param selectors */ - case class Import(expr: Tree, selectors: List[(Name, Name)]) + case class Import(expr: Tree, selectors: List[ImportSelector]) extends SymTree // The symbol of an Import is an import symbol @see Symbol.newImport // It's used primarily as a marker to check that the import has been typechecked. @@ -1042,7 +1053,7 @@ trait Trees { def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef - def Import(tree: Tree, expr: Tree, selectors: List[(Name, Name)]): Import + def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import def DocDef(tree: Tree, comment: String, definition: Tree): DocDef def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template def Block(tree: Tree, stats: List[Tree], expr: Tree): Block @@ -1097,7 +1108,7 @@ trait Trees { new TypeDef(mods, name, tparams, rhs).copyAttrs(tree) def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = new LabelDef(name, params, rhs).copyAttrs(tree) - def Import(tree: Tree, expr: Tree, selectors: List[(Name, Name)]) = + def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = new Import(expr, selectors).copyAttrs(tree) def DocDef(tree: Tree, comment: String, definition: Tree) = new DocDef(comment, definition).copyAttrs(tree) @@ -1213,7 +1224,7 @@ trait Trees { if (name0 == name) && (params0 == params) && (rhs0 == rhs) => t case _ => treeCopy.LabelDef(tree, name, params, rhs) } - def Import(tree: Tree, expr: Tree, selectors: List[(Name, Name)]) = tree match { + def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = tree match { case t @ Import(expr0, selectors0) if (expr0 == expr) && (selectors0 == selectors) => t case _ => treeCopy.Import(tree, expr, selectors) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 9540351a65..7730b2c48e 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1892,8 +1892,9 @@ self => } def loop(): Tree = if (in.token == USCORE) { + val uscoreOffset = in.offset in.nextToken() - Import(t, List((nme.WILDCARD, null))) + Import(t, List(ImportSelector(nme.WILDCARD, uscoreOffset, null, -1))) } else if (in.token == LBRACE) { Import(t, importSelectors()) } else { @@ -1906,7 +1907,7 @@ self => in.nextToken() loop() } else { - Import(t, List((name, name))) + Import(t, List(ImportSelector(name, nameOffset, name, nameOffset))) } } atPos(start) { loop() } @@ -1914,8 +1915,8 @@ self => /** ImportSelectors ::= `{' {ImportSelector `,'} (ImportSelector | `_') `}' */ - def importSelectors(): List[(Name, Name)] = { - val names = new ListBuffer[(Name, Name)] + def importSelectors(): List[ImportSelector] = { + val names = new ListBuffer[ImportSelector] accept(LBRACE) var isLast = importSelector(names) while (!isLast && in.token == COMMA) { @@ -1928,19 +1929,31 @@ self => /** ImportSelector ::= Id [`=>' Id | `=>' `_'] */ - def importSelector(names: ListBuffer[(Name, Name)]): Boolean = + def importSelector(names: ListBuffer[ImportSelector]): Boolean = if (in.token == USCORE) { - in.nextToken(); names += ((nme.WILDCARD, null)); true + val uscoreOffset = in.offset + in.nextToken(); names += ImportSelector(nme.WILDCARD, uscoreOffset, null, -1); true } else { + val nameOffset = in.offset val name = ident() - names += (( - name, + + val (name1, name1Offset) = if (in.token == ARROW) { in.nextToken() - if (in.token == USCORE) { in.nextToken(); nme.WILDCARD } else ident() + if (in.token == USCORE) { + val uscoreOffset = in.offset + in.nextToken(); + (nme.WILDCARD, uscoreOffset) + } else { + val renameOffset = in.offset + val rename = ident() + (rename, renameOffset) + } } else { - name - })) + (name, nameOffset) + } + + names += ImportSelector(name, nameOffset, name1, name1Offset) false } diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 1406416f5f..5f5db8015a 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -630,7 +630,7 @@ trait JavaParsers extends JavaScanners { def importCompanionObject(cdef: ClassDef): Tree = atPos(cdef.pos) { - Import(Ident(cdef.name.toTermName), List((nme.WILDCARD, null))) + Import(Ident(cdef.name.toTermName), List(ImportSelector(nme.WILDCARD, -1, null, -1))) } // Importing the companion object members cannot be done uncritically: see @@ -661,21 +661,24 @@ trait JavaParsers extends JavaScanners { accept(IMPORT) val pos = in.currentPos val buf = new ListBuffer[Name] - def collectIdents() { + def collectIdents() : Int = { if (in.token == ASTERISK) { + val starOffset = in.pos in.nextToken buf += nme.WILDCARD + starOffset } else { + val nameOffset = in.pos buf += ident() if (in.token == DOT) { in.nextToken collectIdents() - } + } else nameOffset } } if (in.token == STATIC) in.nextToken else buf += nme.ROOTPKG - collectIdents() + val lastnameOffset = collectIdents() accept(SEMI) val names = buf.toList if (names.length < 2) { @@ -686,8 +689,8 @@ trait JavaParsers extends JavaScanners { val lastname = names.last List { atPos(pos) { - if (lastname == nme.WILDCARD) Import(qual, List((lastname, null))) - else Import(qual, List((lastname, lastname))) + if (lastname == nme.WILDCARD) Import(qual, List(ImportSelector(lastname, lastnameOffset, null, -1))) + else Import(qual, List(ImportSelector(lastname, lastnameOffset, lastname, lastnameOffset))) } } } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 3ef8f38a9f..a5521c7eb9 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -265,7 +265,7 @@ abstract class Pickler extends SubComponent { case Import(expr, selectors) => putTree(expr) - for ((from,to) <- selectors) { + for (ImportSelector(from, _, to, _) <- selectors) { putEntry(from) putEntry(to) } @@ -714,7 +714,7 @@ abstract class Pickler extends SubComponent { writeRef(tree.tpe) writeRef(tree.symbol) writeRef(expr) - for ((from, to) <- selectors) { + for (ImportSelector(from, _, to, _) <- selectors) { writeRef(from) writeRef(to) } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index 9dba9f9925..2b4d7d33de 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -545,7 +545,7 @@ abstract class UnPickler { val selectors = until(end, () => { val from = readNameRef() val to = readNameRef() - (from, to) + ImportSelector(from, -1, to, -1) }) (Import(expr, selectors). setSymbol(symbol). diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index fcb4833df7..058a731670 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -63,7 +63,7 @@ trait Contexts { self: Analyzer => assert(pkg ne null) val qual = gen.mkAttributedStableRef(pkg) sc = sc.makeNewImport( - Import(qual, List((nme.WILDCARD, null))) + Import(qual, List(ImportSelector(nme.WILDCARD, -1, null, -1))) .setSymbol(NoSymbol.newImport(NoPosition).setFlag(SYNTHETIC).setInfo(ImportType(qual))) .setType(NoType)) sc.depth += 1 @@ -465,10 +465,10 @@ trait Contexts { self: Analyzer => private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = { val pre = imp.qual.tpe - def collect(sels: List[(Name, Name)]): List[ImplicitInfo] = sels match { + def collect(sels: List[ImportSelector]): List[ImplicitInfo] = sels match { case List() => List() - case List((nme.WILDCARD, _)) => collectImplicits(pre.implicitMembers, pre) - case (from, to) :: sels1 => + case List(ImportSelector(nme.WILDCARD, _, _, _)) => collectImplicits(pre.implicitMembers, pre) + case ImportSelector(from, _, to, _) :: sels1 => var impls = collect(sels1) filter (info => info.name != from) if (to != nme.WILDCARD) { val sym = imp.importedSymbol(to) @@ -550,7 +550,7 @@ trait Contexts { self: Analyzer => /** Is name imported explicitly, not via wildcard? */ def isExplicitImport(name: Name): Boolean = - tree.selectors exists (_._2 == name.toTermName) + tree.selectors exists (_.rename == name.toTermName) /** The symbol with name <code>name</code> imported from import clause * <code>tree</code>. @@ -560,15 +560,15 @@ trait Contexts { self: Analyzer => var renamed = false var selectors = tree.selectors while (selectors != Nil && result == NoSymbol) { - if (selectors.head._1 != nme.WILDCARD) - notifyImport(name, qual.tpe, selectors.head._1, selectors.head._2) + if (selectors.head.name != nme.WILDCARD) + notifyImport(name, qual.tpe, selectors.head.name, selectors.head.rename) - if (selectors.head._2 == name.toTermName) + if (selectors.head.rename == name.toTermName) result = qual.tpe.member( - if (name.isTypeName) selectors.head._1.toTypeName else selectors.head._1) - else if (selectors.head._1 == name.toTermName) + if (name.isTypeName) selectors.head.name.toTypeName else selectors.head.name) + else if (selectors.head.name == name.toTermName) renamed = true - else if (selectors.head._1 == nme.WILDCARD && !renamed) + else if (selectors.head.name == nme.WILDCARD && !renamed) result = qual.tpe.member(name) selectors = selectors.tail } @@ -578,10 +578,10 @@ trait Contexts { self: Analyzer => def allImportedSymbols: List[Symbol] = qual.tpe.members flatMap (transformImport(tree.selectors, _)) - private def transformImport(selectors: List[(Name, Name)], sym: Symbol): List[Symbol] = selectors match { + private def transformImport(selectors: List[ImportSelector], sym: Symbol): List[Symbol] = selectors match { case List() => List() - case List((nme.WILDCARD, _)) => List(sym) - case (from, to) :: _ if (from == sym.name) => + case List(ImportSelector(nme.WILDCARD, _, _, _)) => List(sym) + case ImportSelector(from, _, to, _) :: _ if (from == sym.name) => if (to == nme.WILDCARD) List() else { val sym1 = sym.cloneSymbol; sym1.name = to; List(sym1) } case _ :: rest => transformImport(rest, sym) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 9128b4ed29..f31394407e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1182,17 +1182,17 @@ trait Namers { self: Analyzer => } true } - def checkSelectors(selectors: List[(Name, Name)]): Unit = selectors match { - case (from, to) :: rest => + def checkSelectors(selectors: List[ImportSelector]): Unit = selectors match { + case ImportSelector(from, _, to, _) :: rest => if (from != nme.WILDCARD && base != ErrorType) { if (base.member(from) == NoSymbol && base.member(from.toTypeName) == NoSymbol) context.error(tree.pos, from.decode + " is not a member of " + expr); if (checkNotRedundant(tree.pos, from, to)) checkNotRedundant(tree.pos, from.toTypeName, to.toTypeName) } - if (from != nme.WILDCARD && (rest.exists (sel => sel._1 == from))) + if (from != nme.WILDCARD && (rest.exists (sel => sel.name == from))) context.error(tree.pos, from.decode + " is renamed twice"); - if ((to ne null) && to != nme.WILDCARD && (rest exists (sel => sel._2 == to))) + if ((to ne null) && to != nme.WILDCARD && (rest exists (sel => sel.rename == to))) context.error(tree.pos, to.decode + " appears twice as a target of a renaming"); checkSelectors(rest) case Nil => diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index df17dcc416..68f6009127 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1830,8 +1830,9 @@ trait Typers { self: Analyzer => if (imp0 ne null) { context = context.makeNewImport(imp0) imp0.symbol.initialize - } - EmptyTree + imp0 + } else + EmptyTree case _ => if (localTarget && !includesTargetPos(stat)) { stat |