This repository was archived by the owner on Nov 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathparseYAML.js
149 lines (124 loc) · 4.99 KB
/
parseYAML.js
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* eslint-disable no-use-before-define */
const yaml = require('yaml-js');
const { createWarning } = require('./annotations');
function translateSourceMap(start, offset, startLine, startCol, endLine, endCol, namespace) {
const begin = new namespace.elements.Number(start);
const length = new namespace.elements.Number(offset);
begin.attributes.set('line', startLine + 1);
begin.attributes.set('column', startCol + 1);
length.attributes.set('line', endLine + 1);
length.attributes.set('column', endCol + 1);
return new namespace.elements.Array([new namespace.elements.SourceMap([[begin, length]])]);
}
function copySourceMap(startMark, endMark, element, namespace) {
element.attributes.set('sourceMap', translateSourceMap(
startMark.pointer,
endMark.pointer - startMark.pointer,
startMark.line,
startMark.column,
endMark.line,
endMark.column,
namespace
));
}
function yamlToObject(node, annotations, context) {
if (node.value) {
return new context.namespace.elements.Object(node.value.map((nodes) => {
const key = convert(nodes[0], annotations, context);
const value = convert(nodes[1], annotations, context);
return new context.namespace.elements.Member(key, value);
}));
}
return new context.namespace.elements.Object();
}
function yamlToArray(node, annotations, context) {
if (node.value) {
return new context.namespace.elements.Array(node.value.map(nodes => convert(nodes, annotations, context)));
}
return new context.namespace.elements.Array();
}
function convert(node, annotations, context) {
const { namespace } = context;
let element;
if (node.tag === 'tag:yaml.org,2002:map') {
element = yamlToObject(node, annotations, context);
} else if (node.tag === 'tag:yaml.org,2002:seq') {
element = yamlToArray(node, annotations, context);
} else if (node.tag === 'tag:yaml.org,2002:str') {
element = new namespace.elements.String(node.value);
} else if (node.tag === 'tag:yaml.org,2002:int' || node.tag === 'tag:yaml.org,2002:float') {
element = new namespace.elements.Number(Number(node.value));
} else if (node.tag === 'tag:yaml.org,2002:bool') {
element = new namespace.elements.Boolean(Boolean(node.value));
} else if (node.tag === 'tag:yaml.org,2002:null') {
element = new namespace.elements.Null();
} else if (node.tag === 'tag:yaml.org,2002:binary') {
element = new namespace.elements.String(node.value);
const warning = createWarning(namespace, 'Interpreting YAML !!binary as string', element);
copySourceMap(node.start_mark, node.end_mark, warning, namespace);
annotations.push(warning);
} else if (node.tag === 'tag:yaml.org,2002:timestamp') {
element = new namespace.elements.String(node.value);
const warning = createWarning(namespace, 'Interpreting YAML !!timestamp as string', element);
copySourceMap(node.start_mark, node.end_mark, warning, namespace);
annotations.push(warning);
} else if (node.tag === 'tag:yaml.org,2002:omap') {
element = yamlToObject(node, annotations, context);
const warning = createWarning(namespace, 'Interpreting YAML !!omap as object', element);
copySourceMap(node.start_mark, node.end_mark, warning, namespace);
annotations.push(warning);
} else if (node.tag === 'tag:yaml.org,2002:pairs') {
element = yamlToObject(node, annotations, context);
const warning = createWarning(namespace, 'Interpreting YAML !!pairs as object', element);
copySourceMap(node.start_mark, node.end_mark, warning, namespace);
annotations.push(warning);
} else if (node.tag === 'tag:yaml.org,2002:set') {
element = yamlToArray(node, annotations, context);
const warning = createWarning(namespace, 'Interpreting YAML !!set as array', element);
copySourceMap(node.start_mark, node.end_mark, warning, namespace);
annotations.push(warning);
} else {
throw new Error(`Unsupported YAML node '${node.tag}'`);
}
copySourceMap(node.start_mark, node.end_mark, element, namespace);
return element;
}
function parse(source, context) {
const { namespace } = context;
const parseResult = new namespace.elements.ParseResult();
let ast;
try {
ast = yaml.compose(source);
} catch (error) {
let message;
if (error.problem) {
const problem = error.problem.replace('\t', '\\t');
message = `${problem}, ${error.context}`;
} else if (error.context) {
message = error.context;
} else {
({ message } = error);
}
const annotation = new namespace.elements.Annotation(
`YAML Syntax: ${message}`,
{ classes: ['error'] }
);
const marker = error.context_mark || error.problem_mark;
if (marker) {
copySourceMap(
marker,
marker,
annotation,
namespace
);
}
parseResult.push(annotation);
return parseResult;
}
const annotations = [];
const result = convert(ast, annotations, context);
parseResult.push(result);
parseResult.content = parseResult.content.concat(annotations);
return parseResult;
}
module.exports = parse;