diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/javac/JavaScanners.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/javac/JavaScanners.scala | 286 |
1 files changed, 113 insertions, 173 deletions
diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index e230585a8b..f9b1e57e66 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -10,7 +10,7 @@ import scala.tools.nsc.util.JavaCharArrayReader import scala.reflect.internal.util._ import scala.reflect.internal.Chars._ import JavaTokens._ -import scala.annotation.switch +import scala.annotation.{ switch, tailrec } import scala.language.implicitConversions // Todo merge these better with Scanners @@ -57,23 +57,14 @@ trait JavaScanners extends ast.parser.ScannersCommon { /** ... */ abstract class AbstractJavaScanner extends AbstractJavaTokenData { - implicit def p2g(pos: Position): ScanPosition implicit def g2p(pos: ScanPosition): Position - /** the last error position - */ - var errpos: ScanPosition - var lastPos: ScanPosition - def skipToken: ScanPosition def nextToken(): Unit def next: AbstractJavaTokenData 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) - /** return recent scala doc, if any */ - def flushDoc: DocComment + def intVal: Long = intVal(negated = false) + def floatVal: Double = floatVal(negated = false) def currentPos: Position } @@ -227,17 +218,9 @@ trait JavaScanners extends ast.parser.ScannersCommon { abstract class JavaScanner extends AbstractJavaScanner with JavaTokenData with Cloneable with ScannerCommon { override def intVal = super.intVal// todo: needed? override def floatVal = super.floatVal - override var errpos: Int = NoPos def currentPos: Position = g2p(pos - 1) - var in: JavaCharArrayReader = _ - def dup: JavaScanner = { - val dup = clone().asInstanceOf[JavaScanner] - dup.in = in.dup - dup - } - /** character buffer for literals */ val cbuf = new StringBuilder() @@ -252,22 +235,6 @@ trait JavaScanners extends ast.parser.ScannersCommon { cbuf.setLength(0) } - /** buffer for the documentation comment - */ - var docBuffer: StringBuilder = null - - def flushDoc: DocComment = { - val ret = if (docBuffer != null) DocComment(docBuffer.toString, NoPosition) else null - docBuffer = null - ret - } - - /** add the given character to the documentation buffer - */ - protected def putDocChar(c: Char) { - if (docBuffer ne null) docBuffer.append(c) - } - private class JavaTokenData0 extends JavaTokenData /** we need one token lookahead @@ -277,13 +244,6 @@ trait JavaScanners extends ast.parser.ScannersCommon { // Get next token ------------------------------------------------------------ - /** read next token and return last position - */ - def skipToken: Int = { - val p = pos; nextToken - p - 1 - } - def nextToken() { if (next.token == EMPTY) { fetchToken() @@ -296,7 +256,7 @@ trait JavaScanners extends ast.parser.ScannersCommon { def lookaheadToken: Int = { prev copyFrom this - nextToken + nextToken() val t = token next copyFrom this this copyFrom prev @@ -308,11 +268,10 @@ trait JavaScanners extends ast.parser.ScannersCommon { private def fetchToken() { if (token == EOF) return lastPos = in.cpos - 1 - //var index = bp while (true) { in.ch match { case ' ' | '\t' | CR | LF | FF => - in.next + in.next() case _ => pos = in.cpos (in.ch: @switch) match { @@ -329,47 +288,47 @@ trait JavaScanners extends ast.parser.ScannersCommon { 'u' | 'v' | 'w' | 'x' | 'y' | 'z' => putChar(in.ch) - in.next - getIdentRest + in.next() + getIdentRest() return case '0' => putChar(in.ch) - in.next + in.next() if (in.ch == 'x' || in.ch == 'X') { - in.next + in.next() base = 16 } else { base = 8 } - getNumber + getNumber() return case '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => base = 10 - getNumber + getNumber() return case '\"' => - in.next + in.next() while (in.ch != '\"' && (in.isUnicode || in.ch != CR && in.ch != LF && in.ch != SU)) { getlitch() } if (in.ch == '\"') { token = STRINGLIT setName() - in.next + in.next() } else { syntaxError("unclosed string literal") } return case '\'' => - in.next + in.next() getlitch() if (in.ch == '\'') { - in.next + in.next() token = CHARLIT setName() } else { @@ -379,31 +338,31 @@ trait JavaScanners extends ast.parser.ScannersCommon { case '=' => token = ASSIGN - in.next + in.next() if (in.ch == '=') { token = EQEQ - in.next + in.next() } return case '>' => token = GT - in.next + in.next() if (in.ch == '=') { token = GTEQ - in.next + in.next() } else if (in.ch == '>') { token = GTGT - in.next + in.next() if (in.ch == '=') { token = GTGTEQ - in.next + in.next() } else if (in.ch == '>') { token = GTGTGT - in.next + in.next() if (in.ch == '=') { token = GTGTGTEQ - in.next + in.next() } } } @@ -411,145 +370,145 @@ trait JavaScanners extends ast.parser.ScannersCommon { case '<' => token = LT - in.next + in.next() if (in.ch == '=') { token = LTEQ - in.next + in.next() } else if (in.ch == '<') { token = LTLT - in.next + in.next() if (in.ch == '=') { token = LTLTEQ - in.next + in.next() } } return case '!' => token = BANG - in.next + in.next() if (in.ch == '=') { token = BANGEQ - in.next + in.next() } return case '~' => token = TILDE - in.next + in.next() return case '?' => token = QMARK - in.next + in.next() return case ':' => token = COLON - in.next + in.next() return case '@' => token = AT - in.next + in.next() return case '&' => token = AMP - in.next + in.next() if (in.ch == '&') { token = AMPAMP - in.next + in.next() } else if (in.ch == '=') { token = AMPEQ - in.next + in.next() } return case '|' => token = BAR - in.next + in.next() if (in.ch == '|') { token = BARBAR - in.next + in.next() } else if (in.ch == '=') { token = BAREQ - in.next + in.next() } return case '+' => token = PLUS - in.next + in.next() if (in.ch == '+') { token = PLUSPLUS - in.next + in.next() } else if (in.ch == '=') { token = PLUSEQ - in.next + in.next() } return case '-' => token = MINUS - in.next + in.next() if (in.ch == '-') { token = MINUSMINUS - in.next + in.next() } else if (in.ch == '=') { token = MINUSEQ - in.next + in.next() } return case '*' => token = ASTERISK - in.next + in.next() if (in.ch == '=') { token = ASTERISKEQ - in.next + in.next() } return case '/' => - in.next + in.next() if (!skipComment()) { token = SLASH - in.next + in.next() if (in.ch == '=') { token = SLASHEQ - in.next + in.next() } return } case '^' => token = HAT - in.next + in.next() if (in.ch == '=') { token = HATEQ - in.next + in.next() } return case '%' => token = PERCENT - in.next + in.next() if (in.ch == '=') { token = PERCENTEQ - in.next + in.next() } return case '.' => token = DOT - in.next + in.next() if ('0' <= in.ch && in.ch <= '9') { - putChar('.'); getFraction + putChar('.'); getFraction() } else if (in.ch == '.') { - in.next + in.next() if (in.ch == '.') { - in.next + in.next() token = DOTDOTDOT } else syntaxError("`.' character expected") } @@ -557,60 +516,60 @@ trait JavaScanners extends ast.parser.ScannersCommon { case ';' => token = SEMI - in.next + in.next() return case ',' => token = COMMA - in.next + in.next() return case '(' => token = LPAREN - in.next + in.next() return case '{' => token = LBRACE - in.next + in.next() return case ')' => token = RPAREN - in.next + in.next() return case '}' => token = RBRACE - in.next + in.next() return case '[' => token = LBRACKET - in.next + in.next() return case ']' => token = RBRACKET - in.next + in.next() return case SU => if (!in.hasNext) token = EOF else { syntaxError("illegal character") - in.next + in.next() } return case _ => if (Character.isUnicodeIdentifierStart(in.ch)) { putChar(in.ch) - in.next - getIdentRest + in.next() + getIdentRest() } else { syntaxError("illegal character: "+in.ch.toInt) - in.next + in.next() } return } @@ -618,33 +577,20 @@ trait JavaScanners extends ast.parser.ScannersCommon { } } - private def skipComment(): Boolean = { - if (in.ch == '/') { - do { - in.next - } while ((in.ch != CR) && (in.ch != LF) && (in.ch != SU)) - true - } else if (in.ch == '*') { - docBuffer = null - in.next - val scalaDoc = ("/**", "*/") - if (in.ch == '*' && forScaladoc) - docBuffer = new StringBuilder(scalaDoc._1) - do { - do { - if (in.ch != '*' && in.ch != SU) { - in.next; putDocChar(in.ch) - } - } while (in.ch != '*' && in.ch != SU) - while (in.ch == '*') { - in.next; putDocChar(in.ch) - } - } while (in.ch != '/' && in.ch != SU) - if (in.ch == '/') in.next - else incompleteInputError("unclosed comment") - true - } else { - false + protected def skipComment(): Boolean = { + @tailrec def skipLineComment(): Unit = in.ch match { + case CR | LF | SU => + case _ => in.next; skipLineComment() + } + @tailrec def skipJavaComment(): Unit = in.ch match { + case SU => incompleteInputError("unclosed comment") + case '*' => in.next; if (in.ch == '/') in.next else skipJavaComment() + case _ => in.next; skipJavaComment() + } + in.ch match { + case '/' => in.next ; skipLineComment() ; true + case '*' => in.next ; skipJavaComment() ; true + case _ => false } } @@ -668,12 +614,12 @@ trait JavaScanners extends ast.parser.ScannersCommon { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => putChar(in.ch) - in.next + in.next() case '_' => putChar(in.ch) - in.next - getIdentRest + in.next() + getIdentRest() return case SU => setName() @@ -682,7 +628,7 @@ trait JavaScanners extends ast.parser.ScannersCommon { case _ => if (Character.isUnicodeIdentifierPart(in.ch)) { putChar(in.ch) - in.next + in.next() } else { setName() token = JavaScannerConfiguration.name2token(name) @@ -698,17 +644,17 @@ trait JavaScanners extends ast.parser.ScannersCommon { */ protected def getlitch() = if (in.ch == '\\') { - in.next + in.next() if ('0' <= in.ch && in.ch <= '7') { val leadch: Char = in.ch var oct: Int = digit2int(in.ch, 8) - in.next + in.next() if ('0' <= in.ch && in.ch <= '7') { oct = oct * 8 + digit2int(in.ch, 8) - in.next + in.next() if (leadch <= '3' && '0' <= in.ch && in.ch <= '7') { oct = oct * 8 + digit2int(in.ch, 8) - in.next + in.next() } } putChar(oct.asInstanceOf[Char]) @@ -726,11 +672,11 @@ trait JavaScanners extends ast.parser.ScannersCommon { syntaxError(in.cpos - 1, "invalid escape character") putChar(in.ch) } - in.next + in.next() } } else { putChar(in.ch) - in.next + in.next() } /** read fractional part and exponent of floating point number @@ -740,35 +686,35 @@ trait JavaScanners extends ast.parser.ScannersCommon { token = DOUBLELIT while ('0' <= in.ch && in.ch <= '9') { putChar(in.ch) - in.next + in.next() } if (in.ch == 'e' || in.ch == 'E') { val lookahead = in.copy - lookahead.next + lookahead.next() if (lookahead.ch == '+' || lookahead.ch == '-') { - lookahead.next + lookahead.next() } if ('0' <= lookahead.ch && lookahead.ch <= '9') { putChar(in.ch) - in.next + in.next() if (in.ch == '+' || in.ch == '-') { putChar(in.ch) - in.next + in.next() } while ('0' <= in.ch && in.ch <= '9') { putChar(in.ch) - in.next + in.next() } } token = DOUBLELIT } if (in.ch == 'd' || in.ch == 'D') { putChar(in.ch) - in.next + in.next() token = DOUBLELIT } else if (in.ch == 'f' || in.ch == 'F') { putChar(in.ch) - in.next + in.next() token = FLOATLIT } setName() @@ -828,23 +774,23 @@ trait JavaScanners extends ast.parser.ScannersCommon { protected def getNumber() { while (digit2int(in.ch, if (base < 10) 10 else base) >= 0) { putChar(in.ch) - in.next + in.next() } token = INTLIT if (base <= 10 && in.ch == '.') { val lookahead = in.copy - lookahead.next + lookahead.next() lookahead.ch match { case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'd' | 'D' | 'e' | 'E' | 'f' | 'F' => putChar(in.ch) - in.next - return getFraction + in.next() + return getFraction() case _ => if (!isIdentifierStart(lookahead.ch)) { putChar(in.ch) - in.next - return getFraction + in.next() + return getFraction() } } } @@ -852,11 +798,11 @@ trait JavaScanners extends ast.parser.ScannersCommon { (in.ch == 'e' || in.ch == 'E' || in.ch == 'f' || in.ch == 'F' || in.ch == 'd' || in.ch == 'D')) { - return getFraction + return getFraction() } setName() if (in.ch == 'l' || in.ch == 'L') { - in.next + in.next() token = LONGLIT } } @@ -868,7 +814,6 @@ trait JavaScanners extends ast.parser.ScannersCommon { def syntaxError(pos: Int, msg: String) { error(pos, msg) token = ERROR - errpos = pos } /** generate an error at the current token position @@ -879,7 +824,6 @@ trait JavaScanners extends ast.parser.ScannersCommon { def incompleteInputError(msg: String) { incompleteInputError(pos, msg) token = EOF - errpos = pos } override def toString() = token match { @@ -908,21 +852,17 @@ trait JavaScanners extends ast.parser.ScannersCommon { /** INIT: read lookahead character and token. */ def init() { - in.next - nextToken + in.next() + nextToken() } } - /** ... - */ class JavaUnitScanner(unit: CompilationUnit) extends JavaScanner { in = new JavaCharArrayReader(unit.source.content, !settings.nouescape.value, syntaxError) - init - def warning(pos: Int, msg: String) = unit.warning(pos, msg) + init() def error (pos: Int, msg: String) = unit. error(pos, msg) def incompleteInputError(pos: Int, msg: String) = unit.incompleteInputError(pos, msg) def deprecationWarning(pos: Int, msg: String) = unit.deprecationWarning(pos, msg) - implicit def p2g(pos: Position): Int = if (pos.isDefined) pos.point else -1 implicit def g2p(pos: Int): Position = new OffsetPosition(unit.source, pos) } } |