summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-02-12 11:06:34 +0000
committerMartin Odersky <odersky@gmail.com>2007-02-12 11:06:34 +0000
commit94e3a13f24d98e3e71bc8f041df8241beb43b234 (patch)
treeba6235220d7e2b4f4afd4b629b7e7dec312439a3 /src/compiler
parentd7dc0ad355418a5d297f5baf269404d95a2976b2 (diff)
downloadscala-94e3a13f24d98e3e71bc8f041df8241beb43b234.tar.gz
scala-94e3a13f24d98e3e71bc8f041df8241beb43b234.tar.bz2
scala-94e3a13f24d98e3e71bc8f041df8241beb43b234.zip
small fixes to newline behavior.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala66
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala15
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Tokens.scala11
-rw-r--r--src/compiler/scala/tools/nsc/util/CharArrayReader.scala23
4 files changed, 67 insertions, 48 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
}
}