# See the License for the specific language governing permissions and
# limitations under the License.
+# This module is used to model Nit source-file and locations in source-file
package location
+# A raw text Nit source file
+class SourceFile
+ # The path of the source
+ var filename: String
+
+ # The content of the source
+ var string: String
+
+ # Create a new sourcefile using a filename and a stream
+ init(filename: String, stream: IStream)
+ do
+ self.filename = filename
+ string = stream.read_all
+ line_starts[0] = 0
+ end
+
+ # Position of each line start
+ var line_starts: Array[Int] = new Array[Int]
+end
+
+# A location inside a source file
class Location
-special Comparable
+ super Comparable
redef type OTHER: Location
- readable var _file: String
+ readable var _file: nullable SourceFile
readable var _line_start: Int
readable var _line_end: Int
readable var _column_start: Int
readable var _column_end: Int
- init(f: String, line_s: Int, line_e: Int, column_s: Int, column_e: Int) do
+ init(f: nullable SourceFile, line_s: Int, line_e: Int, column_s: Int, column_e: Int) do
_file = f
_line_start = line_s
_line_end = line_e
_column_end = column_e
end
- init with_file(f: String) do init(f,0,0,0,0)
+ init with_file(f: SourceFile) do init(f,0,0,0,0)
redef fun ==(other: nullable Object): Bool do
if other == null then return false
end
redef fun to_s: String do
+ var file_part = ""
+ if file != null then
+ file_part = file.filename
+ if file.filename.length > 0 then file_part += ":"
+ end
+
if line_start == line_end then
if column_start == column_end then
- return "{file}:{line_start},{column_start}"
+ return "{file_part}{line_start},{column_start}"
else
- return "{file}:{line_start},{column_start}--{column_end}"
+ return "{file_part}{line_start},{column_start}--{column_end}"
end
else
- return "{file}:{line_start},{column_start}--{line_end}:{column_end}"
+ return "{file_part}{line_start},{column_start}--{line_end},{column_end}"
+ end
+ end
+
+ fun relative_to(loc: nullable Location): String do
+ var relative: Location
+ if loc != null and loc.file == self.file then
+ relative = new Location(null, self.line_start, self.line_end, self.column_start, self.column_end)
+ else
+ relative = new Location(self.file, self.line_start, self.line_end, self.column_start, self.column_end)
end
+ return relative.to_s
end
redef fun <(other: OTHER): Bool do