summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-12-04 18:33:23 +0000
committerPaul Phillips <paulp@improving.org>2010-12-04 18:33:23 +0000
commitb1e969a11b2b24f5883198dc0b90d9ab5513498b (patch)
tree434257c2afc84c4d86e55cd2bf78d9e29ca66dc9 /src/compiler
parent3d97123034a9d82e6e6961d589ccd3a1afde4390 (diff)
downloadscala-b1e969a11b2b24f5883198dc0b90d9ab5513498b.tar.gz
scala-b1e969a11b2b24f5883198dc0b90d9ab5513498b.tar.bz2
scala-b1e969a11b2b24f5883198dc0b90d9ab5513498b.zip
A foot in the door with Parsers/JavaParsers and...
A foot in the door with Parsers/JavaParsers and Scanners/JavaScanners. Recently clued in as to how this situation came to be, I now know there's no reason not to start containing the damage. Also more work on names: made a general method for transforming Trees into type-named Trees and put it to work. No review.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala18
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala62
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala32
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala84
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaScanners.scala20
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Names.scala3
9 files changed, 125 insertions, 100 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index dd775d1a23..aeab9f75d7 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -821,7 +821,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
* we know how to enumerate the identifiers.
*/
val importedNames: List[Name] =
- selectorRenames filterNot (_ == USCOREkw) flatMap (x => List(x.toTypeName, x.toTermName))
+ selectorRenames filterNot (_ == USCOREkw) flatMap (_.bothNames)
override def resultExtractionCode(req: Request, code: PrintWriter) =
code println codegenln(imp.toString)
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index d93496a7c4..e606b1c6af 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -361,15 +361,19 @@ abstract class TreeGen {
else
mkCast(tree, pt)
+ /** Translate names in Select/Ident nodes to type names.
+ */
+ def convertToTypeName(tree: Tree): Option[RefTree] = tree match {
+ case Select(qual, name) => Some(Select(qual, name.toTypeName))
+ case Ident(name) => Some(Ident(name.toTypeName))
+ case _ => None
+ }
+
/** Try to convert Select(qual, name) to a SelectFromTypeTree.
*/
- def convertToSelectFromType(qual: Tree, origName: Name): Tree = {
- def selFromType(qual1: Tree) = SelectFromTypeTree(qual1 setPos qual.pos, origName)
- qual match {
- case Select(qual1, name) => selFromType(Select(qual1, name.toTypeName))
- case Ident(name) => selFromType(Ident(name.toTypeName))
- case _ => EmptyTree
- }
+ def convertToSelectFromType(qual: Tree, origName: Name) = convertToTypeName(qual) match {
+ case Some(qual1) => SelectFromTypeTree(qual1 setPos qual.pos, origName)
+ case _ => EmptyTree
}
/** Used in situations where you need to access value of an expression several times
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index cc3910fdf3..2eb6b8c5f4 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -13,6 +13,39 @@ import util.{ OffsetPosition }
import scala.reflect.generic.{ ModifierFlags => Flags }
import Tokens._
+/** Historical note: JavaParsers started life as a direct copy of Parsers
+ * but at a time when that Parsers had been replaced by a different one.
+ * Later it was dropped and the original Parsers reinstated, leaving us with
+ * massive duplication between Parsers and JavaParsers.
+ *
+ * This trait and the similar one for Scanners/JavaScanners represents
+ * the beginnings of a campaign against this latest incursion by Cutty
+ * McPastington and his army of very similar soldiers.
+ */
+trait ParsersCommon extends ScannersCommon {
+ val global : Global
+ import global._
+
+ trait ParserCommon {
+ val in: ScannerCommon
+ def freshName(prefix: String): Name
+ def freshTermName(prefix: String): TermName
+ def freshTypeName(prefix: String): TypeName
+ def deprecationWarning(off: Int, msg: String): Unit
+
+ def accept(token: Int): Int
+ def surround[T](open: Int, close: Int)(f: => T, orElse: T): T = {
+ val wasOpened = in.token == open
+ accept(open)
+ if (wasOpened) {
+ val ret = f
+ accept(close)
+ ret
+ } else orElse
+ }
+ }
+}
+
//todo verify when stableId's should be just plain qualified type ids
/** <p>Performs the following context-free rewritings:</p>
@@ -50,7 +83,7 @@ import Tokens._
* </li>
* </ol>
*/
-trait Parsers extends Scanners with MarkupParsers {
+trait Parsers extends Scanners with MarkupParsers with ParsersCommon {
self =>
val global: Global
import global._
@@ -81,8 +114,7 @@ self =>
def r2p(start: Int, mid: Int, end: Int): Position = rangePos(unit.source, start, mid, end)
def warning(offset: Int, msg: String) { unit.warning(o2p(offset), msg) }
- def deprecationWarning(offset: Int,
- msg: String) {
+ def deprecationWarning(offset: Int, msg: String) {
unit.deprecationWarning(o2p(offset), msg)
}
@@ -141,7 +173,7 @@ self =>
import nme.raw
- abstract class Parser {
+ abstract class Parser extends ParserCommon {
val in: Scanner
def freshName(prefix: String): Name
@@ -367,7 +399,6 @@ self =>
}
def warning(offset: Int, msg: String): Unit
def incompleteInputError(msg: String): Unit
- def deprecationWarning(offset: Int, msg: String): Unit
private def syntaxError(pos: Position, msg: String, skipIt: Boolean) {
syntaxError(pos pointOrElse in.offset, msg, skipIt)
}
@@ -417,16 +448,6 @@ self =>
offset
}
- def surround[T](open: Int, close: Int)(f: => T, orElse: T): T = {
- val wasOpened = in.token == open
- accept(open)
- if (wasOpened) {
- val ret = f
- accept(close)
- ret
- } else orElse
- }
-
/** semi = nl {nl} | `;'
* nl = `\n' // where allowed
*/
@@ -587,14 +608,9 @@ self =>
/** Convert (qual)ident to type identifier
*/
def convertToTypeId(tree: Tree): Tree = atPos(tree.pos) {
- tree match {
- case Ident(name) =>
- Ident(name.toTypeName)
- case Select(qual, name) =>
- Select(qual, name.toTypeName)
- case _ =>
- syntaxError(tree.pos, "identifier expected", false)
- errorTypeTree
+ convertToTypeName(tree) getOrElse {
+ syntaxError(tree.pos, "identifier expected", false)
+ errorTypeTree
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 25b65f0791..0835a1b2d0 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -12,7 +12,26 @@ import scala.annotation.switch
import scala.collection.mutable.{ListBuffer, ArrayBuffer}
import scala.xml.Utility.{ isNameStart }
-trait Scanners {
+/** See Parsers.scala / ParsersCommon for some explanation of ScannersCommon.
+ */
+trait ScannersCommon {
+ val global : Global
+ import global._
+
+ trait CommonTokenData {
+ def token: Int
+ def name: TermName
+ }
+
+ trait ScannerCommon extends CommonTokenData {
+ // things to fill in, in addition to buf, decodeUni
+ def warning(off: Int, msg: String): Unit
+ def error (off: Int, msg: String): Unit
+ def incompleteInputError(off: Int, msg: String): Unit
+ }
+}
+
+trait Scanners extends ScannersCommon {
val global : Global
import global._
@@ -22,7 +41,7 @@ trait Scanners {
/** An undefined offset */
val NoOffset: Offset = -1
- trait TokenData {
+ trait TokenData extends CommonTokenData {
/** the next token */
var token: Int = EMPTY
@@ -52,7 +71,7 @@ trait Scanners {
}
}
- abstract class Scanner extends CharArrayReader with TokenData {
+ abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon {
def flush = { charOffset = offset; nextChar(); this }
@@ -62,12 +81,6 @@ trait Scanners {
nextToken()
}
- // things to fill in, in addition to buf, decodeUni
- def warning(off: Offset, msg: String): Unit
- def error (off: Offset, msg: String): Unit
- def incompleteInputError(off: Offset, msg: String): Unit
- def deprecationWarning(off: Offset, msg: String): Unit
-
/** the last error offset
*/
var errOffset: Offset = NoOffset
@@ -1022,7 +1035,6 @@ trait Scanners {
def warning(off: Offset, msg: String) = unit.warning(unit.position(off), msg)
def error (off: Offset, msg: String) = unit.error(unit.position(off), msg)
def incompleteInputError(off: Offset, msg: String) = unit.incompleteInputError(unit.position(off), msg)
- def deprecationWarning(off: Offset, msg: String) = unit.deprecationWarning(unit.position(off), msg)
private var bracePatches: List[BracePatch] = patches
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index afb9999db8..c75ca15959 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -33,6 +33,8 @@ abstract class TreeBuilder {
def productConstr = gen.productConstr
def serializableConstr = gen.serializableConstr
+ def convertToTypeName(t: Tree) = gen.convertToTypeName(t)
+
/** Convert all occurrences of (lower-case) variables in a pattern as follows:
* x becomes x @ _
* x: T becomes x @ (_: T)
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index d6cfdd24b1..d4167998e5 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -8,12 +8,12 @@
package scala.tools.nsc
package javac
-import scala.tools.nsc.util.{OffsetPosition, BatchSourceFile}
+import scala.tools.nsc.util.OffsetPosition
import scala.collection.mutable.ListBuffer
import symtab.Flags
import JavaTokens._
-trait JavaParsers extends JavaScanners {
+trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val global : Global
import global._
import definitions._
@@ -22,22 +22,25 @@ trait JavaParsers extends JavaScanners {
class JavaUnitParser(val unit: global.CompilationUnit) extends JavaParser {
val in = new JavaUnitScanner(unit)
- def freshName(prefix : String) = unit.freshTermName(prefix)
+ def freshName(prefix: String): Name = freshTermName(prefix)
+ def freshTermName(prefix: String): TermName = unit.freshTermName(prefix)
+ def freshTypeName(prefix: String): TypeName = unit.freshTypeName(prefix)
+ def deprecationWarning(off: Int, msg: String) = unit.deprecationWarning(off, msg)
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)
}
- abstract class JavaParser {
-
+ abstract class JavaParser extends ParserCommon {
val in: JavaScanner
+
protected def posToReport: Int = in.currentPos
- protected def freshName(prefix : String): Name
+ def freshName(prefix : String): Name
protected implicit def i2p(offset : Int) : Position
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
+ private var thisPackageName: TypeName = tpnme.EMPTY
/** this is the general parse method
*/
@@ -92,9 +95,9 @@ trait JavaParsers extends JavaScanners {
}
def warning(msg: String) : Unit = warning(in.currentPos, msg)
- def errorTypeTree = TypeTree().setType(ErrorType).setPos((in.currentPos))
- def errorTermTree = Literal(Constant(null)).setPos((in.currentPos))
- def errorPatternTree = blankExpr.setPos((in.currentPos))
+ def errorTypeTree = TypeTree().setType(ErrorType) setPos in.currentPos
+ def errorTermTree = Literal(Constant(null)) setPos in.currentPos
+ def errorPatternTree = blankExpr setPos in.currentPos
// --------- tree building -----------------------------
@@ -123,17 +126,11 @@ trait JavaParsers extends JavaScanners {
if (treeInfo.firstConstructor(stats) == EmptyTree) makeConstructor(List()) :: stats
else stats)
- def makeParam(name: Name, tpt: Tree) =
- ValDef(Modifiers(Flags.JAVA | Flags.PARAM), name, tpt, EmptyTree)
+ def makeParam(name: String, tpt: Tree) =
+ ValDef(Modifiers(Flags.JAVA | Flags.PARAM), newTermName(name), tpt, EmptyTree)
def makeConstructor(formals: List[Tree]) = {
- var count = 0
- val vparams =
- for (formal <- formals)
- yield {
- count += 1
- makeParam(newTermName("x$"+count), formal)
- }
+ val vparams = formals.zipWithIndex map { case (p, i) => makeParam("x$" + (i + 1), p) }
DefDef(Modifiers(Flags.JAVA), nme.CONSTRUCTOR, List(), List(vparams), TypeTree(), blankExpr)
}
@@ -225,16 +222,15 @@ trait JavaParsers extends JavaScanners {
/** Convert (qual)ident to type identifier
*/
- def convertToTypeId(tree: Tree): Tree = tree match {
- case Ident(name) =>
- Ident(name.toTypeName).setPos(tree.pos)
- case Select(qual, name) =>
- Select(qual, name.toTypeName).setPos(tree.pos)
- case AppliedTypeTree(_, _) | ExistentialTypeTree(_, _) | SelectFromTypeTree(_, _) =>
- tree
- case _ =>
- syntaxError(tree.pos, "identifier expected", false)
- errorTypeTree
+ def convertToTypeId(tree: Tree): Tree = gen.convertToTypeName(tree) match {
+ case Some(t) => t setPos tree.pos
+ case _ => tree match {
+ case AppliedTypeTree(_, _) | ExistentialTypeTree(_, _) | SelectFromTypeTree(_, _) =>
+ tree
+ case _ =>
+ syntaxError(tree.pos, "identifier expected", false)
+ errorTypeTree
+ }
}
// -------------------- specific parsing routines ------------------
@@ -390,8 +386,7 @@ trait JavaParsers extends JavaScanners {
def modifiers(inInterface: Boolean): Modifiers = {
var flags: Long = Flags.JAVA
- // assumed true unless we see public/private/protected - see bug #1240
- // Todo: look at pos/t1176, #1240, #1840, #1842, see what current access issues are.
+ // assumed true unless we see public/private/protected
var isPackageAccess = true
var annots: List[Tree] = Nil
def addAnnot(sym: Symbol) =
@@ -433,7 +428,7 @@ trait JavaParsers extends JavaScanners {
case SYNCHRONIZED | STRICTFP =>
in.nextToken
case _ =>
- val privateWithin: Name =
+ val privateWithin: TypeName =
if (isPackageAccess && !inInterface) thisPackageName
else tpnme.EMPTY
@@ -698,12 +693,11 @@ trait JavaParsers extends JavaScanners {
} else {
val qual = ((Ident(names.head): Tree) /: names.tail.init) (Select(_, _))
val lastname = names.last
- List {
- atPos(pos) {
- if (lastname == nme.WILDCARD) Import(qual, List(ImportSelector(lastname, lastnameOffset, null, -1)))
- else Import(qual, List(ImportSelector(lastname, lastnameOffset, lastname, lastnameOffset)))
- }
+ val selector = lastname match {
+ case nme.WILDCARD => ImportSelector(lastname, lastnameOffset, null, -1)
+ case _ => ImportSelector(lastname, lastnameOffset, lastname, lastnameOffset)
}
+ List(atPos(pos)(Import(qual, List(selector))))
}
}
@@ -850,7 +844,7 @@ trait JavaParsers extends JavaScanners {
blankExpr),
DefDef(
Modifiers(Flags.JAVA | Flags.STATIC), newTermName("valueOf"), List(),
- List(List(makeParam(newTermName("x"), TypeTree(StringClass.tpe)))),
+ List(List(makeParam("x", TypeTree(StringClass.tpe)))),
enumType,
blankExpr))
accept(RBRACE)
@@ -881,11 +875,11 @@ trait JavaParsers extends JavaScanners {
}
def typeDecl(mods: Modifiers): List[Tree] = in.token match {
- case ENUM => enumDecl(mods)
+ case ENUM => enumDecl(mods)
case INTERFACE => interfaceDecl(mods)
- case AT => annotationDecl(mods)
- case CLASS => classDecl(mods)
- case _ => in.nextToken; syntaxError("illegal start of type declaration", true); List(errorTypeTree)
+ case AT => annotationDecl(mods)
+ case CLASS => classDecl(mods)
+ case _ => in.nextToken; syntaxError("illegal start of type declaration", true); List(errorTypeTree)
}
/** CompilationUnit ::= [package QualId semi] TopStatSeq
@@ -903,9 +897,9 @@ trait JavaParsers extends JavaScanners {
} else {
Ident(nme.EMPTY_PACKAGE_NAME)
}
- thisPackageName = pkg match {
- case Ident(name) => name.toTypeName
- case Select(_, name) => name.toTypeName
+ thisPackageName = gen.convertToTypeName(pkg) match {
+ case Some(t) => t.name
+ case _ => tpnme.EMPTY
}
val buf = new ListBuffer[Tree]
while (in.token == IMPORT)
diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
index fd69f15edc..76137ccdf4 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
@@ -12,9 +12,10 @@ import JavaTokens._
import scala.annotation.switch
// Todo merge these better with Scanners
-trait JavaScanners {
+trait JavaScanners extends ast.parser.ScannersCommon {
val global : Global
import global._
+
abstract class AbstractJavaTokenData {
def token: Int
type ScanPosition
@@ -56,10 +57,7 @@ trait JavaScanners {
abstract class AbstractJavaScanner extends AbstractJavaTokenData {
implicit def p2g(pos: Position): ScanPosition
implicit def g2p(pos: ScanPosition): Position
- def warning(pos: ScanPosition, msg: String): Unit
- def error (pos: ScanPosition, msg: String): Unit
- def incompleteInputError(pos: ScanPosition, msg: String): Unit
- def deprecationWarning(pos: ScanPosition, msg: String): Unit
+
/** the last error position
*/
var errpos: ScanPosition
@@ -250,7 +248,7 @@ trait JavaScanners {
*
* @author Martin Odersky
*/
- abstract class JavaScanner extends AbstractJavaScanner with JavaTokenData with Cloneable {
+ abstract class JavaScanner extends AbstractJavaScanner with JavaTokenData with Cloneable with ScannerCommon {
override def intVal = super.intVal// todo: needed?
override def floatVal = super.floatVal
override var errpos: Int = NoPos
@@ -312,12 +310,9 @@ trait JavaScanners {
def nextToken {
if (next.token == EMPTY) {
- //print("[")
- val t = fetchToken()
- //print(this)
- //print("]")
- t
- } else {
+ fetchToken()
+ }
+ else {
this copyFrom next
next.token = EMPTY
}
@@ -950,7 +945,6 @@ trait JavaScanners {
def warning(pos: Int, msg: String) = unit.warning(pos, msg)
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 = 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/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 87f88d1c5b..9cfa17996c 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -658,7 +658,7 @@ trait Definitions extends reflect.generic.StandardDefinitions {
abbrvTag(clazz) = tag
if (weight > 0) numericWeight(clazz) = weight
- val module = ScalaPackageClass.newModule(NoPosition, name.toTermName)
+ val module = ScalaPackageClass.newModule(NoPosition, name)
ScalaPackageClass.info.decls.enter(module)
val mclass = module.moduleClass
mclass.setInfo(ClassInfoType(List(AnyRefClass.tpe, AnyValCompanionClass.tpe), new Scope, mclass))
diff --git a/src/compiler/scala/tools/nsc/symtab/Names.scala b/src/compiler/scala/tools/nsc/symtab/Names.scala
index 1e4ff419ea..c794aadd62 100644
--- a/src/compiler/scala/tools/nsc/symtab/Names.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Names.scala
@@ -176,6 +176,7 @@ trait Names extends reflect.generic.Names {
def isTypeName: Boolean
def toTermName: TermName
def toTypeName: TypeName
+ def companionName: Name
def bothNames: List[Name] = List(toTermName, toTypeName)
/** Copy bytes of this name to buffer cs, starting at position `offset`.
@@ -429,6 +430,7 @@ trait Names extends reflect.generic.Names {
n = new TypeName(index, len, h);
n
}
+ def companionName: TypeName = toTypeName
def subName(from: Int, to: Int): TermName =
newTermName(chrs, start + from, to - from)
}
@@ -448,6 +450,7 @@ trait Names extends reflect.generic.Names {
n
}
def toTypeName: TypeName = this
+ def companionName: TermName = toTermName
def subName(from: Int, to: Int): TypeName =
newTypeName(chrs, start + from, to - from)
}