diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 33 |
2 files changed, 34 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 40439a5379..a89a994377 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -156,6 +156,17 @@ self => def newScanner(): Scanner = new SourceFileScanner(source) + /** Scoping operator used to temporarily look into the future. + * Backs up scanner data before evaluating a block and restores it after. + */ + def lookingAhead[T](body: => T): T = { + val snapshot = (new ScannerData{}).copyFrom(in) + in.nextToken() + val res = body + in copyFrom snapshot + res + } + val in = newScanner() in.init() diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 2dca39f7a3..03cdead472 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -5,7 +5,7 @@ package scala.tools.nsc package ast.parser -import scala.tools.nsc.util.CharArrayReader +import scala.tools.nsc.util.{ CharArrayReader, CharArrayReaderData } import scala.reflect.internal.util._ import scala.reflect.internal.Chars._ import Tokens._ @@ -71,17 +71,37 @@ trait Scanners extends ScannersCommon { /** the base of a number */ var base: Int = 0 - def copyFrom(td: TokenData) = { + def copyFrom(td: TokenData): this.type = { this.token = td.token this.offset = td.offset this.lastOffset = td.lastOffset this.name = td.name this.strVal = td.strVal this.base = td.base + this } } - abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon { + /** An interface to most of mutable data in Scanner defined in TokenData + * and CharArrayReader (+ next, prev fields) with copyFrom functionality + * to backup/restore data (used by quasiquotes' lookingAhead). + */ + trait ScannerData extends TokenData with CharArrayReaderData { + /** we need one token lookahead and one token history + */ + val next: TokenData = new TokenData{} + val prev: TokenData = new TokenData{} + + def copyFrom(sd: ScannerData): this.type = { + this.next copyFrom sd.next + this.prev copyFrom sd.prev + super[CharArrayReaderData].copyFrom(sd) + super[TokenData].copyFrom(sd) + this + } + } + + abstract class Scanner extends CharArrayReader with TokenData with ScannerData with ScannerCommon { private def isDigit(c: Char) = java.lang.Character isDigit c private var openComments = 0 @@ -194,13 +214,6 @@ trait Scanners extends ScannersCommon { cbuf.clear() } - private class TokenData0 extends TokenData - - /** we need one token lookahead and one token history - */ - val next : TokenData = new TokenData0 - val prev : TokenData = new TokenData0 - /** a stack of tokens which indicates whether line-ends can be statement separators * also used for keeping track of nesting levels. * We keep track of the closing symbol of a region. This can be |