diff options
9 files changed, 91 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala index 99541ff4b4..9646ee1cf0 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/CoreTestDefs.scala @@ -90,8 +90,9 @@ private[tests] trait CoreTestDefs compiler.askLinkPos(tree.symbol, source, r) r.get match { case Left(pos) => + val resolvedPos = if (tree.symbol.pos.isDefined) tree.symbol.pos else pos withResponseDelimiter { - reporter.println("[response] found askHyperlinkPos for `" + tree.symbol.name + "` at " + format(pos) + " " + tree.symbol.sourceFile.name) + reporter.println("[response] found askHyperlinkPos for `" + tree.symbol.name + "` at " + format(resolvedPos) + " " + tree.symbol.sourceFile.name) } case Right(ex) => ex.printStackTrace() diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index 96d92e0609..e5dc8e9ca9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -46,7 +46,7 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => val outer = newTermName("<outer>") val runOrElse = newTermName("runOrElse") val zero = newTermName("zero") - val _match = newTermName("__match") // don't call it __match, since that will trigger virtual pattern matching... + val _match = newTermName("__match") // don't call the val __match, since that will trigger virtual pattern matching... def counted(str: String, i: Int) = newTermName(str+i) } @@ -1067,7 +1067,7 @@ class Foo(x: Other) { x._1 } // no error in this order // assert(owner ne null); assert(owner ne NoSymbol) def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") = - NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo /*repackExistential*/(tp) + NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo tp // codegen relevant to the structure of the translation (how extractors are combined) trait AbsCodegen { @@ -1141,7 +1141,7 @@ class Foo(x: Other) { x._1 } // no error in this order val matchStrategy: Tree def inMatchMonad(tp: Type): Type = appliedType(oneSig, List(tp)).finalResultType - def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.head + def pureType(tp: Type): Type = appliedType(oneSig, List(tp)).paramTypes.headOption getOrElse NoType // fail gracefully (otherwise we get crashes) protected def matchMonadSym = oneSig.finalResultType.typeSymbol import CODE._ diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a956b9a177..934a7567d5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -83,6 +83,9 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser private def isPastTyper = phase.id > currentRun.typerPhase.id + // don't translate matches in presentation compiler: it loses vital symbols that are needed to do hyperlinking + @inline private def doMatchTranslation = !forInteractive && opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id) + abstract class Typer(context0: Context) extends TyperDiagnostics with Adaptation with Tagging with TyperContextErrors { import context0.unit import typeDebug.{ ptTree, ptBlock, ptLine } @@ -2436,7 +2439,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser fun.body match { // later phase indicates scaladoc is calling (where shit is messed up, I tell you) // -- so fall back to old patmat, which is more forgiving - case Match(sel, cases) if opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id) => + case Match(sel, cases) if doMatchTranslation => // go to outer context -- must discard the context that was created for the Function since we're discarding the function // thus, its symbol, which serves as the current context.owner, is not the right owner // you won't know you're using the wrong owner until lambda lift crashes (unless you know better than to use the wrong owner) @@ -3828,7 +3831,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser } def typedTranslatedMatch(tree: Tree, selector: Tree, cases: List[CaseDef]): Tree = { - if (opt.virtPatmat && (phase.id < currentRun.uncurryPhase.id)) { + if (doMatchTranslation) { if (selector ne EmptyTree) { val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt) typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt) @@ -4732,9 +4735,8 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser catches1 = catches1 map (adaptCase(_, mode, owntype)) } - if((phase.id < currentRun.uncurryPhase.id) && opt.virtPatmat) { + if (doMatchTranslation) catches1 = (MatchTranslator(this)).translateTry(catches1, owntype, tree.pos) - } treeCopy.Try(tree, block1, catches1, finalizer1) setType owntype diff --git a/test/files/presentation/callcc-interpreter/Runner.scala b/test/files/presentation/callcc-interpreter/Runner.scala index 61b6efd50d..1ef3cf9025 100644 --- a/test/files/presentation/callcc-interpreter/Runner.scala +++ b/test/files/presentation/callcc-interpreter/Runner.scala @@ -1,5 +1,3 @@ import scala.tools.nsc.interactive.tests._ -object Test extends InteractiveTest { - settings.XoldPatmat.value = true // TODO: could this be running into some kind of race condition? sometimes the match has been translated, sometimes it hasn't -}
\ No newline at end of file +object Test extends InteractiveTest
\ No newline at end of file diff --git a/test/files/presentation/patmat.check b/test/files/presentation/patmat.check new file mode 100644 index 0000000000..29fd8b8e68 --- /dev/null +++ b/test/files/presentation/patmat.check @@ -0,0 +1,36 @@ +reload: PatMatTests.scala + +askHyperlinkPos for `CaseOne` at (12,18) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `CaseOne` at (5,12) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `first` at (14,21) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `first` at (12,29) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `tmp` at (15,19) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `tmp` at (13,13) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `CaseTwo` at (17,18) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `CaseTwo` at (6,12) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `mystring` at (18,24) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `mystring` at (17,25) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `x` at (25,13) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `x` at (23,10) PatMatTests.scala +================================================================================ + +askHyperlinkPos for `y` at (25,21) PatMatTests.scala +================================================================================ +[response] found askHyperlinkPos for `y` at (23,13) PatMatTests.scala +================================================================================ diff --git a/test/files/presentation/patmat.flags b/test/files/presentation/patmat.flags new file mode 100644 index 0000000000..468b48c9e3 --- /dev/null +++ b/test/files/presentation/patmat.flags @@ -0,0 +1,3 @@ +# This test will fail in the new pattern matcher because +# it generates trees whose positions are not transparent +-Xoldpatmat diff --git a/test/files/presentation/patmat/Runner.scala b/test/files/presentation/patmat/Runner.scala new file mode 100644 index 0000000000..3d19f2d948 --- /dev/null +++ b/test/files/presentation/patmat/Runner.scala @@ -0,0 +1,11 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest { + override def runTests() { + // make sure typer is done.. the virtual pattern matcher might translate + // some trees and mess up positions. But we'll catch it red handed! + sourceFiles foreach (src => askLoadedTyped(src).get) + super.runTests() + } + +}
\ No newline at end of file diff --git a/test/files/presentation/patmat/src/PatMatTests.scala b/test/files/presentation/patmat/src/PatMatTests.scala new file mode 100644 index 0000000000..bbd0f2e7ed --- /dev/null +++ b/test/files/presentation/patmat/src/PatMatTests.scala @@ -0,0 +1,28 @@ +package patmat + +abstract class BaseType + +case class CaseOne(x: Int, y: List[Int]) extends BaseType +case class CaseTwo(str: String) extends BaseType + +class PatMatTests { + + def foo(x: BaseType) { + x match { + case CaseOne/*#*/(10, first :: second :: Nil) => + val tmp = 23 + println(first/*#*/) + println(tmp/*#*/) + + case CaseTwo/*#*/(mystring) => + println(mystring/*#*/) + } + } + + def multipleAssign() { + val (x, y) = ("abc", "def") + + println(x/*#*/, y/*#*/) + } + +}
\ No newline at end of file diff --git a/test/files/presentation/random.check b/test/files/presentation/random.check index 1b73720312..fce4b69fb3 100644 --- a/test/files/presentation/random.check +++ b/test/files/presentation/random.check @@ -4,8 +4,7 @@ askType at Random.scala(18,14) ================================================================================ [response] askTypeAt at (18,14) val filter: Int => Boolean = try { - case <synthetic> val x1: Int = java.this.lang.Integer.parseInt(args.apply(0)); - x1 match { + java.this.lang.Integer.parseInt(args.apply(0)) match { case 1 => ((x: Int) => x.%(2).!=(0)) case 2 => ((x: Int) => x.%(2).==(0)) case _ => ((x: Int) => x.!=(0)) |