diff options
author | Sean McDirmid <sean.mcdirmid@gmail.com> | 2007-04-19 05:16:02 +0000 |
---|---|---|
committer | Sean McDirmid <sean.mcdirmid@gmail.com> | 2007-04-19 05:16:02 +0000 |
commit | 2ef5d4c6d81e5008fdb2ae1b4f2ecdd9d9901fd2 (patch) | |
tree | 1d1b222bd6a0caa29c0a02e465842bdf30cfae52 /src | |
parent | e43c7bef06d64b98f00752bd06510768ba37910a (diff) | |
download | scala-2ef5d4c6d81e5008fdb2ae1b4f2ecdd9d9901fd2.tar.gz scala-2ef5d4c6d81e5008fdb2ae1b4f2ecdd9d9901fd2.tar.bz2 scala-2ef5d4c6d81e5008fdb2ae1b4f2ecdd9d9901fd2.zip |
Switching over to position objects from positio...
Switching over to position objects from position type parameters.
Positions are no longer ints.
Diffstat (limited to 'src')
74 files changed, 1201 insertions, 998 deletions
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala index 39d4f5e167..b06d916eec 100644 --- a/src/compiler/scala/tools/ant/Scalac.scala +++ b/src/compiler/scala/tools/ant/Scalac.scala @@ -634,17 +634,17 @@ class Scalac extends MatchingTask { "(no error message provided); see the error output for details.") } reporter.printSummary() - if (reporter.errors > 0) + if (reporter.hasErrors) error( "Compile failed with " + - reporter.errors + " error" + - (if (reporter.errors > 1) "s" else "") + + reporter.ERROR.count + " error" + + (if (reporter.ERROR.count > 1) "s" else "") + "; see the compiler error output for details.") - else if (reporter.warnings > 0) + else if (reporter.WARNING.count > 0) log( "Compile suceeded with " + - reporter.warnings + " warning" + - (if (reporter.warnings > 1) "s" else "") + + reporter.WARNING.count + " warning" + + (if (reporter.WARNING.count > 1) "s" else "") + "; see the compiler output for details.") } diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala index 67d36d1180..17b2852f52 100644 --- a/src/compiler/scala/tools/ant/Scaladoc.scala +++ b/src/compiler/scala/tools/ant/Scaladoc.scala @@ -486,7 +486,6 @@ class Scaladoc extends MatchingTask { .replaceAll("&", "&").replaceAll(""", "\"") settings.deprecation.value = deprecation settings.unchecked.value = unchecked - log("Scaladoc params = '" + addParams + "'", Project.MSG_DEBUG) var args = if (addParams.trim() == "") Nil @@ -520,17 +519,17 @@ class Scaladoc extends MatchingTask { def documentTitle = settings.documenttitle.value } generator.process(run.units) - if (reporter.errors > 0) + if (reporter.ERROR.count > 0) error( "Document failed with " + - reporter.errors + " error" + - (if (reporter.errors > 1) "s" else "") + + reporter.ERROR.count + " error" + + (if (reporter.ERROR.count > 1) "s" else "") + "; see the documenter error output for details.") - else if (reporter.warnings > 0) + else if (reporter.WARNING.count > 0) log( "Document succeeded with " + - reporter.warnings + " warning" + - (if (reporter.warnings > 1) "s" else "") + + reporter.WARNING.count + " warning" + + (if (reporter.WARNING.count > 1) "s" else "") + "; see the documenter output for details.") reporter.printSummary() } catch { diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 2250ac379c..6ee28f477b 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -6,7 +6,7 @@ package scala.tools.nsc -import scala.tools.nsc.util.{FreshNameCreator,Position,SourceFile} +import scala.tools.nsc.util.{FreshNameCreator,OffsetPosition,Position,SourceFile} import scala.tools.nsc.io.AbstractFile import scala.collection.mutable.HashSet @@ -28,39 +28,39 @@ trait CompilationUnits requires Global { */ val depends = new HashSet[Symbol] - def position(pos: int) = new Position(source, pos) + def position(pos: Int) = new OffsetPosition(source, pos) /** The icode representation of classes in this compilation unit. * It is empty up to phase 'icode'. */ val icode: HashSet[icodes.IClass] = new HashSet - val errorPositions = new HashSet[int] + val errorPositions = new HashSet[Position] - def error(pos: int, msg: String) = + def error(pos: Position, msg: String) = if (!(errorPositions contains pos)) { errorPositions += pos - reporter.error(position(pos), msg) + reporter.error((pos), msg) } - def warning(pos: int, msg: String) = + def warning(pos: Position, msg: String) = if (!(errorPositions contains pos)) { errorPositions += pos - reporter.warning(position(pos), msg) + reporter.warning((pos), msg) } - def deprecationWarning(pos: int, msg: String) = + def deprecationWarning(pos: Position, msg: String) = if (settings.deprecation.value) warning(pos, msg) else currentRun.deprecationWarnings = true - def uncheckedWarning(pos: int, msg: String) = + def uncheckedWarning(pos: Position, msg: String) = if (settings.unchecked.value) warning(pos, msg) else currentRun.uncheckedWarnings = true - def incompleteInputError(pos:int, msg:String) = + def incompleteInputError(pos: Position, msg:String) = if (!(errorPositions contains pos)) { errorPositions += pos - reporter.incompleteInputError(position(pos), msg) + reporter.incompleteInputError((pos), msg) } override def toString() = source.toString() diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 811f9ae6e0..4df833f002 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -12,7 +12,7 @@ import java.nio.charset._ import compat.Platform.currentTime import scala.tools.nsc.io.{SourceReader, AbstractFile} import scala.tools.nsc.reporters._ -import scala.tools.nsc.util.{ClassPath, Position, SourceFile} +import scala.tools.nsc.util.{ClassPath, SourceFile} import scala.collection.mutable.{HashSet, HashMap, ListBuffer} @@ -648,26 +648,4 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable def onlyPresentation = settings.doc.value // used to disable caching in lampion IDE. def inIDE = false - - // position stuff - final val positionConfiguration: PositionConfiguration = initConfig; - protected def initConfig : PositionConfiguration = posConfig; - - private object posConfig extends PositionConfiguration { - type PositionType = Int - def coercePosToInt(pos: Int): Int = pos - def coerceIntToPos(pos: Int): Int = pos - val NoPos: Int = Position.NOPOS - val FirstPos: Int = Position.FIRSTPOS - } - final type PositionType = positionConfiguration.PositionType - final val FirstPos = { - val posConfig : PositionConfiguration = positionConfiguration; - posConfig.FirstPos.asInstanceOf[PositionType]; - } - final def NoPos = positionConfiguration.NoPos - final def coerceIntToPos(pos: Int): PositionType = - positionConfiguration.coerceIntToPos(pos) - implicit final def coercePosToInt(pos: PositionType): Int = - positionConfiguration.coercePosToInt(pos) } diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index a69ed3b394..4b385cf604 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -13,7 +13,7 @@ import java.net.{URL, URLClassLoader} import scala.collection.mutable import scala.collection.mutable.{ListBuffer, HashSet, ArrayBuffer} -import ast.parser.SyntaxAnalyzer +//import ast.parser.SyntaxAnalyzer import io.PlainFile import reporters.{ConsoleReporter, Reporter} import symtab.Flags @@ -333,7 +333,9 @@ class Interpreter(val settings: Settings, reporter: Reporter, out: PrintWriter) val unit = new CompilationUnit( new SourceFile("<console>", code.toCharArray())) - new compiler.syntaxAnalyzer.Parser(unit).templateStatSeq._2 + val scanner = new compiler.syntaxAnalyzer.UnitParser(unit); + val xxx = scanner.templateStatSeq; + xxx._2 } // parse the main code along with the imports diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala index 089a0f7d23..d522ee07ff 100644 --- a/src/compiler/scala/tools/nsc/Main.scala +++ b/src/compiler/scala/tools/nsc/Main.scala @@ -28,7 +28,7 @@ object Main extends AnyRef with EvalLoop { msg + "\n scalac -help gives more information") /* needed ?? */ - def errors() = reporter.errors + //def errors() = reporter.errors def resident(compiler: Global): unit = loop { line => diff --git a/src/compiler/scala/tools/nsc/MainTokenMetric.scala b/src/compiler/scala/tools/nsc/MainTokenMetric.scala index e1a0e6f906..05b0f3c33c 100644 --- a/src/compiler/scala/tools/nsc/MainTokenMetric.scala +++ b/src/compiler/scala/tools/nsc/MainTokenMetric.scala @@ -18,15 +18,15 @@ object MainTokenMetric { def tokenMetric(compiler: Global, fnames: List[String]): unit = { import compiler.CompilationUnit - import compiler.syntaxAnalyzer.Scanner + import compiler.syntaxAnalyzer.UnitScanner import ast.parser.Tokens.EOF var totale = 0 for (val source <- fnames) { - val s = new Scanner(new CompilationUnit(compiler.getSourceFile(source))) + val s = new UnitScanner(new CompilationUnit(compiler.getSourceFile(source))) var i = 0 while(s.token != EOF) { i = i + 1 - s.nextToken() + s.nextToken } var j = 0 ; while(j + log(i) / log(10) < 7) { j = j+1 diff --git a/src/compiler/scala/tools/nsc/PositionConfiguration.scala b/src/compiler/scala/tools/nsc/PositionConfiguration.scala deleted file mode 100644 index 26176ce31a..0000000000 --- a/src/compiler/scala/tools/nsc/PositionConfiguration.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tools.nsc; - -abstract class PositionConfiguration { - type PositionType; - def coercePosToInt(pos : PositionType) : Int; - def coerceIntToPos(pos : Int) : PositionType; - val NoPos : PositionType; - val FirstPos : PositionType; -} diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index cd13db5e5a..d792b084fe 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -10,7 +10,7 @@ import java.io.{PrintWriter, StringWriter} import scala.tools.nsc.symtab.Flags import scala.tools.nsc.symtab.Flags._ -import scala.tools.nsc.util.{HashSet, Position, SourceFile} +import scala.tools.nsc.util.{HashSet, Position, NoPosition, SourceFile} trait Trees { @@ -71,13 +71,13 @@ trait Trees { if (Statistics.enabled) nodeCount += 1 } - private var rawpos: PositionType = NoPos + private var rawpos: Position = NoPosition def pos = rawpos var tpe: Type = _ //var kindStar = false //@M: kindStar implies !tpe.isHigherKinded --> if true, setType does not accept higher-kinded types - def setPos(pos: PositionType): this.type = { rawpos = pos; this } + def setPos(pos: Position): this.type = { rawpos = pos; this } def setType(tp: Type): this.type = { /*assert(kindingIrrelevant(tp) || !kindStar || !tp.isHigherKinded, ""+tp+" should not be higher-kinded");*/ tpe = tp; this } def symbol: Symbol = null @@ -353,7 +353,7 @@ trait Trees { */ case class AbsTypeDef(mods: Modifiers, name: Name, tparams: List[AbsTypeDef], lo: Tree, hi: Tree) extends DefTree { - def namePos = pos - name.length + def namePos = pos.offset.map(n => n - name.length).get(-1) } def AbsTypeDef(sym: Symbol): AbsTypeDef = @@ -1462,13 +1462,13 @@ trait Trees { } object posAssigner extends Traverser { - private var pos: PositionType = _ + private var pos: Position = _ override def traverse(t: Tree): unit = - if (t != EmptyTree && t.pos == NoPos) { + if (t != EmptyTree && t.pos == NoPosition) { t.setPos(pos) super.traverse(t) } - def atPos[T <: Tree](pos: PositionType)(tree: T): T = { + def atPos[T <: Tree](pos: Position)(tree: T): T = { this.pos = pos traverse(tree) tree @@ -1477,7 +1477,7 @@ trait Trees { object resetPos extends Traverser { override def traverse(t: Tree): unit = { - if (t != EmptyTree) t.setPos(NoPos) + if (t != EmptyTree) t.setPos(NoPosition) super.traverse(t) } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index 793d2b56c4..90d003c813 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -22,20 +22,23 @@ trait MarkupParsers requires SyntaxAnalyzer { import global._ //import posAssigner.atPos -class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean) /*with scala.xml.parsing.MarkupParser[Tree,Tree] */{ +class MarkupParser(p: UnitParser, presWS: boolean) /*with scala.xml.parsing.MarkupParser[Tree,Tree] */{ import Tokens.{EMPTY, LBRACE, RBRACE} final val preserveWS = presWS; import p.{symbXMLBuilder => handle} - import s.token + def s = p.in + import p.in.g2p + import p.in.p2g + import p.in.token /** holds the position in the source file */ - /*[Duplicate]*/ var pos: Int = _ + /*[Duplicate]*/ var pos: Position = _ /** holds temporary values of pos */ - /*[Duplicate]*/ var tmppos: Int = _ + /*[Duplicate]*/ var tmppos: Position = _ /** holds the next character */ /*[Duplicate]*/ var ch: Char = _ @@ -58,7 +61,7 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean else reportSyntaxError("'" + that + "' expected instead of '" + ch + "'") - var debugLastStartElement = new mutable.Stack[(Int, String)] + var debugLastStartElement = new mutable.Stack[(Position, String)] /** checks whether next character starts a Scala block, if yes, skip it. * @return true if next character starts a scala block @@ -266,7 +269,7 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean * @param ts ... * @param txt ... */ - /*[Duplicate]*/ def appendText(pos: int, ts: mutable.Buffer[Tree], + /*[Duplicate]*/ def appendText(pos: Position, ts: mutable.Buffer[Tree], txt: String): Unit = if (!preserveWS) { for (val t <- TextBuffer.fromString(txt).toText) { @@ -298,7 +301,7 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean * @precond ch == '{' * @postcond: xEmbeddedBlock == false! */ - def content_BRACE(p: Int, ts:mutable.ArrayBuffer[Tree]): Unit = { + def content_BRACE(p: Position, ts:mutable.ArrayBuffer[Tree]): Unit = { if (xCheckEmbeddedBlock) ts.append(xEmbeddedExpr) else { @@ -520,7 +523,7 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean lastch = s.in.ch xSpaceOpt } - tree = handle.makeXMLseq( pos, ts ) + tree = handle.makeXMLseq((pos), ts ) } else { assert(ts.length == 1) tree = ts(0) @@ -532,13 +535,13 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean //} //Console.println("out of xLiteral, parsed:"+tree.toString()); s.next.token = Tokens.EMPTY; - s.nextToken() + s.nextToken popScannerState tree } catch { case _:ArrayIndexOutOfBoundsException => - s.syntaxError(debugLastStartElement.top._1, + s.syntaxError((debugLastStartElement.top._1), "missing end tag in XML literal for <" +debugLastStartElement.top._2+">"); EmptyTree; @@ -555,12 +558,12 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean var tree = xPattern; xSpaceOpt; handle.isPattern = oldMode; s.next.token = Tokens.EMPTY; - s.nextToken() + s.nextToken popScannerState tree } catch { case _:ArrayIndexOutOfBoundsException => - s.syntaxError(debugLastStartElement.top._1, + s.syntaxError((debugLastStartElement.top._1), "missing end tag in XML literal for <" +debugLastStartElement.top._2+">"); EmptyTree; diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index ccb932bf0c..d41a5fa515 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.ast.parser -import scala.tools.nsc.util.{ListBuffer, Position} +import scala.tools.nsc.util.{ListBuffer, Position, OffsetPosition} import symtab.Flags import Tokens._ @@ -52,26 +52,52 @@ import Tokens._ trait Parsers requires SyntaxAnalyzer { import global._ - import RequiresIntsAsPositions._ + //import RequiresIntsAsPositions._ private val glob: global.type = global import global.posAssigner.atPos - class Parser(unit: global.CompilationUnit) { + class UnitParser(unit : global.CompilationUnit) extends Parser { + val in = new UnitScanner(unit) + in.init + import in.ScanPosition + def freshName(prefix : String) = unit.fresh.newName(prefix) + import in.{p2g, g2p} + def posToReport = + if (!in.currentPos.line.isEmpty && !in.lastPos.line.isEmpty && + in.currentPos.line.get > in.lastPos.line.get) in.lastPos; + else in.currentPos + } - val in = new Scanner(unit) + abstract class Parser { + protected val in : AbstractScanner + import in.ScanPosition + protected def freshName(prefix : String) : Name + protected def posToReport : ScanPosition + import in.{p2g, g2p} /** the markup parser */ - val xmlp = new MarkupParser(unit, in, Parser.this, true) + def xmlp = { + if (xmlp0 == null) + xmlp0 = this match { + case in : UnitParser => new MarkupParser(in, true) + case _ => + Console.println("Cannot create XML PARSER " + in) + null + } + xmlp0; + } + private var xmlp0 : MarkupParser = null; + object treeBuilder extends TreeBuilder { val global: Parsers.this.global.type = Parsers.this.global - def freshName(prefix: String): Name = unit.fresh.newName(prefix) + def freshName(prefix: String): Name = Parser.this.freshName(prefix) } import treeBuilder._ object symbXMLBuilder extends SymbolicXMLBuilder(treeBuilder, Parser.this, true) { // DEBUG choices val global: Parsers.this.global.type = Parsers.this.global - def freshName(prefix: String): Name = unit.fresh.newName(prefix) + def freshName(prefix: String): Name = Parser.this.freshName(prefix) } /** The implicit view parameters of the surrounding class */ @@ -92,8 +118,8 @@ trait Parsers requires SyntaxAnalyzer { /////// ERROR HANDLING ////////////////////////////////////////////////////// - private def skip() { - //System.out.println("<skipping> " + in.token2string(in.token))//DEBUG + private def skip(): Unit = { + //System.out.println("<skipping> " + in.configuration.token2string(in.token))//DEBUG var nparens = 0 var nbraces = 0 while (true) { @@ -117,16 +143,16 @@ trait Parsers requires SyntaxAnalyzer { nbraces += 1 case _ => } - in.nextToken() + in.nextToken } } def syntaxError(msg: String, skipIt: boolean): unit = syntaxError(in.currentPos, msg, skipIt) - def syntaxError(pos: int, msg: String, skipIt: boolean) { + def syntaxError(pos: ScanPosition, msg: String, skipIt: boolean): Unit = { if (pos != in.errpos) { - unit.error(pos, msg) + in.error(pos, msg) in.errpos = pos } if (skipIt) { @@ -141,89 +167,100 @@ trait Parsers requires SyntaxAnalyzer { def warning(msg: String) = if (in.currentPos != in.errpos) { - unit.warning(in.currentPos, msg) + in.warning(in.currentPos, msg) in.errpos = in.currentPos } - def incompleteInputError(pos: int, msg: String) { + def incompleteInputError(pos: ScanPosition, msg: String): Unit = { if (pos != in.errpos) { - unit.incompleteInputError(pos, msg) + in.incompleteInputError(pos, msg) in.errpos = pos } } - def incompleteInputError(msg: String): unit = + def incompleteInputError(msg: String): Unit = incompleteInputError(in.currentPos, msg) // in.currentPos should be at the EOF - def syntaxErrorOrIncomplete(msg: String, skipIt: Boolean) { - if (in.token == EOF) + def syntaxErrorOrIncomplete(msg: String, skipIt: Boolean): Unit = { + if(in.token == EOF) incompleteInputError(msg) else syntaxError(in.currentPos, msg, skipIt) } + def mismatch(expected : Int, found : Int) = { + val posToReport = this.posToReport + val msg = + in.configuration.token2string(expected) + " expected but " + + in.configuration.token2string(found) + " found." + + if(found == EOF) + incompleteInputError(posToReport, msg) + else + syntaxError(posToReport, msg, true) + } + /** Consume one token of the specified type, or * signal an error if it is not there. */ - def accept(token: int): int = { + def accept(token: Int): ScanPosition = { val pos = in.currentPos if (in.token != token) { val posToReport = - if (Position.line(unit.source, in.currentPos) > - Position.line(unit.source, in.lastPos)) + if (in.currentPos.line.get(0) > in.lastPos.line.get(0)) in.lastPos else in.currentPos val msg = - in.token2string(token) + " expected but " + - in.token2string(in.token) + " found." + in.configuration.token2string(token) + " expected but " + + in.configuration.token2string(in.token) + " found." if (in.token == EOF) incompleteInputError(posToReport, msg) else syntaxError(posToReport, msg, true) } - if (in.token == token) in.nextToken() + if (in.token == token) in.nextToken pos } /** semi = nl {nl} | `;' * nl = `\n' // where allowed */ - def acceptStatSep(): unit = - if (in.token == NEWLINE || in.token == NEWLINES) in.nextToken() + def acceptStatSep(): Unit = + if (in.token == NEWLINE || in.token == NEWLINES) in.nextToken else accept(SEMI) - def errorTypeTree = TypeTree().setType(ErrorType).setPos(in.currentPos) - def errorTermTree = Literal(Constant(null)).setPos(in.currentPos) - def errorPatternTree = Ident(nme.WILDCARD).setPos(in.currentPos) + def errorTypeTree = TypeTree().setType(ErrorType).setPos((in.currentPos)) + def errorTermTree = Literal(Constant(null)).setPos((in.currentPos)) + def errorPatternTree = Ident(nme.WILDCARD).setPos((in.currentPos)) /////// TOKEN CLASSES ////////////////////////////////////////////////////// - def isModifier: boolean = in.token match { + def isModifier: Boolean = in.token match { case ABSTRACT | FINAL | SEALED | PRIVATE | PROTECTED | OVERRIDE | IMPLICIT => true case _ => false } - def isLocalModifier: boolean = in.token match { + def isLocalModifier: Boolean = in.token match { case ABSTRACT | FINAL | SEALED | IMPLICIT => true case _ => false } - def isDefIntro: boolean = in.token match { + def isDefIntro: Boolean = in.token match { case VAL | VAR | DEF | TYPE | OBJECT | CASEOBJECT | CLASS | CASECLASS | TRAIT => true case _ => false } - def isDclIntro: boolean = in.token match { + def isDclIntro: Boolean = in.token match { case VAL | VAR | DEF | TYPE => true case _ => false } def isIdent = in.token == IDENTIFIER || in.token == BACKQUOTED_IDENT - def isExprIntroToken(token: int): boolean = token match { + def isExprIntroToken(token: int): Boolean = token match { case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL | IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER | IF | FOR | NEW | USCORE | TRY | WHILE | @@ -231,19 +268,19 @@ trait Parsers requires SyntaxAnalyzer { case _ => false } - def isExprIntro: boolean = isExprIntroToken(in.token) + def isExprIntro: Boolean = isExprIntroToken(in.token) - def isTypeIntroToken(token: int): boolean = token match { + def isTypeIntroToken(token: Int): Boolean = token match { case IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER | USCORE | LPAREN | AT => true case _ => false } - def isTypeIntro: boolean = isTypeIntroToken(in.token) + def isTypeIntro: Boolean = isTypeIntroToken(in.token) - def isStatSep(token: int): boolean = + def isStatSep(token: Int): Boolean = token == NEWLINE || token == NEWLINES || token == SEMI - def isStatSep: boolean = isStatSep(in.token) + def isStatSep: Boolean = isStatSep(in.token) /////// COMMENT AND ATTRIBUTE COLLECTION ////////////////////////////////////// @@ -251,10 +288,9 @@ trait Parsers requires SyntaxAnalyzer { /** Join the comment associated with a definition */ def joinComment(trees: => List[Tree]): List[Tree] = { - val buf = in.docBuffer + val buf = in.flushDoc if (buf ne null) { - in.docBuffer = null - trees map (t => DocDef(buf.toString(), t) setPos t.pos) + trees map (t => DocDef(buf, t) setPos t.pos) } else trees } @@ -298,7 +334,7 @@ trait Parsers requires SyntaxAnalyzer { /** make closure from tree staring with a `.' */ def makeDotClosure(tree: Tree): Tree = { - val pname = unit.fresh.newName("x$") + val pname = freshName("x$") def insertParam(tree: Tree): Tree = atPos(tree.pos) { tree match { case Ident(name) => @@ -319,7 +355,7 @@ trait Parsers requires SyntaxAnalyzer { /////// OPERAND/OPERATOR STACK ///////////////////////////////////////////////// - case class OpInfo(operand: Tree, operator: Name, pos: int) + case class OpInfo(operand: Tree, operator: Name, pos: ScanPosition) var opstack: List[OpInfo] = Nil def precedence(operator: Name): int = @@ -347,7 +383,7 @@ trait Parsers requires SyntaxAnalyzer { if (size > max) syntaxError("too many "+kind+", maximum = "+max, false) } - def checkAssoc(pos: int, op: Name, leftAssoc: boolean) = + def checkAssoc(pos: ScanPosition, op: Name, leftAssoc: boolean) = if (treeInfo.isLeftAssoc(op) != leftAssoc) syntaxError( pos, "left- and right-associative operators with same precedence may not be mixed", false) @@ -383,7 +419,7 @@ trait Parsers requires SyntaxAnalyzer { def ident(): Name = if (in.token == IDENTIFIER || in.token == BACKQUOTED_IDENT) { val name = in.name.encode - in.nextToken() + in.nextToken name } else { if (settings.migrate.value && in.token == MATCH || in.token == REQUIRES || in.token == IMPLICIT) @@ -405,16 +441,16 @@ trait Parsers requires SyntaxAnalyzer { def path(thisOK: boolean, typeOK: boolean): Tree = { var t: Tree = null if (in.token == THIS) { - t = atPos(in.skipToken()) { This(nme.EMPTY.toTypeName) } + t = atPos(in.skipToken) { This(nme.EMPTY.toTypeName) } if (!thisOK || in.token == DOT) t = selectors(t, typeOK, accept(DOT)) } else if (in.token == SUPER) { - t = atPos(in.skipToken()) { + t = atPos(in.skipToken) { Super(nme.EMPTY.toTypeName, mixinQualifierOpt()) } t = atPos(accept(DOT)) { selector(t) } if (in.token == DOT) - t = selectors(t, typeOK, in.skipToken()) + t = selectors(t, typeOK, in.skipToken) } else { val i = atPos(in.currentPos) { if (in.token == BACKQUOTED_IDENT) new BackQuotedIdent(ident()) @@ -422,18 +458,18 @@ trait Parsers requires SyntaxAnalyzer { } t = i if (in.token == DOT) { - val pos = in.skipToken() + val pos = in.skipToken if (in.token == THIS) { - in.nextToken() + in.nextToken t = atPos(i.pos) { This(i.name.toTypeName) } if (!thisOK || in.token == DOT) t = selectors(t, typeOK, accept(DOT)) } else if (in.token == SUPER) { - in.nextToken() + in.nextToken t = atPos(i.pos) { Super(i.name.toTypeName, mixinQualifierOpt()) } t = atPos(accept(DOT)) {selector(t)} if (in.token == DOT) - t = selectors(t, typeOK, in.skipToken()) + t = selectors(t, typeOK, in.skipToken) } else { t = selectors(t, typeOK, pos) } @@ -442,13 +478,13 @@ trait Parsers requires SyntaxAnalyzer { t } - def selectors(t: Tree, typeOK: boolean, pos : Int): Tree = + def selectors(t: Tree, typeOK: boolean, pos : ScanPosition): Tree = if (typeOK && in.token == TYPE) { - in.nextToken() + in.nextToken atPos(pos) { SingletonTypeTree(t) } } else { val t1 = atPos(pos) { selector(t); } - if (in.token == DOT) { selectors(t1, typeOK, in.skipToken()) } + if (in.token == DOT) { selectors(t1, typeOK, in.skipToken) } else t1 } @@ -456,7 +492,7 @@ trait Parsers requires SyntaxAnalyzer { */ def mixinQualifierOpt(): Name = if (in.token == LBRACKET) { - in.nextToken() + in.nextToken val name = ident().toTypeName accept(RBRACKET) name @@ -475,7 +511,7 @@ trait Parsers requires SyntaxAnalyzer { */ def qualId(): Tree = { val id = atPos(in.currentPos) { Ident(ident()) } - if (in.token == DOT) { selectors(id, false, in.skipToken()) } + if (in.token == DOT) { selectors(id, false, in.skipToken) } else id } @@ -513,7 +549,7 @@ trait Parsers requires SyntaxAnalyzer { val isSymLit = in.token == SYMBOLLIT val t = litToTree() - val pos = in.skipToken() + val pos = in.skipToken if (isSymLit) { atPos(pos) { var symid = scalaDot(nme.Symbol) @@ -529,13 +565,13 @@ trait Parsers requires SyntaxAnalyzer { def newLineOpt(): unit = if (in.token == NEWLINE) { if (settings.migrate.value) in.newNewLine = false - in.nextToken() + in.nextToken } def newLinesOpt(): unit = if (in.token == NEWLINE || in.token == NEWLINES) { if (settings.migrate.value) in.newNewLine = false - in.nextToken() + in.nextToken } def newLineOptWhenFollowedBy(token: int): unit = { @@ -553,7 +589,7 @@ trait Parsers requires SyntaxAnalyzer { /** TypedOpt ::= [`:' Type] */ def typedOpt(): Tree = - if (in.token == COLON) { in.nextToken(); typ() } + if (in.token == COLON) { in.nextToken; typ() } else TypeTree() /** RequiresTypedOpt ::= [requires AnnotType] @@ -562,7 +598,7 @@ trait Parsers requires SyntaxAnalyzer { if (in.token == COLON | in.token == REQUIRES) { if (in.token == COLON) warning("`:' has been deprecated; use `requires' instead") - in.nextToken(); annotType(false) + in.nextToken; annotType(false) } else TypeTree() @@ -574,7 +610,7 @@ trait Parsers requires SyntaxAnalyzer { def types(isPattern: boolean): List[Tree] = { val ts = new ListBuffer[Tree] + argType(isPattern) while (in.token == COMMA) { - in.nextToken() + in.nextToken if (in.token == RPAREN) return List(makeTupleType(ts.toList, false)) ts += argType(isPattern) } @@ -588,29 +624,30 @@ trait Parsers requires SyntaxAnalyzer { /** Type ::= InfixType [`=>' Type] * | `(' [`=>' Type] `)' `=>' Type + * XXX: Hook for IDE. */ def typ(): Tree = { val t = if (in.token == LPAREN) { - val pos = in.skipToken() + val pos = in.skipToken if (in.token == RPAREN) { - in.nextToken() + in.nextToken atPos(accept(ARROW)) { makeFunctionTypeTree(List(), typ()) } } else if (in.token == ARROW) { - in.nextToken() + in.nextToken val t0 = typ() accept(RPAREN) atPos(accept(ARROW)) { makeByNameFunctionTypeTree(t0, typ()) } } else { val ts = types(false) accept(RPAREN) - if (in.token == ARROW) atPos(in.skipToken()) { makeFunctionTypeTree(ts, typ()) } + if (in.token == ARROW) atPos(in.skipToken) { makeFunctionTypeTree(ts, typ()) } else infixTypeRest(pos, makeTupleType(ts, true), false, FirstOp) } } else { infixType(false, FirstOp) } - if (in.token == ARROW) atPos(in.skipToken()) { makeFunctionTypeTree(List(t), typ()) } + if (in.token == ARROW) atPos(in.skipToken) { makeFunctionTypeTree(List(t), typ()) } else t } @@ -620,7 +657,7 @@ trait Parsers requires SyntaxAnalyzer { def infixType(isPattern: boolean, mode: int): Tree = infixTypeRest(in.currentPos, annotType(isPattern), isPattern, mode) - def infixTypeRest(pos: int, t0: Tree, isPattern: boolean, mode: int): Tree = { + def infixTypeRest(pos: ScanPosition, t0: Tree, isPattern: boolean, mode: int): Tree = { val t = compoundTypeRest(pos, t0, isPattern) if (isIdent && in.name != nme.STAR) { val opPos = in.currentPos @@ -643,10 +680,10 @@ trait Parsers requires SyntaxAnalyzer { def compoundType(isPattern: boolean): Tree = compoundTypeRest(in.currentPos, annotType(isPattern), isPattern) - def compoundTypeRest(pos: int, t: Tree, isPattern: boolean): Tree = { + def compoundTypeRest(pos: ScanPosition, t: Tree, isPattern: boolean): Tree = { var ts = new ListBuffer[Tree] + t while (in.token == WITH) { - in.nextToken(); ts += annotType(isPattern) + in.nextToken; ts += annotType(isPattern) } newLineOptWhenFollowedBy(LBRACE) atPos(pos) { @@ -673,7 +710,7 @@ trait Parsers requires SyntaxAnalyzer { val pos = in.currentPos var t: Tree = if (in.token == LPAREN) { - in.nextToken() + in.nextToken val ts = types(isPattern) accept(RPAREN) atPos(pos) { makeTupleType(ts, true) } @@ -691,7 +728,7 @@ trait Parsers requires SyntaxAnalyzer { var done = false while (!done) { if (in.token == HASH) { - t = atPos(in.skipToken()) { + t = atPos(in.skipToken) { SelectFromTypeTree(t, ident().toTypeName) } } else if (in.token == LBRACKET) { @@ -721,7 +758,7 @@ trait Parsers requires SyntaxAnalyzer { def argType(isPattern: boolean): Tree = if (isPattern) { if (in.token == USCORE) - atPos(in.skipToken()) { Bind(nme.WILDCARD.toTypeName, EmptyTree) } + atPos(in.skipToken) { Bind(nme.WILDCARD.toTypeName, EmptyTree) } else if (in.token == IDENTIFIER && treeInfo.isVariableName(in.name.toTypeName)) atPos(in.currentPos) { Bind(ident().toTypeName, EmptyTree) } else { @@ -787,7 +824,7 @@ trait Parsers requires SyntaxAnalyzer { } val ts = new ListBuffer[Tree] + first while (in.token == COMMA) { - in.nextToken(); + in.nextToken; if (in.token == RPAREN) return List(makeTupleTerm(ts.toList, false)) ts += expr() if (!implicitParams.isEmpty) { @@ -827,39 +864,41 @@ trait Parsers requires SyntaxAnalyzer { * | `:' `_' `*' */ def expr(): Tree = expr(Local) + + /** XXX: Hook for IDE */ def expr(location: int): Tree = in.token match { case IF => - val pos = in.skipToken() + val pos = in.skipToken accept(LPAREN) val cond = expr() accept(RPAREN) newLinesOpt() val thenp = expr() val elsep = - if (in.token == ELSE) { in.nextToken(); expr() } + if (in.token == ELSE) { in.nextToken; expr() } else EmptyTree atPos(pos) { If(cond, thenp, elsep) } case TRY => - atPos(in.skipToken()) { + atPos(in.skipToken) { accept(LBRACE) val body = block() accept(RBRACE) val catches = if (in.token == CATCH) { - in.nextToken() + in.nextToken accept(LBRACE) val cases = caseClauses() accept(RBRACE) cases } else List() val finalizer = - if (in.token == FINALLY) { in.nextToken(); expr() } + if (in.token == FINALLY) { in.nextToken; expr() } else EmptyTree Try(body, catches, finalizer) } case WHILE => - val lname: Name = unit.fresh.newName("while$") - val pos = in.skipToken() + val lname: Name = freshName("while$") + val pos = in.skipToken accept(LPAREN) val cond = expr() accept(RPAREN) @@ -867,36 +906,36 @@ trait Parsers requires SyntaxAnalyzer { val body = expr() atPos(pos) { makeWhile(lname, cond, body) } case DO => - val lname: Name = unit.fresh.newName("doWhile$") - val pos = in.skipToken() + val lname: Name = freshName("doWhile$") + val pos = in.skipToken val body = expr() - if (isStatSep) in.nextToken() + if (isStatSep) in.nextToken accept(WHILE) accept(LPAREN) val cond = expr() accept(RPAREN) atPos(pos) { makeDoWhile(lname, body, cond) } case FOR => - atPos(in.skipToken()) { + atPos(in.skipToken) { val startToken = in.token accept(if (startToken == LBRACE) LBRACE else LPAREN) val enums = enumerators() accept(if (startToken == LBRACE) RBRACE else RPAREN) newLinesOpt() if (in.token == YIELD) { - in.nextToken(); makeForYield(enums, expr()) + in.nextToken; makeForYield(enums, expr()) } else makeFor(enums, expr()) } case RETURN => - atPos(in.skipToken()) { + atPos(in.skipToken) { Return(if (isExprIntro) expr() else Literal(())) } case THROW => - atPos(in.skipToken()) { + atPos(in.skipToken) { Throw(expr()) } case DOT => - atPos(in.skipToken()) { + atPos(in.skipToken) { if (isIdent) { makeDotClosure(stripParens(simpleExpr())) } else { @@ -909,17 +948,17 @@ trait Parsers requires SyntaxAnalyzer { if (in.token == EQUALS) { t match { case Ident(_) | Select(_, _) | Apply(_, _) => - t = atPos(in.skipToken()) { makeAssign(t, expr()) } + t = atPos(in.skipToken) { makeAssign(t, expr()) } case _ => } } else if (in.token == COLON) { t = stripParens(t) - val pos = in.skipToken() + val pos = in.skipToken val annots = annotations() if (in.token == USCORE) { - val pos1 = in.skipToken() + val pos1 = in.skipToken if (isIdent && in.name == nme.STAR) { - in.nextToken() + in.nextToken t = atPos(pos) { Typed(t, atPos(pos1) { Ident(nme.WILDCARD_STAR.toTypeName) }) } @@ -937,7 +976,7 @@ trait Parsers requires SyntaxAnalyzer { t = (t /: annots) (makeAnnotated) } } else if (in.token == MATCH) { - t = atPos(in.skipToken()) { + t = atPos(in.skipToken) { accept(LBRACE) val cases = caseClauses() accept(RBRACE) @@ -945,7 +984,7 @@ trait Parsers requires SyntaxAnalyzer { } } if (in.token == ARROW && location != InTemplate) { - t = atPos(in.skipToken()) { + t = atPos(in.skipToken) { Function(convertToParams(t), if (location == Local) expr() else block()) } } @@ -999,7 +1038,7 @@ trait Parsers requires SyntaxAnalyzer { atPos(pos) { Typed(stripParens(simpleExpr()), Function(List(), EmptyTree)) } /* XX-LIFTING } else if (settings.Xexperimental.value && isIdent && in.name == SLASH) { - val pos = in.skipToken() + val pos = in.skipToken val name = freshName() liftedGenerators += ValFrom(pos, Bind(name, Ident(nme.WILDCARD)), simpleExpr()) Ident(name) setPos pos @@ -1027,26 +1066,27 @@ trait Parsers requires SyntaxAnalyzer { case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL => t = literal(false, false) - case XMLSTART => + case XMLSTART if xmlp != null => + assert(xmlp != null) t = xmlp.xLiteral case IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER => t = path(true, false) case USCORE => - val pname = unit.fresh.newName("x$") - val pos = in.skipToken() + val pname = freshName("x$") + val pos = in.skipToken val param = makeSyntheticParam(pname) setPos pos implicitParams = param :: implicitParams t = atPos(pos) { Ident(pname) } case LPAREN => - val pos = in.skipToken() + val pos = in.skipToken val ts = if (in.token == RPAREN) List() else exprs() accept(RPAREN) - t = Parens(ts) setPos pos + t = Parens(ts) setPos g2p(pos) case LBRACE => t = blockExpr() canApply = false case NEW => - t = atPos(in.skipToken()) { + t = atPos(in.skipToken) { val (parents, argss, self, stats) = template(false) makeNew(parents, self, stats, argss) } @@ -1063,12 +1103,11 @@ trait Parsers requires SyntaxAnalyzer { } simpleExprRest(t, canApply) } - def simpleExprRest(t: Tree, canApply: boolean): Tree = { if (canApply) newLineOptWhenFollowedBy(LBRACE) in.token match { case DOT => - simpleExprRest(atPos(in.skipToken()) { selector(stripParens(t)) }, true) + simpleExprRest(atPos(in.skipToken) { selector(stripParens(t)) }, true) case LBRACKET => t match { case Ident(_) | Select(_, _) => @@ -1134,7 +1173,7 @@ trait Parsers requires SyntaxAnalyzer { /** Guard ::= if PostfixExpr */ def guard(): Tree = - if (in.token == IF) { in.nextToken(); stripParens(postfixExpr()) } + if (in.token == IF) { in.nextToken; stripParens(postfixExpr()) } else EmptyTree /** Enumerators ::= Generator {semi Enumerator} @@ -1147,7 +1186,7 @@ trait Parsers requires SyntaxAnalyzer { val enums = new ListBuffer[Enumerator] generator(enums, false) while (isStatSep) { - in.nextToken() + in.nextToken if (newStyle) { if (in.token == IF) enums += Filter(guard()) else generator(enums, true) @@ -1163,14 +1202,15 @@ trait Parsers requires SyntaxAnalyzer { */ def generator(enums: ListBuffer[Enumerator], eqOK: boolean) { val pos = in.currentPos; - if (in.token == VAL) in.nextToken() + if (in.token == VAL) in.nextToken val pat = pattern1(false) val tok = in.token - if (tok == EQUALS && eqOK) in.nextToken() + if (tok == EQUALS && eqOK) in.nextToken else accept(LARROW) enums += makeGenerator(pos, pat, tok == EQUALS, expr) if (in.token == IF) enums += Filter(guard()) } + //def p2i(pos : ScanPosition) : Int; //////// PATTERNS //////////////////////////////////////////////////////////// @@ -1182,7 +1222,7 @@ trait Parsers requires SyntaxAnalyzer { def patterns(seqOK: boolean): List[Tree] = { val ts = new ListBuffer[Tree] + pattern(seqOK) while (in.token == COMMA) { - in.nextToken(); + in.nextToken; if (in.token == RPAREN) return List(makeTupleTerm(ts.toList, false)) ts += pattern(seqOK) } @@ -1198,7 +1238,7 @@ trait Parsers requires SyntaxAnalyzer { if (isIdent && in.name == BAR) { val ts = new ListBuffer[Tree] + t while (isIdent && in.name == BAR) { - in.nextToken(); ts += pattern1(seqOK) + in.nextToken; ts += pattern1(seqOK) } atPos(pos) { makeAlternative(ts.toList) } } else t @@ -1220,7 +1260,7 @@ trait Parsers requires SyntaxAnalyzer { val p = pattern2(seqOK) p match { case Ident(name) if (treeInfo.isVarPattern(p) && in.token == COLON) => - atPos(in.skipToken()) { Typed(p, compoundType(true)) } + atPos(in.skipToken) { Typed(p, compoundType(true)) } case _ => p } @@ -1238,9 +1278,9 @@ trait Parsers requires SyntaxAnalyzer { p match { case Ident(name) => if (name == nme.WILDCARD) { - in.nextToken(); pattern3(seqOK) + in.nextToken; pattern3(seqOK) } else if (treeInfo.isVarPattern(p)) { - in.nextToken() + in.nextToken atPos(p.pos) { Bind(name, pattern3(seqOK)) } } else { p @@ -1261,11 +1301,11 @@ trait Parsers requires SyntaxAnalyzer { var top = simplePattern(seqOK) if (seqOK && isIdent) { if (in.name == STAR) - return atPos(in.skipToken())(Star(top)) + return atPos(in.skipToken)(Star(top)) else if (in.name == PLUS) - return atPos(in.skipToken())(makePlus(top)) + return atPos(in.skipToken)(makePlus(top)) else if (in.name == OPT) - return atPos(in.skipToken())(makeOpt(top)) + return atPos(in.skipToken)(makeOpt(top)) } while (isIdent && in.name != BAR) { top = reduceStack( @@ -1291,6 +1331,8 @@ trait Parsers requires SyntaxAnalyzer { * | `<' xLiteralPattern * | StableId [TypePatArgs] [`(' [SeqPatterns [`,']] `)'] * | `(' [SeqPatterns [`,']] `)' + * + * XXX: Hook for IDE */ def simplePattern(seqOK: boolean): Tree = in.token match { case IDENTIFIER | BACKQUOTED_IDENT | THIS => @@ -1318,15 +1360,16 @@ trait Parsers requires SyntaxAnalyzer { atPos(in.currentPos) { Apply(t, argumentPatterns()) } } else t case USCORE => - atPos(in.skipToken()) { Ident(nme.WILDCARD) } + atPos(in.skipToken) { Ident(nme.WILDCARD) } case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT | STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL => literal(true, false) case LPAREN => - val pos = in.skipToken() + val pos = in.skipToken val ps = if (in.token == RPAREN) List() else patterns(false) accept(RPAREN) - Parens(ps) setPos pos - case XMLSTART => + Parens(ps) setPos g2p(pos) + case XMLSTART if xmlp != null => + assert(xmlp != null) xmlp.xLiteralPattern case _ => if (settings.migrate.value && @@ -1355,7 +1398,7 @@ trait Parsers requires SyntaxAnalyzer { private def addMod(mods: Modifiers, mod: int): Modifiers = { if (mods hasFlag mod) syntaxError(in.currentPos, "repeated modifier", false) - in.nextToken() + in.nextToken mods | mod } @@ -1364,10 +1407,10 @@ trait Parsers requires SyntaxAnalyzer { def accessQualifierOpt(mods: Modifiers) = { var result = mods if (in.token == LBRACKET) { - in.nextToken() + in.nextToken if (mods.privateWithin != nme.EMPTY.toTypeName) syntaxError("duplicate private/protected qualifier", false) - result = if (in.token == THIS) { in.nextToken(); mods | Flags.LOCAL } + result = if (in.token == THIS) { in.nextToken; mods | Flags.LOCAL } else Modifiers(mods.flags, ident().toTypeName) accept(RBRACKET) } @@ -1378,8 +1421,8 @@ trait Parsers requires SyntaxAnalyzer { */ def accessModifierOpt(): Modifiers = normalize { in.token match { - case PRIVATE => in.nextToken(); accessQualifierOpt(Modifiers(Flags.PRIVATE)) - case PROTECTED => in.nextToken(); accessQualifierOpt(Modifiers(Flags.PROTECTED)) + case PRIVATE => in.nextToken; accessQualifierOpt(Modifiers(Flags.PRIVATE)) + case PROTECTED => in.nextToken; accessQualifierOpt(Modifiers(Flags.PROTECTED)) case _ => NoMods } } @@ -1436,12 +1479,12 @@ trait Parsers requires SyntaxAnalyzer { def annotations(): List[Annotation] = { var annots = new ListBuffer[Annotation] if (in.token == LBRACKET) { - unit.deprecationWarning(in.pos, "The [attribute] syntax has been deprecated; use @annotation instead") + in.deprecationWarning(in.pos, "The [attribute] syntax has been deprecated; use @annotation instead") while (in.token == LBRACKET) { - in.nextToken() + in.nextToken annots += annotation() while (in.token == COMMA) { - in.nextToken() + in.nextToken annots += annotation() } accept(RBRACKET) @@ -1449,7 +1492,7 @@ trait Parsers requires SyntaxAnalyzer { } } else { while (in.token == AT) { - in.nextToken() + in.nextToken annots += annotation() newLineOpt() } @@ -1491,10 +1534,10 @@ trait Parsers requires SyntaxAnalyzer { val args = if (in.token == LPAREN) argumentExprs() else List() newLineOptWhenFollowedBy(LBRACE) val nameValuePairs: List[Tree] = if (in.token == LBRACE) { - in.nextToken() + in.nextToken val nvps = new ListBuffer[Tree] + nameValuePair() while (in.token == COMMA) { - in.nextToken() + in.nextToken nvps += nameValuePair() } accept(RBRACE) @@ -1525,10 +1568,10 @@ trait Parsers requires SyntaxAnalyzer { if (owner.isTypeName) { mods = modifiers() | Flags.PARAMACCESSOR if (in.token == VAL) { - in.nextToken() + in.nextToken } else if (in.token == VAR) { mods = mods | Flags.MUTABLE - in.nextToken() + in.nextToken } else { if (mods.flags != Flags.PARAMACCESSOR) accept(VAL) if (!(caseParam)) mods = mods | Flags.PRIVATE | Flags.LOCAL @@ -1561,12 +1604,12 @@ trait Parsers requires SyntaxAnalyzer { if (in.token == IMPLICIT) { if (!implicitViews.isEmpty) syntaxError("cannot have both view bounds `<%' and implicit parameters", false) - in.nextToken() + in.nextToken implicitmod = Flags.IMPLICIT } params += param() while (in.token == COMMA) { - in.nextToken(); params += param() + in.nextToken; params += param() } } params.toList @@ -1575,7 +1618,7 @@ trait Parsers requires SyntaxAnalyzer { val pos = in.currentPos newLineOptWhenFollowedBy(LPAREN) while (implicitmod == 0 && in.token == LPAREN) { - in.nextToken() + in.nextToken vds += paramClause() accept(RPAREN) caseParam = false @@ -1598,14 +1641,14 @@ trait Parsers requires SyntaxAnalyzer { */ def paramType(): Tree = if (in.token == ARROW) - atPos(in.skipToken()) { + atPos(in.skipToken) { AppliedTypeTree( scalaDot(nme.BYNAME_PARAM_CLASS_NAME.toTypeName), List(typ())) } else { val t = typ() if (isIdent && in.name == STAR) { - in.nextToken() + in.nextToken atPos(t.pos) { AppliedTypeTree( scalaDot(nme.REPEATED_PARAM_CLASS_NAME.toTypeName), List(t)) @@ -1625,24 +1668,24 @@ trait Parsers requires SyntaxAnalyzer { var mods = Modifiers(Flags.PARAM) if (owner.isTypeName && isIdent) { if (in.name == PLUS) { - in.nextToken() + in.nextToken mods = mods | Flags.COVARIANT } else if (in.name == MINUS) { - in.nextToken() + in.nextToken mods = mods | Flags.CONTRAVARIANT } } val pos = in.currentPos val pname = if (in.token == USCORE) { // @M! also allow underscore - in.nextToken() + in.nextToken nme.WILDCARD } else ident() val tparams = typeParamClauseOpt(pname.toTypeName, null) // @M TODO null --> no higher-order view bounds for now val param = atPos(pos) { typeBounds(mods, pname, tparams) } if (in.token == VIEWBOUND && (implicitViewBuf ne null)) - implicitViewBuf += atPos(in.skipToken()) { + implicitViewBuf += atPos(in.skipToken) { makeFunctionTypeTree(List(Ident(pname.toTypeName)), typ()) } param @@ -1650,10 +1693,10 @@ trait Parsers requires SyntaxAnalyzer { val params = new ListBuffer[AbsTypeDef] newLineOptWhenFollowedBy(LBRACKET) if (in.token == LBRACKET) { - in.nextToken() + in.nextToken params += typeParam() while (in.token == COMMA) { - in.nextToken() + in.nextToken params += typeParam() } accept(RBRACKET) @@ -1669,7 +1712,7 @@ trait Parsers requires SyntaxAnalyzer { bound(SUBTYPE, nme.Any)) def bound(tok: int, default: Name): Tree = - if (in.token == tok) { in.nextToken(); typ() } + if (in.token == tok) { in.nextToken; typ() } else scalaDot(default.toTypeName) //////// DEFS //////////////////////////////////////////////////////////////// @@ -1681,17 +1724,18 @@ trait Parsers requires SyntaxAnalyzer { accept(IMPORT) val ts = new ListBuffer[Tree] + importExpr() while (in.token == COMMA) { - in.nextToken(); ts += importExpr() + in.nextToken; ts += importExpr() } ts.toList } /** ImportExpr ::= StableId `.' (Id | `_' | ImportSelectors) + * XXX: Hook for IDE */ def importExpr(): Tree = atPos(in.currentPos) { var t: Tree = null - var pos = 0 + var pos : ScanPosition = null.asInstanceOf[ScanPosition] if (in.token == THIS) { t = atPos(in.currentPos) { This(nme.EMPTY.toTypeName) } t = atPos(accept(DOT)) { selector(t) } @@ -1700,7 +1744,7 @@ trait Parsers requires SyntaxAnalyzer { val i = atPos(in.currentPos) { Ident(ident()) } pos = accept(DOT) if (in.token == THIS) { - in.nextToken() + in.nextToken t = atPos(i.pos) { This(i.name.toTypeName) } t = atPos(accept(DOT)) { selector(t) } pos = accept(DOT) @@ -1710,7 +1754,7 @@ trait Parsers requires SyntaxAnalyzer { } def loop: Tree = if (in.token == USCORE) { - in.nextToken() + in.nextToken Import(t, List((nme.WILDCARD, null))) } else if (in.token == LBRACE) { Import(t, importSelectors()) @@ -1734,7 +1778,7 @@ trait Parsers requires SyntaxAnalyzer { accept(LBRACE) var isLast = importSelector(names) while (!isLast && in.token == COMMA) { - in.nextToken() + in.nextToken isLast = importSelector(names) } accept(RBRACE) @@ -1745,14 +1789,14 @@ trait Parsers requires SyntaxAnalyzer { */ def importSelector(names: ListBuffer[(Name, Name)]): boolean = if (in.token == USCORE) { - in.nextToken(); names += (nme.WILDCARD, null); true + in.nextToken; names += (nme.WILDCARD, null); true } else { val name = ident() names += ( name, if (in.token == ARROW) { - in.nextToken() - if (in.token == USCORE) { in.nextToken(); nme.WILDCARD } else ident() + in.nextToken + if (in.token == USCORE) { in.nextToken; nme.WILDCARD } else ident() } else { name }) @@ -1768,6 +1812,7 @@ trait Parsers requires SyntaxAnalyzer { * | var ValDcl * | def FunDcl * | type [nl] TypeDcl + * XXX: Hook for IDE. */ def defOrDcl(mods: Modifiers): List[Tree] = in.token match { @@ -1778,7 +1823,7 @@ trait Parsers requires SyntaxAnalyzer { case DEF => List(funDefOrDcl(mods)) case TYPE => - in.nextToken() + in.nextToken newLinesOpt() List(typeDefOrDcl(mods)) case _ => @@ -1792,7 +1837,7 @@ trait Parsers requires SyntaxAnalyzer { var newmods = mods var lhs = new ListBuffer[Tree] do { - in.nextToken() + in.nextToken lhs += stripParens(pattern2(false)) } while (in.token == COMMA) val tp = typedOpt() @@ -1828,15 +1873,15 @@ trait Parsers requires SyntaxAnalyzer { */ def varDefOrDcl(mods: Modifiers): List[Tree] = { var newmods = mods | Flags.MUTABLE - val lhs = new ListBuffer[(Int, Name)] + val lhs = new ListBuffer[(ScanPosition, Name)] do { - lhs += (in.skipToken(), ident()) + lhs += (in.skipToken, ident()) } while (in.token == COMMA) val tp = typedOpt() val rhs = if (tp.isEmpty || in.token == EQUALS) { accept(EQUALS) if (!tp.isEmpty && in.token == USCORE) { - in.nextToken() + in.nextToken EmptyTree } else { expr() @@ -1856,9 +1901,9 @@ trait Parsers requires SyntaxAnalyzer { * FunSig ::= id [FunTypeParamClause] ParamClauses */ def funDefOrDcl(mods: Modifiers): Tree = - atPos(in.skipToken()) { + atPos(in.skipToken) { if (in.token == THIS) { - in.nextToken() + in.nextToken val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (.duplicate), false) newLineOptWhenFollowedBy(LBRACE) val rhs = if (in.token == LBRACE) constrBlock(vparamss) @@ -1908,10 +1953,10 @@ trait Parsers requires SyntaxAnalyzer { /** ConstrBlock ::= `{' SelfInvocation {semi BlockStat} `}' */ def constrBlock(vparamss: List[List[ValDef]]): Tree = - atPos(in.skipToken()) { + atPos(in.skipToken) { val statlist = new ListBuffer[Tree] statlist += selfInvocation(vparamss) - val stats = if (isStatSep) { in.nextToken(); blockStatSeq(statlist) } + val stats = if (isStatSep) { in.nextToken; blockStatSeq(statlist) } else statlist.toList accept(RBRACE) Block(stats, Literal(())) @@ -1934,7 +1979,7 @@ trait Parsers requires SyntaxAnalyzer { in.token match { case EQUALS => - in.nextToken() + in.nextToken AliasTypeDef(mods, name, tparams, typ()) case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE => typeBounds(mods | Flags.DEFERRED, name, tparams) @@ -1944,6 +1989,9 @@ trait Parsers requires SyntaxAnalyzer { } } + /** XXX: Hook for IDE? */ + def tmplDefHooked(mods: Modifiers): Tree = tmplDef(mods) + /** TmplDef ::= [case] class ClassDef * | [case] object ObjectDef * | trait TraitDef @@ -1969,7 +2017,7 @@ trait Parsers requires SyntaxAnalyzer { * TraitDef ::= Id [TypeParamClause] RequiresTypeOpt TraitTemplateOpt */ def classDef(mods: Modifiers): ClassDef = - atPos(in.skipToken()) { + atPos(in.skipToken) { val name = ident().toTypeName val savedViews = implicitClassViews val implicitViewBuf = new ListBuffer[Tree] @@ -1999,7 +2047,7 @@ trait Parsers requires SyntaxAnalyzer { /** ObjectDef ::= Id ClassTemplateOpt */ def objectDef(mods: Modifiers): ModuleDef = - atPos(in.skipToken()) { + atPos(in.skipToken) { val name = ident() val (self, template0) = templateOpt(mods, name, NoMods, List()) val template = self match { @@ -2023,7 +2071,7 @@ trait Parsers requires SyntaxAnalyzer { do { argss += argumentExprs() } while (in.token == LPAREN) else argss += List() while (in.token == WITH) { - in.nextToken() + in.nextToken parents += annotType(false) } (parents.toList, argss.toList) @@ -2046,7 +2094,7 @@ trait Parsers requires SyntaxAnalyzer { syntaxError(stat.pos, "only concrete field definitions allowed in early object initialization section", false) List() } - in.nextToken() + in.nextToken val (parents, argss) = templateParents(isTrait) val (self1, body1) = templateBodyOpt(isTrait) (parents, argss, self1, vdefs ::: body1) @@ -2067,7 +2115,7 @@ trait Parsers requires SyntaxAnalyzer { val pos = in.currentPos; val (parents0, argss, self, body) = if (in.token == EXTENDS) { - in.nextToken() + in.nextToken template(mods hasFlag Flags.TRAIT) } else { newLineOptWhenFollowedBy(LBRACE) @@ -2084,7 +2132,7 @@ trait Parsers requires SyntaxAnalyzer { /** TemplateBody ::= [nl] `{' TemplateStatSeq `}' */ - def templateBody(): (ValDef, List[Tree]) = { + def templateBody() = { accept(LBRACE) val result @ (self, stats) = templateStatSeq() accept(RBRACE) @@ -2149,7 +2197,7 @@ trait Parsers requires SyntaxAnalyzer { in.token == AT || isModifier) { val annots = annotations() - stats ++ joinComment(List(tmplDef(modifiers() withAnnotations annots))) + stats ++ joinComment(List(tmplDefHooked(modifiers() withAnnotations annots))) } else if (!isStatSep) { syntaxErrorOrIncomplete("expected class or object definition", true) } @@ -2166,7 +2214,7 @@ trait Parsers requires SyntaxAnalyzer { * | super ArgumentExprs {ArgumentExprs} * | */ - def templateStatSeq(): (ValDef, List[Tree]) = { + def templateStatSeq() = { var self: ValDef = emptyValDef val stats = new ListBuffer[Tree] if (isExprIntro) { @@ -2177,7 +2225,7 @@ trait Parsers requires SyntaxAnalyzer { self = makeSelfDef(name, tpt) case _ => } - in.nextToken() + in.nextToken } else stats += first } while (in.token != RBRACE && in.token != EOF) { @@ -2224,7 +2272,7 @@ trait Parsers requires SyntaxAnalyzer { def blockStatSeq(stats: ListBuffer[Tree]): List[Tree] = { def localDef(mods: Modifiers) = { if (!(mods hasFlag ~Flags.IMPLICIT)) stats ++= defOrDcl(mods) - else stats += tmplDef(mods) + else stats += tmplDefHooked(mods) if (in.token == RBRACE || in.token == CASE) syntaxError("block must end in result expression, not in definition", false) else @@ -2245,7 +2293,7 @@ trait Parsers requires SyntaxAnalyzer { } else if (isLocalModifier) { localDef(localModifiers()) } else if (isStatSep) { - in.nextToken() + in.nextToken } else { syntaxErrorOrIncomplete("illegal start of statement", true) } @@ -2254,18 +2302,20 @@ trait Parsers requires SyntaxAnalyzer { } /** CompilationUnit ::= [package QualId semi] TopStatSeq + * + * XXX: hook in IDE? */ def compilationUnit(): Tree = atPos(in.currentPos) { val ts = new ListBuffer[Tree] if (in.token == PACKAGE) { - in.nextToken() + in.nextToken val pkg = qualId() newLineOptWhenFollowedBy(LBRACE) if (in.token == EOF) { ts += makePackaging(pkg, List()) } else if (isStatSep) { - in.nextToken() + in.nextToken ts += makePackaging(pkg, topStatSeq()) } else { accept(LBRACE) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 33f0c7db71..4f6f06fb0b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -8,34 +8,40 @@ package scala.tools.nsc.ast.parser import compat.StringBuilder import Tokens._ -import scala.tools.nsc.util.{Position, SourceFile} +import scala.tools.nsc.util.{Position, OffsetPosition, SourceFile} import SourceFile.{LF, FF, CR, SU} import scala.tools.nsc.util.CharArrayReader trait Scanners requires SyntaxAnalyzer { - import global._ - + abstract class AbstractTokenData { + def token : Int + type ScanPosition + val NoPos : ScanPosition + def pos : ScanPosition + def currentPos : ScanPosition + def name : Name + } /** A class for representing a token's data. */ - class TokenData { + trait TokenData extends AbstractTokenData { + type ScanPosition = Int - /** the next token */ - var token: int = EMPTY + val NoPos = -1 + /** the next token */ + var token: Int = EMPTY /** the token's position */ - var pos: int = 0 + var pos: Int = (0) + override def currentPos : Int = pos - 1 /** the first character position after the previous token */ - var lastPos: int = 0 - - def currentPos = pos - 1 - + var lastPos: Int = 0 /** the name of an identifier or token */ var name: Name = null /** the base of a number */ - var base: int = 0 + var base: Int = 0 def copyFrom(td: TokenData) = { this.token = td.token @@ -45,20 +51,198 @@ trait Scanners requires SyntaxAnalyzer { this.base = td.base } } + abstract class AbstractScanner extends AbstractTokenData { + implicit def p2g(pos : Position ) : ScanPosition + implicit def g2p(pos : ScanPosition) : Position + def configuration : ScannerConfiguration + 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 + var lastPos : ScanPosition + def skipToken: ScanPosition + def nextToken: Unit + def next : AbstractTokenData + def intVal(negated: Boolean): Long + def floatVal(negated: Boolean): Double + def intVal : Long = intVal(false) + def floatVal : Double = floatVal(false) + //def token2string(token : Int) : String = configuration.token2string(token) + /* disabled in presentation compiler */ + var newNewLine : Boolean + /* disabled in presentation compiler */ + var skipping : Boolean + /** return recent scala doc, if any */ + def flushDoc : String + + } + + + trait ScannerConfiguration { +// Keywords ----------------------------------------------------------------- + /** Keyword array; maps from name indices to tokens */ + private var key: Array[byte] = _ + private var maxKey = 0 + private var tokenName = new Array[Name](128) + + { + var tokenCount = 0 + + // Enter keywords + + def enterKeyword(n: Name, tokenId: int): unit = { + while (tokenId >= tokenName.length) { + val newTokName = new Array[Name](tokenName.length * 2) + Array.copy(tokenName, 0, newTokName, 0, newTokName.length) + tokenName = newTokName + } + tokenName(tokenId) = n + if (n.start > maxKey) maxKey = n.start + if (tokenId >= tokenCount) tokenCount = tokenId + 1 + } + + enterKeyword(nme.ABSTRACTkw, ABSTRACT) + enterKeyword(nme.CASEkw, CASE) + enterKeyword(nme.CATCHkw, CATCH) + enterKeyword(nme.CLASSkw, CLASS) + enterKeyword(nme.DEFkw, DEF) + enterKeyword(nme.DOkw, DO) + enterKeyword(nme.ELSEkw, ELSE) + enterKeyword(nme.EXTENDSkw, EXTENDS) + enterKeyword(nme.FALSEkw, FALSE) + enterKeyword(nme.FINALkw, FINAL) + enterKeyword(nme.FINALLYkw, FINALLY) + enterKeyword(nme.FORkw, FOR) + enterKeyword(nme.IFkw, IF) + enterKeyword(nme.IMPLICITkw, IMPLICIT) + enterKeyword(nme.IMPORTkw, IMPORT) + enterKeyword(nme.MATCHkw, MATCH) + enterKeyword(nme.NEWkw, NEW) + enterKeyword(nme.NULLkw, NULL) + enterKeyword(nme.OBJECTkw, OBJECT) + enterKeyword(nme.OVERRIDEkw, OVERRIDE) + enterKeyword(nme.PACKAGEkw, PACKAGE) + enterKeyword(nme.PRIVATEkw, PRIVATE) + enterKeyword(nme.PROTECTEDkw, PROTECTED) + enterKeyword(nme.REQUIRESkw, REQUIRES) + enterKeyword(nme.RETURNkw, RETURN) + enterKeyword(nme.SEALEDkw, SEALED) + enterKeyword(nme.SUPERkw, SUPER) + enterKeyword(nme.THISkw, THIS) + enterKeyword(nme.THROWkw, THROW) + enterKeyword(nme.TRAITkw, TRAIT) + enterKeyword(nme.TRUEkw, TRUE) + enterKeyword(nme.TRYkw, TRY) + enterKeyword(nme.TYPEkw, TYPE) + enterKeyword(nme.VALkw, VAL) + enterKeyword(nme.VARkw, VAR) + enterKeyword(nme.WHILEkw, WHILE) + enterKeyword(nme.WITHkw, WITH) + enterKeyword(nme.YIELDkw, YIELD) + enterKeyword(nme.DOTkw, DOT) + enterKeyword(nme.USCOREkw, USCORE) + enterKeyword(nme.COLONkw, COLON) + enterKeyword(nme.EQUALSkw, EQUALS) + enterKeyword(nme.ARROWkw, ARROW) + enterKeyword(nme.LARROWkw, LARROW) + enterKeyword(nme.SUBTYPEkw, SUBTYPE) + enterKeyword(nme.VIEWBOUNDkw, VIEWBOUND) + enterKeyword(nme.SUPERTYPEkw, SUPERTYPE) + enterKeyword(nme.HASHkw, HASH) + enterKeyword(nme.ATkw, AT) + + // Build keyword array + key = new Array[byte](maxKey+1) + for (val i <- 0 to maxKey) + key(i) = IDENTIFIER + for (val j <- 0 until tokenCount) + if (tokenName(j) ne null) + key(tokenName(j).start) = j.asInstanceOf[byte] + + } +//Token representation ----------------------------------------------------- + + /** Convert name to token */ + def name2token(name: Name): int = + if (name.start <= maxKey) key(name.start) else IDENTIFIER + + /** Returns the string representation of given token. */ + def token2string(token: int): String = token match { + case IDENTIFIER | BACKQUOTED_IDENT => + "identifier"/* + \""+name+"\""*/ + case CHARLIT => + "character literal" + case INTLIT => + "integer literal" + case LONGLIT => + "long literal" + case FLOATLIT => + "float literal" + case DOUBLELIT => + "double literal" + case STRINGLIT => + "string literal" + case SYMBOLLIT => + "symbol literal" + case LPAREN => + "'('" + case RPAREN => + "')'" + case LBRACE => + "'{'" + case RBRACE => + "'}'" + case LBRACKET => + "'['" + case RBRACKET => + "']'" + case EOF => + "eof" + case ERROR => + "something" + case SEMI => + "';'" + case NEWLINE => + "';'" + case NEWLINES => + "';'" + case COMMA => + "','" + case CASECLASS => + "case class" + case CASEOBJECT => + "case object" + case XMLSTART => + "$XMLSTART$<" + case _ => + try { + "'" + tokenName(token) + "'" + } catch { + case _: ArrayIndexOutOfBoundsException => + "'<" + token + ">'" + case _: NullPointerException => + "'<(" + token + ")>'" + } + } + } + /** A scanner for the programming language Scala. * * @author Matthias Zenger, Martin Odersky, Burak Emir * @version 1.1 */ - class Scanner(unit: CompilationUnit) extends TokenData { - + abstract class Scanner extends AbstractScanner with TokenData { import Tokens._ import java.lang.{Integer, Long, Float, Double, Character} + override def intVal = super.intVal + override def floatVal = super.floatVal + override var errpos : Int = -1 - /** Character input reader - */ - val in = new CharArrayReader(unit.source.getContent(), !settings.nouescape.value, syntaxError) + val in : CharArrayReader /** character buffer for literals */ @@ -78,19 +262,29 @@ trait Scanners requires SyntaxAnalyzer { */ var docBuffer: StringBuilder = null + def flushDoc = { + val ret = if (docBuffer != null) docBuffer.toString else null; + docBuffer = null + ret + } + + + /** Process comments and strings in scanner */ + protected def matchInScanner = true + + /** add the given character to the documentation buffer */ protected def putDocChar(c: char): unit = if (docBuffer ne null) docBuffer.append(c) + private class TokenData0 extends TokenData { + } /** we need one token lookahead */ - val next = new TokenData() - val prev = new TokenData() + val next : TokenData = new TokenData0 + val prev : TokenData = new TokenData0 - /** the last error position - */ - var errpos = -1 /** a stack which indicates whether line-ends can be statement separators */ @@ -110,13 +304,13 @@ trait Scanners requires SyntaxAnalyzer { /** read next token and return last position */ - def skipToken(): int = { - val p = pos; nextToken() + def skipToken: Int = { + val p = pos; nextToken // XXX: account for off by one error //??? - p - 1 + (p - 1) } - def nextToken(): unit = { + def nextToken: Unit = { if (token == LPAREN) { sepRegions = RPAREN :: sepRegions } else if (token == LBRACKET) { @@ -136,7 +330,7 @@ trait Scanners requires SyntaxAnalyzer { } if (newNewLine && !skipping) { - unit.warning(pos, migrateMsg + "new line will start a new statement here;\n" + warning(pos, migrateMsg + "new line will start a new statement here;\n" + "to suppress it, enclose expression in parentheses (...)") newNewLine = false } @@ -148,7 +342,6 @@ trait Scanners requires SyntaxAnalyzer { this copyFrom next next.token = EMPTY } - if (token == CASE) { prev copyFrom this fetchToken() @@ -169,6 +362,13 @@ trait Scanners requires SyntaxAnalyzer { next copyFrom this this copyFrom prev } + } else if (token == IDENTIFIER && name == nme.MIXINkw) { //todo: remove eventually + prev.copyFrom(this) + fetchToken() + if (token == CLASS) + warning(prev.pos, "`mixin' is no longer a reserved word; you should use `trait' instead of `mixin class'"); + next.copyFrom(this) + this.copyFrom(prev) } if (afterLineEnd() && inLastOfStat(lastToken) && inFirstOfStat(token) && @@ -240,6 +440,23 @@ trait Scanners requires SyntaxAnalyzer { in.next getOperatorRest; // XXX return + + case '/' if !matchInScanner => + in.next + if (in.ch == '/') { + in.next; token = LINE_COMMENT + return + } else if (in.ch == '*') { + in.next + if (in.ch == '*') { + in.next; token = DOC_START + } else token = COMMENT_START + return + } else { + putChar('/') + getOperatorRest + return + } case '/' => in.next if (!skipComment()) { @@ -247,7 +464,6 @@ trait Scanners requires SyntaxAnalyzer { getOperatorRest return } - case '0' => putChar(in.ch) in.next @@ -264,10 +480,27 @@ trait Scanners requires SyntaxAnalyzer { base = 10 getNumber return + case '`' if !matchInScanner => + in.next; token = BACK_QUOTE + return case '`' => in.next getStringLit('`', BACKQUOTED_IDENT) return + case '\"' if !matchInScanner => + in.next + if (in.ch == '\"') { + in.next + if (in.ch == '\"') { + in.next; token = MULTI_QUOTE + } else { + token = EMPTY_STRING + } + return + } else { + token = DOUBLE_QUOTE + return + } case '\"' => in.next if (in.ch == '\"') { @@ -396,7 +629,8 @@ trait Scanners requires SyntaxAnalyzer { } } - private def skipComment(): boolean = + private def skipComment(): boolean = { + assert(matchInScanner) if (in.ch == '/') { do { in.next @@ -406,8 +640,9 @@ trait Scanners requires SyntaxAnalyzer { docBuffer = null var openComments = 1 in.next + val scalaDoc = ("/**", "*/") if (in.ch == '*' && onlyPresentation) - docBuffer = new StringBuilder("/**") + docBuffer = new StringBuilder(scalaDoc._1) while (openComments > 0) { do { do { @@ -434,6 +669,7 @@ trait Scanners requires SyntaxAnalyzer { } else { false } + } def inFirstOfStat(token: int) = token match { case EOF | CASE | CATCH | ELSE | EXTENDS | FINALLY | MATCH | REQUIRES | WITH | YIELD | @@ -500,7 +736,7 @@ trait Scanners requires SyntaxAnalyzer { return case SU => setName - token = name2token(name) + token = configuration.name2token(name) return case _ => if (java.lang.Character.isUnicodeIdentifierPart(in.ch)) { @@ -508,7 +744,7 @@ trait Scanners requires SyntaxAnalyzer { in.next } else { setName - token = name2token(name) + token = configuration.name2token(name) return } } @@ -525,20 +761,23 @@ trait Scanners requires SyntaxAnalyzer { in.next case '/' => in.next - if (skipComment()) { + if (matchInScanner && skipComment) { setName - token = name2token(name) + token = configuration.name2token(name) return - } else { - putChar('/') - } + } else if (!matchInScanner && (in.ch == '*' || in.ch == '/')) { + in.rewind + setName + token = configuration.name2token(name) + return + } else putChar('/') case _ => if (isSpecial(in.ch)) { putChar(in.ch) in.next } else { setName - token = name2token(name) + token = configuration.name2token(name) return } } @@ -557,11 +796,13 @@ trait Scanners requires SyntaxAnalyzer { if (isSpecial(in.ch)) getOperatorRest else { setName - token = name2token(name) + token = configuration.name2token(name) } } - private def getStringLit(delimiter: char, litType: int): unit = { + private def getStringLit(delimiter: char, litType: int): Unit = { + assert(matchInScanner) + //assert((litType==STRINGLIT) || (litType==IDENTIFIER)) while (in.ch != delimiter && (in.isUnicode || in.ch != CR && in.ch != LF && in.ch != SU)) { getlitch() } @@ -575,7 +816,8 @@ trait Scanners requires SyntaxAnalyzer { } } - private def getMultiLineStringLit: unit = + private def getMultiLineStringLit: Unit = { + assert(matchInScanner) if (in.ch == '\"') { in.next if (in.ch == '\"') { @@ -600,6 +842,7 @@ trait Scanners requires SyntaxAnalyzer { in.next getMultiLineStringLit } + } // Literals ----------------------------------------------------------------- @@ -716,7 +959,6 @@ trait Scanners requires SyntaxAnalyzer { } } - def intVal: long = intVal(false) /** convert name, base to double value */ @@ -724,7 +966,7 @@ trait Scanners requires SyntaxAnalyzer { val limit: double = if (token == DOUBLELIT) Double.MAX_VALUE else Float.MAX_VALUE try { - val value = Double.valueOf(name.toString()).doubleValue() + val value : double = Double.valueOf(name.toString()).doubleValue() if (value > limit) syntaxError("floating point number too large") if (negated) -value else value @@ -734,9 +976,6 @@ trait Scanners requires SyntaxAnalyzer { 0.0 } } - - def floatVal: double = floatVal(false) - /** read a number into name and set base */ protected def getNumber:unit = { @@ -779,7 +1018,7 @@ trait Scanners requires SyntaxAnalyzer { def xSync = { token = NEWLINE; // avoid getting NEWLINE from nextToken if last was RBRACE //in.next - nextToken() + nextToken } // Errors ----------------------------------------------------------------- @@ -787,7 +1026,7 @@ trait Scanners requires SyntaxAnalyzer { /** generate an error at the given position */ def syntaxError(pos: int, msg: String): unit = { - unit.error(pos, msg) + error(pos, msg) token = ERROR errpos = pos } @@ -798,159 +1037,11 @@ trait Scanners requires SyntaxAnalyzer { /** signal an error where the input ended in the middle of a token */ def incompleteInputError(msg: String): unit = { - unit.incompleteInputError(pos, msg) + incompleteInputError(pos, msg) token = EOF errpos = pos } -// Keywords ----------------------------------------------------------------- - - /** Keyword array; maps from name indices to tokens */ - private var key: Array[byte] = _ - private var maxKey = 0 - private var tokenName = new Array[Name](128) - - { - var tokenCount = 0 - - // Enter keywords - - def enterKeyword(n: Name, tokenId: int): unit = { - while (tokenId >= tokenName.length) { - val newTokName = new Array[Name](tokenName.length * 2) - Array.copy(tokenName, 0, newTokName, 0, newTokName.length) - tokenName = newTokName - } - tokenName(tokenId) = n - if (n.start > maxKey) maxKey = n.start - if (tokenId >= tokenCount) tokenCount = tokenId + 1 - } - - enterKeyword(nme.ABSTRACTkw, ABSTRACT) - enterKeyword(nme.CASEkw, CASE) - enterKeyword(nme.CATCHkw, CATCH) - enterKeyword(nme.CLASSkw, CLASS) - enterKeyword(nme.DEFkw, DEF) - enterKeyword(nme.DOkw, DO) - enterKeyword(nme.ELSEkw, ELSE) - enterKeyword(nme.EXTENDSkw, EXTENDS) - enterKeyword(nme.FALSEkw, FALSE) - enterKeyword(nme.FINALkw, FINAL) - enterKeyword(nme.FINALLYkw, FINALLY) - enterKeyword(nme.FORkw, FOR) - enterKeyword(nme.IFkw, IF) - enterKeyword(nme.IMPLICITkw, IMPLICIT) - enterKeyword(nme.IMPORTkw, IMPORT) - enterKeyword(nme.MATCHkw, MATCH) - enterKeyword(nme.NEWkw, NEW) - enterKeyword(nme.NULLkw, NULL) - enterKeyword(nme.OBJECTkw, OBJECT) - enterKeyword(nme.OVERRIDEkw, OVERRIDE) - enterKeyword(nme.PACKAGEkw, PACKAGE) - enterKeyword(nme.PRIVATEkw, PRIVATE) - enterKeyword(nme.PROTECTEDkw, PROTECTED) - enterKeyword(nme.REQUIRESkw, REQUIRES) - enterKeyword(nme.RETURNkw, RETURN) - enterKeyword(nme.SEALEDkw, SEALED) - enterKeyword(nme.SUPERkw, SUPER) - enterKeyword(nme.THISkw, THIS) - enterKeyword(nme.THROWkw, THROW) - enterKeyword(nme.TRAITkw, TRAIT) - enterKeyword(nme.TRUEkw, TRUE) - enterKeyword(nme.TRYkw, TRY) - enterKeyword(nme.TYPEkw, TYPE) - enterKeyword(nme.VALkw, VAL) - enterKeyword(nme.VARkw, VAR) - enterKeyword(nme.WHILEkw, WHILE) - enterKeyword(nme.WITHkw, WITH) - enterKeyword(nme.YIELDkw, YIELD) - enterKeyword(nme.DOTkw, DOT) - enterKeyword(nme.USCOREkw, USCORE) - enterKeyword(nme.COLONkw, COLON) - enterKeyword(nme.EQUALSkw, EQUALS) - enterKeyword(nme.ARROWkw, ARROW) - enterKeyword(nme.LARROWkw, LARROW) - enterKeyword(nme.SUBTYPEkw, SUBTYPE) - enterKeyword(nme.VIEWBOUNDkw, VIEWBOUND) - enterKeyword(nme.SUPERTYPEkw, SUPERTYPE) - enterKeyword(nme.HASHkw, HASH) - enterKeyword(nme.ATkw, AT) - - // Build keyword array - key = new Array[byte](maxKey+1) - for (val i <- 0 to maxKey) - key(i) = IDENTIFIER - for (val j <- 0 until tokenCount) - if (tokenName(j) ne null) - key(tokenName(j).start) = j.asInstanceOf[byte] - - } - -// Token representation ----------------------------------------------------- - - /** Convert name to token */ - def name2token(name: Name): int = - if (name.start <= maxKey) key(name.start) else IDENTIFIER - - /** Returns the string representation of given token. */ - def token2string(token: int): String = token match { - case IDENTIFIER | BACKQUOTED_IDENT => - "identifier"/* + \""+name+"\""*/ - case CHARLIT => - "character literal" - case INTLIT => - "integer literal" - case LONGLIT => - "long literal" - case FLOATLIT => - "float literal" - case DOUBLELIT => - "double literal" - case STRINGLIT => - "string literal" - case SYMBOLLIT => - "symbol literal" - case LPAREN => - "'('" - case RPAREN => - "')'" - case LBRACE => - "'{'" - case RBRACE => - "'}'" - case LBRACKET => - "'['" - case RBRACKET => - "']'" - case EOF => - "eof" - case ERROR => - "something" - case SEMI => - "';'" - case NEWLINE => - "';'" - case NEWLINES => - "';'" - case COMMA => - "','" - case CASECLASS => - "case class" - case CASEOBJECT => - "case object" - case XMLSTART => - "$XMLSTART$<" - case _ => - try { - "'" + tokenName(token) + "'" - } catch { - case _: ArrayIndexOutOfBoundsException => - "'<" + token + ">'" - case _: NullPointerException => - "'<(" + token + ")>'" - } - } - override def toString() = token match { case IDENTIFIER | BACKQUOTED_IDENT => "id(" + name + ")" @@ -975,12 +1066,24 @@ trait Scanners requires SyntaxAnalyzer { case COMMA => "," case _ => - token2string(token) + configuration.token2string(token) } /** INIT: read lookahead character and token. */ - in.next - nextToken() + def init = { + in.next + nextToken + } + } + class UnitScanner(unit : CompilationUnit) extends Scanner with ScannerConfiguration { + override def configuration = this + val in = new CharArrayReader(unit.source.getContent(), !settings.nouescape.value, syntaxError) + 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 = pos.offset.get(-1) + implicit def g2p(pos : Int ) : Position = new OffsetPosition(unit.source, pos) } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index de28a75e64..ce5d39e43b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -21,7 +21,6 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser val global: Global import global._ - import RequiresIntsAsPositions._ import global.posAssigner.atPos //import scala.tools.scalac.ast.{TreeList => myTreeList} @@ -103,7 +102,7 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser * @todo map: a map of attributes !!! */ - protected def mkXML(pos: int, isPattern: boolean, pre: Tree, label: Tree, attrs: /*Array[*/Tree/*]*/ , scope:Tree, children: mutable.Buffer[Tree]): Tree = { + protected def mkXML(pos: Position, isPattern: boolean, pre: Tree, label: Tree, attrs: /*Array[*/Tree/*]*/ , scope:Tree, children: mutable.Buffer[Tree]): Tree = { if (isPattern) { convertToTextPat(children) atPos (pos) { //@todo maybe matching on attributes, scope? @@ -118,12 +117,12 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser } } - final def entityRef(pos: int, n: String) = { + final def entityRef(pos: Position, n: String) = { atPos(pos) { New( _scala_xml_EntityRef, LL(Literal(Constant( n )))) } }; // create scala.xml.Text here <: scala.xml.Node - final def text(pos: Int, txt:String): Tree = { + final def text(pos: Position, txt:String): Tree = { //makeText( isPattern, gen.mkStringLit( txt )) val txt1 = Literal(Constant(txt)) atPos(pos) { @@ -141,15 +140,15 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser New(_scala_xml_Text, LL(txt)) // create - def comment(pos: int, text: String): Tree = + def comment(pos: Position, text: String): Tree = atPos(pos) { Comment( Literal(Constant(text))) } // create - def charData(pos: int, txt: String): Tree = + def charData(pos: Position, txt: String): Tree = atPos(pos) { makeText1(Literal(Constant(txt))) }; //{ CharData( Literal(Constant(txt))) }; // create scala.xml.Text here <: scala.xml.Node - def procInstr( pos: int, target: String, txt: String ) = + def procInstr( pos: Position, target: String, txt: String ) = atPos(pos) { ProcInstr(Literal(Constant(target)), Literal(Constant(txt))) } protected def Comment(txt: Tree) = New(_scala_xml_Comment, LL(txt)) @@ -158,7 +157,7 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser New(_scala_xml_ProcInstr, LL(target, txt)) /** @todo: attributes */ - def makeXMLpat(pos: int, n: String, args: mutable.Buffer[Tree]): Tree = { + def makeXMLpat(pos: Position, n: String, args: mutable.Buffer[Tree]): Tree = { val (prepat, labpat) = n.indexOf(':') match { case -1 => (Ident(nme.WILDCARD), Literal(Constant(n))) //case 0 => // is erroneous, but cannot happen @@ -180,7 +179,7 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser case _ => t } - def parseAttribute(pos: Int, s: String): Tree = { + def parseAttribute(pos: Position, s: String): Tree = { val ns = xml.Utility.parseAttributeValue(s) val ts:collection.mutable.ListBuffer[Tree] = new collection.mutable.ListBuffer val it = ns.elements @@ -213,7 +212,7 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser case _ => false } - def makeXMLseq( pos:int, args:mutable.Buffer[Tree] ) = { + def makeXMLseq(pos: Position, args:mutable.Buffer[Tree] ) = { var _buffer = New( _scala_xml_NodeBuffer, List(Nil)) val it = args.elements while (it.hasNext) { @@ -231,18 +230,18 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser if (i != -1) Some(name.substring(0, i)) else None } - def group(pos: int, args: mutable.Buffer[Tree]): Tree = { + def group(pos: Position, args: mutable.Buffer[Tree]): Tree = { atPos(pos) { New( _scala_xml_Group, LL( makeXMLseq(pos, args))) } } /** code that constructs an unparsed node */ - def unparsed(pos: int, str: String): Tree = { + def unparsed(pos: Position, str: String): Tree = { atPos(pos) { New( _scala_xml_Unparsed, LL( Literal(Constant(str)))) } } /** makes an element */ - def element(pos: int, qname: String, attrMap: mutable.Map[String,Tree], args: mutable.Buffer[Tree]): Tree = { + def element(pos: Position, qname: String, attrMap: mutable.Map[String,Tree], args: mutable.Buffer[Tree]): Tree = { //Console.println("SymbolicXMLBuilder::element("+pos+","+qname+","+attrMap+","+args+")"); var setNS = new mutable.HashMap[String, Tree] diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala index 2a2374164f..7d5c95cb71 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala @@ -17,7 +17,7 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse class ParserPhase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) { def apply(unit: global.CompilationUnit): unit = { global.informProgress("parsing " + unit) - unit.body = new Parser(unit).parse() + unit.body = new UnitParser(unit).parse() } } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index 0aed4e8eae..914f92ee8b 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -97,4 +97,14 @@ object Tokens { /** XML mode */ final val XMLSTART = 96 + + /** for IDE only */ + final val LINE_COMMENT = 97 + final val COMMENT_START = 98 + final val COMMENT_END = 99 + final val DOC_START = 100 + final val DOUBLE_QUOTE = 101 + final val BACK_QUOTE = 102 + final val MULTI_QUOTE = 103 + final val EMPTY_STRING = 104 } diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index e1b72f557d..63e368480d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -5,6 +5,7 @@ // $Id$ package scala.tools.nsc.ast.parser +import scala.tools.nsc.util.Position import symtab.Flags._ import scala.collection.mutable.ListBuffer @@ -13,7 +14,6 @@ abstract class TreeBuilder { val global: Global import global._ - import RequiresIntsAsPositions._; import posAssigner.atPos; def freshName(prefix: String): Name @@ -184,7 +184,7 @@ abstract class TreeBuilder { else Block(stats.init, stats.last) /** Create tree for for-comprehension generator <val pat0 <- rhs0> */ - def makeGenerator(pos: int, pat: Tree, valeq: boolean, rhs: Tree): Enumerator = { + def makeGenerator(pos: Position, pat: Tree, valeq: boolean, rhs: Tree): Enumerator = { val pat1 = patvarTransformer.transform(pat); val rhs1 = if (valeq) rhs @@ -212,8 +212,8 @@ abstract class TreeBuilder { ValDef(Modifiers(PARAM | SYNTHETIC), pname, TypeTree(), EmptyTree) abstract class Enumerator - case class ValFrom(pos: int, pat: Tree, rhs: Tree) extends Enumerator - case class ValEq(pos: int, pat: Tree, rhs: Tree) extends Enumerator + case class ValFrom(pos: Position, pat: Tree, rhs: Tree) extends Enumerator + case class ValEq(pos: Position, pat: Tree, rhs: Tree) extends Enumerator case class Filter(test: Tree) extends Enumerator /** Create tree for for-comprehension <for (enums) do body> or diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index 2704345841..ac96121d78 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -10,7 +10,7 @@ package scala.tools.nsc.backend.icode import compat.StringBuilder import scala.tools.nsc.ast._ import scala.collection.mutable.{Map, Set, LinkedHashSet} -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} import scala.tools.nsc.backend.icode.analysis.ProgramPoint trait BasicBlocks requires ICodes { @@ -301,9 +301,9 @@ trait BasicBlocks requires ICodes { if (!instructionList.isEmpty) emit(instr, instructionList.head.pos) else - emit(instr, Position.NOPOS) + emit(instr, NoPosition) - def emit(instr: Instruction, pos: Int) = { + def emit(instr: Instruction, pos: Position) = { if (closed) { print() Console.println("trying to emit: " + instr) diff --git a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala index 0bd4de0e10..97f42e12a8 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala @@ -564,7 +564,7 @@ abstract class Checkers { printed = printed + 1 }); buf foreach Console.println - Console.println("at: " + clasz.cunit.position(buf.head.pos)) + Console.println("at: " + (buf.head.pos)) } def error(msg: String, stack: TypeStack): Unit = diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 0a2e024a57..2325d27060 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -196,7 +196,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: " + unit.position(tree.pos).line) + log("at line: " + (tree.pos).line.map(.toString).get(tree.pos.toString)) /** * Generate code for primitive arithmetic operations. @@ -404,7 +404,7 @@ abstract class GenICode extends SubComponent { if (rhs == EmptyTree) { if (settings.debug.value) - log("Uninitialized variable " + tree + " at: " + unit.position(tree.pos)); + log("Uninitialized variable " + tree + " at: " + (tree.pos)); ctx.bb.emit(getZeroOf(local.kind)) } @@ -686,7 +686,7 @@ abstract class GenICode extends SubComponent { l case _ => abort("Unknown label target: " + sym + - " at: " + unit.position(fun.pos) + ": ctx: " + ctx) + " at: " + (fun.pos) + ": ctx: " + ctx) } } val ctx1 = genLoadLabelArguments(args, label, ctx) @@ -768,7 +768,7 @@ abstract class GenICode extends SubComponent { generatedType = scalaPrimitives.generatedKind(code) } else abort("Primitive operation not handled yet: " + sym.fullNameString + "(" + - fun.symbol.simpleName + ") " + " at: " + unit.position(tree.pos)); + fun.symbol.simpleName + ") " + " at: " + (tree.pos)); ctx1 } else { // normal method call if (settings.debug.value) @@ -827,7 +827,7 @@ abstract class GenICode extends SubComponent { assert(tree.symbol.isModule, "Selection of non-module from empty package: " + tree.toString() + " sym: " + tree.symbol + - " at: " + unit.position(tree.pos)) + " at: " + (tree.pos)) if (settings.debug.value) log("LOAD_MODULE from Select(<emptypackage>): " + tree.symbol); ctx.bb.emit(LOAD_MODULE(tree.symbol), tree.pos) @@ -944,7 +944,7 @@ abstract class GenICode extends SubComponent { case _ => abort("Invalid case statement in switch-like pattern match: " + - tree + " at: " + unit.position(tree.pos)) + tree + " at: " + (tree.pos)) } ctx1.bb.emit(SWITCH(tags.reverse map (x => List(x)), (default :: targets).reverse), tree.pos) @@ -955,7 +955,7 @@ abstract class GenICode extends SubComponent { case _ => abort("Unexpected tree in genLoad: " + tree + " at: " + - unit.position(tree.pos)) + (tree.pos)) } // emit conversion @@ -975,7 +975,7 @@ abstract class GenICode extends SubComponent { case _ => assert(from != UNIT, "Can't convert from UNIT to " + to + - tree + " at: " + unit.position(tree.pos)); + tree + " at: " + (tree.pos)); ctx.bb.emit(CALL_PRIMITIVE(Conversion(from, to)), tree.pos); } } else if (from == SCALA_ALL) { @@ -1401,8 +1401,8 @@ abstract class GenICode extends SubComponent { ctx.method.symbol.newVariable(l.pos, eqEqTempName).setFlag(Flags.SYNTHETIC) eqEqTempVar.setInfo(definitions.AnyRefClass.typeConstructor) val local = ctx.method.addLocal(new Local(eqEqTempVar, REFERENCE(definitions.AnyRefClass), false)) - local.start = unit.position(l.pos).line - local.end = unit.position(r.pos).line + local.start = (l.pos).line.get + local.end = (r.pos).line.get local } diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index 4cd6c6312f..db89fe4912 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -9,7 +9,7 @@ package scala.tools.nsc.backend.icode; import scala.tools.nsc.ast._; -import scala.tools.nsc.util.Position; +import scala.tools.nsc.util.{Position,NoPosition}; /* A pattern match @@ -75,7 +75,7 @@ trait Opcodes requires ICodes { def difference = produced-consumed; /** The corresponding position in the source file */ - var pos: Int = Position.NOPOS; + var pos: Position = NoPosition; /** Used by dead code elimination. */ var useful: Boolean = false diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 9c28ba880f..3d059f971b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -13,7 +13,7 @@ import java.nio.ByteBuffer import scala.collection.immutable.{Set, ListSet} import scala.collection.mutable.{Map, HashMap, HashSet} import scala.tools.nsc.symtab._ -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position, NoPosition} import ch.epfl.lamp.fjbg._ @@ -424,7 +424,7 @@ abstract class GenJVM extends SubComponent { if (outerField != NoSymbol) { log("Adding fake local to represent outer 'this' for closure " + clasz) val _this = new Local( - method.symbol.newVariable(NoPos, "this$"), toTypeKind(outerField.tpe), false) + method.symbol.newVariable(NoPosition, "this$"), toTypeKind(outerField.tpe), false) m.locals = m.locals ::: List(_this) computeLocalVarsIndex(m) // since we added a new local, we need to recompute indexes @@ -999,13 +999,17 @@ abstract class GenJVM extends SubComponent { } crtPC = jcode.getPC() + val crtLine = instr.pos.line.get(lastLineNr); + /* val crtLine = try { - clasz.cunit.position(instr.pos).line + (instr.pos).line.get } catch { - case _: Error => + case _: NoSuchElementException => log("Warning: wrong position in: " + method) lastLineNr } + */ + if (b.lastInstruction == instr) endPC(b) = jcode.getPC(); @@ -1033,7 +1037,7 @@ abstract class GenJVM extends SubComponent { * @param primitive ... * @param pos ... */ - def genPrimitive(primitive: Primitive, pos: Int): Unit = { + def genPrimitive(primitive: Primitive, pos: Position): Unit = { primitive match { case Negation(kind) => kind match { @@ -1169,7 +1173,7 @@ abstract class GenJVM extends SubComponent { log("Converting from: " + src + " to: " + dst); if (dst == BOOL) { Console.println("Illegal conversion at: " + clasz + - " at: " + method.sourceFile + ":" + Position.line(clasz.cunit.source, pos)); + " at: " + method.sourceFile + ":" + pos.line.get(-1)); } 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 98f0f4bdf4..1b5bd62ecd 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -489,7 +489,7 @@ abstract class GenMSIL extends SubComponent { } } - tBuilder.setPosition(iclass.cunit.position(sym.pos).line, iclass.cunit.source.file.name) + tBuilder.setPosition((sym.pos).line.get, iclass.cunit.source.file.name) if (isTopLevelModule(sym)) { if (settings.debug.value) @@ -1177,7 +1177,7 @@ abstract class GenMSIL extends SubComponent { needAdditionalRet = false - var currentLineNr = try { clasz.cunit.position(instr.pos).line } catch { + var currentLineNr = try { (instr.pos).line.get } catch { case _: Error => log("Warning: wrong position in: " + method) lastLineNr @@ -1579,7 +1579,7 @@ abstract class GenMSIL extends SubComponent { } // end genBlock - def genPrimitive(primitive: Primitive, pos: Int): Unit = { + def genPrimitive(primitive: Primitive, pos: Position): Unit = { primitive match { case Negation(kind) => kind match { @@ -1630,7 +1630,7 @@ abstract class GenMSIL extends SubComponent { case _ => Console.println("Illegal conversion at: " + clasz + " at: " + method.sourceFile + ":" + - Position.line(clasz.cunit.source, pos)) + pos.line.get) } case ArrayLength(_) => diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index a98bb82155..d99aa70966 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -14,7 +14,6 @@ import scala.tools.nsc.symtab._; */ abstract class Inliners extends SubComponent { import global._; - import RequiresIntsAsPositions._; import icodes._; import icodes.opcodes._; @@ -67,7 +66,7 @@ abstract class Inliners extends SubComponent { callee: IMethod): Unit = { log("Inlining " + callee + " in " + caller + " at pos: " + (try { - classes(caller.symbol.owner).cunit.position(instr.pos).toString + instr.pos.offset.get } catch { case _ => "<nopos>" })); diff --git a/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala b/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala index 1cf4914081..bb10ec205a 100644 --- a/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala +++ b/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala @@ -232,7 +232,7 @@ trait ModelExtractor { } }); } - def members0(f : Symbol => Boolean) = decls.pfilterKeys(e => f(e)).valueSet; + def members0(f : Symbol => Boolean) = decls.projection.filterKeys(f).valueSet; def members(c : Category) : Iterable[Member] = members0(c.f); object inherited extends jcl.LinkedHashMap[Symbol,List[Member]]() { override def default(tpe : Symbol) = Nil; diff --git a/src/compiler/scala/tools/nsc/doc/ModelFrames.scala b/src/compiler/scala/tools/nsc/doc/ModelFrames.scala index 392ea938f2..cd20387f00 100644 --- a/src/compiler/scala/tools/nsc/doc/ModelFrames.scala +++ b/src/compiler/scala/tools/nsc/doc/ModelFrames.scala @@ -324,7 +324,7 @@ trait ModelFrames extends ModelExtractor { out.close() } catch { case _ => - error("Resource file '" + base + "' not found") + System.err.println("Resource file '" + rsrcdir + base + "' not found") } } } diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala index 9926fbd915..a1cddb604c 100644 --- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala +++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala @@ -209,7 +209,7 @@ trait CodeFactory requires transform.ExplicitOuter { def GreaterThanOrEquals(left: Tree, right: Tree): Tree = Apply(Select(left, nme.GE), List(right)) - def ThrowMatchError(pos: PositionType, obj: Tree) = + def ThrowMatchError(pos: Position, obj: Tree) = atPos(pos) { Throw( New( diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 5431152f76..b0cae8edb7 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -519,7 +519,7 @@ trait ParallelMatching requires (transform.ExplicitOuter with PatternMatchers wi // ---------------------------------- helper functions that generate symbols, trees for type tests, pattern tests - def newVar(pos: PositionType, name: Name, tpe: Type)(implicit theOwner: Symbol): Symbol = { + def newVar(pos: Position, name: Name, tpe: Type)(implicit theOwner: Symbol): Symbol = { if(tpe eq null) assert(tpe ne null, "newVar("+name+", null)") val sym = theOwner.newVariable(pos, name) // careful: pos has special meaning sym.setFlag(symtab.Flags.TRANS_FLAG) @@ -527,7 +527,7 @@ trait ParallelMatching requires (transform.ExplicitOuter with PatternMatchers wi sym } - def newVar(pos: PositionType, tpe: Type)(implicit theOwner: Symbol): Symbol = + def newVar(pos: Position, tpe: Type)(implicit theOwner: Symbol): Symbol = newVar(pos, cunit.fresh.newName("temp"), tpe).setFlag(symtab.Flags.SYNTHETIC) /** returns the condition in "if(cond) k1 else k2" diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala index c2537baa93..c160818c14 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.matching import compat.StringBuilder -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} /** This trait ... * @@ -74,36 +74,36 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes with P // factories - def pSequencePat(pos: PositionType, tpe: Type, len: int) = new SequencePat(newVar(FirstPos, tpe), len) set ((pos,tpe)) + def pSequencePat(pos: Position, tpe: Type, len: int) = new SequencePat(newVar(NoPosition, tpe), len) set ((pos,tpe)) - def pRightIgnoringSequencePat(pos: PositionType, tpe: Type, castedRest: Symbol, minlen: int) = - new RightIgnoringSequencePat(newVar(FirstPos, tpe), castedRest, minlen) set ((pos,tpe)) + def pRightIgnoringSequencePat(pos: Position, tpe: Type, castedRest: Symbol, minlen: int) = + new RightIgnoringSequencePat(newVar(NoPosition, tpe), castedRest, minlen) set ((pos,tpe)) - def pDefaultPat(pos: PositionType, tpe: Type) = new DefaultPat() set ((pos,tpe)) + def pDefaultPat(pos: Position, tpe: Type) = new DefaultPat() set ((pos,tpe)) - def pConstrPat(pos: PositionType, tpe: Type) = new ConstrPat(newVar(pos, tpe)) set ((pos,tpe)) + def pConstrPat(pos: Position, tpe: Type) = new ConstrPat(newVar(pos, tpe)) set ((pos,tpe)) - def pUnapplyPat(pos: PositionType, fn: Tree) = { + def pUnapplyPat(pos: Position, fn: Tree) = { var tpe = defs.unapplyUnwrap(fn.tpe) if(defs.isOptionOrSomeType(tpe)) { tpe = tpe.typeArgs.head } new UnapplyPat(newVar(pos, tpe), fn) set ((pos,tpe)) } - def pConstantPat(pos: PositionType, tpe: Type, value: Any) = new ConstantPat(value) set ((pos,tpe)) + def pConstantPat(pos: Position, tpe: Type, value: Any) = new ConstantPat(value) set ((pos,tpe)) - def pVariablePat(pos: PositionType, tree: Tree) = new VariablePat(tree) set ((pos,tree.tpe)) + def pVariablePat(pos: Position, tree: Tree) = new VariablePat(tree) set ((pos,tree.tpe)) - def pAltPat(pos: PositionType, header: Header) = new AltPat(header) set ((pos, header.tpe)) + def pAltPat(pos: Position, header: Header) = new AltPat(header) set ((pos, header.tpe)) - def pHeader(pos: PositionType, tpe: Type, selector: Tree) = new Header(selector, null) set ((pos,tpe)) + def pHeader(pos: Position, tpe: Type, selector: Tree) = new Header(selector, null) set ((pos,tpe)) - def pBody(pos: PositionType) = { + def pBody(pos: Position) = { val node = new Body(new Array[Array[ValDef]](0), new Array[Tree](0),new Array[Tree](0)) node.pos = pos node } - def pBody(pos: PositionType, bound: Array[ValDef], guard: Tree, body: Tree) = { + def pBody(pos: Position, bound: Array[ValDef], guard: Tree, body: Tree) = { val node = new Body(Array(bound), Array(guard), Array(body)) node.pos = pos node @@ -423,10 +423,10 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes with P type SelectorMap = collection.mutable.HashMap[(Symbol,Symbol),List[Symbol]] val selectorMap = new SelectorMap - private def newHeader(pos: PositionType, casted: Symbol, index: Int): Header = { + private def newHeader(pos: Position, casted: Symbol, index: Int): Header = { //Console.println("newHeader(pos,"+casted+" (has CASE flag? "+casted.tpe.symbol.hasFlag(Flags.CASE)+") of type "+casted.tpe+" with pos "+casted.pos+"(equals FIRSTPOS? "+(casted.pos == Position.FIRSTPOS)+"),"+index+")"); val ident = typed(Ident(casted)) - if (casted.pos == Position.FIRSTPOS) { // load the result of casted(i) + if (casted.pos == NoPosition) { // load the result of casted(i) //Console.println("FIRSTPOS"); val t = typed( Apply(Select(ident, ident.tpe.member(nme.apply)), diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala index 7f80ab47a7..cafefc0e16 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.matching import compat.StringBuilder -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position, NoPosition} trait PatternNodes requires transform.ExplicitOuter { @@ -44,7 +44,7 @@ trait PatternNodes requires transform.ExplicitOuter { /** Intermediate data structure for algebraic + pattern matcher */ sealed class PatternNode { - var pos = FirstPos + var pos : Position = NoPosition var tpe: Type = _ var or: PatternNode = _ var and: PatternNode = _ @@ -79,7 +79,7 @@ trait PatternNodes requires transform.ExplicitOuter { null } - def set(p:(PositionType,Type)): this.type = { /*assert(tpe ne null); */ this.pos = p._1; this.tpe = p._2; this } + def set(p:(Position,Type)): this.type = { /*assert(tpe ne null); */ this.pos = p._1; this.tpe = p._2; this } def dup(): PatternNode = { var res: PatternNode = this match { diff --git a/src/compiler/scala/tools/nsc/models/Models.scala b/src/compiler/scala/tools/nsc/models/Models.scala index 3c0d6ba889..553ea5f2a4 100644 --- a/src/compiler/scala/tools/nsc/models/Models.scala +++ b/src/compiler/scala/tools/nsc/models/Models.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.models import scala.tools.nsc.Global -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} /** This abstract class ... * @@ -331,7 +331,7 @@ abstract class Models { } else super.member(tree, members) def sym = tree0.symbol - if ((tree0 eq null) || tree0.pos == NoPos) null + if ((tree0 eq null) || tree0.pos == NoPosition) null else if (!acceptPrivate && tree0.isInstanceOf[ValOrDefDef] && tree.asInstanceOf[ValOrDefDef].mods.isPrivate) null diff --git a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala index 2584b0286e..fe2b4367a9 100644 --- a/src/compiler/scala/tools/nsc/models/SemanticTokens.scala +++ b/src/compiler/scala/tools/nsc/models/SemanticTokens.scala @@ -11,7 +11,7 @@ import java.lang.Character.isJavaIdentifierPart import scala.collection.mutable.{HashMap,HashSet} import scala.tools.nsc.Global import scala.tools.nsc.symtab.{Flags,Names} -import scala.tools.nsc.util.{NameTransformer,Position,SourceFile} +import scala.tools.nsc.util.{NameTransformer,Position,SourceFile,NoPosition} import scala.tools.nsc.symtab.Flags.DEFERRED class SemanticTokens(val compiler: Global) { @@ -39,11 +39,11 @@ class SemanticTokens(val compiler: Global) { if (keywords.isEmpty) pos else if (pos == source.content.length) - NoPos + -1 else if (source.beginsWith(pos, " ")) eatKeywords(source, pos + 1) else if (source.beginsWith(pos, keywords.head + " ")) - eatKeywords(source, pos + keywords.head.length() + 1) + eatKeywords(source, pos + keywords.head.length + 1) else eatKeyword(source, pos, keywords.tail) } @@ -52,7 +52,7 @@ class SemanticTokens(val compiler: Global) { val keywords = "package" :: "val" :: "var" :: "def" :: "class" :: "trait" :: "override" :: "case" :: "object" :: "sealed" :: "private" :: "protected" :: Nil - if (pos != NoPos) eatKeyword(source, pos, keywords) + if (pos != -1) eatKeyword(source, pos, keywords) else pos } @@ -131,13 +131,13 @@ class SemanticTokens(val compiler: Global) { def source = unit.source def dbg(tree : Tree) = { - def treePos : Int = if (tree ne null) tree.pos else -1; + def treePos : Position = if (tree ne null) tree.pos else NoPosition; ( "TREE=" + tree + (if (tree ne null) (" CLASS=" + tree.getClass()) else "") + " SYM=" + tree.symbol + " POS=" + - (new Position(source, treePos)).dbgString + treePos.dbgString )} val symbols = new HashMap[Symbol,Info]; @@ -200,14 +200,14 @@ class SemanticTokens(val compiler: Global) { for (val tree : T <- trees) build(tree) def build(tree0: Tree) : Unit = try { - /* if (tree0.pos != NoPos) */ tree0 match { + /* if (tree0.pos != NoPosition) */ tree0 match { case tree: ImplDef => - val pos = eatKeywords(unit.source, tree.pos) - if (pos == NoPos) { + val pos = eatKeywords(unit.source, tree.pos.offset.get) + if (pos == -1) { // inner types. // Console.err.println("NOPOS: " + tree.getClass() + " " + (new Position(unit.source, tree.pos)).dbgString); //Thread.dumpStack(); - } else buildDef(tree.symbol, eatKeywords(unit.source, tree.pos)); + } else buildDef(tree.symbol, eatKeywords(unit.source, tree.pos.offset.get)); tree match { case cdef: ClassDef => build(cdef.tparams) case _ => ; @@ -221,13 +221,13 @@ class SemanticTokens(val compiler: Global) { // Adding the condition thus keeps the old behavior. // todo: review whether this is correct, or whether abstract getters should be included. { - val pos : Int = if (tree.name.toString().equals("<init>")) NoPos else - eatKeywords(unit.source, tree.pos); + val pos : Int = if (tree.name.toString().equals("<init>")) -1 else + eatKeywords(unit.source, tree.pos.offset.get); if (false) Console.err.println("VALDEF: tree=" + tree + " sym=" + tree.symbol + " pos0=" + tree.symbol.pos + " alias=" + tree.symbol.alias + " pos1=" + - pos + " pos2=" + tree.pos + " " + unit.source.dbg(tree.pos) + " " + tree.symbol.hasFlag(Flags.SYNTHETIC)); + pos + " pos2=" + tree.pos.dbgString + " " + tree.symbol.hasFlag(Flags.SYNTHETIC)); - if (pos != NoPos && !tree.hasFlag(Flags.SYNTHETIC)) + if (pos != -1 && !tree.hasFlag(Flags.SYNTHETIC)) buildDef(tree.symbol, pos); } @@ -236,8 +236,8 @@ class SemanticTokens(val compiler: Global) { build(ddef.tparams); for (val l0 <- ddef.vparamss; val arg <- l0) { - val pos0 : Int = if (!unit.source.beginsWith(arg.pos, "val ")) arg.pos; - else unit.source.skipWhitespace(arg.pos + ("val ").length()); + 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()); buildDef(arg.symbol, pos0); build(arg.tpt); } @@ -261,22 +261,22 @@ class SemanticTokens(val compiler: Global) { case tree: PackageDef => //Console.err.println("PACKAGE: " + tree.name); if (false) { - val pos = eatKeywords(unit.source, tree.pos) - if (pos != NoPos) + val pos = eatKeywords(unit.source, tree.pos.offset.get(-1)) + if (pos != -1) buildDef(tree.symbol, pos) } build(tree.stats) case tree: Function => - for (val arg <- tree.vparams) if (arg.pos != NoPos) { + for (val arg <- tree.vparams) if (arg.pos != NoPosition) { val name = arg.name.toString().trim() val pos: Int = - if (unit.source.beginsWith(arg.pos, "val ")) - unit.source.skipWhitespace(arg.pos + ("val ").length()) - else if (unit.source.content(arg.pos) == ':') { - var posx : Int = arg.pos + if (unit.source.beginsWith(arg.pos.offset.get(-1), "val ")) + unit.source.skipWhitespace(arg.pos.offset.get(-1) + ("val ").length()) + else if (unit.source.content(arg.pos.offset.get) == ':') { + var posx : Int = arg.pos.offset.get while (unit.source.content(posx - 1).isWhitespace) posx = posx - 1 posx - name.length() - } else arg.pos + } else arg.pos.offset.get buildDef(arg.symbol, pos) build(arg.tpt) } @@ -291,19 +291,19 @@ class SemanticTokens(val compiler: Global) { if (false) Console.err.println("NO_ORIGINAL: " + tree + " " + tree.tpe + " " + classes(tree.tpe.getClass())); } if (tree.tpe ne null) buildT(tree1, tree.tpe); - def buildT( tree : Tree, tpe : Type) : Unit = if (tree.pos != NoPos) tpe match { + def buildT( tree : Tree, tpe : Type) : Unit = if (tree.pos != NoPosition) tpe match { case tpe0 : TypeRef => tree match { case apt : AppliedTypeTree => - buildUse(tpe.symbol, apt.tpt.pos, tpe0); + buildUse(tpe.symbol, apt.tpt.pos.offset.get(-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, tpe0); + case ident : Ident => buildUse(tpe0.sym, ident.pos.offset.get(-1), tpe0); case select : Select => if (select.symbol == NoSymbol) - if (false) Console.err.println("BUILD_SELECT: " + select + " @ " + tpe0 + " SYM=" + select.symbol + " " + unit.source.dbg(select.pos)); + if (false) Console.err.println("BUILD_SELECT: " + select + " @ " + tpe0 + " SYM=" + select.symbol + " " + (select.pos).dbgString); try { // build(select); buildUse(tpe0.symbol, selectPos(select), tpe0); @@ -311,32 +311,32 @@ class SemanticTokens(val compiler: Global) { buildT(select.qualifier, tpe0.prefix); } catch { case e : Error => - Console.err.println("BUILD_SELECT: " + select + " @ " + tpe0 + " " + unit.source.dbg(select.pos)); + Console.err.println("BUILD_SELECT: " + select + " @ " + tpe0 + " " + (select.pos).dbgString); throw e; } case tpt : TypeTree => if (tpt.symbol ne null) { - Console.err.println("SYM0 " + tpt.symbol + " " + unit.source.dbg(tpt.pos)); - buildUse(tpt.symbol, tpt.pos, tpe0); + Console.err.println("SYM0 " + tpt.symbol + " " + (tpt.pos).dbgString); + buildUse(tpt.symbol, tpt.pos.offset.get(-1), tpe0); } else if (tpe0.symbol ne null) { //Console.err.println("TYPE_SYM1 " + tpe0.symbol + " " + unit.source.dbg(tpt.pos)); - buildUse(tpe0.symbol, tpt.pos, tpe0); + buildUse(tpe0.symbol, tpt.pos.offset.get(-1), tpe0); } else { - Console.err.println("UNKNOWN TPT0: " + unit.source.dbg(tpt.pos) + " tpt=" + tpt + " " + tpt.symbol + " tpe0="+ tpe0 + " " + tpe0.symbol + " tpe0.args=" + tpe0.args); + Console.err.println("UNKNOWN TPT0: " + (tpt.pos).dbgString + " tpt=" + tpt + " " + tpt.symbol + " tpe0="+ tpe0 + " " + tpe0.symbol + " tpe0.args=" + tpe0.args); } case sft : SelectFromTypeTree => build(sft.qualifier); // XXX: broken if (false) Console.err.println("SFTT: " + sft + " sym=" + sft.symbol + " selector=" + sft.selector + " qual=" + sft.qualifier + " qual.sym=" + sft.qualifier.symbol + - " qual.pos=" + unit.source.dbg(sft.qualifier.pos) + " symbol=" + sft.symbol + " type=" + tpe0 + + " qual.pos=" + (sft.qualifier.pos).dbgString + " symbol=" + sft.symbol + " type=" + tpe0 + " type.sym=" + tpe0.symbol); - case _ => Console.err.println("UNKNOWN TPT2: " + tree + " vs. " + tpe0 + " " + tree.getClass() + " " + unit.source.content(tree.pos)); + case _ => Console.err.println("UNKNOWN TPT2: " + tree + " vs. " + tpe0 + " " + tree.getClass() + " " + (tree.pos).dbgString); } case tpe0 : MethodType => tree match { case tpt: TypeTree => if (tpt.original ne null) buildT(tpt.original, tpe); else { - Console.err.println("UNKNOWN TPT3: " + tree + " vs. " + tpe0 + " " + unit.source.content(tree.pos)); + Console.err.println("UNKNOWN TPT3: " + tree + " vs. " + tpe0 + " " + (tree.pos).dbgString); } case ident : Ident => buildT(ident, tpe0.resultType); case select : Select => buildT(select, tpe0.resultType); @@ -355,33 +355,33 @@ class SemanticTokens(val compiler: Global) { case stt : SingletonTypeTree => stt.ref match { case ths : This => build(ths); - case _ => Console.err.println("UNKNOWN TPE11: " + tpe0 + " " + stt + " " + stt.ref + " " + stt.ref.getClass() + " " + unit.source.dbg(tree.pos)); + case _ => Console.err.println("UNKNOWN TPE11: " + tpe0 + " " + stt + " " + stt.ref + " " + stt.ref.getClass() + " " + (tree.pos).dbgString); } case tt : This => case _ : Ident => case _ : Select => case tt : TypeTree => - if (false) Console.err.println("UNKNOWN TPE12: " + tpe0 + " " + tree + " " + tree.getClass() + " " + unit.source.dbg(tree.pos)); + if (false) Console.err.println("UNKNOWN TPE12: " + tpe0 + " " + tree + " " + tree.getClass() + " " + (tree.pos).dbgString); case _ => - if (false) Console.err.println("UNKNOWN TPE10: " + tpe0 + " " + tree + " " + tree.getClass() + " " + unit.source.dbg(tree.pos)); + 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, tpe0); + case ident : Ident => buildUse(tpe0.sym, ident.pos.offset.get(-1), tpe0); case select : Select => buildUse(tpe0.symbol, 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); buildT(select.qualifier, tpe0.prefix); case _ => - if (false) Console.err.println("UNKNOWN TPE8: " + tree + " " + unit.source.dbg(tree.pos) + " TPE=" + tpe0 + " PRE=" + tpe0.pre + " SYM=" + tpe0.sym); + if (false) Console.err.println("UNKNOWN TPE8: " + tree + " " + (tree.pos).dbgString + " TPE=" + tpe0 + " PRE=" + tpe0.pre + " SYM=" + tpe0.sym); } case ctype : ConstantType => - if (false) Console.err.println("UNKNOWN CONSTANT_TYPE: " + tree + " " + ctype + " " + unit.source.dbg(tree.pos)); + if (false) Console.err.println("UNKNOWN CONSTANT_TYPE: " + tree + " " + ctype + " " + (tree.pos).dbgString); case ErrorType => case _ => { - if (false) Console.err.println("UNKNOWN TPE4: " + tree + " " + tpe + " " + tpe.getClass() + " " + unit.source.dbg(tree.pos)); + if (false) Console.err.println("UNKNOWN TPE4: " + tree + " " + tpe + " " + tpe.getClass() + " " + (tree.pos).dbgString); } }; def buildTs(trees : List[Tree], types : List[Type]): Unit = if (!trees.isEmpty && !types.isEmpty) { @@ -392,53 +392,53 @@ class SemanticTokens(val compiler: Global) { Console.println("" + treex + " vs. " + treex.original); if (treex.original ne null) Console.println("" + treex.tpe + " vs. " + treex.original.tpe); - logError("Tree vs. Type mismatch: " + trees + " " + types + " " + unit.source.dbg(tree.pos), null); + logError("Tree vs. Type mismatch: " + trees + " " + types + " " + (tree.pos).dbgString, null); doLog = false; } }; case tree: AbsTypeDef => - //Console.err.println("ABS: " + tree.symbol + " " + unit.source.dbg(tree.namePos) + " " + unit.source.dbg(tree.pos)); + //Console.err.println("ABS: " + tree.symbol + " " + unit.source.dbg(tree.namePos) + " " + tree.pos.dbgString); buildDef(tree.symbol, tree.namePos) - buildDef(tree.symbol, tree.pos) + buildDef(tree.symbol, tree.pos.offset.get(-1)) build(tree.tparams); //@M build(tree.lo) build(tree.hi) case tree: Bind => - buildDef(tree.symbol, tree.pos) + buildDef(tree.symbol, tree.pos.offset.get(-1)) build(tree.body) case tree: Ident => - buildUse(tree.symbol, tree.pos, tree.tpe) + buildUse(tree.symbol, tree.pos.offset.get(-1), tree.tpe) case tree: Select => try { build(tree.qualifier) } catch { - case e : Error => Console.err.println("SELECTQ: " + tree + " " + tree.qualifier + " " + unit.source.dbg(tree.qualifier.pos)); throw e; + case e : Error => Console.err.println("SELECTQ: " + tree + " " + tree.qualifier + " " + (tree.qualifier.pos).dbgString); throw e; } try { - if (tree.pos >= unit.source.content.length) { - if (false) Console.err.println("BAD_SELECT_QUALIFIER " + tree + " @ " + unit.source.dbg(tree.pos)); + if (tree.pos.offset.get >= unit.source.content.length) { + if (false) Console.err.println("BAD_SELECT_QUALIFIER " + tree + " @ " + (tree.pos).dbgString); } else { - //Console.err.println("SELECT-0: " + tree.symbol + " " + unit.source.dbg(tree.pos) + " " + (tree.pos - selectPos(tree))); + //Console.err.println("SELECT-0: " + tree.symbol + " " + tree.pos.dbgString + " " + (tree.pos - selectPos(tree))); buildUse(tree.symbol, selectPos(tree), tree.tpe); } } catch { - case e : Error => Console.err.println("SELECTU: " + tree + " " + tree.symbol + " " + unit.source.dbg(tree.pos)); throw e; + case e : Error => Console.err.println("SELECTU: " + tree + " " + tree.symbol + " " + tree.pos.dbgString); throw e; } case tree: TypeApply => - //Console.err.println("TYPE_APPLY: " + tree + " " + unit.source.dbg(tree.pos)); + //Console.err.println("TYPE_APPLY: " + tree + " " + tree.pos.dbgString); if (!tree.args.isEmpty) { //Console.err.println("ARGS: " + unit.source.dbg(tree.args0.head.pos)); } build(tree.fun) build(tree.args) case tree: Apply => - //Console.err.println("NORM_APPLY: " + tree + " " + unit.source.dbg(tree.pos)); + //Console.err.println("NORM_APPLY: " + tree + " " + tree.pos.dbgString); build(tree.fun) build(tree.args) case tree: GenericApply => - //Console.err.println("GEN_APPLY: " + tree + " " + unit.source.dbg(tree.pos)); + //Console.err.println("GEN_APPLY: " + tree + " " + tree.pos.dbgString); build(tree.fun) build(tree.args) case tree: Typed => @@ -469,12 +469,12 @@ class SemanticTokens(val compiler: Global) { case tree : Try => build(tree.block); build(tree.catches); build(tree.finalizer); case tree : Alternative => build(tree.trees); case tree : This => - //Console.err.println("THIS: " + tree.symbol + " " + tree.qual + " " + unit.source.dbg(tree.pos) + " " + tree.tpe); - if (tree.symbol ne null) buildUse(tree.symbol, tree.pos, tree.tpe); + //Console.err.println("THIS: " + tree.symbol + " " + tree.qual + " " + tree.pos.dbgString + " " + tree.tpe); + if (tree.symbol ne null) buildUse(tree.symbol, tree.pos.offset.get(-1), tree.tpe); //Thread.dumpStack(); case tree : AliasTypeDef => //Console.err.println("ALIAS: " + tree); - build(tree.rhs); build(tree.tparams); buildDef(tree.symbol, tree.pos); + build(tree.rhs); build(tree.tparams); buildDef(tree.symbol, tree.pos.offset.get(-1)); case tree : DocDef => build(tree.definition); case tree: Import => build(tree.expr) case tree: AppliedTypeTree => ; @@ -484,11 +484,11 @@ class SemanticTokens(val compiler: Global) { case tree: Literal => ; case EmptyTree => ; case _ => ; - Console.err.println("BAIL: " + unit.source.dbg(tree0.pos) + " " + tree0 + " " + tree0.getClass()); + Console.err.println("BAIL: " + (tree0.pos) + " " + tree0 + " " + tree0.getClass()); } } catch { case t: Throwable => - logError("Error occured at " + unit.source.dbg(tree0.pos), t) + logError("Error occured at " + (tree0.pos), t) } def buildUse(term: Symbol, pos: Int, tpe: Type) = buildSym(term, pos, false, tpe) @@ -497,7 +497,7 @@ class SemanticTokens(val compiler: Global) { def buildSym(term: Symbol, pos: Int, isDef: Boolean, tpe: Type): Unit = if (term.hasFlag(Flags.ACCESSOR)) buildSym(analyzer.underlying(term), pos, isDef, tpe) - else if (pos == NoPos) { + else if (pos == -1) { //Console.err.println("NOPOS: " + term) //Thread.dumpStack() } @@ -528,9 +528,9 @@ class SemanticTokens(val compiler: Global) { } } - def selectPos(tree : Select): Int = if (tree.pos == NoPos) NoPos else { + def selectPos(tree : Select): Int = if (tree.pos == NoPosition) -1 else { val buf = unit.source.content - if (tree.pos >= buf.length) { + if (tree.pos.offset.get >= buf.length) { if (false) { Console.err.println("" + tree + "@" + tree.pos + " not in " + unit.source.file.name + "[" + buf.length + "]"); @@ -541,13 +541,13 @@ class SemanticTokens(val compiler: Global) { } val pos : Int = - if (buf(tree.pos) != '.') tree.pos + if (buf(tree.pos.offset.get) != '.') tree.pos.offset.get else { def f(x : Int) : Int = { if (buf(x).isWhitespace) f(x + 1) else x } - f(tree.pos + 1) + f(tree.pos.offset.get + 1) } pos }; @@ -597,8 +597,8 @@ class SemanticTokens(val compiler: Global) { sem.symbol.pos == tok.symbol.pos) return; if (false) { - Console.err.println("NOT_GAP: " + sem.symbol + " " + sem.symbol.getClass() + " " + unit.source.dbg(sem.symbol.pos) + " " + sem.symbol.flags); - Console.err.println("NOT_GAP: " + tok.symbol + " " + tok.symbol.getClass() + " " + unit.source.dbg(tok.symbol.pos) + " " + tok.symbol.flags); + Console.err.println("NOT_GAP: " + sem.symbol + " " + sem.symbol.getClass() + " " + (sem.symbol.pos).dbgString + " " + sem.symbol.flags); + Console.err.println("NOT_GAP: " + tok.symbol + " " + tok.symbol.getClass() + " " + (tok.symbol.pos).dbgString + " " + tok.symbol.flags); Console.err.println("LIST: " + this); Console.err.println("POS: " + unit.source.dbg(offset)); diff --git a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala index c1c6aee3a3..536cbe7e15 100644 --- a/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.reporters import scala.collection.mutable.HashSet -import nsc.util.Position +import scala.tools.nsc.util.Position import nsc.Settings /** diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala index 38bb1580b1..fe2678e93e 100644 --- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala @@ -7,16 +7,15 @@ package scala.tools.nsc.reporters import java.io.{BufferedReader, InputStreamReader, IOException, PrintWriter} +import util.{FakePos,Position} import compat.StringBuilder -import scala.tools.nsc.util.{FakePos, Position} /** * This class implements a Reporter that displays messages on a text * console. */ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: PrintWriter) extends AbstractReporter { - /** Whether a short file name should be displayed before errors */ var shortname: Boolean = false @@ -40,7 +39,7 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr * @return ... */ private def getCountString(severity: Severity): String = - countElementsAsString(count(severity), label(severity)) + countElementsAsString((severity).count, label(severity)) /** Prints the message. */ @@ -52,13 +51,12 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr val pos = posIn.inUltimateSource val buf = new StringBuilder(msg) buf.insert(0, " ") - if (pos.line != Position.NOLINE) - buf.insert(0, ":" + pos.line + ":") + buf.insert(0, pos.line.map(ln => ":" + pos.line.get + ":").get(":")) pos match { case FakePos(msg) => buf.insert(0, msg) - case _ => - val file = pos.source.file + case _ if !pos.source.isEmpty => + val file = pos.source.get.file buf.insert(0, if (shortname) file.name else file.path) } printMessage(buf.toString()) @@ -72,7 +70,7 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr /** * @param pos ... */ - def printSourceLine(pos: Position) = if ((pos ne null) && pos.offset != Position.NOPOS) { + def printSourceLine(pos: Position) = { printMessage(pos.lineContent.stripLineEnd) printColumnMarker(pos) } @@ -81,25 +79,25 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr * * @param pos ... */ - def printColumnMarker(pos: Position) = if (pos ne null) { - val buffer = new StringBuilder(pos.column) + def printColumnMarker(pos: Position) = if (!pos.column.isEmpty) { + val buffer = new StringBuilder(pos.column.get) var i = 1 - while (i < pos.column) { + while (i < pos.column.get) { buffer.append(' ') i = i + 1 } - if (pos.column > 0) buffer.append('^') + if (pos.column.get > 0) buffer.append('^') printMessage(buffer.toString()) } /** Prints the number of errors and warnings if their are non-zero. */ def printSummary() = { - if (warnings > 0) printMessage(getCountString(WARNING) + " found") - if ( errors > 0) printMessage(getCountString(ERROR ) + " found") + if (WARNING.count > 0) printMessage(getCountString(WARNING) + " found") + if ( ERROR.count > 0) printMessage(getCountString(ERROR ) + " found") } def display(pos: Position, msg: String, severity: Severity): Unit = { - incr(severity) + severity.count = severity.count + 1 print(pos, msg, severity) } diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala index 4981a7c9fa..d5ae69ca0c 100644 --- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala @@ -13,38 +13,28 @@ import scala.tools.nsc.util.Position * error messages. */ abstract class Reporter { - abstract class Severity(val code: Int) - object INFO extends Severity(0) - object WARNING extends Severity(1) - object ERROR extends Severity(2) + object severity extends Enumeration + abstract class Severity extends severity.Value { + var count : Int = 0 + } + object INFO extends Severity { def id = 0 } + object WARNING extends Severity { def id = 1 } + object ERROR extends Severity { def id = 2 } def reset: Unit = { - errors = 0 - warnings = 0 + INFO.count = 0 + ERROR.count = 0 + WARNING.count = 0 cancelled = false } - def count(severity: Severity): Int = severity match { - case ERROR => errors - case WARNING => warnings - case INFO => 0 - } - - def incr(severity: Severity): Unit = severity match { - case ERROR => errors = errors + 1 - case WARNING => warnings = warnings + 1 - case INFO => {} - } - - var errors : Int = 0 - var warnings : Int = 0 - var cancelled: boolean = false - def hasErrors: boolean = errors != 0 || cancelled + var cancelled: Boolean = false + def hasErrors: Boolean = ERROR.count != 0 || cancelled protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit - def info(pos: Position, msg: String, force: Boolean): Unit = info0(pos, msg, INFO , force) + def info(pos: Position, msg: String, force: Boolean): Unit = info0(pos, msg, INFO, force) def warning(pos: Position, msg: String ): Unit = info0(pos, msg, WARNING, false) def error(pos: Position, msg: String ): Unit = info0(pos, msg, ERROR, false) diff --git a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala index e4734fcee7..26453c7748 100644 --- a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala @@ -7,9 +7,8 @@ // $Id$ package scala.tools.nsc.reporters; -import scala.tools.nsc.util.Position; import scala.collection.mutable.HashSet; - +import scala.tools.nsc.util.Position import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; @@ -20,7 +19,6 @@ import java.io.PrintWriter; * console. */ class StoreReporter extends Reporter { - class Info(val pos: Position, val msg: String, val severity: Severity) { override def toString() = "pos: " + pos + " " + msg + " " + severity; } @@ -29,7 +27,7 @@ class StoreReporter extends Reporter { protected def info0(pos : Position, msg : String, severity : Severity, force : Boolean) : Unit = if (!force) { infos += new Info(pos, msg, severity); - incr(severity); + (severity).count = severity.count + 1 } override def reset = { super.reset; diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index a16837eae9..f8c55edf10 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.symtab import scala.collection.mutable.{HashMap, HashSet} -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position, NoPosition} import Flags._ trait Definitions { @@ -399,7 +399,7 @@ trait Definitions { } private def newClass(owner: Symbol, name: Name, parents: List[Type]): Symbol = { - val clazz = owner.newClass(NoPos, name.toTypeName) + val clazz = owner.newClass(NoPosition, name.toTypeName) clazz.setInfo(ClassInfoType(parents, newScope, clazz)) owner.info.decls.enter(clazz) clazz @@ -415,14 +415,14 @@ trait Definitions { } private def newAlias(owner: Symbol, name: Name, alias: Type): Symbol = { - val tpsym = owner.newAliasType(NoPos, name.toTypeName) + val tpsym = owner.newAliasType(NoPosition, name.toTypeName) tpsym.setInfo(alias) owner.info.decls.enter(tpsym) tpsym } private def newMethod(owner: Symbol, name: Name): Symbol = { - val msym = owner.newMethod(NoPos, name.encode) + val msym = owner.newMethod(NoPosition, name.encode) owner.info.decls.enter(msym) msym } @@ -440,7 +440,7 @@ trait Definitions { newMethod(owner, name).setInfo(PolyType(List(),restpe)) private def newTypeParam(owner: Symbol, index: int): Symbol = - owner.newTypeParameter(NoPos, "T" + index) + owner.newTypeParameter(NoPosition, "T" + index) .setInfo(mkTypeBounds(AllClass.typeConstructor, AnyClass.typeConstructor)) val boxedClass = new HashMap[Symbol, Symbol] @@ -492,7 +492,7 @@ trait Definitions { refClass(clazz) = getClass("scala.runtime." + name + "Ref") abbrvTag(clazz) = tag - val module = ScalaPackageClass.newModule(NoPos, name) + val module = ScalaPackageClass.newModule(NoPosition, name) ScalaPackageClass.info.decls.enter(module) val mclass = module.moduleClass mclass.setInfo(ClassInfoType(List(), newScope, mclass)) @@ -693,14 +693,14 @@ trait Definitions { if (isInitialized) return isInitialized = true RootClass = - NoSymbol.newClass(NoPos, nme.ROOT.toTypeName) + NoSymbol.newClass(NoPosition, nme.ROOT.toTypeName) .setFlag(FINAL | MODULE | PACKAGE | JAVA).setInfo(rootLoader) - RootPackage = NoSymbol.newValue(NoPos, nme.ROOTPKG) + RootPackage = NoSymbol.newValue(NoPosition, nme.ROOTPKG) .setFlag(FINAL | MODULE | PACKAGE | JAVA) .setInfo(PolyType(List(), RootClass.tpe)) EmptyPackage = - RootClass.newPackage(NoPos, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL) + RootClass.newPackage(NoPosition, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL) EmptyPackageClass = EmptyPackage.moduleClass EmptyPackageClass.setInfo(ClassInfoType(List(), newScope, EmptyPackageClass)) @@ -848,7 +848,7 @@ trait Definitions { String_+ = newMethod( StringClass, "+", anyparam, StringClass.typeConstructor) setFlag FINAL - PatternWildcard = NoSymbol.newValue(NoPos, "_").setInfo(AllClass.typeConstructor) + PatternWildcard = NoSymbol.newValue(NoPosition, "_").setInfo(AllClass.typeConstructor) BoxedNumberClass = if (forMSIL) null else getClass("scala.runtime.BoxedNumber") BoxedArrayClass = getClass("scala.runtime.BoxedArray") diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala index 3e8e7792ae..89d5060a88 100644 --- a/src/compiler/scala/tools/nsc/symtab/Flags.scala +++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala @@ -6,7 +6,8 @@ package scala.tools.nsc.symtab -object Flags { +object Flags extends Enumeration { + // modifiers final val IMPLICIT = 0x00000001 final val FINAL = 0x00000002 @@ -209,4 +210,36 @@ object Flags { def isVariable = (mods & MUTABLE) != 0 def isPublic = !isPrivate && !isProtected } + case class FlagEnum(mask : Int) extends Val(maskToBit(mask), flagToString(mask)); + + val Implicit = FlagEnum(IMPLICIT) + val Final = FlagEnum(FINAL) + val Private = FlagEnum(PRIVATE) + val Protected= FlagEnum(PROTECTED) + val Sealed = FlagEnum(SEALED) + val Override = FlagEnum(OVERRIDE) + val Case = FlagEnum(CASE) + val Abstract = FlagEnum(ABSTRACT) + val Deferred = FlagEnum(DEFERRED) + val Method = FlagEnum(METHOD) + val Module = FlagEnum(MODULE) + val Interface= FlagEnum(INTERFACE) + val Mutable = FlagEnum(MUTABLE) + val Param = FlagEnum(PARAM) + val Package = FlagEnum(PACKAGE) + val Deprecated=FlagEnum(DEPRECATED) + val Covariant=FlagEnum(COVARIANT) + val Contravariant=FlagEnum(CONTRAVARIANT) + val AbsOverride=FlagEnum(ABSOVERRIDE) + val Local=FlagEnum(LOCAL) + val Synthetic=FlagEnum(SYNTHETIC) + val Stable=FlagEnum(STABLE) + val CaseAccessor=FlagEnum(CASEACCESSOR) + val Trait=FlagEnum(TRAIT) + val Bridge=FlagEnum(BRIDGE) + val Accessor=FlagEnum(ACCESSOR) + val SuperAccessor=FlagEnum(SUPERACCESSOR) + val ParamAccessor=FlagEnum(PARAMACCESSOR) + val ModuleVar=FlagEnum(MODULEVAR) + } diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 25fc9448d3..384324d2e2 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -10,7 +10,7 @@ import compat.Platform.currentTime import java.io.{File, IOException} import scala.collection.mutable.{HashMap, HashSet} import scala.tools.nsc.io.AbstractFile -import scala.tools.nsc.util.{ClassPath, NameTransformer, Position} +import scala.tools.nsc.util.{ClassPath, NameTransformer, Position, NoPosition} import classfile.{ClassfileParser, SymblfileParser} import Flags._ import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute}; @@ -101,7 +101,7 @@ abstract class SymbolLoaders { protected var root: Symbol = _ def enterPackage(name: String, completer: SymbolLoader): unit = { - val pkg = root.newPackage(NoPos, newTermName(name)) + val pkg = root.newPackage(NoPosition, newTermName(name)) pkg.moduleClass.setInfo(completer) pkg.setInfo(pkg.moduleClass.tpe) root.info.decls.enter(pkg) @@ -112,8 +112,8 @@ abstract class SymbolLoaders { val owner = if (root.isRoot) definitions.EmptyPackageClass else root val className = newTermName(name) assert(owner.info.decls.lookup(name) == NoSymbol, owner.fullNameString + "." + name) - val clazz = owner.newClass(NoPos, name.toTypeName) - val module = owner.newModule(NoPos, name) + val clazz = owner.newClass(NoPosition, name.toTypeName) + val module = owner.newModule(NoPosition, name) clazz.setInfo(completer) module.setInfo(completer) module.moduleClass.setInfo(moduleClassLoader) diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 9c93de816a..a00efde133 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.symtab import scala.tools.nsc.io.AbstractFile -import scala.tools.nsc.util.{Position, SourceFile} +import scala.tools.nsc.util.{Position, NoPosition, SourceFile} import Flags._ trait Symbols { @@ -23,18 +23,20 @@ trait Symbols { val emptySymbolArray = new Array[Symbol](0) val emptySymbolSet = Set.empty[Symbol] - type PositionType; - def NoPos : PositionType; - def FirstPos : PositionType; - implicit def coercePosToInt(pos : PositionType) : Int; - def coerceIntToPos(pos : Int) : PositionType; +/* + type Position; + def NoPos : Position; + def FirstPos : Position; + implicit def coercePosToInt(pos : Position) : Int; + def coerceIntToPos(pos : Int) : Position; object RequiresIntsAsPositions { implicit def coerceIntToPos0(pos: Int) = coerceIntToPos(pos) } + */ /** The class for all symbols */ - abstract class Symbol(initOwner: Symbol, initPos: PositionType, initName: Name) { + abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name) { var rawowner = initOwner var rawname = initName @@ -45,12 +47,12 @@ trait Symbols { var validTo: Period = NoPeriod def pos = rawpos - def setPos(pos: PositionType): this.type = { this.rawpos = pos; this } + def setPos(pos: Position): this.type = { this.rawpos = pos; this } def namePos(source: SourceFile) = { - val pos: Int = this.pos + val pos: Int = this.pos.offset.get(-1) val buf = source.content - if (pos == Position.NOPOS) Position.NOPOS + if (pos == -1) -1 else if (isTypeParameter) pos - name.length else if (isVariable || isMethod || isClass || isModule) { var ret = pos @@ -84,46 +86,46 @@ trait Symbols { // Creators ------------------------------------------------------------------- - final def newValue(pos: PositionType, name: Name) = + final def newValue(pos: Position, name: Name) = new TermSymbol(this, pos, name) - final def newVariable(pos: PositionType, name: Name) = + final def newVariable(pos: Position, name: Name) = newValue(pos, name).setFlag(MUTABLE) - final def newValueParameter(pos: PositionType, name: Name) = + final def newValueParameter(pos: Position, name: Name) = newValue(pos, name).setFlag(PARAM) - final def newLocalDummy(pos: PositionType) = + final def newLocalDummy(pos: Position) = newValue(pos, nme.LOCAL(this)).setInfo(NoType) - final def newMethod(pos: PositionType, name: Name) = + final def newMethod(pos: Position, name: Name) = newValue(pos, name).setFlag(METHOD) - final def newLabel(pos: PositionType, name: Name) = + final def newLabel(pos: Position, name: Name) = newMethod(pos, name).setFlag(LABEL) - final def newConstructor(pos: PositionType) = + final def newConstructor(pos: Position) = newMethod(pos, nme.CONSTRUCTOR) - final def newModule(pos: PositionType, name: Name, clazz: ClassSymbol) = + final def newModule(pos: Position, name: Name, clazz: ClassSymbol) = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) .setModuleClass(clazz) - final def newModule(pos: PositionType, name: Name) = { + final def newModule(pos: Position, name: Name) = { val m = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) m.setModuleClass(new ModuleClassSymbol(m)) } - final def newPackage(pos: PositionType, name: Name) = { + final def newPackage(pos: Position, name: Name) = { assert(name == nme.ROOT || isPackageClass) val m = newModule(pos, name).setFlag(JAVA | PACKAGE) m.moduleClass.setFlag(JAVA | PACKAGE) m } - final def newThisSym(pos: PositionType) = + final def newThisSym(pos: Position) = newValue(pos, nme.this_).setFlag(SYNTHETIC) final def newThisSkolem: Symbol = new ThisSkolem(owner, pos, name, this) .setFlag(SYNTHETIC | FINAL) - final def newImport(pos: PositionType) = + final def newImport(pos: Position) = newValue(pos, nme.IMPORT) final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol = newValue(alternatives.head.pos, alternatives.head.name) .setFlag(OVERLOADED) .setInfo(OverloadedType(pre, alternatives)) - final def newOuterAccessor(pos: PositionType) = { + final def newOuterAccessor(pos: Position) = { val sym = newMethod(pos, nme.OUTER) sym setFlag (STABLE | SYNTHETIC) if (isTrait) sym setFlag DEFERRED @@ -134,28 +136,28 @@ trait Symbols { final def newErrorValue(name: Name) = newValue(pos, name).setFlag(SYNTHETIC | IS_ERROR).setInfo(ErrorType) - final def newAliasType(pos: PositionType, name: Name) = + final def newAliasType(pos: Position, name: Name) = new TypeSymbol(this, pos, name) - final def newAbstractType(pos: PositionType, name: Name) = + final def newAbstractType(pos: Position, name: Name) = new TypeSymbol(this, pos, name).setFlag(DEFERRED) - final def newTypeParameter(pos: PositionType, name: Name) = + final def newTypeParameter(pos: Position, name: Name) = newAbstractType(pos, name).setFlag(PARAM) final def newTypeSkolem: Symbol = new TypeSkolem(owner, pos, name, this) .setFlag(flags) - final def newClass(pos: PositionType, name: Name) = + final def newClass(pos: Position, name: Name) = new ClassSymbol(this, pos, name) - final def newModuleClass(pos: PositionType, name: Name) = + final def newModuleClass(pos: Position, name: Name) = new ModuleClassSymbol(this, pos, name) - final def newAnonymousClass(pos: PositionType) = + final def newAnonymousClass(pos: Position) = newClass(pos, nme.ANON_CLASS_NAME.toTypeName) - final def newAnonymousFunctionClass(pos: PositionType) = { + final def newAnonymousFunctionClass(pos: Position) = { val anonfun = newClass(pos, nme.ANON_FUN_NAME.toTypeName) anonfun.attributes = AnnotationInfo(definitions.SerializableAttr.tpe, List(), List()) :: anonfun.attributes anonfun } - final def newRefinementClass(pos: PositionType) = + final def newRefinementClass(pos: Position) = newClass(pos, nme.REFINE_CLASS_NAME.toTypeName) final def newErrorClass(name: Name) = { val clazz = newClass(pos, name).setFlag(SYNTHETIC | IS_ERROR) @@ -1038,7 +1040,7 @@ trait Symbols { } /** A class for term symbols */ - class TermSymbol(initOwner: Symbol, initPos: PositionType, initName: Name) + class TermSymbol(initOwner: Symbol, initPos: Position, initName: Name) extends Symbol(initOwner, initPos, initName) { override def isTerm = true @@ -1080,7 +1082,7 @@ trait Symbols { } /** A class for module symbols */ - class ModuleSymbol(initOwner: Symbol, initPos: PositionType, initName: Name) + class ModuleSymbol(initOwner: Symbol, initPos: Position, initName: Name) extends TermSymbol(initOwner, initPos, initName) { private var flatname = nme.EMPTY @@ -1108,7 +1110,7 @@ trait Symbols { } /** A class for type parameters viewed from inside their scopes */ - class ThisSkolem(initOwner: Symbol, initPos: PositionType, + class ThisSkolem(initOwner: Symbol, initPos: Position, initName: Name, clazz: Symbol) extends TermSymbol(initOwner, initPos, initName) { override def deSkolemize = clazz @@ -1121,7 +1123,7 @@ trait Symbols { /** A class of type symbols. Alias and abstract types are direct instances * of this class. Classes are instances of a subclass. */ - class TypeSymbol(initOwner: Symbol, initPos: PositionType, initName: Name) + class TypeSymbol(initOwner: Symbol, initPos: Position, initName: Name) extends Symbol(initOwner, initPos, initName) { override def isType = true privateWithin = NoSymbol @@ -1184,7 +1186,7 @@ trait Symbols { } /** A class for type parameters viewed from inside their scopes */ - class TypeSkolem(initOwner: Symbol, initPos: PositionType, + class TypeSkolem(initOwner: Symbol, initPos: Position, initName: Name, typeParam: Symbol) extends TypeSymbol(initOwner, initPos, initName) { override def deSkolemize = typeParam @@ -1198,7 +1200,7 @@ trait Symbols { } /** A class for class symbols */ - class ClassSymbol(initOwner: Symbol, initPos: PositionType, initName: Name) + class ClassSymbol(initOwner: Symbol, initPos: Position, initName: Name) extends TypeSymbol(initOwner, initPos, initName) { /** The classfile from which this class was loaded. Maybe null. */ @@ -1287,7 +1289,7 @@ trait Symbols { * Note: Not all module classes are of this type; when unpickled, we get * plain class symbols! */ - class ModuleClassSymbol(owner: Symbol, pos: PositionType, name: Name) + class ModuleClassSymbol(owner: Symbol, pos: Position, name: Name) extends ClassSymbol(owner, pos, name) { private var module: Symbol = null def this(module: TermSymbol) = { @@ -1300,7 +1302,7 @@ trait Symbols { } /** An object repreesenting a missing symbol */ - object NoSymbol extends Symbol(null, NoPos, nme.NOSYMBOL) { + object NoSymbol extends Symbol(null, NoPosition, nme.NOSYMBOL) { setInfo(NoType) privateWithin = this override def setInfo(info: Type): this.type = { diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index c358188b38..3ad981a38d 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.symtab import compat.Platform.currentTime import scala.collection.mutable.{ListBuffer, HashMap} -import scala.tools.nsc.util.{HashSet, Position} +import scala.tools.nsc.util.{HashSet, Position, NoPosition} import Flags._ /* A standard type pattern match: @@ -1474,7 +1474,7 @@ A type's symbol should never be inspected directly. if (phase.erasedTypes) if (parents.isEmpty) ObjectClass.tpe else parents.head else { - val clazz = owner.newRefinementClass(NoPos) + val clazz = owner.newRefinementClass(NoPosition) val result = refinementOfClass(clazz, parents, decls) clazz.setInfo(result) result @@ -1894,7 +1894,7 @@ A type's symbol should never be inspected directly. def subst(sym: Symbol, from: List[Symbol], to: List[T]): Type = if (from.isEmpty) tp - else if (to.isEmpty && inIDE) throw new TypeError(NoPos, "type parameter list problem"); + else if (to.isEmpty && inIDE) throw new TypeError(NoPosition, "type parameter list problem"); else if (matches(from.head, sym)) toType(tp, to.head) else subst(sym, from.tail, to.tail) @@ -2920,8 +2920,8 @@ A type's symbol should never be inspected directly. // Errors and Diagnostics ----------------------------------------------------- /** An exception signalling a type error */ - class TypeError(val pos: PositionType, val msg: String) extends java.lang.Error(msg) { - def this(msg: String) = this(NoPos, msg) + class TypeError(val pos: Position, val msg: String) extends java.lang.Error(msg) { + def this(msg: String) = this(NoPosition, msg) } class NoCommonType(tps: List[Type]) extends java.lang.Error( diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 319ea13a35..35b86d9323 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -16,7 +16,7 @@ */ package scala.tools.nsc.symtab.classfile -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} import scala.tools.nsc.io.AbstractFile import scala.collection.mutable.{ListBuffer, ArrayBuffer} import scala.collection.immutable.{Map, ListMap} @@ -399,7 +399,7 @@ abstract class ClassfileParser { { //Console.println("adding constructor to " + clazz);//DEBUG instanceDefs.enter( - clazz.newConstructor(NoPos) + clazz.newConstructor(NoPosition) .setFlag(clazz.flags & ConstrFlags) .setInfo(MethodType(List(), clazz.tpe))) @@ -409,7 +409,7 @@ abstract class ClassfileParser { val value = instanceDefs.lookup(nme.value) if (value != NoSymbol) { instanceDefs.enter( - clazz.newConstructor(NoPos) + clazz.newConstructor(NoPosition) .setFlag(clazz.flags & ConstrFlags) .setInfo(MethodType(List(value.tpe.resultType), clazz.tpe))) } @@ -428,7 +428,7 @@ abstract class ClassfileParser { val name = pool.getName(in.nextChar) val info = pool.getType(in.nextChar) val sym = getOwner(jflags) - .newValue(NoPos, name).setFlag(sflags) + .newValue(NoPosition, name).setFlag(sflags) sym.setInfo(if ((jflags & JAVA_ACC_ENUM) == 0) info else mkConstantType(Constant(sym))) setPrivateWithin(sym, jflags) parseAttributes(sym, info) @@ -458,7 +458,7 @@ abstract class ClassfileParser { info = MethodType(formals, clazz.tpe) } val sym = getOwner(jflags) - .newMethod(NoPos, name).setFlag(sflags).setInfo(info) + .newMethod(NoPosition, name).setFlag(sflags).setInfo(info) setPrivateWithin(sym, jflags) parseAttributes(sym, info) getScope(jflags).enter(sym) @@ -505,9 +505,9 @@ abstract class ClassfileParser { } val name = fresh.newName("T_" + sym.name) val newtparam = - if (covariant) clazz.newAbstractType(NoPos, name) + if (covariant) clazz.newAbstractType(NoPosition, name) else { - val s = sym.newTypeParameter(NoPos, name) + val s = sym.newTypeParameter(NoPosition, name) newTParams += s s } @@ -564,7 +564,7 @@ abstract class ClassfileParser { index = index + 1 while (sig(index) != '>') { val tpname = subName(':'.==).toTypeName - val s = sym.newTypeParameter(NoPos, tpname) + val s = sym.newTypeParameter(NoPosition, tpname) tparams = tparams + tpname -> s val ts = new ListBuffer[Type] while (sig(index) == ':') { @@ -716,12 +716,12 @@ abstract class ClassfileParser { (jflags & (JAVA_ACC_PUBLIC | JAVA_ACC_PROTECTED)) != 0 && pool.getClassSymbol(outerIndex) == sym) { val innerAlias = getOwner(jflags) - .newAliasType(NoPos, pool.getName(nameIndex).toTypeName) + .newAliasType(NoPosition, pool.getName(nameIndex).toTypeName) .setInfo(pool.getClassSymbol(innerIndex).tpe) getScope(jflags).enter(innerAlias) if ((jflags & JAVA_ACC_STATIC) != 0) { - val innerVal = staticModule.newValue(NoPos, pool.getName(nameIndex).toTermName) + val innerVal = staticModule.newValue(NoPosition, pool.getName(nameIndex).toTermName) .setInfo(pool.getClassSymbol(innerIndex).linkedModuleOfClass.moduleClass.thisType) staticDefs.enter(innerVal) } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 320b9a6286..c03011f5ce 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -12,7 +12,7 @@ import scala.collection.mutable._ import scala.tools.nsc._ import scala.tools.nsc.backend.icode._ import scala.tools.nsc.io._ -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} import ClassfileConstants._ import Flags._ @@ -863,7 +863,7 @@ abstract class ICodeReader extends ClassfileParser { /** Return a fresh Local variable for the given index. */ def freshLocal(idx: Int, kind: TypeKind, isArg: Boolean) = { - val sym = method.symbol.newVariable(NoPos, "loc" + idx).setInfo(kind.toType); + val sym = method.symbol.newVariable(NoPosition, "loc" + idx).setInfo(kind.toType); val l = new Local(sym, kind, isArg) method.addLocal(l) l diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala index e68e6914f5..06e464bbaa 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/MetaParser.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.symtab.classfile import java.util.{StringTokenizer, NoSuchElementException} import scala.collection.mutable.ListBuffer -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} abstract class MetaParser{ @@ -66,7 +66,7 @@ abstract class MetaParser{ else if (token == "-") { nextToken(); Flags.CONTRAVARIANT } else 0; assert(token.startsWith("?")); - val sym = owner.newTypeParameter(NoPos, newTypeName(token)).setFlag(vflag) + val sym = owner.newTypeParameter(NoPosition, newTypeName(token)).setFlag(vflag) nextToken() val lo = if (token == ">") { nextToken(); parseType() } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index be95558b6b..84c0efe5aa 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.symtab.classfile import java.lang.{Float, Double} import scala.collection.mutable.HashMap -import scala.tools.nsc.util.{Position, ShowPickled} +import scala.tools.nsc.util.{Position, NoPosition, ShowPickled} import Flags._ import PickleFormat._ @@ -310,8 +310,8 @@ abstract class Pickler extends SubComponent { */ private def writeSymInfo(sym: Symbol): int = { var posOffset = 0 - if (sym.pos != Position.NOPOS && sym.owner.isClass) { - writeNat(sym.pos) + if (sym.pos != NoPosition && sym.owner.isClass && !sym.pos.offset.isEmpty) { + writeNat(sym.pos.offset.get) posOffset = PosOffset } writeRef(sym.name) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index 136a69f126..45e43db93e 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -6,7 +6,7 @@ package scala.tools.nsc.symtab.classfile -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} import scala.tools.util.UTF8Codec import java.lang.{Float, Double} @@ -23,7 +23,6 @@ import java.io.IOException abstract class UnPickler { val global: Global import global._ - import RequiresIntsAsPositions._; /** * @param bytes bytearray from which we unpickle @@ -156,11 +155,11 @@ abstract class UnPickler { case NONEsym => sym = NoSymbol case _ => - val unusedPos = { - if (tag > PosOffset) readNat(); - else Position.NOPOS + val unusedPos : Int = { + if (tag > PosOffset) readNat; + else -1 } - val pos : PositionType = if (true) FirstPos else unusedPos; + val pos : Position = NoPosition; val name = readNameRef() val owner = readSymbolRef() val flags = readNat() diff --git a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala index 067f495c55..13e02725bb 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala @@ -6,7 +6,7 @@ package scala.tools.nsc.symtab.clr; -import scala.tools.nsc.util.Position; +import scala.tools.nsc.util.{Position,NoPosition}; import scala.collection.mutable.{ListBuffer, Map, HashMap, Set, HashSet}; import java.util.{Arrays, Comparator, StringTokenizer}; @@ -190,7 +190,7 @@ abstract class CLRTypes { return assem; } } - global.reporter.error(new Position(null, Position.NOPOS), + global.reporter.error(NoPosition, "cannot find assembly " + name + "; use the -r option to specify its location"); throw new Error(); } diff --git a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala index b12f79898e..a750bf0301 100644 --- a/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/clr/TypeParser.scala @@ -6,7 +6,7 @@ package scala.tools.nsc.symtab.clr; -import scala.tools.nsc.util.Position; +import scala.tools.nsc.util.{Position,NoPosition}; import classfile.UnPickler; import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, _}; @@ -108,8 +108,8 @@ abstract class TypeParser { || ntype.IsInterface) ) { val loader = new loaders.MSILTypeLoader(ntype) - val nclazz = statics.newClass(NoPos, ntype.Name.toTypeName) - val nmodule = statics.newModule(NoPos, ntype.Name) + val nclazz = statics.newClass(NoPosition, ntype.Name.toTypeName) + val nmodule = statics.newModule(NoPosition, ntype.Name) nclazz.setInfo(loader) nmodule.setInfo(loader) staticDefs.enter(nclazz) @@ -128,7 +128,7 @@ abstract class TypeParser { ConstantType(getConstant(getCLRType(field.FieldType), field.getValue)) else getCLRType(field.FieldType); val owner = if (field.IsStatic()) statics else clazz; - val sym = owner.newValue(NoPos, name).setFlag(flags).setInfo(fieldType); + val sym = owner.newValue(NoPosition, name).setFlag(flags).setInfo(fieldType); // TODO: set private within!!! -> look at typechecker/Namers.scala (if (field.IsStatic()) staticDefs else instanceDefs).enter(sym); clrTypes.fields(sym) = field; @@ -159,7 +159,7 @@ abstract class TypeParser { val mtype: Type = if (gparamsLength == 0) PolyType(List(), propType) else methodType(getter, getter.ReturnType); val owner: Symbol = if (getter.IsStatic) statics else clazz; - val methodSym = owner.newMethod(NoPos, name).setFlag(flags).setInfo(mtype); + val methodSym = owner.newMethod(NoPosition, name).setFlag(flags).setInfo(mtype); methodSym.setFlag(Flags.ACCESSOR); (if (getter.IsStatic) staticDefs else instanceDefs).enter(methodSym) clrTypes.methods(methodSym) = getter; @@ -180,7 +180,7 @@ abstract class TypeParser { val flags = translateAttributes(setter); val mtype: Type = methodType(setter, definitions.UnitClass.tpe); val owner: Symbol = if (setter.IsStatic) statics else clazz; - val methodSym = owner.newMethod(NoPos, name).setFlag(flags).setInfo(mtype); + val methodSym = owner.newMethod(NoPosition, name).setFlag(flags).setInfo(mtype); methodSym.setFlag(Flags.ACCESSOR); (if (setter.IsStatic) staticDefs else instanceDefs).enter(methodSym); clrTypes.methods(methodSym) = setter; @@ -232,10 +232,10 @@ abstract class TypeParser { // create the box/unbox methods for value types if (typ.IsValueType) { - val box = statics.newMethod(NoPos, nme.box). + val box = statics.newMethod(NoPosition, nme.box). setInfo(MethodType(List(clazz.tpe), definitions.ObjectClass.tpe)); definitions.boxMethod(clazz) = box; - val unbox = statics.newMethod(NoPos, nme.unbox). + val unbox = statics.newMethod(NoPosition, nme.unbox). setInfo(MethodType(List(definitions.ObjectClass.tpe), clazz.tpe)); definitions.unboxMethod(clazz) = unbox; //Console.println(typ.FullName + " : " + parents); @@ -252,14 +252,14 @@ abstract class TypeParser { val flags = Flags.JAVA | Flags.FINAL; for (val cmpName <- ENUM_CMP_NAMES) { val enumCmpType: Type = JavaMethodType(List(clazz.tpe), definitions.BooleanClass.tpe); - val enumCmp: Symbol = clazz.newMethod(NoPos, cmpName); + val enumCmp: Symbol = clazz.newMethod(NoPosition, cmpName); enumCmp.setFlag(flags).setInfo(enumCmpType) instanceDefs.enter(enumCmp); } for (val bitLogName <- ENUM_BIT_LOG_NAMES) { val enumBitLogType = JavaMethodType(List(clazz.tpe), classInfo); - val enumBitLog = clazz.newMethod(NoPos, bitLogName); + val enumBitLog = clazz.newMethod(NoPosition, bitLogName); enumBitLog.setFlag(flags).setInfo(enumBitLogType); instanceDefs.enter(enumBitLog); } @@ -275,7 +275,7 @@ abstract class TypeParser { if (mtype == null) return; val flags = translateAttributes(method); val owner = if (method.IsStatic()) statics else clazz; - val methodSym = owner.newMethod(NoPos, getName(method)).setFlag(flags). + val methodSym = owner.newMethod(NoPosition, getName(method)).setFlag(flags). setInfo(mtype); (if (method.IsStatic()) staticDefs else instanceDefs).enter(methodSym); if (method.IsConstructor()) @@ -290,7 +290,7 @@ abstract class TypeParser { } private def createMethod(name: Name, flags: Long, mtype: Type, method: MethodInfo, statik: Boolean): Symbol = { - val methodSym: Symbol = (if (statik) statics else clazz).newMethod(NoPos, name); + val methodSym: Symbol = (if (statik) statics else clazz).newMethod(NoPosition, name); methodSym.setFlag(flags).setInfo(mtype); (if (statik) staticDefs else instanceDefs).enter(methodSym); if (method != null) diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 101fea6f23..ad0912cafc 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -48,7 +48,7 @@ abstract class CleanUp extends Transform { private def freshClassConstantMethName() = unit.fresh.newName("class$Method") private def freshClassConstantVarName() = unit.fresh.newName("class$Cache") - private def classConstantMethod(pos: PositionType, sig: String): Symbol = classConstantMeth.get(sig) match { + private def classConstantMethod(pos: Position, sig: String): Symbol = classConstantMeth.get(sig) match { case Some(meth) => meth case None => diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 38b46209c9..47f0ed2293 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -540,7 +540,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { sym1 + ":" + tpe1 + (if (sym1.owner == root) "" else sym1.locationString) + " and\n" + sym2 + ":" + tpe2 + - (if (sym2.owner == root) " at line " + Position.line(unit.source, sym2.pos) else sym2.locationString) + + (if (sym2.owner == root) " at line " + (sym2.pos).line.get else sym2.locationString) + "\nhave same type" + (if (tpe1 =:= tpe2) "" else " after erasure: " + atPhase(phase.next)(sym1.tpe))) sym1.setInfo(ErrorType) diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 6759e24e08..3ffffcf3bf 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -10,6 +10,7 @@ import symtab._ import Flags._ import util.TreeSet import scala.collection.mutable.{HashMap, ListBuffer} +import scala.tools.nsc.util.{Position, NoPosition} abstract class LambdaLift extends InfoTransform { import global._ @@ -306,7 +307,7 @@ abstract class LambdaLift extends InfoTransform { } } - private def addFreeArgs(pos: PositionType, sym: Symbol, args: List[Tree]) = { + private def addFreeArgs(pos: Position, sym: Symbol, args: List[Tree]) = { def freeArg(fv: Symbol) = atPos(pos)(proxyRef(fv)) val fvs = freeVars(sym).toList if (fvs.isEmpty) args else args ::: (fvs map freeArg) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 4e5da87e8a..f015344395 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -9,7 +9,7 @@ package scala.tools.nsc.transform import symtab._ import Flags._ import scala.collection.mutable.ListBuffer -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} abstract class Mixin extends InfoTransform { import global._ @@ -376,7 +376,7 @@ abstract class Mixin extends InfoTransform { * * @param pos ... */ - private def selfRef(pos: PositionType) = + private def selfRef(pos: Position) = gen.mkAttributedIdent(self) setPos pos /** Replace a super reference by this or the self parameter, depending @@ -419,7 +419,7 @@ abstract class Mixin extends InfoTransform { val newDefs = new ListBuffer[Tree] /** Attribute given tree and anchor at given position */ - def attributedDef(pos: PositionType, tree: Tree): Tree = { + def attributedDef(pos: Position, tree: Tree): Tree = { if (settings.debug.value) log("add new def to " + clazz + ": " + tree) localTyper.typed { atPos(pos) { tree } } } @@ -427,10 +427,10 @@ abstract class Mixin extends InfoTransform { /** The position of given symbol, or, if this is undefined, * the position of the current class. */ def position(sym: Symbol) = - if (sym.pos == NoPos) clazz.pos else sym.pos + if (sym.pos == NoPosition) clazz.pos else sym.pos /** Add tree at given position as new definition */ - def addDef(pos: PositionType, tree: Tree): unit = + def addDef(pos: Position, tree: Tree): unit = newDefs += attributedDef(pos, tree) /** Add new method definition. diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 2148790c34..33a0c3f3a1 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -282,7 +282,7 @@ abstract class TailCalls extends Transform private def rewriteTailCall(fun: Tree, args: List[Tree]): Tree = { log("Rewriting tail recursive method call at: " + - unit.position(fun.pos)) + (fun.pos)) ctx.accessed = true typed(atPos(fun.pos)( Apply(Ident(ctx.label), args))) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 20bc433c2f..a9617225a6 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -8,6 +8,7 @@ package scala.tools.nsc.transform import symtab.Flags._ import scala.collection.mutable.{HashMap, HashSet} +import scala.tools.nsc.util.{Position} /*<export>*/ /** - uncurry all symbol and tree types (@see UnCurryPhase) @@ -286,7 +287,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { } } - def transformArgs(pos: PositionType, args: List[Tree], formals: List[Type]) = { + def transformArgs(pos: Position, args: List[Tree], formals: List[Type]) = { if (formals.isEmpty) { assert(args.isEmpty); List() } else { @@ -415,7 +416,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { case Try(block, catches, finalizer) => if (needTryLift) { if (settings.debug.value) - log("lifting try at: " + unit.position(tree.pos)); + log("lifting try at: " + (tree.pos)); val sym = currentOwner.newMethod(tree.pos, unit.fresh.newName("liftedTry")); sym.setInfo(MethodType(List(), tree.tpe)); diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 6943c78226..a4990fc865 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.typechecker import symtab.Flags._ -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position,NoPosition} /** This trait ... * @@ -42,7 +42,7 @@ trait Contexts requires Analyzer { val qual = gen.mkAttributedStableRef(pkg) sc = sc.makeNewImport( Import(qual, List((nme.WILDCARD, null))) - .setSymbol(NoSymbol.newImport(NoPos).setFlag(SYNTHETIC).setInfo(ImportType(qual))) + .setSymbol(NoSymbol.newImport(NoPosition).setFlag(SYNTHETIC).setInfo(ImportType(qual))) .setType(NoType)) sc.depth = sc.depth + 1 } @@ -253,7 +253,7 @@ trait Contexts requires Analyzer { c } - def error(pos: Int, err: Error) { + def error(pos: Position, err: Error) { val msg = err.getMessage() if (reportGeneralErrors) unit.error(pos, if (checking) "**** ERROR DURING INTERNAL CHECKING ****\n" + msg else msg) @@ -261,14 +261,14 @@ trait Contexts requires Analyzer { throw err } - def error(pos: PositionType, msg: String) { + def error(pos: Position, msg: String) { if (reportGeneralErrors) unit.error(pos, if (checking) "**** ERROR DURING INTERNAL CHECKING ****\n" + msg else msg) else throw new TypeError(pos, msg) } - def warning(pos: PositionType, msg: String) { + def warning(pos: Position, msg: String) { if (reportGeneralErrors) unit.warning(pos, msg) } @@ -279,7 +279,7 @@ trait Contexts requires Analyzer { * @param sym2 ... * @param rest ... */ - def ambiguousError(pos: PositionType, pre: Type, sym1: Symbol, + def ambiguousError(pos: Position, pre: Type, sym1: Symbol, sym2: Symbol, rest: String): unit = { val msg = ("ambiguous reference to overloaded definition,\n" + diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index a0ee58feab..af34a088df 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -5,7 +5,7 @@ // $Id$ package scala.tools.nsc.typechecker - +import scala.tools.nsc.util.{Position, NoPosition} import scala.collection.mutable.ListBuffer import symtab.Flags._ @@ -55,7 +55,7 @@ trait Infer requires Analyzer { List(if (actuals.length == 0) UnitClass.tpe else tupleType(actuals)) else actuals - def actualArgs(pos: PositionType, actuals: List[Tree], nformals: int): List[Tree] = + def actualArgs(pos: Position, actuals: List[Tree], nformals: int): List[Tree] = if (nformals == 1 && actuals.length != 1) List(atPos(pos)(gen.mkTuple(actuals))) else actuals /** A fresh type varable with given type parameter as origin. @@ -257,7 +257,7 @@ trait Infer requires Analyzer { "\n possible cause: missing arguments for method or constructor" else "") - def error(pos: PositionType, msg: String): unit = + def error(pos: Position, msg: String): unit = context.error(pos, msg) def errorTree(tree: Tree, msg: String): Tree = { @@ -265,7 +265,7 @@ trait Infer requires Analyzer { setError(tree) } - def typeError(pos: PositionType, found: Type, req: Type) { + def typeError(pos: Position, found: Type, req: Type) { if (!found.isErroneous && !req.isErroneous) { error(pos, typeErrorMsg(found, req)) if (settings.explaintypes.value) explainTypes(found, req) @@ -594,7 +594,7 @@ trait Infer requires Analyzer { } /** error if arguments not within bounds. */ - def checkBounds(pos: PositionType, pre: Type, owner: Symbol, + def checkBounds(pos: Position, pre: Type, owner: Symbol, tparams: List[Symbol], targs: List[Type], prefix: String) = { //@M validate variances & bounds of targs wrt variances & bounds of tparams //@M TODO: better place to check this? @@ -897,7 +897,7 @@ trait Infer requires Analyzer { } } - def checkCheckable(pos: PositionType, tp: Type): unit = { + def checkCheckable(pos: Position, tp: Type): unit = { def patternWarning(tp: Type, prefix: String) = context.unit.uncheckedWarning(pos, prefix+tp+" in type pattern is unchecked since it is eliminated by erasure") def isLocalBinding(sym: Symbol) = @@ -954,7 +954,7 @@ trait Infer requires Analyzer { } } - def inferTypedPattern(pos: PositionType, pattp: Type, pt: Type): Type = { + def inferTypedPattern(pos: Position, pattp: Type, pt: Type): Type = { checkCheckable(pos, pattp) if (!(pattp <:< pt)) { val tpparams = freeTypeParamsOfTerms.collect(pattp) @@ -1049,7 +1049,7 @@ trait Infer requires Analyzer { /* -- Overload Resolution ---------------------------------------------- */ - def checkNotShadowed(pos: PositionType, pre: Type, best: Symbol, eligible: List[Symbol]) = + def checkNotShadowed(pos: Position, pre: Type, best: Symbol, eligible: List[Symbol]) = if (!phase.erasedTypes) for (val alt <- eligible) { if (alt.owner != best.owner && alt.owner.isSubClass(best.owner)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 969ab1cce2..9adfbe07fc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -65,7 +65,7 @@ trait Namers requires Analyzer { sym } - def updatePosFlags(sym: Symbol, pos: PositionType, flags: long): Symbol = { + def updatePosFlags(sym: Symbol, pos: Position, flags: long): Symbol = { if (settings.debug.value) log("overwriting " + sym) val lockedFlag = sym.flags & LOCKED sym.reset(NoType) @@ -114,7 +114,7 @@ trait Namers requires Analyzer { innerNamer } - private def doubleDefError(pos: PositionType, sym: Symbol): unit = + private def doubleDefError(pos: Position, sym: Symbol): unit = context.error(pos, sym.name.toString() + " is already defined as " + (if (sym.hasFlag(CASE)) "case class " + sym.name else sym.toString())) @@ -135,7 +135,7 @@ trait Namers requires Analyzer { sym } - def enterPackageSymbol(pos: PositionType, name: Name): Symbol = { + def enterPackageSymbol(pos: Position, name: Name): Symbol = { val cscope = if (context.owner == EmptyPackageClass) RootClass.info.decls else context.scope val p: Symbol = cscope.lookup(name) @@ -154,7 +154,7 @@ trait Namers requires Analyzer { if (context.owner.isConstructor && !context.inConstructorSuffix) INCONSTRUCTOR else 0l - private def enterClassSymbol(pos: PositionType, flags: long, name: Name): Symbol = { + private def enterClassSymbol(pos: Position, flags: long, name: Name): Symbol = { var c: Symbol = context.scope.lookup(name) if (c.isType && !currentRun.compiles(c) && context.scope == c.owner.info.decls) { updatePosFlags(c, pos, flags) @@ -176,7 +176,7 @@ trait Namers requires Analyzer { c } - private def enterModuleSymbol(pos: PositionType, flags: long, name: Name): Symbol = { + private def enterModuleSymbol(pos: Position, flags: long, name: Name): Symbol = { var m: Symbol = context.scope.lookup(name) if (m.isModule && !m.isPackage && !currentRun.compiles(m) && (context.scope == m.owner.info.decls)) { @@ -196,7 +196,7 @@ trait Namers requires Analyzer { m } - private def enterCaseFactorySymbol(pos: PositionType, flags: long, name: Name): Symbol = { + private def enterCaseFactorySymbol(pos: Position, flags: long, name: Name): Symbol = { var m: Symbol = context.scope.lookup(name) if (m.isTerm && !m.isPackage && !currentRun.compiles(m) && context.scope == m.owner.info.decls) { updatePosFlags(m, pos, flags) @@ -677,7 +677,7 @@ trait Namers requires Analyzer { val expr1 = typer.typedQualifier(expr) val base = expr1.tpe typer.checkStable(expr1) - def checkNotRedundant(pos: PositionType, from: Name, to: Name): boolean = { + def checkNotRedundant(pos: Position, from: Name, to: Name): boolean = { if (!tree.symbol.hasFlag(SYNTHETIC) && !((expr1.symbol ne null) && expr1.symbol.isInterpreterWrapper) && base.member(from) != NoSymbol) { diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index cfb4c3e270..3d8c664ae6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -9,7 +9,7 @@ package scala.tools.nsc.typechecker import symtab.Flags._ import collection.mutable.HashMap import transform.InfoTransform - +import scala.tools.nsc.util.{Position, NoPosition} import compat.Math.MIN_INT /** <p> @@ -422,7 +422,7 @@ abstract class RefChecks extends InfoTransform { class LevelInfo(val outer: LevelInfo) { val scope: Scope = if (outer eq null) newScope else newScope(outer.scope) var maxindex: int = MIN_INT - var refpos: int = _ + var refpos: Position = _ var refsym: Symbol = _ } @@ -451,7 +451,7 @@ abstract class RefChecks extends InfoTransform { } } - private def enterReference(pos: int, sym: Symbol): unit = + private def enterReference(pos: Position, sym: Symbol): unit = if (sym.isLocal) { val e = currentLevel.scope.lookupEntry(sym.name) if ((e ne null) && sym == e.sym) { @@ -471,7 +471,7 @@ abstract class RefChecks extends InfoTransform { def apply(tp: Type) = mapOver(tp).normalize } - def checkSensible(pos: int, fn: Tree, args: List[Tree]) = fn match { + def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match { case Select(qual, name) if (args.length == 1) => def isNew(tree: Tree) = tree match { case Function(_, _) @@ -519,7 +519,7 @@ abstract class RefChecks extends InfoTransform { // Transformation ------------------------------------------------------------ /* Convert a reference to a case factory of type `tpe' to a new of the class it produces. */ - def toConstructor(pos: PositionType, tpe: Type): Tree = { + def toConstructor(pos: Position, tpe: Type): Tree = { var rtpe = tpe.finalResultType assert(rtpe.symbol hasFlag CASE, tpe); localTyper.typedOperator { diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 61bd300472..0b88b7e340 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -8,6 +8,7 @@ package scala.tools.nsc.typechecker import scala.collection.mutable.ListBuffer import nsc.symtab.Flags._ +import scala.tools.nsc.util.{Position} /** This phase adds super accessors for all super calls that * either appear in a trait or have as a target a member of some outer class. @@ -289,7 +290,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT * inherit anything. Since we can't (yet) add accessors for 'required' * classes, this has to be signaled as error. */ - private def needsProtectedAccessor(sym: Symbol, pos: PositionType): Boolean = { + private def needsProtectedAccessor(sym: Symbol, pos: Position): Boolean = { val res = /* settings.debug.value && */ ((sym hasFlag PROTECTED) && (!validCurrentOwner || !(currentOwner.enclClass.thisSym isSubClass sym.owner)) diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index 2cceae8059..88e630705a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.typechecker import scala.tools.nsc.reporters.AbstractReporter import scala.tools.nsc.symtab.Flags._ -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position, NoPosition} abstract class TreeCheckers extends Analyzer { @@ -99,7 +99,7 @@ abstract class TreeCheckers extends Analyzer { } case _ => } - if (tree.pos == NoPos && tree != EmptyTree) { + if (tree.pos == NoPosition && tree != EmptyTree) { error(tree.pos, "tree without position: " + tree) } else if ((tree.tpe eq null) && phase.id >= currentRun.typerPhase.id) { error(tree.pos, "tree without type: " + tree) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 38a7bcea62..cec250063a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -12,7 +12,7 @@ package scala.tools.nsc.typechecker import scala.collection.mutable.{HashMap, ListBuffer} import scala.compat.Platform.currentTime -import scala.tools.nsc.util.{HashSet, Position, Set} +import scala.tools.nsc.util.{HashSet, Position, Set, NoPosition} import symtab.Flags._ import util.HashSet @@ -144,7 +144,7 @@ trait Typers requires Analyzer { override def isCoercible(tp: Type, pt: Type): boolean = ( tp.isError || pt.isError || context0.implicitsEnabled && // this condition prevents chains of views - inferView(NoPos, tp, pt, false) != EmptyTree + inferView(NoPosition, tp, pt, false) != EmptyTree ) } @@ -155,7 +155,7 @@ trait Typers requires Analyzer { * @param reportAmbiguous ... * @return ... */ - private def inferView(pos: PositionType, from: Type, to: Type, reportAmbiguous: boolean): Tree = { + private def inferView(pos: Position, from: Type, to: Type, reportAmbiguous: boolean): Tree = { if (settings.debug.value) log("infer view from "+from+" to "+to)//debug if (phase.id > currentRun.typerPhase.id) EmptyTree else from match { @@ -180,7 +180,7 @@ trait Typers requires Analyzer { * @param reportAmbiguous ... * @return ... */ - private def inferView(pos: PositionType, from: Type, name: Name, tp: Type, reportAmbiguous: boolean): Tree = { + private def inferView(pos: Position, from: Type, name: Name, tp: Type, reportAmbiguous: boolean): Tree = { val to = refinedType(List(WildcardType), NoSymbol) val psym = (if (name.isTypeName) to.symbol.newAbstractType(pos, name) else to.symbol.newValue(pos, name)) setInfo tp @@ -205,9 +205,9 @@ trait Typers requires Analyzer { * @param pos0 The position where to report the error * @param ex The exception that caused the error */ - def reportTypeError(pos0: PositionType, ex: TypeError): unit = { + def reportTypeError(pos0: Position, ex: TypeError): unit = { if (settings.debug.value) ex.printStackTrace() - val pos = if (ex.pos == NoPos) pos0 else ex.pos + val pos = if (ex.pos == NoPosition) pos0 else ex.pos ex match { case CyclicReference(sym, info: TypeCompleter) => val msg = @@ -244,7 +244,7 @@ trait Typers requires Analyzer { * @param tp ... * @return <code>true</code> if <code>tp</code> is not a subtype of itself. */ - def checkNonCyclic(pos: PositionType, tp: Type): boolean = { + def checkNonCyclic(pos: Position, tp: Type): boolean = { def checkNotLocked(sym: Symbol): boolean = { sym.initialize if (sym hasFlag LOCKED) { @@ -271,7 +271,7 @@ trait Typers requires Analyzer { } } - def checkNonCyclic(pos: PositionType, tp: Type, lockedSym: Symbol): boolean = { + def checkNonCyclic(pos: Position, tp: Type, lockedSym: Symbol): boolean = { lockedSym.setFlag(LOCKED) val result = checkNonCyclic(pos, tp) lockedSym.resetFlag(LOCKED) @@ -288,7 +288,7 @@ trait Typers requires Analyzer { } } - def checkParamsConvertible(pos: PositionType, tpe: Type): unit = tpe match { + def checkParamsConvertible(pos: Position, tpe: Type): unit = tpe match { case MethodType(formals, restpe) => if (formals.exists(.symbol.==(ByNameParamClass)) && formals.length != 1) error(pos, "methods with `=>'-parameter can be converted to function values only if they take no other parameters") @@ -298,7 +298,7 @@ trait Typers requires Analyzer { case _ => } - def checkRegPatOK(pos: PositionType, mode: int): unit = + def checkRegPatOK(pos: Position, mode: int): unit = if ((mode & REGPATmode) == 0) { error(pos, "no regular expression pattern allowed here\n"+ "(regular expression patterns are only allowed in arguments to *-parameters)") @@ -644,7 +644,7 @@ trait Typers requires Analyzer { } catch { case tpe : TypeError => throw tpe case t : Throwable => - logError("CONTEXT: " + context.unit.source.dbg(tree.pos), t) + logError("CONTEXT: " + (tree.pos).dbgString, t) throw t } tree1 @@ -1395,7 +1395,7 @@ trait Typers requires Analyzer { val result = checkDead(localTyper.typed(stat)) if (treeInfo.isSelfOrSuperConstrCall(result)) { context.inConstructorSuffix = true - if (treeInfo.isSelfConstrCall(result) && result.symbol.pos >= exprOwner.enclMethod.pos) + if (treeInfo.isSelfConstrCall(result) && result.symbol.pos.offset.get(0) >= exprOwner.enclMethod.pos.offset.get(0)) error(stat.pos, "called constructor's definition must precede calling constructor's definition") } result @@ -1645,7 +1645,7 @@ trait Typers requires Analyzer { def typedAnnotation[T](annot: Annotation, reify: Tree => T): AnnotationInfo[T] = { var attrError: Boolean = false; - def error(pos: PositionType, msg: String): Null = { + def error(pos: Position, msg: String): Null = { context.error(pos, msg) attrError = true null @@ -2160,8 +2160,8 @@ trait Typers requires Analyzer { qual.tpe.widen+" does not have a constructor" else decode(name)+" is not a member of "+qual.tpe.widen + - (if (!inIDE && (context.unit ne null) && Position.line(context.unit.source, qual.pos) < - Position.line(context.unit.source, tree.pos)) + (if (!inIDE && (context.unit ne null) && (qual.pos).line.get < + tree.pos.line.get) "\npossible cause: maybe a semicolon is missing before `"+decode(name)+"'?" else "")) } @@ -2232,9 +2232,9 @@ trait Typers requires Analyzer { defEntry = cx.scope.lookupEntry(name) if (inIDE && (defEntry ne null) && defEntry.sym.exists) { val sym = defEntry.sym - val namePos : Int = tree.pos - val symPos : Int = sym.pos - if (namePos < symPos) defEntry = null + val namePos : Position = tree.pos + val symPos : Position = sym.pos + if (namePos.offset.get < symPos.offset.get) defEntry = null } if ((defEntry ne null) && qualifies(defEntry.sym)) { defSym = defEntry.sym @@ -2629,7 +2629,7 @@ trait Typers requires Analyzer { // Console.println("exception when typing "+tree+", pt = "+pt) if ((context ne null) && (context.unit ne null) && (context.unit.source ne null) && (tree ne null)) - logError("AT: " + context.unit.source.dbg(tree.pos), ex); + logError("AT: " + (tree.pos).dbgString, ex); throw(ex) } @@ -2739,7 +2739,7 @@ trait Typers requires Analyzer { * to <code>pt</code>, EmptyTree otherwise. * @pre <code>info.tpe</code> does not contain an error */ - private def typedImplicit(pos: PositionType, info: ImplicitInfo, pt: Type, isLocal: boolean): Tree = { + private def typedImplicit(pos: Position, info: ImplicitInfo, pt: Type, isLocal: boolean): Tree = { def isStable(tp: Type): boolean = tp match { case TypeRef(pre, sym, _) => sym.isPackageClass || sym.isModuleClass && isStable(pre) case _ => tp.isStable @@ -2780,7 +2780,7 @@ trait Typers requires Analyzer { * @return ... * @see <code>isCoercible</code> */ - private def inferImplicit(pos: PositionType, pt: Type, isView: boolean, reportAmbiguous: boolean): Tree = { + private def inferImplicit(pos: Position, pt: Type, isView: boolean, reportAmbiguous: boolean): Tree = { if (util.Statistics.enabled) implcnt = implcnt + 1 val startTime = if (util.Statistics.enabled) currentTime else 0l diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala index f11061e30d..101cf51121 100644 --- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala @@ -22,6 +22,9 @@ class CharArrayReader(buf: Array[char], start: int, /* startline: int, startcol: */ var ch: char = _ var bp = start + var oldBp = -1 + var oldCh : char = _ + //private var cline: int = _ //private var ccol: int = _ def cpos = bp @@ -51,6 +54,8 @@ class CharArrayReader(buf: Array[char], start: int, /* startline: int, startcol: //cline = nextline //ccol = nextcol if(!hasNext) return SU // there is an endless stream of SU's at the end + oldBp = bp + oldCh = ch; ch = buf(bp) isUnicode = false bp = bp + 1 @@ -91,6 +96,13 @@ class CharArrayReader(buf: Array[char], start: int, /* startline: int, startcol: // nextcol = nextcol + 1 } } + def rewind = { + if (oldBp == -1) throw new IllegalArgumentException + bp = oldBp + ch = oldCh + oldBp = -1 + oldCh = 'x' + } def copy: CharArrayReader = new CharArrayReader(buf, bp, /* nextcol, nextline, */ decodeUni, error) diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala index 70988b771c..b294dc8c4d 100644 --- a/src/compiler/scala/tools/nsc/util/Position.scala +++ b/src/compiler/scala/tools/nsc/util/Position.scala @@ -7,115 +7,75 @@ \* */ // $Id$ - - package scala.tools.nsc.util +object NoPosition extends Position { + def offset = None + def line = None + def column = None + def source = None +} +case class FakePos(msg : String) extends Position { + def offset = None + def line = None + def column = None + def source = None +} -import compat.StringBuilder - -/** This position uses offset in character buffer rather than line/column - * relationship. - * - * @author Sean McDirmid - * @version 1.0 - */ -object Position { - val NOPOS = -1 - val FIRSTPOS = 0 - val NOLINE = 0 - val FIRSTLINE = 1 - - def line(source : SourceFile, offset : Int) = - (new Position(source, offset)).line +abstract class Position { + def offset : Option[Int] + def line : Option[Int] + def column : Option[Int] + def source : Option[SourceFile] + def lineContent: String = + if (!line.isEmpty && !source.isEmpty) source.get.lineToString(line.get - 1) + else "NO_LINE" + /** Map this position to a position in an original source + * file. If the SourceFile is a normal SourceFile, simply + * return this. + */ + def inUltimateSource = if (!source.isEmpty) source.get.positionInUltimateSource(this) + else this - def lineToOffset(line : Int) = { - assert(line >= 1) - NOPOS - line + def dbgString = { + (if (source.isEmpty) "" else "source-" + source.get.path) + + (if (line.isEmpty) "" else "line-" + line.get) + + (if (offset.isEmpty || source.isEmpty) "" + else if (offset.get >= source.get.content.length) "out-of-bounds-" + offset.get + else { + val ret = "offset=" + offset.get; + var add = ""; + while (offset.get + add.length < source.get.content.length && + add.length < 10) add = add + source.get.content(offset.get + add.length()); + ret + " c[0..9]=\"" + add + "\""; + }) } - def offsetToLine(pos : Int) = { - assert(pos < NOPOS) - NOPOS - pos - } } - -class Position( val source : SourceFile, val offset: Int) { - import Position._ - +case class LinePosition(line0 : Int, val source : Option[SourceFile]) extends Position { + def this(line0 : Int) = this(line0, None) + assert(line0 >= 1) + def offset = None + def column = None + def line = Some(line0) +} +case class OffsetPosition(source0 : SourceFile, offset0 : Int) extends Position { private val tabInc = 8 - - //def this(sourceName : String) = this(new SourceFile(sourceName, new Array[Char](0)), Position.NOPOS); - //def this(sourceName : String, _offset : Int) = this(new SourceFile(sourceName, new Array[Char](0)), _offset); - - private def hasOffset = offset > NOPOS - private def isLine = offset < NOPOS - - def line: Int = - if (hasOffset) source.offsetToLine(offset) + FIRSTLINE - else if (isLine) Position.offsetToLine(offset) - else NOLINE - - // for display purposes only. - def column: Int = if (hasOffset) { + def source = Some(source0) + def offset = Some(offset0) + def line = Some(source0.offsetToLine(offset0) + 1) + def column = { var column = 1 - // find beginning offset for line - val line = source.offsetToLine(offset) - var coffset = source.lineToOffset(line) + val line = source0.offsetToLine(offset0) + var coffset = source0.lineToOffset(line) var continue = true while (continue) { - if (coffset == offset) continue = false - else if (source.content(coffset) == '\t') column = ((column - 1) / tabInc * tabInc) + tabInc + 1; - else column = column + 1; + if (coffset == offset.get(-1)) continue = false + else if (source0.content(coffset) == '\t') column = ((column - 1) / tabInc * tabInc) + tabInc + 1 + else column = column + 1 coffset = coffset + 1 } - column - } else 0 - - /** Map this position to a position in an original source - * file. If the SourceFile is a normal SourceFile, simply - * return this. - */ - def inUltimateSource = source.positionInUltimateSource(this) - - def dbgString = { - "source: " + (if (source eq null) source else source . path) + " " + - (if (isLine) "line-" + line - else if (!hasOffset) "NOP" - else if (offset >= source.content.length) "out-of-bounds-" + offset else { - val ret = "offset=" + offset + " line=" + line - var add = "" - while (offset + add.length() < source.content.length && - add.length() < 10) add = add + source.content(offset + add.length()); - ret + " c[0..9]=\"" + add + "\""; - }) - } - - def lineContent: String = - if (hasOffset) source.lineToString(line - FIRSTLINE) - else "NO_LINE" - - /** Returns a string representation of the encoded position. */ - override def toString(): String = { - if(inUltimateSource != this) - return inUltimateSource.toString - - val sb = new StringBuilder() - if (source ne null) { - sb.append(source.file.path) - if (hasOffset) { - sb.append(line) - sb.append(':') - sb.append(column) - } - } else sb.append("::" + offset) - sb.toString() + Some(column) } -} - -/** this class merely serves to communicate a string to ConsoleReporter - */ -case class FakePos(msg: String) extends Position(null, Position.NOPOS) { - override def inUltimateSource = this -} +}
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/util/SourceFile.scala b/src/compiler/scala/tools/nsc/util/SourceFile.scala index c72e1899e7..4f7f0607d4 100644 --- a/src/compiler/scala/tools/nsc/util/SourceFile.scala +++ b/src/compiler/scala/tools/nsc/util/SourceFile.scala @@ -50,10 +50,10 @@ class SourceFile(val file: AbstractFile, _content: Array[Char]) { else true def position(offset: Int) = - new Position(this, offset) + new OffsetPosition(this, offset) def position(line: Int, column: Int) = - new Position(this, lineToOffset(line) + column) + new OffsetPosition(this, lineToOffset(line) + column) /** Map a position to a position in the underlying source file. * For regular source files, simply return the argument. @@ -65,17 +65,19 @@ class SourceFile(val file: AbstractFile, _content: Array[Char]) { // NOTE: all indexes are based on zero!!!! override def toString(): String = file.name /* + ":" + content.length */ - def dbg(offset: Int) = (new Position(this, offset)).dbgString + def dbg(offset: Int) = (new OffsetPosition(this, offset)).dbgString object line { var index = 0 var offset = 0 + + def find(toFind: Int, isIndex: Boolean): Int = { if (toFind == 0) return 0 - if (!isIndex) assert(toFind != Position.NOPOS) - if ( isIndex) assert(toFind > Position.NOLINE - Position.FIRSTLINE) + //if (!isIndex) assert(toFind != -1) + //if ( isIndex) assert(toFind > 0) if (!isIndex && (toFind >= content.length)) throw new Error(toFind + " not valid offset in " + @@ -177,13 +179,16 @@ extends SourceFile(name, contents) this("(virtual file)", components.toList:_*) override def positionInUltimateSource(position: Position) = { - var off = position.offset - var compsLeft = components - while(compsLeft.head.content.length-1 <= off) { - off = off - compsLeft.head.content.length + 1 - compsLeft = compsLeft.tail + if (position.offset.isEmpty) super.positionInUltimateSource(position) + else { + var off = position.offset.get + var compsLeft = components + while(compsLeft.head.content.length-1 <= off) { + off = off - compsLeft.head.content.length + 1 + compsLeft = compsLeft.tail + } + compsLeft.head.positionInUltimateSource(new OffsetPosition(compsLeft.head, off)) } - compsLeft.head.positionInUltimateSource(new Position(compsLeft.head, off)) } } @@ -216,7 +221,8 @@ extends SourceFile(name, contents) stop) override def positionInUltimateSource(position: Position) = { - underlyingFile.positionInUltimateSource( - new Position(underlyingFile, position.offset + start)) + if (position.offset.isEmpty) super.positionInUltimateSource(position) + else underlyingFile.positionInUltimateSource( + new OffsetPosition(underlyingFile, position.offset.get + start)) } } diff --git a/src/library/scala/Iterable.scala b/src/library/scala/Iterable.scala index 2f09f4e136..934afd685f 100644 --- a/src/library/scala/Iterable.scala +++ b/src/library/scala/Iterable.scala @@ -426,42 +426,53 @@ trait Iterable[+A] { /** Is this collection empty? */ def isEmpty = elements.hasNext - private class Projection[+B](elements0 : () => Iterator[B]) extends Iterable[B] { + private class ProjectionImpl[+B](elements0 : () => Iterator[B]) extends Iterable[B] { def elements = elements0(); } - /** Returns all the elements of this iterable that satisfy the - * predicate <code>p</code>. The order of the elements is preserved. - * Unlike <code>filter</code>, this API is not strict - * and will terminate on infinite-sized collections. - * - * @param p the predicate used to filter the list. - * @return the elements of this list satisfying <code>p</code>. - */ - def pfilter(p: A => Boolean) : Iterable[A] = new Projection[A](() => { - Iterable.this.elements.filter(p) - }) - /** Returns the iterable resulting from applying the given function - * <code>f</code> to each element of this iterable. Unlike <code>map</code>, - * this API is not strict and will terminate on infinite-sized collections. - * - * @param f function to apply to each element. - * @return <code>f(a<sub>0</sub>), ..., f(a<sub>n</sub>)</code> - * if this iterable is <code>a<sub>0</sub>, ..., an</code>. - */ - def pmap[B](f: A => B) : Iterable[B] = new Projection[B](() => { - Iterable.this.elements.map(f) - }) - /** Applies the given function <code>f</code> to each element of - * this iterable, then concatenates the results. Unlike <code>flatMap</code>, - * this API is not strict and will terminate on infinite-sized collections. - * - * @param f the function to apply on each element. - * @return <code>f(a<sub>0</sub>) ::: ... ::: f(a<sub>n</sub>)</code> if - * this iterable is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. + + trait Projection { + /** Returns all the elements of this iterable that satisfy the + * predicate <code>p</code>. The order of the elements is preserved. + * Unlike <code>filter</code> in <code>Iterable</code>, this API is + * not strict and will terminate on infinite-sized collections. + * + * @param p the predicate used to filter the list. + * @return the elements of this list satisfying <code>p</code>. + */ + def filter(p : A => Boolean) : Iterable[A] = new ProjectionImpl[A](() => { + Iterable.this.elements.filter(p) + }) + /** Returns the iterable resulting from applying the given function + * <code>f</code> to each element of this iterable. Unlike <code>map</code> + * in <code>Iterable</code>, this API is not strict and will terminate on + * infinite-sized collections. + * + * @param f function to apply to each element. + * @return <code>f(a<sub>0</sub>), ..., f(a<sub>n</sub>)</code> + * if this iterable is <code>a<sub>0</sub>, ..., an</code>. + */ + def map[B](f: A => B) : Iterable[B] = new ProjectionImpl[B](() => { + Iterable.this.elements.map(f) + }) + /** Applies the given function <code>f</code> to each element of + * this iterable, then concatenates the results. Unlike <code>flatMap</code> + * in <code>Iterable</code>, + * this API is not strict and will terminate on infinite-sized collections. + * + * @param f the function to apply on each element. + * @return <code>f(a<sub>0</sub>) ::: ... ::: f(a<sub>n</sub>)</code> if + * this iterable is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. + */ + def flatMap[B](f: A => Iterable[B]) : Iterable[B] = new ProjectionImpl[B](() => { + Iterable.this.elements.flatMap(a => f(a).elements) + }) + } + /** + * returns a facade that can be used to call non-strict <code>filter</code>, + * <code>map</code>, and <code>flatMap</code> methods that build projections + * of the collection. */ - def pflatMap[B](f: A => Iterable[B]) : Iterable[B] = new Projection[B](() => { - Iterable.this.elements.flatMap(a => f(a).elements) - }) + def projection : Projection = new Projection {}; /** returns true iff this collection has a bound size. * Only true if this iterable is a <code>Collection</code>. diff --git a/src/library/scala/collection/Map.scala b/src/library/scala/collection/Map.scala index 30ce8a1ab9..6047513b20 100644 --- a/src/library/scala/collection/Map.scala +++ b/src/library/scala/collection/Map.scala @@ -163,4 +163,17 @@ trait Map[A, +B] extends PartialFunction[A, B] with Collection[(A, B)] { */ def default(key: A): B = throw new NoSuchElementException("key not found: " + key) + + trait Projection extends super.Projection { + /** filter based on keys only */ + def filterKeys(p : A => Boolean) = filter(e => p(e._1)) + /** map elements using existing key set */ + def mapElements[C](f : B => C) : Map[A,C] = new Map[A,C] { + def elements = Map.this.elements.map(e => (e._1, f(e._2))) + def size = Map.this.size + override def contains(key : A) = Map.this.contains(key) + override def get(key : A) = Map.this.get(key).map(f) + } + } + override def projection : Projection = new Projection {} } diff --git a/src/library/scala/collection/jcl/Buffer.scala b/src/library/scala/collection/jcl/Buffer.scala index 28aa87dc98..15033867e9 100644 --- a/src/library/scala/collection/jcl/Buffer.scala +++ b/src/library/scala/collection/jcl/Buffer.scala @@ -17,6 +17,12 @@ package scala.collection.jcl; trait Buffer[A] extends MutableSeq[A] with Collection[A] with Ranged[Int,A] { final protected type SortedSelf = Buffer[A]; + trait MutableSeqProjection extends super[MutableSeq].Projection; + trait Projection extends MutableSeqProjection with super[Collection].Projection { + override def filter(p : A => Boolean) = super[MutableSeqProjection].filter(p); + } + override def projection = new Projection {} + override def elements : BufferIterator[Int,A]; /** The first index of a buffer is 0. */ override def first = 0; @@ -83,7 +89,6 @@ trait Buffer[A] extends MutableSeq[A] with Collection[A] with Ranged[Int,A] { override def +(a : A) : this.type = super[Collection].+(a); override def -=(a : A) = super[Collection].-=(a); override def isEmpty = super[MutableSeq].isEmpty; - override def pfilter(p : A => Boolean) : MutableSeq[A] = super[MutableSeq].pfilter(p); override def rangeImpl(from : Option[Int], until : Option[Int]) : Buffer[A] = new Range(from, until); diff --git a/src/library/scala/collection/jcl/Collection.scala b/src/library/scala/collection/jcl/Collection.scala index e9344c0ef8..74ed7345af 100644 --- a/src/library/scala/collection/jcl/Collection.scala +++ b/src/library/scala/collection/jcl/Collection.scala @@ -56,13 +56,11 @@ trait Collection[A] extends MutableIterable[A] { */ def transform(f: A => A): Boolean; - /** Used for non-strict filtered collection that only includes elements of this collection that are true for "p." - ** Any elements added to or removed from the resulting - ** filter will update this collection. Any changes to this collection - ** can update the filtered collection. - ** @return a non-strict filter of this collection. - **/ - override def pfilter(p : A => Boolean) : MutableIterable[A] = new Filter(p); + trait Projection extends super.Projection { + override def filter(p : A => Boolean) : MutableIterable[A] = new Filter(p); + } + override def projection : Projection = new Projection {} + /** Base implementation of a filtered collection */ class Filter(p : A => Boolean) extends Collection[A] { @@ -77,8 +75,11 @@ trait Collection[A] extends MutableIterable[A] { if (!p(a)) throw new IllegalArgumentException; Collection.this.remove(a); } - override def pfilter(p1 : A => Boolean) : MutableIterable[A] = - Collection.this.pfilter(a => p(a) && p1(a)); + class Projection extends super.Projection { + override def filter(p0 : A => Boolean) : MutableIterable[A] = + Collection.this.projection.filter(a => p(a) && p0(a)); + } + override def projection : Projection = new Projection; def elements = Collection.this.elements.filter(p); def size = size0; } diff --git a/src/library/scala/collection/jcl/Map.scala b/src/library/scala/collection/jcl/Map.scala index 5c66986626..34b5d92918 100644 --- a/src/library/scala/collection/jcl/Map.scala +++ b/src/library/scala/collection/jcl/Map.scala @@ -22,7 +22,7 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl /** The values of this map as a projection, which means removals from the returned collection will remove the element from this map. @returns a projection of this map's elements. */ - def valueSet : MutableIterable[E] = pmap(._2); + def valueSet : MutableIterable[E] = projection.map(._2); def put(key : K, elem : E) : Option[E]; def putAll(that : Iterable[Tuple2[K,E]]) : Unit = that.foreach(p => put(p._1, p._2)); @@ -52,10 +52,14 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl } override def -=(key : K) : Unit = remove(key); override def elements : MutableIterator[Tuple2[K,E]]; - /** Produces a filtered projection of this map that includes only entries of the map - * whose keys are true with respect to predicate "p." - */ - def pfilterKeys(p : K => Boolean) : jcl.Map[K,E] = new Filter(p); + + trait MutableIterableProjection extends super[MutableIterable].Projection; + trait Projection extends MutableIterableProjection with super[Map].Projection { + override def filterKeys(p : K => Boolean) : jcl.Map[K,E] = new Filter(p); + override def map[B](f : ((K,E)) => B) : MutableIterable[B] = super[MutableIterableProjection].map(f); + } + override def projection : Projection = new Projection {} + /** */ def lense[F](f : E => F, g : F => E) : jcl.Map[K,F] = new Lense[F](f,g); @@ -65,14 +69,19 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl override def remove(key : K) = Map.this.remove(key).map(f); override def put(key : K, elem : F) = Map.this.put(key, g(elem)).map(f); override def get(key : K) = Map.this.get(key).map(f); - override def pfilterKeys(p : K => Boolean) : jcl.Map[K,F] = - Map.this.pfilterKeys(p).lense(f, g); + + trait Projection extends super.Projection { + override def filterKeys(p : K => Boolean) : jcl.Map[K,F] = + Map.this.projection.filterKeys(p).lense(f, g); + } + override def projection = new Projection {} + override def lense[G](f0 : F => G, g0 : G => F) : jcl.Map[K,G] = Map.this.lense[G](x => f0(f(x)), y => g(g0(y))); override def size = size0; } protected class Filter(p : K => Boolean) extends jcl.Map[K,E] { - override def elements = Map.this.elements.filter(k => p(k._1)); + override def elements = Map.this.elements.filter(e => p(e._1)); override def remove(key : K) = { if (!p(key)) throw new IllegalArgumentException; Map.this.remove(key); @@ -86,8 +95,10 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl if (!p(key)) None; else Map.this.get(key); } - override def pfilterKeys(p0 : K => Boolean) : jcl.Map[K,E] = - Map.this.pfilterKeys(k => p(k) && p0(k)); + class Projection extends super.Projection { + override def filterKeys(p0 : K => Boolean) : jcl.Map[K,E] = + Map.this.projection.filterKeys(e => p(e) && p0(e)); + } override def size = size0; } protected class KeySet extends Set[K] { diff --git a/src/library/scala/collection/jcl/MutableIterable.scala b/src/library/scala/collection/jcl/MutableIterable.scala index fef43d9ea1..411a7ffc01 100644 --- a/src/library/scala/collection/jcl/MutableIterable.scala +++ b/src/library/scala/collection/jcl/MutableIterable.scala @@ -63,12 +63,10 @@ trait MutableIterable[A] extends scala.Collection[A] { i.next; i.remove; } } - /** Creates a non-strict map of this collection. Any removals from the returned - * collection will remove from this collection, while any changes to this collection will also be - * reflected in the mapped collection. - * @return a non-strict map of this collection. - */ - override def pmap[B](f : A => B) : MutableIterable[B] = new Map[B](f); + trait Projection extends super.Projection { + override def map[B](f : A => B) : MutableIterable[B] = new Map[B](f); + } + override def projection = new Projection {} /** The default implementation of a map over mutable iterable collections. **/ protected class Map[B](f : A => B) extends MutableIterable[B] { diff --git a/src/library/scala/collection/jcl/MutableSeq.scala b/src/library/scala/collection/jcl/MutableSeq.scala index 2d3147ca6d..95325b2e22 100644 --- a/src/library/scala/collection/jcl/MutableSeq.scala +++ b/src/library/scala/collection/jcl/MutableSeq.scala @@ -20,10 +20,11 @@ trait MutableSeq[A] extends MutableIterable[A] with Seq[A] { override def isEmpty = super[MutableIterable].isEmpty; override def apply(idx : Int) = elements.seek(idx); - - override def pfilter(p : A => Boolean) : MutableSeq[A] = new Filter(p); - - override def pmap[B](f : A => B) : MutableSeq[B] = new Map[B](f); + trait Projection extends super.Projection { + override def filter(p : A => Boolean) : MutableSeq[A] = new Filter(p); + override def map[B](f : A => B) : MutableSeq[B] = new Map[B](f); + } + override def projection = new Projection {} /** Find the index of "a" in this sequence. * @returns None if the "a" is not in this sequence. diff --git a/src/library/scala/collection/jcl/Set.scala b/src/library/scala/collection/jcl/Set.scala index 975b76a167..c42faf4c31 100644 --- a/src/library/scala/collection/jcl/Set.scala +++ b/src/library/scala/collection/jcl/Set.scala @@ -44,13 +44,14 @@ trait Set[A] extends Collection[A] with scala.collection.mutable.Set[A] { } addAll(toAdd) } - - override def pfilter(p: A => Boolean): Set[A] = new Filter(p) - - class Filter(p: A => Boolean) extends super.Filter(p) with Set[A] { - override def filter(p: A => Boolean): scala.collection.mutable.Set[A] = { - super[Set].retain(p) - this - } + trait Projection extends super.Projection { + override def filter(p : A => Boolean) : Set[A] = new Filter(p); + } + override def projection : Projection = new Projection {} + class Filter(p : A => Boolean) extends super.Filter(p) with Set[A] { + override def retain(p0 : A => Boolean): Unit = + Set.this.retain(e => !p(e) || p0(e)) + trait Projection extends super[Filter].Projection with super[Set].Projection {} + override def projection : Projection = new Projection {} } } diff --git a/src/library/scala/collection/jcl/SortedMap.scala b/src/library/scala/collection/jcl/SortedMap.scala index 1f6dacddd6..3188d4d6bf 100644 --- a/src/library/scala/collection/jcl/SortedMap.scala +++ b/src/library/scala/collection/jcl/SortedMap.scala @@ -26,13 +26,21 @@ trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with } override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = Range(from, until); override def keySet : SortedSet[K] = new KeySet; - override def pfilterKeys(p : K => Boolean) : SortedMap[K,E] = new Filter(p); + + class Projection extends super.Projection { + override def filterKeys(p : K => Boolean) : SortedMap[K,E] = new Filter(p); + } + override def projection = new Projection; + override def lense[F](f : E => F, g : F => E) : jcl.SortedMap[K,F] = new Lense[F](f,g); protected class Lense[F](f : E => F, g : F => E) extends super.Lense[F](f,g) with SortedMap[K,F] { def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0, k1); - override def pfilterKeys(p : K => Boolean) : jcl.SortedMap[K,F] = - SortedMap.this.pfilterKeys(p).lense(f, g); + class Projection extends super.Projection { + override def filterKeys(p : K => Boolean) : SortedMap[K,F] = + SortedMap.this.projection.filterKeys(p).lense(f,g); + } + override def projection = new Projection; override def lense[G](f0 : F => G, g0 : G => F) : jcl.SortedMap[K,G] = SortedMap.this.lense[G]({x:E => f0(f(x))}, {y:G => g(g0(y))}); override def rangeImpl(from : Option[K], until : Option[K]) = @@ -48,11 +56,13 @@ trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with protected class SuperFilter(p : K => Boolean) extends super.Filter(p); protected class Filter(p : K => Boolean) extends SuperFilter(p) with SortedMap[K,E] { def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1); - override def pfilterKeys(p0 : K => Boolean) : SortedMap[K,E] = - SortedMap.this.pfilterKeys(k => p(k) && p0(k)); - + class Projection extends super.Projection { + override def filterKeys(p0 : K => Boolean) : SortedMap[K,E] = + SortedMap.this.projection.filterKeys(k => p(k) && p0(k)); + } + override def projection = new Projection; override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = - SortedMap.this.Range(from, until).pfilterKeys(p); + SortedMap.this.Range(from, until).projection.filterKeys(p); } protected def Range(from : Option[K], until : Option[K]) : SortedMap[K,E] = new Range(from,until); @@ -78,13 +88,18 @@ trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with if (until != None && compare(this.until.get, until.get) < 0) return rangeImpl(from, this.until); SortedMap.this.Range(from, until); } - override def pfilterKeys(p : K => Boolean) : SortedMap[K,E] = new Filter(p); + class Projection extends super.Projection { + override def filterKeys(p : K => Boolean) : SortedMap[K,E] = new Filter(p); + } + override def projection = new Projection; protected class Filter(p : K => Boolean) extends SuperFilter(p) with SortedMap[K,E] { def compare(k0 : K, k1 : K) = Range.this.compare(k0, k1); - override def pfilterKeys(p0 : K => Boolean) = - Range.this.pfilterKeys(key => p(key) && p0(key)); + class Projection extends super.Projection { + override def filterKeys(p0 : K => Boolean) = Range.this.projection.filterKeys(k => p(k) && p0(k)); + } + override def projection = new Projection; override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = - Range.this.rangeImpl(from,until).pfilterKeys(p); + Range.this.rangeImpl(from,until).projection.filterKeys(p); } } } diff --git a/src/library/scala/collection/jcl/SortedSet.scala b/src/library/scala/collection/jcl/SortedSet.scala index bc381edb83..0223c04a70 100644 --- a/src/library/scala/collection/jcl/SortedSet.scala +++ b/src/library/scala/collection/jcl/SortedSet.scala @@ -34,9 +34,17 @@ trait SortedSet[A] extends scala.collection.SortedSet[A] with jcl.Set[A] with So else last; } override def rangeImpl(from : Option[A], until : Option[A]) : SortedSet[A] = new Range(from, until); - override def pfilter(p : A => Boolean) : SortedSet[A] = new Filter(p); + trait Projection extends super.Projection { + override def filter(p : A => Boolean) : SortedSet[A] = new Filter(p); + } + override def projection : Projection = new Projection {} + protected class Filter(p : A => Boolean) extends super.Filter(p) with SortedSet[A] { def compare(a0 : A, a1 : A) : Int = SortedSet.this.compare(a0, a1); + trait Projection extends super[Filter].Projection with super[SortedSet].Projection { + override def filter(p0 : A => Boolean) = SortedSet.this.projection.filter(k => p(k) && p0(k)); + } + override def projection : Projection = new Projection {}; } protected class Range(from : Option[A], until : Option[A]) extends Filter(key => { diff --git a/src/library/scala/collection/jcl/Tests.scala b/src/library/scala/collection/jcl/Tests.scala index b81a6f1984..3fab33be2f 100644 --- a/src/library/scala/collection/jcl/Tests.scala +++ b/src/library/scala/collection/jcl/Tests.scala @@ -29,11 +29,11 @@ private[jcl] object Tests { rset + "bad"; Console.println(rset); Console.println(set); - val fset : SortedSet[String] = rset.pfilter(.endsWith("d")); + val fset : SortedSet[String] = rset.projection.filter(.endsWith("d")); Console.println(fset); fset += "cd"; Console.println(set); - set.pmap(.length).retain(x => x == 3); + set.projection.map(.length).retain(x => x == 3); Console.println(set); Console.println(rset); Console.println(fset); @@ -47,7 +47,7 @@ private[jcl] object Tests { rmap + ("bad" -> 10); Console.println(rmap); //Console.println(map); - val fmap : SortedMap[String,Integer] = rmap.pfilterKeys(k => k.length == 2); + val fmap : SortedMap[String,Integer] = rmap.projection.filterKeys(k => k.length == 2); Console.println(fmap); } @@ -55,7 +55,7 @@ private[jcl] object Tests { val set = new HashSet[String]; set + "hello" + "world" + "you" + "to"; Console.println(set); - val fset = set.pfilter(s => s.length <= 3); + val fset = set.projection.filter(s => s.length <= 3); Console.println(fset); fset += "xxx"; Console.println(set); @@ -66,7 +66,7 @@ private[jcl] object Tests { case e : IllegalArgumentException => case _ => throw new Error; } - val mset : MutableIterable[Int] = set.pmap(s => s.length); + val mset : MutableIterable[Int] = set.projection.map(s => s.length); Console.println(mset); mset.retain(n => n < 5); Console.println(set); |