All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.org.antlr.v4.kotlinruntime.ast.Point.kt Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
// Copyright 2017-present Strumenta and contributors, licensed under Apache 2.0.
// Copyright 2024-present Strumenta and contributors, licensed under BSD 3-Clause.
package org.antlr.v4.kotlinruntime.ast

/**
 * Represents a `[line:column]` coordinate inside a textual source.
 *
 * @param line Should be in the `1..n` range
 * @param column Should be in the `0..n` range
 */
public data class Point(val line: Int, val column: Int) {
  private companion object {
    private val lineBreakRegex = Regex("\r\n|\r|\n")
  }

  init {
    require(line >= 1) {
      "Line should be equal or greater than 1, but was $line"
    }

    require(column >= 0) {
      "Column should be equal or greater than 0, but was $column"
    }
  }

  override fun toString(): String =
    "line $line : column $column"

  /**
   * Translate the point to an offset in the original code stream.
   */
  public fun offset(code: String): Int {
    val lines = code.split("\n")

    require(lines.size >= line) {
      "The point does not exist in the given text. It indicates line $line but there are only ${lines.size} lines"
    }

    require(lines[line - 1].length >= column) {
      "The column does not exist in the given text. Line $line has ${lines[line - 1].length} columns, the point indicates column $column"
    }

    val newLines = line - 1
    val foldedLines = lines.subList(0, line - 1).foldRight(0) { it, acc ->
      it.length + acc
    }

    return foldedLines + newLines + column
  }

  public fun isBefore(other: Point): Boolean =
    line < other.line || (line == other.line && column < other.column)

  public fun advance(text: String): Point {
    val matches = lineBreakRegex.findAll(text)
    val line = line + matches.count()
    val col = if (matches.none()) {
      column + text.length
    } else {
      text.length - matches.last().range.last - 1
    }

    return Point(line, col)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy