From 32b1ff7d42a6126cbcc316ba55315e3dd28df7c5 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 6 Jan 2019 22:38:16 +0100 Subject: [PATCH 1/5] Open patch file for writing later Open patch file for writing later only once all patches are applied, so that any assertion errors during patch generation cannot result in an empty output file. --- compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala b/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala index 6dc080502a2e..9eeea228963d 100644 --- a/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala +++ b/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala @@ -51,9 +51,9 @@ object Rewrites { } def writeBack(): Unit = { - val out = source.file.output val chars = apply(source.underlying.content) val bytes = new String(chars).getBytes + val out = source.file.output out.write(bytes) out.close() } From 642ebaffd613d978547293c6282aff6834795561 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 6 Jan 2019 22:39:11 +0100 Subject: [PATCH 2/5] Don't rewrite when syntax highlighting The syntax highlighter creates its own copy of a parser. This parser should not apply any patches, since these would be duplicates. --- compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala b/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala index 9eeea228963d..34b29d7c54bf 100644 --- a/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala +++ b/compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala @@ -6,6 +6,7 @@ import Positions.Position import core.Contexts.Context import collection.mutable import scala.annotation.tailrec +import dotty.tools.dotc.reporting.Reporter /** Handles rewriting of Scala2 files to Dotty */ object Rewrites { @@ -63,10 +64,11 @@ object Rewrites { * given by `pos` in `source` by `replacement` */ def patch(source: SourceFile, pos: Position, replacement: String)(implicit ctx: Context): Unit = - for (rewrites <- ctx.settings.rewrite.value) - rewrites.patched - .getOrElseUpdate(source, new Patches(source)) - .addPatch(pos, replacement) + if (ctx.reporter != Reporter.NoReporter) // NoReporter is used for syntax highlighting + for (rewrites <- ctx.settings.rewrite.value) + rewrites.patched + .getOrElseUpdate(source, new Patches(source)) + .addPatch(pos, replacement) /** Patch position in `ctx.compilationUnit.source`. */ def patch(pos: Position, replacement: String)(implicit ctx: Context): Unit = From c84349a22767559128a7961cc631bc458f692e09 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 6 Jan 2019 22:40:03 +0100 Subject: [PATCH 3/5] Allow symbol literals only in Scala-2 mode Offer to rewrite them to Symbol("...") calls. --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index cc42e77d38d6..541b50bf4079 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -659,7 +659,15 @@ object Parsers { } val isNegated = negOffset < in.offset atPos(negOffset) { - if (in.token == SYMBOLLIT) atPos(in.skipToken()) { SymbolLit(in.strVal) } + if (in.token == SYMBOLLIT) { + migrationWarningOrError(em"""symbol literal '${in.name} is no longer supported, + |use a string literal "${in.name}" or an application Symbol("${in.name}") instead.""") + if (in.isScala2Mode) { + patch(source, Position(in.offset, in.offset + 1), "Symbol(\"") + patch(source, Position(in.charOffset - 1), "\")") + } + atPos(in.skipToken()) { SymbolLit(in.strVal) } + } else if (in.token == INTERPOLATIONID) interpolatedString(inPattern) else finish(in.token match { case CHARLIT => in.charVal From 1b8b47a00ffed2e780e8e1e84c998154a3f36836 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 6 Jan 2019 23:02:45 +0100 Subject: [PATCH 4/5] Update tests to not use symbol literals All tests were automatically rewritten --- tests/{ => invalid}/pos/sip23-symbols.scala | 0 tests/neg/sip23-symbols.scala | 8 +++--- tests/pos/desugar.scala | 2 +- tests/pos/literals.scala | 1 - tests/pos/t389.scala | 8 +++--- tests/pos/t4579.scala | 30 ++++++++++----------- tests/pos/t4812.scala | 2 +- tests/run/arrays.scala | 2 +- tests/run/fors.scala | 2 +- tests/run/t4601.scala | 2 +- tests/run/t6632.scala | 12 ++++----- tests/run/t6633.scala | 6 ++--- tests/run/t6634.scala | 2 +- tests/run/t8933b/A.scala | 2 +- tests/run/t8933b/Test.scala | 2 +- 15 files changed, 40 insertions(+), 41 deletions(-) rename tests/{ => invalid}/pos/sip23-symbols.scala (100%) diff --git a/tests/pos/sip23-symbols.scala b/tests/invalid/pos/sip23-symbols.scala similarity index 100% rename from tests/pos/sip23-symbols.scala rename to tests/invalid/pos/sip23-symbols.scala diff --git a/tests/neg/sip23-symbols.scala b/tests/neg/sip23-symbols.scala index 430cced5ffc7..cbec1f5816a2 100644 --- a/tests/neg/sip23-symbols.scala +++ b/tests/neg/sip23-symbols.scala @@ -1,7 +1,7 @@ object Test { - val sym0 = 's + val sym0 = 's // error: no longer supported //sym0: Symbol - sym0: 's // error + sym0: 's // error // error: no longer supported //val sym1: 's = 's //sym1: Symbol @@ -15,9 +15,9 @@ object Test { type Identity[T] = T def narrow[T <: Singleton](t: T): Identity[T] = t - final val sym3 = id('s) + final val sym3 = id('s) // error: no longer supported //sym3: Symbol - sym3: 's // error + sym3: 's // error // error: no longer supported //val sym4 = narrow('s) //sym4: Symbol diff --git a/tests/pos/desugar.scala b/tests/pos/desugar.scala index cc679498578f..7ea56f9c1fb1 100644 --- a/tests/pos/desugar.scala +++ b/tests/pos/desugar.scala @@ -70,7 +70,7 @@ object desugar { } object misc { - 'hello + Symbol("hello") s"this is a $x + ${x + y} string" type ~[X, Y] = Tuple2[X, Y] val pair: Int ~ String = 1 -> "abc" diff --git a/tests/pos/literals.scala b/tests/pos/literals.scala index 003789eff1b9..ff76b6aa372c 100644 --- a/tests/pos/literals.scala +++ b/tests/pos/literals.scala @@ -5,5 +5,4 @@ object Test { val d: 1.0 = 1.0 val e: true = true val f: '*' = '*' - val g: 'a = 'a } diff --git a/tests/pos/t389.scala b/tests/pos/t389.scala index 535bd4de8715..e63ddc09aa0a 100644 --- a/tests/pos/t389.scala +++ b/tests/pos/t389.scala @@ -1,7 +1,7 @@ object Test { - def a = 'a - def b = 'B - def c = '+ + def a = Symbol("a") + def b = Symbol("B") + def c = Symbol("+") //def d = '`\n` //error: unclosed character literal - def e = '\u0041 + def e = Symbol("\u0041") } diff --git a/tests/pos/t4579.scala b/tests/pos/t4579.scala index 907593e5bd73..500ffae40200 100644 --- a/tests/pos/t4579.scala +++ b/tests/pos/t4579.scala @@ -303,17 +303,17 @@ object LispAny extends Lisp { def asBoolean(x: Data): Boolean = x != 0 def normalize(x: Data): Data = x match { - case 'and :: x :: y :: Nil => - normalize('if :: x :: y :: 0 :: Nil) - case 'or :: x :: y :: Nil => - normalize('if :: x :: 1 :: y :: Nil) - case 'def :: (name :: args) :: body :: expr :: Nil => - normalize('def :: name :: ('lambda :: args :: body :: Nil) :: expr :: Nil) - case 'cond :: ('else :: expr :: Nil) :: rest => + case Symbol("and") :: x :: y :: Nil => + normalize(Symbol("if") :: x :: y :: 0 :: Nil) + case Symbol("or") :: x :: y :: Nil => + normalize(Symbol("if") :: x :: 1 :: y :: Nil) + case Symbol("def") :: (name :: args) :: body :: expr :: Nil => + normalize(Symbol("def") :: name :: (Symbol("lambda") :: args :: body :: Nil) :: expr :: Nil) + case Symbol("cond") :: (Symbol("else") :: expr :: Nil) :: rest => normalize(expr); - case 'cond :: (test :: expr :: Nil) :: rest => - normalize('if :: test :: expr :: ('cond :: rest) :: Nil) - case 'cond :: 'else :: expr :: Nil => + case Symbol("cond") :: (test :: expr :: Nil) :: rest => + normalize(Symbol("if") :: test :: expr :: (Symbol("cond") :: rest) :: Nil) + case Symbol("cond") :: Symbol("else") :: expr :: Nil => normalize(expr) case h :: t => normalize(h) :: asList(normalize(t)) @@ -342,15 +342,15 @@ object LispAny extends Lisp { def eval1(x: Data, env: Environment): Data = x match { case Symbol(name) => env lookup name - case 'def :: Symbol(name) :: y :: z :: Nil => + case Symbol("def") :: Symbol(name) :: y :: z :: Nil => eval(z, env.extendRec(name, (env1 => eval(y, env1)))) - case 'val :: Symbol(name) :: y :: z :: Nil => + case Symbol("val") :: Symbol(name) :: y :: z :: Nil => eval(z, env.extend(name, eval(y, env))) - case 'lambda :: params :: y :: Nil => + case Symbol("lambda") :: params :: y :: Nil => mkLambda(params, y, env) - case 'if :: c :: y :: z :: Nil => + case Symbol("if") :: c :: y :: z :: Nil => if (asBoolean(eval(c, env))) eval(y, env) else eval(z, env) - case 'quote :: y :: Nil => + case Symbol("quote") :: y :: Nil => y case y :: z => apply(eval(y, env), z map (x => eval(x, env))) diff --git a/tests/pos/t4812.scala b/tests/pos/t4812.scala index da223677078e..49446160cd18 100644 --- a/tests/pos/t4812.scala +++ b/tests/pos/t4812.scala @@ -1,4 +1,4 @@ trait Test1 { - def m1(sym: Symbol = 'TestSym): Unit + def m1(sym: Symbol = Symbol("TestSym")): Unit def m2(s: String = "TestString"): Unit } diff --git a/tests/run/arrays.scala b/tests/run/arrays.scala index 1a77a191cbcf..1cb4caa88b6e 100644 --- a/tests/run/arrays.scala +++ b/tests/run/arrays.scala @@ -206,7 +206,7 @@ object Test { val a2: Int = 0; val a3: Null = null; val a4: String = "a-z"; - val a5: Symbol = 'token; + val a5: Symbol = Symbol("token"); val a6: HashMap = new HashMap(); val a7: TreeMap = scala.collection.immutable.TreeMap.empty[Int, Any]; val a8: Strings = List("a", "z"); diff --git a/tests/run/fors.scala b/tests/run/fors.scala index f498a3a65c7d..69455b55dc3a 100644 --- a/tests/run/fors.scala +++ b/tests/run/fors.scala @@ -6,7 +6,7 @@ object Test extends dotty.runtime.LegacyApp { val xs = List(1, 2, 3) - val ys = List('a, 'b, 'c) + val ys = List(Symbol("a"), Symbol("b"), Symbol("c")) def it = 0 until 10 diff --git a/tests/run/t4601.scala b/tests/run/t4601.scala index 300da58b276d..ae4e0dd06cab 100644 --- a/tests/run/t4601.scala +++ b/tests/run/t4601.scala @@ -4,7 +4,7 @@ trait B { self: A => def test: Unit = { - println('blubber) + println(Symbol("blubber")) } } diff --git a/tests/run/t6632.scala b/tests/run/t6632.scala index baf4e7309ded..a7a01094fe06 100644 --- a/tests/run/t6632.scala +++ b/tests/run/t6632.scala @@ -1,22 +1,22 @@ object Test extends dotty.runtime.LegacyApp { import collection.mutable.ListBuffer - def newLB = ListBuffer('a, 'b, 'c, 'd, 'e) + def newLB = ListBuffer(Symbol("a"), Symbol("b"), Symbol("c"), Symbol("d"), Symbol("e")) def iiobe[A](f: => A) = try { f } catch { case ex: IndexOutOfBoundsException => println(ex) } val lb0 = newLB - iiobe( lb0.insert(-1, 'x) ) + iiobe( lb0.insert(-1, Symbol("x")) ) val lb1 = newLB - iiobe( lb1.insertAll(-2, Array('x, 'y, 'z)) ) + iiobe( lb1.insertAll(-2, Array(Symbol("x"), Symbol("y"), Symbol("z"))) ) val lb2 = newLB - iiobe( lb2.update(-3, 'u) ) + iiobe( lb2.update(-3, Symbol("u")) ) val lb3 = newLB - iiobe( lb3.updated(-1, 'u) ) - iiobe( lb3.updated(5, 'u) ) + iiobe( lb3.updated(-1, Symbol("u")) ) + iiobe( lb3.updated(5, Symbol("u")) ) } diff --git a/tests/run/t6633.scala b/tests/run/t6633.scala index 852fc571418e..d78bf9ac6aed 100644 --- a/tests/run/t6633.scala +++ b/tests/run/t6633.scala @@ -1,12 +1,12 @@ object Test extends dotty.runtime.LegacyApp { import collection.mutable.ListBuffer - def newLB = ListBuffer('a, 'b, 'c, 'd, 'e) + def newLB = ListBuffer(Symbol("a"), Symbol("b"), Symbol("c"), Symbol("d"), Symbol("e")) val lb0 = newLB try { - lb0.insert(9, 'x) + lb0.insert(9, Symbol("x")) } catch { case ex: IndexOutOfBoundsException => println(ex) } @@ -14,7 +14,7 @@ object Test extends dotty.runtime.LegacyApp { val lb1 = newLB try { - lb1.insert(9, 'x) + lb1.insert(9, Symbol("x")) } catch { case ex: IndexOutOfBoundsException => } diff --git a/tests/run/t6634.scala b/tests/run/t6634.scala index 37076028329f..792f76ec2f54 100644 --- a/tests/run/t6634.scala +++ b/tests/run/t6634.scala @@ -2,7 +2,7 @@ import collection.mutable.ListBuffer //object Test extends dotty.runtime.LegacyApp { object Test extends App { - def newLB = ListBuffer('a, 'b, 'c, 'd, 'e) + def newLB = ListBuffer(Symbol("a"), Symbol("b"), Symbol("c"), Symbol("d"), Symbol("e")) val lb0 = newLB println("Trying lb0 ...") diff --git a/tests/run/t8933b/A.scala b/tests/run/t8933b/A.scala index d25d893c6f47..3442ff426da3 100644 --- a/tests/run/t8933b/A.scala +++ b/tests/run/t8933b/A.scala @@ -1,4 +1,4 @@ trait MixinWithSymbol { self: MotherClass => - def symbolFromTrait: Any = 'traitSymbol + def symbolFromTrait: Any = Symbol("traitSymbol") } diff --git a/tests/run/t8933b/Test.scala b/tests/run/t8933b/Test.scala index 7ce239b7d16b..c6e0551e2501 100644 --- a/tests/run/t8933b/Test.scala +++ b/tests/run/t8933b/Test.scala @@ -1,5 +1,5 @@ class MotherClass extends MixinWithSymbol { - def foo = 'sym1 + def foo = Symbol("sym1") } object Test { From 927cbc77c991f8c9613975cae9755fe417577257 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 6 Jan 2019 23:03:09 +0100 Subject: [PATCH 5/5] Add to drop features documentation --- docs/docs/reference/dropped-features/symlits.md | 7 +++++++ docs/sidebar.yml | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 docs/docs/reference/dropped-features/symlits.md diff --git a/docs/docs/reference/dropped-features/symlits.md b/docs/docs/reference/dropped-features/symlits.md new file mode 100644 index 000000000000..211ceab1aef0 --- /dev/null +++ b/docs/docs/reference/dropped-features/symlits.md @@ -0,0 +1,7 @@ +--- +layout: doc-page +title: Dropped: Symbol Literals +--- + +Symbol literals are no longer supported. The `scala.Symbol` class still exists, so a +literal translation of the symbol literal `'xyz` is `Symbol("xyz")`. However, it is recommended to use a plain string literal `"xyz"` instead. (The `Symbol` class will be deprecated and removed in the future). diff --git a/docs/sidebar.yml b/docs/sidebar.yml index dc86c2949671..afb476df13d7 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -109,6 +109,8 @@ sidebar: url: docs/reference/dropped-features/limit22.html - title: XML literals url: docs/reference/dropped-features/xml.html + - title: Symbol Literals + url: docs/reference/dropped-features/symlits.html - title: Auto-Application url: docs/reference/dropped-features/auto-apply.html - title: Weak Conformance