From 2ef5d4c6d81e5008fdb2ae1b4f2ecdd9d9901fd2 Mon Sep 17 00:00:00 2001 From: Sean McDirmid Date: Thu, 19 Apr 2007 05:16:02 +0000 Subject: Switching over to position objects from positio... Switching over to position objects from position type parameters. Positions are no longer ints. --- src/compiler/scala/tools/ant/Scalac.scala | 12 +- src/compiler/scala/tools/ant/Scaladoc.scala | 13 +- .../scala/tools/nsc/CompilationUnits.scala | 22 +- src/compiler/scala/tools/nsc/Global.scala | 24 +- src/compiler/scala/tools/nsc/Interpreter.scala | 6 +- src/compiler/scala/tools/nsc/Main.scala | 2 +- src/compiler/scala/tools/nsc/MainTokenMetric.scala | 6 +- .../scala/tools/nsc/PositionConfiguration.scala | 9 - src/compiler/scala/tools/nsc/ast/Trees.scala | 16 +- .../scala/tools/nsc/ast/parser/MarkupParsers.scala | 27 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 406 +++++++++-------- .../scala/tools/nsc/ast/parser/Scanners.scala | 505 +++++++++++++-------- .../tools/nsc/ast/parser/SymbolicXMLBuilder.scala | 25 +- .../tools/nsc/ast/parser/SyntaxAnalyzer.scala | 2 +- .../scala/tools/nsc/ast/parser/Tokens.scala | 10 + .../scala/tools/nsc/ast/parser/TreeBuilder.scala | 8 +- .../tools/nsc/backend/icode/BasicBlocks.scala | 6 +- .../scala/tools/nsc/backend/icode/Checkers.scala | 2 +- .../scala/tools/nsc/backend/icode/GenICode.scala | 20 +- .../scala/tools/nsc/backend/icode/Opcodes.scala | 4 +- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 16 +- .../scala/tools/nsc/backend/msil/GenMSIL.scala | 8 +- .../scala/tools/nsc/backend/opt/Inliners.scala | 3 +- .../scala/tools/nsc/doc/ModelExtractor.scala | 2 +- src/compiler/scala/tools/nsc/doc/ModelFrames.scala | 2 +- .../scala/tools/nsc/matching/CodeFactory.scala | 2 +- .../tools/nsc/matching/ParallelMatching.scala | 4 +- .../scala/tools/nsc/matching/PatternMatchers.scala | 30 +- .../scala/tools/nsc/matching/PatternNodes.scala | 6 +- src/compiler/scala/tools/nsc/models/Models.scala | 4 +- .../scala/tools/nsc/models/SemanticTokens.scala | 136 +++--- .../tools/nsc/reporters/AbstractReporter.scala | 2 +- .../tools/nsc/reporters/ConsoleReporter.scala | 28 +- .../scala/tools/nsc/reporters/Reporter.scala | 36 +- .../scala/tools/nsc/reporters/StoreReporter.scala | 6 +- .../scala/tools/nsc/symtab/Definitions.scala | 20 +- src/compiler/scala/tools/nsc/symtab/Flags.scala | 35 +- .../scala/tools/nsc/symtab/SymbolLoaders.scala | 8 +- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 80 ++-- src/compiler/scala/tools/nsc/symtab/Types.scala | 10 +- .../nsc/symtab/classfile/ClassfileParser.scala | 20 +- .../tools/nsc/symtab/classfile/ICodeReader.scala | 4 +- .../tools/nsc/symtab/classfile/MetaParser.scala | 4 +- .../scala/tools/nsc/symtab/classfile/Pickler.scala | 6 +- .../tools/nsc/symtab/classfile/UnPickler.scala | 11 +- .../scala/tools/nsc/symtab/clr/CLRTypes.scala | 4 +- .../scala/tools/nsc/symtab/clr/TypeParser.scala | 24 +- .../scala/tools/nsc/transform/CleanUp.scala | 2 +- .../scala/tools/nsc/transform/Erasure.scala | 2 +- .../scala/tools/nsc/transform/LambdaLift.scala | 3 +- src/compiler/scala/tools/nsc/transform/Mixin.scala | 10 +- .../scala/tools/nsc/transform/TailCalls.scala | 2 +- .../scala/tools/nsc/transform/UnCurry.scala | 5 +- .../scala/tools/nsc/typechecker/Contexts.scala | 12 +- .../scala/tools/nsc/typechecker/Infer.scala | 16 +- .../scala/tools/nsc/typechecker/Namers.scala | 14 +- .../scala/tools/nsc/typechecker/RefChecks.scala | 10 +- .../tools/nsc/typechecker/SuperAccessors.scala | 3 +- .../scala/tools/nsc/typechecker/TreeCheckers.scala | 4 +- .../scala/tools/nsc/typechecker/Typers.scala | 42 +- .../scala/tools/nsc/util/CharArrayReader.scala | 12 + src/compiler/scala/tools/nsc/util/Position.scala | 154 +++---- src/compiler/scala/tools/nsc/util/SourceFile.scala | 32 +- src/library/scala/Iterable.scala | 77 ++-- src/library/scala/collection/Map.scala | 13 + src/library/scala/collection/jcl/Buffer.scala | 7 +- src/library/scala/collection/jcl/Collection.scala | 19 +- src/library/scala/collection/jcl/Map.scala | 31 +- .../scala/collection/jcl/MutableIterable.scala | 10 +- src/library/scala/collection/jcl/MutableSeq.scala | 9 +- src/library/scala/collection/jcl/Set.scala | 17 +- src/library/scala/collection/jcl/SortedMap.scala | 37 +- src/library/scala/collection/jcl/SortedSet.scala | 10 +- src/library/scala/collection/jcl/Tests.scala | 10 +- 74 files changed, 1201 insertions(+), 998 deletions(-) delete mode 100644 src/compiler/scala/tools/nsc/PositionConfiguration.scala 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("", 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(" " + in.token2string(in.token))//DEBUG + private def skip(): Unit = { + //System.out.println(" " + 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(): " + 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 _ => "" })); 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("")) NoPos else - eatKeywords(unit.source, tree.pos); + val pos : Int = if (tree.name.toString().equals("")) -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} /**/ /** - 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 /**

@@ -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 true if tp 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 pt, EmptyTree otherwise. * @pre info.tpe 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 isCoercible */ - 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 p. The order of the elements is preserved. - * Unlike filter, 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 p. - */ - def pfilter(p: A => Boolean) : Iterable[A] = new Projection[A](() => { - Iterable.this.elements.filter(p) - }) - /** Returns the iterable resulting from applying the given function - * f to each element of this iterable. Unlike map, - * this API is not strict and will terminate on infinite-sized collections. - * - * @param f function to apply to each element. - * @return f(a0), ..., f(an) - * if this iterable is a0, ..., an. - */ - def pmap[B](f: A => B) : Iterable[B] = new Projection[B](() => { - Iterable.this.elements.map(f) - }) - /** Applies the given function f to each element of - * this iterable, then concatenates the results. Unlike flatMap, - * this API is not strict and will terminate on infinite-sized collections. - * - * @param f the function to apply on each element. - * @return f(a0) ::: ... ::: f(an) if - * this iterable is a0, ..., an. + + trait Projection { + /** Returns all the elements of this iterable that satisfy the + * predicate p. The order of the elements is preserved. + * Unlike filter in Iterable, 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 p. + */ + def filter(p : A => Boolean) : Iterable[A] = new ProjectionImpl[A](() => { + Iterable.this.elements.filter(p) + }) + /** Returns the iterable resulting from applying the given function + * f to each element of this iterable. Unlike map + * in Iterable, this API is not strict and will terminate on + * infinite-sized collections. + * + * @param f function to apply to each element. + * @return f(a0), ..., f(an) + * if this iterable is a0, ..., an. + */ + def map[B](f: A => B) : Iterable[B] = new ProjectionImpl[B](() => { + Iterable.this.elements.map(f) + }) + /** Applies the given function f to each element of + * this iterable, then concatenates the results. Unlike flatMap + * in Iterable, + * this API is not strict and will terminate on infinite-sized collections. + * + * @param f the function to apply on each element. + * @return f(a0) ::: ... ::: f(an) if + * this iterable is a0, ..., an. + */ + 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 filter, + * map, and flatMap 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 Collection. 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); -- cgit v1.2.3