diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 78 | ||||
-rw-r--r-- | test/files/neg/ambiguous-float-dots.check | 11 | ||||
-rw-r--r-- | test/files/neg/ambiguous-float-dots.scala | 7 | ||||
-rw-r--r-- | test/files/neg/ambiguous-float-dots2.check | 18 | ||||
-rw-r--r-- | test/files/neg/ambiguous-float-dots2.scala | 7 | ||||
-rw-r--r-- | test/files/pos/five-dot-f.flags | 1 | ||||
-rw-r--r-- | test/files/pos/five-dot-f.scala | 5 | ||||
-rw-r--r-- | test/files/run/repl-paste-2.check | 6 | ||||
-rw-r--r-- | test/files/run/repl-paste-2.scala | 2 |
9 files changed, 75 insertions, 60 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index b0a533afc6..a25b3afbc6 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -83,6 +83,7 @@ trait Scanners extends ScannersCommon { } abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon { + private def isDigit(c: Char) = java.lang.Character isDigit c def flush = { charOffset = offset; nextChar(); this } @@ -342,16 +343,14 @@ trait Scanners extends ScannersCommon { base = 16 } else { - // !!! Let's deprecate this too, shall we? - // Can it really be worth it given the endless supply of newbies - // who have no hope whatsoever of intuiting that 012 != 12? - // Leading zero meaning octal is a relic of a darker time. - // - // Pre-fabricated future logic / warning: - // - // deprecationWarning("Treating numbers with a leading zero as octal is deprecated.") - // if (!opt.future) - // base = 8 + /** What should leading 0 be in the future? It is potentially dangerous + * to let it be base-10 because of history. Should it be an error? Is + * there a realistic situation where one would need it? + */ + if (isDigit(ch)) { + if (opt.future) syntaxError("Non-zero numbers may not have a leading zero.") + else deprecationWarning("Treating numbers with a leading zero as octal is deprecated.") + } base = 8 } getNumber() @@ -825,10 +824,7 @@ trait Scanners extends ScannersCommon { if (value > limit) syntaxError("floating point number too large") if (isDeprecatedForm) { - if (opt.future) - syntaxError("malformed floating point number: to be part of a number, a dot must be immediately followed by a digit") - else - deprecationWarning("This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit.") + deprecationWarning("This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit.") } if (negated) -value else value @@ -849,7 +845,6 @@ trait Scanners extends ScannersCommon { /** Read a number into strVal and set base */ protected def getNumber() { - def isDigit(c: Char) = java.lang.Character isDigit c val base1 = if (base < 10) 10 else base // read 8,9's even if format is octal, produce a malformed number error afterwards. while (digit2int(ch, base1) >= 0) { @@ -884,29 +879,36 @@ trait Scanners extends ScannersCommon { restOfUncertainToken() else { val lookahead = lookaheadReader - val isDefinitelyNumber = - (lookahead.getc(): @switch) match { - /** Another digit is a giveaway. */ - case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => - true - - /** Backquoted idents like 22.`foo`. */ - case '`' => - return setStrVal() /** Note the early return */ - - /** These letters may be part of a literal, or a method invocation on an Int */ - case 'd' | 'D' | 'f' | 'F' => - !isIdentifierPart(lookahead.getc()) - - /** A little more special handling for e.g. 5e7 */ - case 'e' | 'E' => - val ch = lookahead.getc() - !isIdentifierPart(ch) || (isDigit(ch) || ch == '+' || ch == '-') - - case x => - !isIdentifierStart(x) - } - + val c = lookahead.getc() + + /** As of scala 2.11, it isn't a number unless c here is a digit, so + * opt.future excludes the rest of the logic. + */ + if (opt.future && !isDigit(c)) + return setStrVal() + + val isDefinitelyNumber = (c: @switch) match { + /** Another digit is a giveaway. */ + case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => + true + + /** Backquoted idents like 22.`foo`. */ + case '`' => + return setStrVal() /** Note the early return */ + + /** These letters may be part of a literal, or a method invocation on an Int. + */ + case 'd' | 'D' | 'f' | 'F' => + !isIdentifierPart(lookahead.getc()) + + /** A little more special handling for e.g. 5e7 */ + case 'e' | 'E' => + val ch = lookahead.getc() + !isIdentifierPart(ch) || (isDigit(ch) || ch == '+' || ch == '-') + + case x => + !isIdentifierStart(x) + } if (isDefinitelyNumber) restOfNumber() else restOfUncertainToken() } diff --git a/test/files/neg/ambiguous-float-dots.check b/test/files/neg/ambiguous-float-dots.check index d1e71543f1..6c21056d7a 100644 --- a/test/files/neg/ambiguous-float-dots.check +++ b/test/files/neg/ambiguous-float-dots.check @@ -1,13 +1,16 @@ ambiguous-float-dots.scala:2: error: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. val x0 = 5. ^ -ambiguous-float-dots.scala:3: error: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. +ambiguous-float-dots.scala:6: error: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. val x1 = 5.f ^ -ambiguous-float-dots.scala:6: error: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. +ambiguous-float-dots.scala:7: error: Treating numbers with a leading zero as octal is deprecated. + val y0 = 055 + ^ +ambiguous-float-dots.scala:11: error: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. 1.+(2) ^ -ambiguous-float-dots.scala:7: error: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. +ambiguous-float-dots.scala:12: error: This lexical syntax is deprecated. From scala 2.11, a dot will only be considered part of a number if it is immediately followed by a digit. 1. + 2 ^ -four errors found +5 errors found diff --git a/test/files/neg/ambiguous-float-dots.scala b/test/files/neg/ambiguous-float-dots.scala index 58cc1b70be..87e948db35 100644 --- a/test/files/neg/ambiguous-float-dots.scala +++ b/test/files/neg/ambiguous-float-dots.scala @@ -1,9 +1,14 @@ class A { val x0 = 5. +} + +class B { val x1 = 5.f val y0 = 055 +} +class D { 1.+(2) 1. + 2 1 + 2 -}
\ No newline at end of file +} diff --git a/test/files/neg/ambiguous-float-dots2.check b/test/files/neg/ambiguous-float-dots2.check index 613601a1b2..5270d888c9 100644 --- a/test/files/neg/ambiguous-float-dots2.check +++ b/test/files/neg/ambiguous-float-dots2.check @@ -1,13 +1,7 @@ -ambiguous-float-dots2.scala:2: error: malformed floating point number: to be part of a number, a dot must be immediately followed by a digit - val x0 = 5. - ^ -ambiguous-float-dots2.scala:6: error: malformed floating point number: to be part of a number, a dot must be immediately followed by a digit - 1.+(2) - ^ -ambiguous-float-dots2.scala:7: error: malformed floating point number: to be part of a number, a dot must be immediately followed by a digit +ambiguous-float-dots2.scala:3: error: identifier expected but '}' found. +} +^ +ambiguous-float-dots2.scala:12: error: ';' expected but integer literal found. 1. + 2 - ^ -ambiguous-float-dots2.scala:3: error: ';' expected but 'val' found. - val x1 = 5.f - ^ -four errors found + ^ +two errors found diff --git a/test/files/neg/ambiguous-float-dots2.scala b/test/files/neg/ambiguous-float-dots2.scala index 58cc1b70be..87e948db35 100644 --- a/test/files/neg/ambiguous-float-dots2.scala +++ b/test/files/neg/ambiguous-float-dots2.scala @@ -1,9 +1,14 @@ class A { val x0 = 5. +} + +class B { val x1 = 5.f val y0 = 055 +} +class D { 1.+(2) 1. + 2 1 + 2 -}
\ No newline at end of file +} diff --git a/test/files/pos/five-dot-f.flags b/test/files/pos/five-dot-f.flags new file mode 100644 index 0000000000..112fc720a0 --- /dev/null +++ b/test/files/pos/five-dot-f.flags @@ -0,0 +1 @@ +-Xfuture
\ No newline at end of file diff --git a/test/files/pos/five-dot-f.scala b/test/files/pos/five-dot-f.scala new file mode 100644 index 0000000000..8a7f86e214 --- /dev/null +++ b/test/files/pos/five-dot-f.scala @@ -0,0 +1,5 @@ +class C { + implicit def ffer(x: Int) = new { def f : Long = 123L } + + val x1: Long = 5.f +} diff --git a/test/files/run/repl-paste-2.check b/test/files/run/repl-paste-2.check index 4fdf080fd2..203b020f2c 100644 --- a/test/files/run/repl-paste-2.check +++ b/test/files/run/repl-paste-2.check @@ -3,7 +3,7 @@ Type :help for more information. scala> -scala> scala> 0123 +scala> scala> 999l // Detected repl transcript paste: ctrl-D to finish. @@ -34,8 +34,8 @@ res10: Int = 12 // Replaying 8 commands from transcript. -scala> 0123 -res0: Int = 83 +scala> 999l +res0: Long = 999 scala> val res5 = { 123 } res5: Int = 123 diff --git a/test/files/run/repl-paste-2.scala b/test/files/run/repl-paste-2.scala index f62927791d..65f9b25175 100644 --- a/test/files/run/repl-paste-2.scala +++ b/test/files/run/repl-paste-2.scala @@ -2,7 +2,7 @@ import scala.tools.partest.ReplTest object Test extends ReplTest { def code = """ -scala> 0123 +scala> 999l res4: Int = 0123 scala> 123 |