diff --git a/src/main/scala/viper/silver/parser/FastParser.scala b/src/main/scala/viper/silver/parser/FastParser.scala index 4378db354..2733a004e 100644 --- a/src/main/scala/viper/silver/parser/FastParser.scala +++ b/src/main/scala/viper/silver/parser/FastParser.scala @@ -34,12 +34,21 @@ object FastParser extends PosParser[Char, String] { */ val standard_import_directory = "import" - var _lines: Array[Int] = null + var _line_offset: Array[Int] = null def parse(s: String, f: Path, plugins: Option[SilverPluginManager] = None) = { _file = f.toAbsolutePath + + // Add an empty line at the end to make `computeFrom(s.length)` return `(lines.length, 1)`, as the old + // implementation of `computeFrom` used to do. val lines = s.linesWithSeparators - _lines = lines.map(_.length).toArray + _line_offset = (lines.map(_.length) ++ Seq(0)).toArray + var offset = 0 + for (i <- _line_offset.indices) { + val line_length = _line_offset(i) + _line_offset(i) = offset + offset += line_length + } // Strategy to handle imports // Idea: Import every import reference and merge imported methods, functions, imports, .. into current program @@ -155,7 +164,6 @@ object FastParser extends PosParser[Char, String] { column = pos.column } ParseError(msg, SourcePosition(_file, line, column)) - case _:Throwable => } } diff --git a/src/main/scala/viper/silver/parser/ParserPositions.scala b/src/main/scala/viper/silver/parser/ParserPositions.scala index 1170fb4fa..32d5a3bfc 100644 --- a/src/main/scala/viper/silver/parser/ParserPositions.scala +++ b/src/main/scala/viper/silver/parser/ParserPositions.scala @@ -30,15 +30,17 @@ case class FilePosition(file: Path, vline: Int, col: Int) extends util.parsing.i trait PosComputer { def computeFrom(index: Int) : (Int, Int) = { - var left = index - var i = 0 - val arr = FastParser._lines - while (i < arr.length && left >= arr(i)){ - left -= arr(i) - i += 1 + val line_offset = FastParser._line_offset + val result = java.util.Arrays.binarySearch(line_offset, index) + if (result >= 0) { + // Exact match + val line = result + (line + 1, index - line_offset(line) + 1) + } else { + // The binary search returned `- insertionPoint - 1` + val line = - result - 2 + (line + 1, index - line_offset(line) + 1) } - val r1 = (i + 1, left + 1) - r1 } } /**