bolt/src/text.ts

101 lines
1.7 KiB
TypeScript
Raw Normal View History

2020-05-10 15:56:34 +02:00
import * as path from "path"
2020-05-23 22:48:24 +02:00
import * as fs from "fs"
import { serializeTag, serialize, deserializable, inspectTag } from "./util";
import { InspectOptionsStylized } from "util";
2020-05-10 15:56:34 +02:00
@deserializable()
2020-05-10 15:56:34 +02:00
export class TextFile {
2020-05-23 22:48:24 +02:00
private cachedText: string | null = null;
2020-05-10 15:56:34 +02:00
constructor(public origPath: string) {
}
2020-05-23 22:48:24 +02:00
public get fullPath() {
2020-05-10 15:56:34 +02:00
return path.resolve(this.origPath)
}
private [inspectTag](depth: numbber | null, options: InspectOptionsStylized) {
return `TextFile { ${this.origPath} }`
}
private [serializeTag]() {
return [ this.origPath ];
}
public getText(encoding: BufferEncoding = 'utf8'): string {
2020-05-23 22:48:24 +02:00
if (this.cachedText !== null) {
return this.cachedText;
}
const text = fs.readFileSync(this.fullPath, encoding);
2020-05-23 22:48:24 +02:00
this.cachedText = text;
return text
}
2020-05-10 15:56:34 +02:00
}
@deserializable()
2020-05-10 15:56:34 +02:00
export class TextPos {
constructor(
public offset: number,
public line: number,
public column: number
) {
}
2020-05-23 22:48:24 +02:00
public clone() {
2020-05-10 15:56:34 +02:00
return new TextPos(this.offset, this.line, this.column)
}
[serializeTag]() {
return [
this.offset,
this.line,
this.column,
]
}
public advance(str: string) {
for (const ch of str) {
if (ch === '\n') {
this.line++;
this.column = 1;
} else {
this.column++;
}
this.offset++;
}
}
2020-05-10 15:56:34 +02:00
}
@deserializable()
2020-05-10 15:56:34 +02:00
export class TextSpan {
constructor(
public file: TextFile,
public start: TextPos,
public end: TextPos
) {
}
2020-05-23 22:48:24 +02:00
public clone() {
2020-05-10 15:56:34 +02:00
return new TextSpan(this.file, this.start.clone(), this.end.clone());
}
[serializeTag]() {
return [
this.file,
this.start,
this.end,
]
}
2020-05-10 15:56:34 +02:00
}