-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcontext.ts
More file actions
123 lines (103 loc) · 2.96 KB
/
context.ts
File metadata and controls
123 lines (103 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import type * as YAML from "yaml";
import type * as YAMLTypes from "yaml/types";
import { createPosition } from "../factories/position.js";
import type {
Comment,
Content,
ParsedCST,
Point,
Position,
Range,
} from "../types.js";
import { transformContent } from "./content.js";
import { transformNode, type YamlNode, type YamlToUnist } from "./transform.js";
type RangeAsLinePosGetter = (this: {
range: { start: number; end: number };
context: any;
}) => {
start: { line: number; col: number };
end: { line: number; col: number };
};
type CSTContext = {
root: { context: { src: string } };
};
let rangeAsLinePosGetter: RangeAsLinePosGetter;
class Context {
text;
comments: Comment[] = [];
#cst;
#cstContext: CSTContext | undefined;
constructor(cst: ParsedCST, text: string) {
this.text = text;
this.#cst = cst;
}
setOrigRanges() {
if (this.#cst.setOrigRanges()) {
return;
}
// From `yaml/parse-cst`
// https://github.com/eemeli/yaml/blob/4cdcde632ece71155f3108ec0120c1a0329a6914/src/cst/parse.js#L22
for (const document of this.#cst) {
document.setOrigRanges([], 0);
}
}
#getRangePosition(range: Range): { start: Point; end: Point } {
if (!rangeAsLinePosGetter) {
const [document] = this.#cst;
const Node = Object.getPrototypeOf(
Object.getPrototypeOf(document),
) as YAML.CST.Node;
rangeAsLinePosGetter = Object.getOwnPropertyDescriptor(
Node,
"rangeAsLinePos",
)!.get as RangeAsLinePosGetter;
}
this.#cstContext ??= { root: { context: { src: this.text } } };
if (this.text === "" && range.origStart === 0 && range.origEnd === 0) {
return {
start: { offset: 0, line: 1, column: 1 },
end: { offset: 0, line: 1, column: 1 },
};
}
const {
start: { line: startLine, col: startColumn },
end: { line: endLine, col: endColumn },
} = rangeAsLinePosGetter.call({
range: {
start: this.#ensureOffsetInRange(range.origStart),
end: this.#ensureOffsetInRange(range.origEnd),
},
context: this.#cstContext,
});
return {
start: { offset: range.origStart, line: startLine, column: startColumn },
end: { offset: range.origEnd, line: endLine, column: endColumn },
};
}
#ensureOffsetInRange(offset: number) {
if (offset < 0) {
return 0;
}
if (offset > this.text.length) {
return this.text.length;
}
return offset;
}
transformOffset(offset: number): Point {
return this.#getRangePosition({
origStart: offset,
origEnd: offset,
}).start;
}
transformRange(range: Range): Position {
const { start, end } = this.#getRangePosition(range);
return createPosition(start, end);
}
transformNode<T extends YamlNode>(node: T): YamlToUnist<T> {
return transformNode(node, this);
}
transformContent(node: YAMLTypes.Node): Content {
return transformContent(node, this);
}
}
export default Context;