/*
* Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
package stdx.chir
import std.fs.*
/**
* A single point in a source file (line and column, 1-based when valid).
*
* Used as start or end position inside DebugLocation.
*/
public struct Position <: ToString {
private let _line: Int64
private let _column: Int64
/**
* 1-based line number in the source file.
* @type { Int64 }
*/
public prop line: Int64 {
get() {
return _line
}
}
/**
* 1-based column number in the source file.
* @type { Int64 }
*/
public prop column: Int64 {
get() {
return _column
}
}
/**
* Whether this position holds a real source location (line and column both greater than 0).
* @return true when line and column are both positive.
*/
public func isValid(): Bool {
return line > 0 && column > 0
}
/**
* Compact string form "-line-column" for debugging.
* @return Text starting with `-` followed by line and column.
*/
public func toString(): String {
let result = StringBuilder()
result.append("-")
result.append(line.toString())
result.append("-")
result.append(column.toString())
return result.toString()
}
internal init() {
this._line = 0
this._column = 0
}
internal init(line: Int64, column: Int64) {
this._line = line
this._column = column
}
}
/**
* Span in a source file (start/end positions and path) for CHIR debug info.
*/
public class DebugLocation <: ToString {
internal var _fileId: UInt64 = 0
internal var _scopeInfo: ArrayList<Int64> = ArrayList<Int64>()
private let _end: Position
private let _filePath: Path
private let _start: Position
/**
* End position of the span.
* @type { Position }
*/
public prop end: Position {
get() {
return _end
}
}
/**
* Absolute or workspace path of the source file.
* @type { Path }
*/
public prop filePath: Path {
get() {
return _filePath
}
}
/**
* Start position of the span (inclusive).
* @type { Position }
*/
public prop start: Position {
get() {
return _start
}
}
internal init() {
this._start = Position()
this._end = Position()
this._filePath = Path(String.empty)
}
internal init(start: Position, end: Position, filePath: Path) {
this._start = start
this._end = end
this._filePath = filePath;
}
internal static func invalid(): DebugLocation {
return DebugLocation()
}
/**
* Whether start, end, and file path are all set meaningfully.
* @return true when `start`, `end`, and `filePath` are all usable.
*/
public func isValid(): Bool {
return start.isValid() && end.isValid() && !filePath.isEmpty()
}
/**
* Human-readable location: file name, line/column range, optional scope chain.
* @return Debug string, or empty when `isValid()` is false.
*/
public func toString(): String {
if (!isValid()) {
return String.empty
}
let result = StringBuilder()
result.append(filePath.fileName)
result.append(start.toString())
if (!_scopeInfo.isEmpty()) {
var scopeStr = ArrayList<String>()
for (info in _scopeInfo) {
scopeStr.add(info.toString())
}
result.append(", scope: ")
result.append(String.join(scopeStr.toArray(), delimiter: "-"))
}
return result.toString()
}
}