summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiles Sabin <miles@milessabin.com>2009-10-07 22:12:48 +0000
committerMiles Sabin <miles@milessabin.com>2009-10-07 22:12:48 +0000
commit611e5bd1f93bc04d7a699be376b53f3505b9414a (patch)
tree3ff4cbc843fcf09c54412655c7462576f137521c /src
parenta8272bce60fae53d9164fbc7660f61bc56e6b2c0 (diff)
downloadscala-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')
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala8
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala6
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala19
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala35
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala15
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala28
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
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