diff options
author | Martin Odersky <odersky@gmail.com> | 2007-02-12 11:06:34 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-02-12 11:06:34 +0000 |
commit | 94e3a13f24d98e3e71bc8f041df8241beb43b234 (patch) | |
tree | ba6235220d7e2b4f4afd4b629b7e7dec312439a3 | |
parent | d7dc0ad355418a5d297f5baf269404d95a2976b2 (diff) | |
download | scala-94e3a13f24d98e3e71bc8f041df8241beb43b234.tar.gz scala-94e3a13f24d98e3e71bc8f041df8241beb43b234.tar.bz2 scala-94e3a13f24d98e3e71bc8f041df8241beb43b234.zip |
small fixes to newline behavior.
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 66 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 15 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Tokens.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/CharArrayReader.scala | 23 | ||||
-rw-r--r-- | src/library/scala/Iterator.scala | 13 | ||||
-rw-r--r-- | test/files/pos/bug082.scala | 2 | ||||
-rw-r--r-- | test/files/pos/partialfun.scala | 3 |
7 files changed, 77 insertions, 56 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index c61edbce53..c0e231de6f 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -98,6 +98,8 @@ trait Parsers requires SyntaxAnalyzer { if (nparens == 0 && nbraces == 0) return case NEWLINE => if (nparens == 0 && nbraces == 0) return + case NEWLINES => + if (nparens == 0 && nbraces == 0) return case RPAREN => nparens = nparens - 1 case RBRACE => @@ -183,7 +185,8 @@ trait Parsers requires SyntaxAnalyzer { * NewLine = `\n' // where allowed */ def acceptStatSep(): unit = - if (in.token == NEWLINE) in.nextToken() else accept(SEMI) + 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) @@ -231,6 +234,11 @@ trait Parsers requires SyntaxAnalyzer { def isTypeIntro: boolean = isTypeIntroToken(in.token) + def isStatSep(token: int): boolean = + token == NEWLINE || token == NEWLINES || token == SEMI + + def isStatSep: boolean = isStatSep(in.token) + /////// COMMENT AND ATTRIBUTE COLLECTION ////////////////////////////////////// @@ -526,6 +534,12 @@ trait Parsers requires SyntaxAnalyzer { in.nextToken() } + def newLinesOpt(): unit = + if (in.token == NEWLINE || in.token == NEWLINES) { + if (settings.migrate.value) in.newNewLine = false + in.nextToken() + } + def newLineOptWhenFollowedBy(token: int): unit = { // note: next is defined here because current == NEWLINE if (in.token == NEWLINE && in.next.token == token) newLineOpt() @@ -850,7 +864,7 @@ trait Parsers requires SyntaxAnalyzer { accept(LPAREN) val cond = localExpr() accept(RPAREN) - newLineOpt() + newLinesOpt() val thenp = expr() val elsep = if (in.token == ELSE) { in.nextToken(); expr() } @@ -880,14 +894,14 @@ trait Parsers requires SyntaxAnalyzer { accept(LPAREN) val cond = noLifting(localExpr()) accept(RPAREN) - newLineOpt() + newLinesOpt() val body = expr() atPos(pos) { makeWhile(lname, cond, body) } case DO => val lname: Name = unit.fresh.newName("doWhile$") val pos = in.skipToken() val body = expr() - if (in.token == SEMI || in.token == NEWLINE) in.nextToken() + if (isStatSep) in.nextToken() accept(WHILE) accept(LPAREN) val cond = noLifting(localExpr()) @@ -899,7 +913,7 @@ trait Parsers requires SyntaxAnalyzer { accept(if (startToken == LBRACE) LBRACE else LPAREN) val enums = enumerators() accept(if (startToken == LBRACE) RBRACE else RPAREN) - newLineOpt() + newLinesOpt() if (in.token == YIELD) { in.nextToken(); makeForYield(enums, expr()) } else makeFor(enums, expr()) @@ -1189,7 +1203,7 @@ trait Parsers requires SyntaxAnalyzer { */ def enumerators(): List[Enumerator] = { val enums = new ListBuffer[Enumerator] + generator(false) - while (in.token == SEMI || in.token == NEWLINE) { + while (isStatSep) { in.nextToken() enums += (if (in.token == VAL) generator(true) else Filter(expr())) } @@ -1629,7 +1643,7 @@ trait Parsers requires SyntaxAnalyzer { param } val params = new ListBuffer[AbsTypeDef] - //newLineOptWhenFollowedBy(LBRACKET) + newLineOptWhenFollowedBy(LBRACKET) if (in.token == LBRACKET) { in.nextToken() params += typeParam() @@ -1760,7 +1774,7 @@ trait Parsers requires SyntaxAnalyzer { List(funDefOrDcl(mods)) case TYPE => in.nextToken() - newLineOpt() + newLinesOpt() List(typeDefOrDcl(mods)) case _ => List(tmplDef(mods)) @@ -1831,7 +1845,7 @@ trait Parsers requires SyntaxAnalyzer { } /** FunDef ::= FunSig `:' Type `=' Expr - | FunSig Block + * | FunSig Block * | this ParamClause ParamClauses (`=' ConstrExpr | ConstrBlock) * FunDcl ::= FunSig [`:' Type] * FunSig ::= id [FunTypeParamClause] ParamClauses @@ -1852,7 +1866,7 @@ trait Parsers requires SyntaxAnalyzer { val vparamss = paramClauses(name, implicitViewBuf.toList, false) var restype = typedOpt() val rhs = - if (in.token == SEMI || in.token == NEWLINE || in.token == RBRACE) { + if (isStatSep || in.token == RBRACE) { if (restype.isEmpty) restype = scalaUnitConstr newmods = newmods | Flags.DEFERRED EmptyTree @@ -1875,7 +1889,9 @@ trait Parsers requires SyntaxAnalyzer { def selfInvocation(vparamss: List[List[ValDef]]): Tree = atPos(accept(THIS)) { var t = Apply(Ident(nme.CONSTRUCTOR), argumentExprs()) - while (in.token == LPAREN) t = Apply(t, argumentExprs()) + while (in.token == LPAREN || in.token == LBRACE) { + t = Apply(t, argumentExprs()) + } if (!implicitClassViews.isEmpty) t = Apply(t, vparamss.last.map(vd => Ident(vd.name))) t } @@ -1886,10 +1902,8 @@ trait Parsers requires SyntaxAnalyzer { atPos(in.skipToken()) { val statlist = new ListBuffer[Tree] statlist += selfInvocation(vparamss) - val stats = - if (in.token == SEMI || in.token == NEWLINE) { - in.nextToken(); blockStatSeq(statlist) - } else statlist.toList + val stats = if (isStatSep) { in.nextToken(); blockStatSeq(statlist) } + else statlist.toList accept(RBRACE) makeBlock(stats) } @@ -1908,7 +1922,7 @@ trait Parsers requires SyntaxAnalyzer { case EQUALS => in.nextToken() AliasTypeDef(mods, name, List(), typ()) - case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | COMMA | RBRACE => + case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE => typeBounds(mods | Flags.DEFERRED, name) case _ => syntaxErrorOrIncomplete("`=', `>:', or `<:' expected", true) @@ -1982,9 +1996,8 @@ trait Parsers requires SyntaxAnalyzer { atPos(in.currentPos) { def acceptEmptyTemplateBody(msg: String): unit = { if (in.token == LPAREN && settings.migrate.value) - syntaxErrorMigrate("traites may not have parameters") - if (!(in.token == SEMI || in.token == NEWLINE || - in.token == COMMA || in.token == RBRACE || in.token == EOF)) + syntaxErrorMigrate("traits may not have parameters") + if (!(isStatSep || in.token == COMMA || in.token == RBRACE || in.token == EOF)) syntaxError(msg, true) } val parents = new ListBuffer[Tree] @@ -2004,6 +2017,7 @@ trait Parsers requires SyntaxAnalyzer { } else { if (in.token == WITH && settings.migrate.value) syntaxErrorMigrate("`extends' needed before `with'") + newLineOptWhenFollowedBy(LBRACE) if (in.token != LBRACE) acceptEmptyTemplateBody("`extends' or `{' expected") argss += List() } @@ -2077,9 +2091,8 @@ trait Parsers requires SyntaxAnalyzer { in.token == LBRACKET || isModifier) { val annots = annotations() - newLineOpt() stats ++ joinComment(List(tmplDef(modifiers() withAnnotations annots))) - } else if (in.token != SEMI && in.token != NEWLINE) { + } else if (!isStatSep) { syntaxErrorOrIncomplete("expected class or object definition", true) } if (in.token != RBRACE && in.token != EOF) acceptStatSep() @@ -2103,9 +2116,8 @@ trait Parsers requires SyntaxAnalyzer { stats += expr() } else if (isDefIntro || isModifier || in.token == LBRACKET) { val annots = annotations() - newLineOpt() stats ++ joinComment(defOrDcl(modifiers() withAnnotations annots)) - } else if (in.token != SEMI && in.token != NEWLINE) { + } else if (!isStatSep) { syntaxErrorOrIncomplete("illegal start of definition", true) } if (in.token != RBRACE && in.token != EOF) acceptStatSep() @@ -2195,7 +2207,7 @@ trait Parsers requires SyntaxAnalyzer { while (in.token != RBRACE && in.token != EOF) { if (isDclIntro) { stats ++= joinComment(defOrDcl(NoMods)) - } else if (in.token != SEMI && in.token != NEWLINE) { + } else if (!isStatSep) { syntaxErrorOrIncomplete("illegal start of declaration", true) } if (in.token != RBRACE) acceptStatSep() @@ -2252,7 +2264,7 @@ trait Parsers requires SyntaxAnalyzer { localDef(NoMods) } else if (isLocalModifier) { localDef(localModifiers()) - } else if (in.token == SEMI || in.token == NEWLINE) { + } else if (isStatSep) { in.nextToken() } else { syntaxErrorOrIncomplete("illegal start of statement", true) @@ -2271,7 +2283,9 @@ trait Parsers requires SyntaxAnalyzer { if (in.token == PACKAGE) { in.nextToken() val pkg = qualId() - if (in.token == SEMI || in.token == NEWLINE || in.token == EOF) { + if (in.token == EOF) { + ts += makePackaging(pkg, List()) + } else if (isStatSep) { in.nextToken() ts += makePackaging(pkg, topStatSeq()) } else { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index a1ed4b088d..ff0309a470 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -183,15 +183,8 @@ trait Scanners requires SyntaxAnalyzer { next.copyFrom(this) pos = in.lineStartPos if (settings.migrate.value) newNewLine = lastToken != RBRACE && token != EOF; - token = NEWLINE - -/* - } else if (lastToken == RBRACE) { - System.out.println("failing to insert NL after RBRACE: " + sepRegions + " " + - lastPos + " " + in.lineStartPos + " " + pos) -*/ + token = if (in.lastBlankLinePos > lastPos) NEWLINES else NEWLINE } -// System.out.println("token: " + toString());//DEBUG } private def afterLineEnd() = ( @@ -450,7 +443,7 @@ trait Scanners requires SyntaxAnalyzer { def inFirstOfStat(token: int) = token match { case EOF | CASE | CATCH | ELSE | EXTENDS | FINALLY | MATCH | REQUIRES | WITH | YIELD | - COMMA | SEMI | NEWLINE | DOT | USCORE | COLON | EQUALS | ARROW | + COMMA | SEMI | NEWLINE | NEWLINES | DOT | USCORE | COLON | EQUALS | ARROW | LARROW | SUBTYPE | VIEWBOUND | SUPERTYPE | HASH | AT | RPAREN | RBRACKET | RBRACE => false @@ -942,6 +935,8 @@ trait Scanners requires SyntaxAnalyzer { "';'" case NEWLINE => "';'" + case NEWLINES => + "';'" case COMMA => "','" case CASECLASS => @@ -980,6 +975,8 @@ trait Scanners requires SyntaxAnalyzer { ";" case NEWLINE => ";" + case NEWLINES => + ";;" case COMMA => "," case _ => diff --git a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala index 7aaae5e07a..0aed4e8eae 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Tokens.scala @@ -80,11 +80,12 @@ object Tokens { final val LARROW = 67 final val ARROW = 68 final val NEWLINE = 69 - final val SUBTYPE = 70 - final val SUPERTYPE = 71 - final val HASH = 72 - final val AT = 73 - final val VIEWBOUND = 74 + final val NEWLINES = 70 + final val SUBTYPE = 71 + final val SUPERTYPE = 72 + final val HASH = 73 + final val AT = 74 + final val VIEWBOUND = 75 /** parenthesis */ final val LPAREN = 90 diff --git a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala index ffe41b0f72..cb6cf200fe 100644 --- a/src/compiler/scala/tools/nsc/util/CharArrayReader.scala +++ b/src/compiler/scala/tools/nsc/util/CharArrayReader.scala @@ -28,9 +28,21 @@ class CharArrayReader(buf: Array[char], start: int, /* startline: int, startcol: var isUnicode: boolean = _ var lastLineStartPos: int = 0 var lineStartPos: int = 0 + var lastBlankLinePos: int = 0 + + private var onlyBlankChars = false //private var nextline = startline //private var nextcol = startcol + private def markNewLine() { + lastLineStartPos = lineStartPos + if (onlyBlankChars) lastBlankLinePos = lineStartPos + lineStartPos = bp + onlyBlankChars = true + //nextline = nextline + 1; + //nextcol = 1; + } + def hasNext: boolean = bp < buf.length def last: char = if(bp > start + 2) buf(bp - 2) else ' ' // XML literals @@ -45,19 +57,13 @@ class CharArrayReader(buf: Array[char], start: int, /* startline: int, startcol: case '\t' => // nextcol = ((nextcol - 1) / tabinc * tabinc) + tabinc + 1; case CR => - //nextline = nextline + 1; - // nextcol = 1; if (buf(bp) == LF) { ch = LF bp = bp + 1 } - lastLineStartPos = lineStartPos - lineStartPos = bp + markNewLine() case LF | FF => - lastLineStartPos = lineStartPos - lineStartPos = bp - //nextline = nextline + 1 - //nextcol = 1 + markNewLine() case '\\' => def evenSlashPrefix: boolean = { var p = bp - 2 @@ -80,6 +86,7 @@ class CharArrayReader(buf: Array[char], start: int, /* startline: int, startcol: isUnicode = true } case _ => + if (ch > ' ') onlyBlankChars = false // nextcol = nextcol + 1 } } diff --git a/src/library/scala/Iterator.scala b/src/library/scala/Iterator.scala index a4f2c27c25..528fd68635 100644 --- a/src/library/scala/Iterator.scala +++ b/src/library/scala/Iterator.scala @@ -21,7 +21,7 @@ import compat.StringBuilder * * @author Martin Odersky * @author Matthias Zenger - * @version 1.1, 04/02/2004 + * @version 1.2, 10/02/2007 */ object Iterator { @@ -291,14 +291,15 @@ trait Iterator[+A] { private def predicatedIterator(p: A => boolean, isFilter: boolean) = new BufferedIterator[A] { private var hd: A = _ private var ahead: Boolean = false - private var hasMore = Iterator.this.hasNext private def skip: Unit = - while (!ahead && hasMore) { + while (!ahead && Iterator.this.hasNext) { hd = Iterator.this.next - hasMore = Iterator.this.hasNext - ahead = p(hd) + ahead = !isFilter || p(hd) } - def hasNext: Boolean = { skip; ahead || isFilter && hasMore } + def hasNext: Boolean = { + skip + ahead && p(hd) + } def next: A = if (hasNext) { ahead = false; hd } else throw new NoSuchElementException("next on empty iterator") diff --git a/test/files/pos/bug082.scala b/test/files/pos/bug082.scala index af57d3beff..e996d41ae7 100644 --- a/test/files/pos/bug082.scala +++ b/test/files/pos/bug082.scala @@ -5,7 +5,7 @@ object Main { case List() => None case List(x) => Some(x) // case x :: Nil => Some(x) - case y :: ys => min0(less, ys) match { + case y :: ys => (min0(less, ys): @unsealed) match { case Some(m) => if (less(y, m)) Some(y) else Some(m) case None => Some(y) } diff --git a/test/files/pos/partialfun.scala b/test/files/pos/partialfun.scala index 21e4d0a096..9f32a22023 100644 --- a/test/files/pos/partialfun.scala +++ b/test/files/pos/partialfun.scala @@ -5,6 +5,7 @@ object partialfun { applyPartial { case Some(xxx) => xxx + case None => throw new MatchError(None) } (None); -}
\ No newline at end of file +} |