diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-11-18 15:08:14 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-18 15:08:14 +1000 |
commit | 4fe94a2ded7bf64b3d665e32f95978f5c0927805 (patch) | |
tree | 518a3e85b8cc95f8ea7262c0047a2123d6e874ac | |
parent | 73678d4dafe250f0b38df2e953787af26b1a4ee3 (diff) | |
parent | d83a00aabaeabb1cd4c647a43cecd7bb4595dcf6 (diff) | |
download | scala-4fe94a2ded7bf64b3d665e32f95978f5c0927805.tar.gz scala-4fe94a2ded7bf64b3d665e32f95978f5c0927805.tar.bz2 scala-4fe94a2ded7bf64b3d665e32f95978f5c0927805.zip |
Merge pull request #5330 from som-snytt/issue/9885
SI-9885 Don't return offset past EOF
-rw-r--r-- | src/reflect/scala/reflect/internal/util/SourceFile.scala | 23 | ||||
-rw-r--r-- | test/junit/scala/reflect/internal/util/SourceFileTest.scala | 19 |
2 files changed, 33 insertions, 9 deletions
diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala index a2642628a4..64b6972298 100644 --- a/src/reflect/scala/reflect/internal/util/SourceFile.scala +++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala @@ -154,18 +154,23 @@ class BatchSourceFile(val file : AbstractFile, content0: Array[Char]) extends So case _ => false } - def calculateLineIndices(cs: Array[Char]) = { - val buf = new ArrayBuffer[Int] - buf += 0 - for (i <- 0 until cs.length) if (isAtEndOfLine(i)) buf += i + 1 - buf += cs.length // sentinel, so that findLine below works smoother - buf.toArray + private lazy val lineIndices: Array[Int] = { + def calculateLineIndices(cs: Array[Char]) = { + val buf = new ArrayBuffer[Int] + buf += 0 + for (i <- 0 until cs.length) if (isAtEndOfLine(i)) buf += i + 1 + buf += cs.length // sentinel, so that findLine below works smoother + buf.toArray + } + calculateLineIndices(content) } - private lazy val lineIndices: Array[Int] = calculateLineIndices(content) - def lineToOffset(index : Int): Int = lineIndices(index) + def lineToOffset(index: Int): Int = { + val offset = lineIndices(index) + if (offset < length) offset else throw new IndexOutOfBoundsException(index.toString) + } - private var lastLine = 0 + private[this] var lastLine = 0 /** Convert offset to line in this source file. * Lines are numbered from 0. diff --git a/test/junit/scala/reflect/internal/util/SourceFileTest.scala b/test/junit/scala/reflect/internal/util/SourceFileTest.scala index cad23eba14..2f2029ad2d 100644 --- a/test/junit/scala/reflect/internal/util/SourceFileTest.scala +++ b/test/junit/scala/reflect/internal/util/SourceFileTest.scala @@ -5,6 +5,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 +import scala.tools.testing.AssertUtil._ + @RunWith(classOf[JUnit4]) class SourceFileTest { def lineContentOf(code: String, offset: Int) = @@ -57,4 +59,21 @@ class SourceFileTest { assertEquals("def", lineContentOf("abc\r\ndef", 8)) assertEquals("def", lineContentOf("abc\r\ndef\r\n", 9)) } + + @Test def si9885_lineToOffset(): Unit = { + val text = "a\nb\nc\n" + val f = new BatchSourceFile("batch", text) + assertThrows[IndexOutOfBoundsException] { + f.lineToOffset(3) + } + assertEquals(4, f.lineToOffset(2)) + + val p = Position.offset(f, text.length - 1) + val q = Position.offset(f, f.lineToOffset(p.line - 1)) + assertEquals(p.line, q.line) + assertEquals(p.column, q.column + 1) + assertThrows[IndexOutOfBoundsException] { + Position.offset(f, f.lineToOffset(p.line)) + } + } } |