Skip to content

Commit e246112

Browse files
committed
feat: add support for abstract references
Ref #9
1 parent 2993e17 commit e246112

File tree

3 files changed

+147
-7
lines changed

3 files changed

+147
-7
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
'use strict';
2+
3+
const { last } = require('ramda');
4+
const { addSourceMap } = require('../source-map');
5+
const { visit } = require('../visitor');
6+
7+
const ArrayVisitor = () => {
8+
const stack = [];
9+
10+
return {
11+
element: null,
12+
13+
object(objectNode) {
14+
const arrayElement = last(stack);
15+
const objectVisitor = ObjectVisitor();
16+
const state = { namespace: this.namespace, sourceMap: this.sourceMap };
17+
18+
visit(objectNode, objectVisitor, { state });
19+
20+
const { element: objectElement } = objectVisitor;
21+
22+
arrayElement.push(this.sourceMap ? addSourceMap(objectNode, objectElement) : objectElement);
23+
24+
return false;
25+
},
26+
27+
string(stringNode) {
28+
const arrayElement = last(stack);
29+
const stringElement = new this.namespace.elements.String(stringNode.value);
30+
31+
arrayElement.push(this.sourceMap ? addSourceMap(stringNode, stringElement) : stringElement);
32+
},
33+
34+
number(numberNode) {
35+
const arrayElement = last(stack);
36+
const numberElement = new this.namespace.elements.Number(Number(numberNode.value));
37+
38+
arrayElement.push(this.sourceMap ? addSourceMap(numberNode, numberElement) : numberElement);
39+
},
40+
41+
true(trueNode) {
42+
const arrayElement = last(stack);
43+
const booleanElement = new this.namespace.elements.Boolean(trueNode.value);
44+
45+
arrayElement.push(this.sourceMap ? addSourceMap(trueNode, booleanElement) : booleanElement);
46+
},
47+
48+
false(falseNode) {
49+
const arrayElement = last(stack);
50+
const booleanElement = new this.namespace.elements.Boolean(falseNode.value);
51+
52+
arrayElement.push(this.sourceMap ? addSourceMap(falseNode, booleanElement) : booleanElement);
53+
},
54+
55+
null(nullNode) {
56+
const arrayElement = last(stack);
57+
const nullElement = new this.namespace.elements.Null(nullNode.value);
58+
59+
arrayElement.push(this.sourceMap ? addSourceMap(nullNode, nullElement) : nullElement);
60+
},
61+
62+
array: {
63+
enter() {
64+
stack.push(new this.namespace.elements.Array());
65+
},
66+
leave() {
67+
this.element = stack.pop();
68+
}
69+
}
70+
};
71+
};
72+
73+
const ObjectVisitor = () => {
74+
const stack = [];
75+
76+
return {
77+
element: null,
78+
79+
property(propertyNode) {
80+
const objElement = last(stack);
81+
const { MemberElement } = this.namespace.elements.Element.prototype;
82+
let keyElement;
83+
let valueElement;
84+
85+
// object property key handling
86+
keyElement = new this.namespace.elements.String(propertyNode.key.value);
87+
88+
// object property value handling
89+
if (propertyNode.value.type === 'object') {
90+
const objectVisitor = ObjectVisitor();
91+
const state = { namespace: this.namespace, sourceMap: this.sourceMap };
92+
93+
visit(propertyNode.value, objectVisitor, { state });
94+
95+
({ element: valueElement } = objectVisitor);
96+
} else if (propertyNode.value.type === 'array') {
97+
const arrayVisitor = ArrayVisitor();
98+
const state = { namespace: this.namespace, sourceMap: this.sourceMap };
99+
100+
visit(propertyNode.value, arrayVisitor, { state });
101+
102+
({ element: valueElement } = arrayVisitor);
103+
} else if (propertyNode.key.value === '$ref') { // $ref property key special handling
104+
valueElement = new this.namespace.elements.Ref(propertyNode.value.value);
105+
valueElement.path = propertyNode.value.value;
106+
} else {
107+
valueElement = this.namespace.toElement(propertyNode.value.value);
108+
}
109+
110+
objElement.content.push(
111+
new MemberElement(
112+
this.sourceMap ? addSourceMap(propertyNode.key, keyElement) : keyElement,
113+
this.sourceMap ? addSourceMap(propertyNode.value, valueElement): valueElement,
114+
)
115+
);
116+
117+
return false;
118+
},
119+
object: {
120+
enter() {
121+
stack.push(new this.namespace.elements.Object());
122+
},
123+
leave() {
124+
this.element = stack.pop();
125+
}
126+
}
127+
};
128+
};
129+
130+
module.exports = {
131+
ObjectVisitor,
132+
ArrayVisitor,
133+
};

apidom/packages/apidom-parser-adapter-openapi3/src/parser/visitors/schema.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
'use strict';
22

3-
const { AST: { JsonNode } } = require('json-ast');
4-
3+
const { addSourceMap } = require('../source-map');
54
const { visit } = require('../visitor');
5+
const { ObjectVisitor } = require('./generics');
66

77
const SchemaVisitor = () => ({
88
element: null,
9-
schema: null,
109

1110
object(objectNode) {
1211
const { MemberElement } = this.namespace.elements.Element.prototype;
12+
const schemaKeyElement = new this.namespace.elements.String(this.schemaKeyNode.value);
13+
const state = { namespace: this.namespace, sourceMap: this.sourceMap };
14+
const objectVisitor = ObjectVisitor();
15+
16+
visit(objectNode, objectVisitor, { state });
17+
const schemaElement = new this.namespace.elements.Schema(objectVisitor.element.content)
1318

14-
this.schema = new this.namespace.elements.Schema(JsonNode.toJSON(objectNode));
15-
this.element = new MemberElement(this.schemaName, this.schema);
19+
this.element = new MemberElement(
20+
this.sourceMap ? addSourceMap(this.schemaKeyNode, schemaKeyElement) : schemaKeyElement,
21+
this.sourceMap ? addSourceMap(objectNode, schemaElement) : schemaElement,
22+
);
1623

1724
return false;
1825
}

apidom/packages/apidom-parser-adapter-openapi3/src/parser/visitors/schemas.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ const SchemasVisitor = () => ({
99

1010
property(propertyNode) {
1111
const state = { namespace: this.namespace, sourceMap: this.sourceMap };
12-
const schemaVisitor = SchemaVisitor();
1312
const schemasElement = parseSchemas(
1413
{ namespace: this.namespace, sourceMap: this.sourceMap },
1514
propertyNode,
1615
);
1716

1817
propertyNode.value.properties.forEach(schemaNode => {
19-
visit(schemaNode, schemaVisitor, { state: { ...state, schemaName: schemaNode.key.value } });
18+
const schemaVisitor = SchemaVisitor();
19+
visit(schemaNode, schemaVisitor, { state: { ...state, schemaKeyNode: schemaNode.key } });
2020

2121
schemasElement.value.content.push(schemaVisitor.element);
2222
});

0 commit comments

Comments
 (0)