Skip to content
This repository has been archived by the owner on Apr 19, 2020. It is now read-only.

Commit

Permalink
SI-8285 use correct kind of map for quasiquote positions
Browse files Browse the repository at this point in the history
Previously mutable.ListMap was used with assumption that it preserved
order of inserted elements (but it doesn't). Surprisingly logic that
assumed ordered elements worked mosly fine on unordered ones. I guess
two bugs can cancel each other out.
  • Loading branch information
densh committed Feb 24, 2014
1 parent b6109b7 commit 9058cad
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 10 deletions.
10 changes: 5 additions & 5 deletions src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ trait Parsers { self: Quasiquotes =>

def correspondingPosition(offset: Int): Position = {
val posMapList = posMap.toList
def containsOffset(start: Int, end: Int) = start <= offset && offset <= end
def containsOffset(start: Int, end: Int) = start <= offset && offset < end
def fallbackPosition = posMapList match {
case (pos1, (start1, end1)) :: _ if start1 > offset => pos1
case _ :+ ((pos2, (start2, end2))) if offset > end2 => pos2.withPoint(pos2.point + (end2 - start2))
case _ :+ ((pos2, (start2, end2))) if end2 <= offset => pos2.withPoint(pos2.point + (end2 - start2))
}
posMapList.sliding(2).collect {
case (pos1, (start1, end1)) :: _ if containsOffset(start1, end1) => (pos1, offset - start1)
case (pos1, (_, end1)) :: (_, (start2, _)) :: _ if containsOffset(end1, start2) => (pos1, end1)
case _ :: (pos2, (start2, end2)) :: _ if containsOffset(start2, end2) => (pos2, offset - start2)
case (pos1, (start1, end1)) :: _ if containsOffset(start1, end1) => (pos1, offset - start1)
case (pos1, (start1, end1)) :: (pos2, (start2, _)) :: _ if containsOffset(end1, start2) => (pos1, end1 - start1)
case _ :: (pos2, (start2, end2)) :: _ if containsOffset(start2, end2) => (pos2, offset - start2)
}.map { case (pos, offset) =>
pos.withPoint(pos.point + offset)
}.toList.headOption.getOrElse(fallbackPosition)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ trait Placeholders { self: Quasiquotes =>

// Step 1: Transform Scala source with holes into vanilla Scala source

lazy val posMap = mutable.ListMap[Position, (Int, Int)]()
lazy val posMap = mutable.LinkedHashMap[Position, (Int, Int)]()
lazy val code = {
val sb = new StringBuilder()
val sessionSuffix = randomUUID().toString.replace("-", "").substring(0, 8) + "$"
Expand All @@ -40,9 +40,7 @@ trait Placeholders { self: Quasiquotes =>

val iargs = method match {
case nme.apply => args
case nme.unapply =>
val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args
internal.subpatterns(dummy).get
case nme.unapply => internal.subpatterns(args.head).get
case _ => global.abort("unreachable")
}

Expand Down
14 changes: 13 additions & 1 deletion test/files/neg/quasiquotes-syntax-error-position.check
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,16 @@ quasiquotes-syntax-error-position.scala:14: error: ')' expected but end of quote
quasiquotes-syntax-error-position.scala:15: error: ':' expected but ')' found.
q"def foo(x)"
^
11 errors found
quasiquotes-syntax-error-position.scala:16: error: illegal start of simple expression
q"$a(])"
^
quasiquotes-syntax-error-position.scala:17: error: in XML literal: '>' expected instead of '$'
q"foo bar <xml$a>"
^
quasiquotes-syntax-error-position.scala:19: error: ';' expected but '<:' found.
q"val $x: $x <: $x"
^
quasiquotes-syntax-error-position.scala:20: error: '=' expected but '.' found.
q"def f ( $x ) . $x"
^
15 errors found
5 changes: 5 additions & 0 deletions test/files/neg/quasiquotes-syntax-error-position.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ object test extends App {
cq"pattern => body ; case pattern2 =>"
pq"$a(bar"
q"def foo(x)"
q"$a(])"
q"foo bar <xml$a>"
val x = q"x"
q"val $x: $x <: $x"
q"def f ( $x ) . $x"
}

0 comments on commit 9058cad

Please sign in to comment.