redsnow 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -1
- data/README.md +12 -0
- data/ext/snowcrash/bin/snowcrash +0 -0
- data/ext/snowcrash/ext/markdown-parser/ext/sundown/src/markdown.c +5 -2
- data/ext/snowcrash/snowcrash.gyp +7 -2
- data/ext/snowcrash/src/ActionParser.h +141 -81
- data/ext/snowcrash/src/AssetParser.h +19 -11
- data/ext/snowcrash/src/Blueprint.h +44 -14
- data/ext/snowcrash/src/BlueprintParser.h +65 -51
- data/ext/snowcrash/src/BlueprintSourcemap.h +254 -0
- data/ext/snowcrash/src/BlueprintUtility.h +3 -24
- data/ext/snowcrash/src/CBlueprint.cc +40 -31
- data/ext/snowcrash/src/CBlueprint.h +54 -58
- data/ext/snowcrash/src/CBlueprintSourcemap.cc +620 -0
- data/ext/snowcrash/src/CBlueprintSourcemap.h +342 -0
- data/ext/snowcrash/src/CSourceAnnotation.cc +14 -0
- data/ext/snowcrash/src/CodeBlockUtility.h +42 -5
- data/ext/snowcrash/src/HeadersParser.h +84 -42
- data/ext/snowcrash/src/ParameterParser.h +110 -68
- data/ext/snowcrash/src/ParametersParser.h +26 -28
- data/ext/snowcrash/src/PayloadParser.h +164 -83
- data/ext/snowcrash/src/ResourceGroupParser.h +35 -41
- data/ext/snowcrash/src/ResourceParser.h +142 -97
- data/ext/snowcrash/src/SectionParser.h +15 -14
- data/ext/snowcrash/src/SectionParserData.h +11 -2
- data/ext/snowcrash/src/SectionProcessor.h +42 -18
- data/ext/snowcrash/src/Serialize.cc +2 -0
- data/ext/snowcrash/src/Serialize.h +3 -1
- data/ext/snowcrash/src/SerializeJSON.cc +608 -16
- data/ext/snowcrash/src/SerializeJSON.h +4 -1
- data/ext/snowcrash/src/SerializeYAML.cc +367 -19
- data/ext/snowcrash/src/SerializeYAML.h +4 -1
- data/ext/snowcrash/src/SymbolTable.h +12 -1
- data/ext/snowcrash/src/ValuesParser.h +12 -11
- data/ext/snowcrash/src/Version.h +1 -1
- data/ext/snowcrash/src/csnowcrash.cc +7 -3
- data/ext/snowcrash/src/csnowcrash.h +4 -2
- data/ext/snowcrash/src/snowcrash.cc +10 -11
- data/ext/snowcrash/src/snowcrash.h +3 -3
- data/ext/snowcrash/src/snowcrash/snowcrash.cc +38 -8
- data/ext/snowcrash/tools/homebrew/snowcrash.rb +1 -1
- data/lib/redsnow.rb +41 -2
- data/lib/redsnow/binding.rb +93 -8
- data/lib/redsnow/blueprint.rb +48 -25
- data/lib/redsnow/parseresult.rb +9 -2
- data/lib/redsnow/sourcemap.rb +369 -0
- data/lib/redsnow/version.rb +1 -1
- data/test/fixtures/sample-api-ast.json +1 -1
- data/test/fixtures/sample-api-sourcemap.json +169 -0
- data/test/redsnow_binding_test.rb +19 -2
- data/test/redsnow_options_test.rb +42 -0
- data/test/redsnow_parseresult_test.rb +5 -1
- data/test/redsnow_test.rb +5 -0
- metadata +11 -2
@@ -23,9 +23,7 @@ namespace snowcrash {
|
|
23
23
|
/** No parameters specified message */
|
24
24
|
const char* const NoParametersMessage = "no parameters specified, expected a nested list of parameters, one parameter per list item";
|
25
25
|
|
26
|
-
/** Internal type alias for Collection of Parameter */
|
27
|
-
typedef Collection<Parameter>::type Parameters;
|
28
|
-
|
26
|
+
/** Internal type alias for Collection iterator of Parameter */
|
29
27
|
typedef Collection<Parameter>::iterator ParameterIterator;
|
30
28
|
|
31
29
|
/**
|
@@ -38,8 +36,7 @@ namespace snowcrash {
|
|
38
36
|
const MarkdownNodes& siblings,
|
39
37
|
SectionParserData& pd,
|
40
38
|
SectionLayout& layout,
|
41
|
-
|
42
|
-
Parameters& out) {
|
39
|
+
ParseResult<Parameters>& out) {
|
43
40
|
|
44
41
|
mdp::ByteBuffer remainingContent;
|
45
42
|
|
@@ -53,9 +50,9 @@ namespace snowcrash {
|
|
53
50
|
ss << " expected a nested list of parameters, one parameter per list item";
|
54
51
|
|
55
52
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
56
|
-
report.warnings.push_back(Warning(ss.str(),
|
57
|
-
|
58
|
-
|
53
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
54
|
+
IgnoringWarning,
|
55
|
+
sourceMap));
|
59
56
|
}
|
60
57
|
|
61
58
|
return ++MarkdownNodeIterator(node);
|
@@ -64,8 +61,7 @@ namespace snowcrash {
|
|
64
61
|
static MarkdownNodeIterator processDescription(const MarkdownNodeIterator& node,
|
65
62
|
const MarkdownNodes& siblings,
|
66
63
|
SectionParserData& pd,
|
67
|
-
|
68
|
-
Parameters& out) {
|
64
|
+
ParseResult<Parameters>& out) {
|
69
65
|
|
70
66
|
return node;
|
71
67
|
}
|
@@ -73,34 +69,37 @@ namespace snowcrash {
|
|
73
69
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
74
70
|
const MarkdownNodes& siblings,
|
75
71
|
SectionParserData& pd,
|
76
|
-
|
77
|
-
Parameters& out) {
|
72
|
+
ParseResult<Parameters>& out) {
|
78
73
|
|
79
74
|
if (pd.sectionContext() != ParameterSectionType) {
|
80
75
|
return node;
|
81
76
|
}
|
82
77
|
|
83
|
-
Parameter parameter;
|
84
|
-
ParameterParser::parse(node, siblings, pd,
|
78
|
+
ParseResult<Parameter> parameter(out.report);
|
79
|
+
ParameterParser::parse(node, siblings, pd, parameter);
|
85
80
|
|
86
|
-
if (!out.empty()) {
|
81
|
+
if (!out.node.empty()) {
|
87
82
|
|
88
|
-
ParameterIterator duplicate = findParameter(out, parameter);
|
83
|
+
ParameterIterator duplicate = findParameter(out.node, parameter.node);
|
89
84
|
|
90
|
-
if (duplicate != out.end()) {
|
85
|
+
if (duplicate != out.node.end()) {
|
91
86
|
|
92
87
|
// WARN: Parameter already defined
|
93
88
|
std::stringstream ss;
|
94
|
-
ss << "overshadowing previous parameter '" << parameter.name << "' definition";
|
89
|
+
ss << "overshadowing previous parameter '" << parameter.node.name << "' definition";
|
95
90
|
|
96
91
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
97
|
-
report.warnings.push_back(Warning(ss.str(),
|
98
|
-
|
99
|
-
|
92
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
93
|
+
RedefinitionWarning,
|
94
|
+
sourceMap));
|
100
95
|
}
|
101
96
|
}
|
102
97
|
|
103
|
-
out.push_back(parameter);
|
98
|
+
out.node.push_back(parameter.node);
|
99
|
+
|
100
|
+
if (pd.exportSourceMap()) {
|
101
|
+
out.sourceMap.collection.push_back(parameter.sourceMap);
|
102
|
+
}
|
104
103
|
|
105
104
|
return ++MarkdownNodeIterator(node);
|
106
105
|
}
|
@@ -147,16 +146,15 @@ namespace snowcrash {
|
|
147
146
|
|
148
147
|
static void finalize(const MarkdownNodeIterator& node,
|
149
148
|
SectionParserData& pd,
|
150
|
-
|
151
|
-
Parameters& out) {
|
149
|
+
ParseResult<Parameters>& out) {
|
152
150
|
|
153
|
-
if (out.empty()) {
|
151
|
+
if (out.node.empty()) {
|
154
152
|
|
155
153
|
// WARN: No parameters defined
|
156
154
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
157
|
-
report.warnings.push_back(Warning(NoParametersMessage,
|
158
|
-
|
159
|
-
|
155
|
+
out.report.warnings.push_back(Warning(NoParametersMessage,
|
156
|
+
FormattingWarning,
|
157
|
+
sourceMap));
|
160
158
|
}
|
161
159
|
}
|
162
160
|
|
@@ -20,6 +20,10 @@
|
|
20
20
|
|
21
21
|
namespace snowcrash {
|
22
22
|
|
23
|
+
/** Internal type alias for Collection iterator of Response */
|
24
|
+
typedef Collection<Response>::const_iterator ResponseIterator;
|
25
|
+
typedef Collection<Request>::const_iterator RequestIterator;
|
26
|
+
|
23
27
|
/// Payload signature
|
24
28
|
enum PayloadSignature {
|
25
29
|
NoPayloadSignature = 0,
|
@@ -48,35 +52,42 @@ namespace snowcrash {
|
|
48
52
|
const MarkdownNodes& siblings,
|
49
53
|
SectionParserData& pd,
|
50
54
|
SectionLayout& layout,
|
51
|
-
|
52
|
-
Payload& out) {
|
55
|
+
ParseResult<Payload>& out) {
|
53
56
|
|
54
57
|
mdp::ByteBuffer signature, remainingContent;
|
55
58
|
signature = GetFirstLine(node->text, remainingContent);
|
56
59
|
|
57
|
-
parseSignature(node, pd, signature,
|
60
|
+
parseSignature(node, pd, signature, out);
|
58
61
|
|
59
62
|
// WARN: missing status code
|
60
|
-
if (out.name.empty() &&
|
63
|
+
if (out.node.name.empty() &&
|
61
64
|
(pd.sectionContext() == ResponseSectionType || pd.sectionContext() == ResponseBodySectionType)) {
|
62
65
|
|
63
66
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
64
|
-
report.warnings.push_back(Warning("missing response HTTP status code, assuming 'Response 200'",
|
65
|
-
|
66
|
-
|
67
|
-
out.name = "200";
|
67
|
+
out.report.warnings.push_back(Warning("missing response HTTP status code, assuming 'Response 200'",
|
68
|
+
EmptyDefinitionWarning,
|
69
|
+
sourceMap));
|
70
|
+
out.node.name = "200";
|
68
71
|
}
|
69
72
|
|
70
73
|
if (!remainingContent.empty()) {
|
71
74
|
if (!isAbbreviated(pd.sectionContext())) {
|
72
|
-
out.description = remainingContent;
|
73
|
-
|
75
|
+
out.node.description = remainingContent;
|
76
|
+
|
77
|
+
if (pd.exportSourceMap() && !out.node.description.empty()) {
|
78
|
+
out.sourceMap.description.sourceMap.append(node->sourceMap);
|
79
|
+
}
|
80
|
+
} else if (!parseSymbolReference(node, pd, remainingContent, out)) {
|
74
81
|
|
75
82
|
// NOTE: NOT THE CORRECT WAY TO DO THIS
|
76
83
|
// https://github.com/apiaryio/snowcrash/commit/a7c5868e62df0048a85e2f9aeeb42c3b3e0a2f07#commitcomment-7322085
|
77
84
|
pd.sectionsContext.push_back(BodySectionType);
|
78
|
-
CodeBlockUtility::signatureContentAsCodeBlock(node, pd, report, out.body);
|
85
|
+
CodeBlockUtility::signatureContentAsCodeBlock(node, pd, out.report, out.node.body);
|
79
86
|
pd.sectionsContext.pop_back();
|
87
|
+
|
88
|
+
if (pd.exportSourceMap() && !out.node.body.empty()) {
|
89
|
+
out.sourceMap.body.sourceMap.append(node->sourceMap);
|
90
|
+
}
|
80
91
|
}
|
81
92
|
}
|
82
93
|
|
@@ -86,35 +97,38 @@ namespace snowcrash {
|
|
86
97
|
static MarkdownNodeIterator processContent(const MarkdownNodeIterator& node,
|
87
98
|
const MarkdownNodes& siblings,
|
88
99
|
SectionParserData& pd,
|
89
|
-
|
90
|
-
Payload& out) {
|
100
|
+
ParseResult<Payload>& out) {
|
91
101
|
|
92
102
|
mdp::ByteBuffer content;
|
93
103
|
|
94
|
-
if (!out.symbol.empty()) {
|
104
|
+
if (!out.node.symbol.empty()) {
|
95
105
|
//WARN: ignoring extraneous content after symbol reference
|
96
106
|
std::stringstream ss;
|
97
107
|
|
98
108
|
ss << "ignoring extraneous content after symbol reference";
|
99
|
-
ss << ", expected symbol reference only e.g. '[" << out.symbol << "][]'";
|
109
|
+
ss << ", expected symbol reference only e.g. '[" << out.node.symbol << "][]'";
|
100
110
|
|
101
111
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
102
|
-
report.warnings.push_back(Warning(ss.str(),
|
103
|
-
|
104
|
-
|
112
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
113
|
+
IgnoringWarning,
|
114
|
+
sourceMap));
|
105
115
|
} else {
|
106
116
|
|
107
|
-
if (!out.body.empty() ||
|
117
|
+
if (!out.node.body.empty() ||
|
108
118
|
node->type != mdp::ParagraphMarkdownNodeType ||
|
109
|
-
!parseSymbolReference(node, pd, node->text,
|
119
|
+
!parseSymbolReference(node, pd, node->text, out)) {
|
110
120
|
|
111
121
|
// NOTE: NOT THE CORRECT WAY TO DO THIS
|
112
122
|
// https://github.com/apiaryio/snowcrash/commit/a7c5868e62df0048a85e2f9aeeb42c3b3e0a2f07#commitcomment-7322085
|
113
123
|
pd.sectionsContext.push_back(BodySectionType);
|
114
|
-
CodeBlockUtility::contentAsCodeBlock(node, pd, report, content);
|
124
|
+
CodeBlockUtility::contentAsCodeBlock(node, pd, out.report, content);
|
115
125
|
pd.sectionsContext.pop_back();
|
116
126
|
|
117
|
-
out.body += content;
|
127
|
+
out.node.body += content;
|
128
|
+
|
129
|
+
if (pd.exportSourceMap() && !content.empty()) {
|
130
|
+
out.sourceMap.body.sourceMap.append(node->sourceMap);
|
131
|
+
}
|
118
132
|
}
|
119
133
|
}
|
120
134
|
|
@@ -124,34 +138,42 @@ namespace snowcrash {
|
|
124
138
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
125
139
|
const MarkdownNodes& siblings,
|
126
140
|
SectionParserData& pd,
|
127
|
-
|
128
|
-
Payload& out) {
|
141
|
+
ParseResult<Payload>& out) {
|
129
142
|
|
130
143
|
switch (pd.sectionContext()) {
|
131
144
|
case HeadersSectionType:
|
132
|
-
|
145
|
+
{
|
146
|
+
ParseResult<Headers> headers(out.report, out.node.headers, out.sourceMap.headers);
|
147
|
+
return HeadersParser::parse(node, siblings, pd, headers);
|
148
|
+
}
|
133
149
|
|
134
150
|
case BodySectionType:
|
135
|
-
|
151
|
+
{
|
152
|
+
if (!out.node.body.empty()) {
|
136
153
|
// WARN: Multiple body section
|
137
154
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
138
|
-
report.warnings.push_back(Warning("ignoring additional 'body' content, it is already defined",
|
139
|
-
|
140
|
-
|
155
|
+
out.report.warnings.push_back(Warning("ignoring additional 'body' content, it is already defined",
|
156
|
+
RedefinitionWarning,
|
157
|
+
sourceMap));
|
141
158
|
}
|
142
159
|
|
143
|
-
|
160
|
+
ParseResult<Asset> asset(out.report, out.node.body, out.sourceMap.body);
|
161
|
+
return AssetParser::parse(node, siblings, pd, asset);
|
162
|
+
}
|
144
163
|
|
145
164
|
case SchemaSectionType:
|
146
|
-
|
165
|
+
{
|
166
|
+
if (!out.node.schema.empty()) {
|
147
167
|
// WARN: Multiple schema section
|
148
168
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
149
|
-
report.warnings.push_back(Warning("ignoring additional 'schema' content, it is already defined",
|
150
|
-
|
151
|
-
|
169
|
+
out.report.warnings.push_back(Warning("ignoring additional 'schema' content, it is already defined",
|
170
|
+
RedefinitionWarning,
|
171
|
+
sourceMap));
|
152
172
|
}
|
153
173
|
|
154
|
-
|
174
|
+
ParseResult<Asset> asset(out.report, out.node.schema, out.sourceMap.schema);
|
175
|
+
return AssetParser::parse(node, siblings, pd, asset);
|
176
|
+
}
|
155
177
|
|
156
178
|
default:
|
157
179
|
break;
|
@@ -164,18 +186,22 @@ namespace snowcrash {
|
|
164
186
|
const MarkdownNodes& siblings,
|
165
187
|
SectionParserData& pd,
|
166
188
|
SectionType& sectionType,
|
167
|
-
|
168
|
-
Payload& out) {
|
189
|
+
ParseResult<Payload>& out) {
|
169
190
|
|
170
191
|
if ((node->type == mdp::ParagraphMarkdownNodeType ||
|
171
192
|
node->type == mdp::CodeMarkdownNodeType) &&
|
172
193
|
sectionType == BodySectionType) {
|
173
194
|
|
174
|
-
CodeBlockUtility::addDanglingAsset(node, pd, sectionType, report, out.body);
|
195
|
+
mdp::ByteBuffer content = CodeBlockUtility::addDanglingAsset(node, pd, sectionType, out.report, out.node.body);
|
196
|
+
|
197
|
+
if (pd.exportSourceMap() && !content.empty()) {
|
198
|
+
out.sourceMap.body.sourceMap.append(node->sourceMap);
|
199
|
+
}
|
200
|
+
|
175
201
|
return ++MarkdownNodeIterator(node);
|
176
202
|
}
|
177
203
|
|
178
|
-
return SectionProcessorBase<Payload>::processUnexpectedNode(node, siblings, pd, sectionType,
|
204
|
+
return SectionProcessorBase<Payload>::processUnexpectedNode(node, siblings, pd, sectionType, out);
|
179
205
|
}
|
180
206
|
|
181
207
|
static bool isDescriptionNode(const MarkdownNodeIterator& node,
|
@@ -270,8 +296,7 @@ namespace snowcrash {
|
|
270
296
|
|
271
297
|
static void finalize(const MarkdownNodeIterator& node,
|
272
298
|
SectionParserData& pd,
|
273
|
-
|
274
|
-
Payload& out) {
|
299
|
+
ParseResult<Payload>& out) {
|
275
300
|
|
276
301
|
bool warnEmptyBody = false;
|
277
302
|
|
@@ -280,8 +305,8 @@ namespace snowcrash {
|
|
280
305
|
|
281
306
|
SectionType sectionType = pd.sectionContext();
|
282
307
|
|
283
|
-
for (
|
284
|
-
it != out.headers.end();
|
308
|
+
for (HeaderIterator it = out.node.headers.begin();
|
309
|
+
it != out.node.headers.end();
|
285
310
|
++it) {
|
286
311
|
|
287
312
|
if (it->first == HTTPHeaderName::ContentLength) {
|
@@ -293,10 +318,10 @@ namespace snowcrash {
|
|
293
318
|
}
|
294
319
|
}
|
295
320
|
|
296
|
-
if ((sectionType == RequestSectionType || sectionType == RequestBodySectionType) && out.body.empty()) {
|
321
|
+
if ((sectionType == RequestSectionType || sectionType == RequestBodySectionType) && out.node.body.empty()) {
|
297
322
|
|
298
323
|
// Warn when content-length or transfer-encoding is specified or both headers and body are empty
|
299
|
-
if (out.headers.empty()) {
|
324
|
+
if (out.node.headers.empty()) {
|
300
325
|
warnEmptyBody = true;
|
301
326
|
} else {
|
302
327
|
warnEmptyBody = !contentLength.empty() || !transferEncoding.empty();
|
@@ -314,29 +339,29 @@ namespace snowcrash {
|
|
314
339
|
}
|
315
340
|
|
316
341
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
317
|
-
report.warnings.push_back(Warning(ss.str(),
|
318
|
-
|
319
|
-
|
342
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
343
|
+
EmptyDefinitionWarning,
|
344
|
+
sourceMap));
|
320
345
|
}
|
321
346
|
} else if ((sectionType == ResponseSectionType || sectionType == ResponseBodySectionType)) {
|
322
347
|
|
323
348
|
HTTPStatusCode code = 200;
|
324
349
|
|
325
|
-
if (!out.name.empty()) {
|
326
|
-
std::stringstream(out.name) >> code;
|
350
|
+
if (!out.node.name.empty()) {
|
351
|
+
std::stringstream(out.node.name) >> code;
|
327
352
|
}
|
328
353
|
|
329
354
|
StatusCodeTraits statusCodeTraits = GetStatusCodeTrait(code);
|
330
355
|
|
331
|
-
if (!statusCodeTraits.allowBody && !out.body.empty()) {
|
356
|
+
if (!statusCodeTraits.allowBody && !out.node.body.empty()) {
|
332
357
|
// WARN: not empty body
|
333
358
|
std::stringstream ss;
|
334
359
|
ss << "the " << code << " response MUST NOT include a " << SectionName(BodySectionType);
|
335
360
|
|
336
361
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
337
|
-
report.warnings.push_back(Warning(ss.str(),
|
338
|
-
|
339
|
-
|
362
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
363
|
+
EmptyDefinitionWarning,
|
364
|
+
sourceMap));
|
340
365
|
}
|
341
366
|
}
|
342
367
|
}
|
@@ -396,8 +421,7 @@ namespace snowcrash {
|
|
396
421
|
static bool parseSignature(const MarkdownNodeIterator& node,
|
397
422
|
SectionParserData& pd,
|
398
423
|
const mdp::ByteBuffer& signature,
|
399
|
-
|
400
|
-
Payload& out) {
|
424
|
+
ParseResult<Payload>& out) {
|
401
425
|
|
402
426
|
const char* regex;
|
403
427
|
mdp::ByteBuffer mediaType;
|
@@ -461,9 +485,9 @@ namespace snowcrash {
|
|
461
485
|
}
|
462
486
|
|
463
487
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
464
|
-
report.warnings.push_back(Warning(ss.str(),
|
465
|
-
|
466
|
-
|
488
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
489
|
+
FormattingWarning,
|
490
|
+
sourceMap));
|
467
491
|
|
468
492
|
return false;
|
469
493
|
}
|
@@ -471,19 +495,29 @@ namespace snowcrash {
|
|
471
495
|
if (pd.sectionContext() == ModelSectionType ||
|
472
496
|
pd.sectionContext() == ModelBodySectionType) {
|
473
497
|
|
474
|
-
out.name = captureGroups[2];
|
498
|
+
out.node.name = captureGroups[2];
|
475
499
|
mediaType = captureGroups[4];
|
476
500
|
} else {
|
477
|
-
out.name = captureGroups[1];
|
501
|
+
out.node.name = captureGroups[1];
|
478
502
|
mediaType = captureGroups[3];
|
479
503
|
}
|
480
504
|
|
481
|
-
TrimString(out.name);
|
505
|
+
TrimString(out.node.name);
|
482
506
|
TrimString(mediaType);
|
483
507
|
|
508
|
+
if (pd.exportSourceMap() && !out.node.name.empty()) {
|
509
|
+
out.sourceMap.name.sourceMap = node->sourceMap;
|
510
|
+
}
|
511
|
+
|
484
512
|
if (!mediaType.empty()) {
|
485
513
|
Header header = std::make_pair(HTTPHeaderName::ContentType, mediaType);
|
486
|
-
out.headers.push_back(header);
|
514
|
+
out.node.headers.push_back(header);
|
515
|
+
|
516
|
+
if (pd.exportSourceMap()) {
|
517
|
+
SourceMap<Header> headerSM;
|
518
|
+
headerSM.sourceMap = node->sourceMap;
|
519
|
+
out.sourceMap.headers.collection.push_back(headerSM);
|
520
|
+
}
|
487
521
|
}
|
488
522
|
}
|
489
523
|
|
@@ -493,16 +527,20 @@ namespace snowcrash {
|
|
493
527
|
static bool parseSymbolReference(const MarkdownNodeIterator& node,
|
494
528
|
SectionParserData& pd,
|
495
529
|
mdp::ByteBuffer& source,
|
496
|
-
|
497
|
-
Payload& out) {
|
530
|
+
ParseResult<Payload>& out) {
|
498
531
|
|
499
532
|
SymbolName symbol;
|
500
533
|
ResourceModel model;
|
534
|
+
SourceMap<ResourceModel> modelSM;
|
501
535
|
|
502
536
|
TrimString(source);
|
503
537
|
|
504
538
|
if (GetSymbolReference(source, symbol)) {
|
505
|
-
out.symbol = symbol;
|
539
|
+
out.node.symbol = symbol;
|
540
|
+
|
541
|
+
if (pd.exportSourceMap() && !symbol.empty()) {
|
542
|
+
out.sourceMap.symbol.sourceMap = node->sourceMap;
|
543
|
+
}
|
506
544
|
|
507
545
|
// If symbol doesn't exist
|
508
546
|
if (pd.symbolTable.resourceModels.find(symbol) == pd.symbolTable.resourceModels.end()) {
|
@@ -512,22 +550,22 @@ namespace snowcrash {
|
|
512
550
|
ss << "Undefined symbol " << symbol;
|
513
551
|
|
514
552
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
515
|
-
report.error = Error(ss.str(), SymbolError, sourceMap);
|
553
|
+
out.report.error = Error(ss.str(), SymbolError, sourceMap);
|
516
554
|
|
517
555
|
return true;
|
518
556
|
}
|
519
557
|
|
520
558
|
model = pd.symbolTable.resourceModels.at(symbol);
|
521
559
|
|
522
|
-
out.description = model.description;
|
523
|
-
out.parameters = model.parameters;
|
560
|
+
out.node.description = model.description;
|
561
|
+
out.node.parameters = model.parameters;
|
524
562
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
563
|
+
HeaderIterator modelContentType = std::find_if(model.headers.begin(),
|
564
|
+
model.headers.end(),
|
565
|
+
std::bind2nd(MatchFirstWith<Header, std::string>(),
|
566
|
+
HTTPHeaderName::ContentType));
|
529
567
|
|
530
|
-
bool isPayloadContentType = !out.headers.empty();
|
568
|
+
bool isPayloadContentType = !out.node.headers.empty();
|
531
569
|
bool isModelContentType = modelContentType != model.headers.end();
|
532
570
|
|
533
571
|
if (isPayloadContentType && isModelContentType) {
|
@@ -539,26 +577,69 @@ namespace snowcrash {
|
|
539
577
|
ss << "specify this header(s) in the referenced model definition instead";
|
540
578
|
|
541
579
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
542
|
-
report.warnings.push_back(Warning(ss.str(),
|
543
|
-
|
544
|
-
|
580
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
581
|
+
IgnoringWarning,
|
582
|
+
sourceMap));
|
545
583
|
}
|
546
584
|
|
547
585
|
if (isPayloadContentType && !isModelContentType) {
|
548
|
-
out.headers.insert(out.headers.end(), model.headers.begin(), model.headers.end());
|
549
|
-
}
|
550
|
-
|
551
|
-
out.headers = model.headers;
|
586
|
+
out.node.headers.insert(out.node.headers.end(), model.headers.begin(), model.headers.end());
|
587
|
+
} else {
|
588
|
+
out.node.headers = model.headers;
|
552
589
|
}
|
553
590
|
|
554
|
-
out.body = model.body;
|
555
|
-
out.schema = model.schema;
|
591
|
+
out.node.body = model.body;
|
592
|
+
out.node.schema = model.schema;
|
593
|
+
|
594
|
+
if (pd.exportSourceMap()) {
|
595
|
+
|
596
|
+
modelSM = pd.symbolSourceMapTable.resourceModels.at(symbol);
|
597
|
+
|
598
|
+
out.sourceMap.description = modelSM.description;
|
599
|
+
out.sourceMap.parameters = modelSM.parameters;
|
600
|
+
out.sourceMap.body = modelSM.body;
|
601
|
+
out.sourceMap.schema = modelSM.schema;
|
602
|
+
|
603
|
+
if (isPayloadContentType && !isModelContentType) {
|
604
|
+
out.sourceMap.headers.collection.insert(out.sourceMap.headers.collection.end(), modelSM.headers.collection.begin(), modelSM.headers.collection.end());
|
605
|
+
} else {
|
606
|
+
out.sourceMap.headers = modelSM.headers;
|
607
|
+
}
|
608
|
+
}
|
556
609
|
|
557
610
|
return true;
|
558
611
|
}
|
559
612
|
|
560
613
|
return false;
|
561
614
|
}
|
615
|
+
|
616
|
+
/**
|
617
|
+
* \brief Find a request within given action.
|
618
|
+
* \param transaction A transaction to check.
|
619
|
+
* \param request A request to look for.
|
620
|
+
* \return Iterator pointing to the matching request within given method requests.
|
621
|
+
*/
|
622
|
+
static RequestIterator findRequest(const TransactionExample& example,
|
623
|
+
const Request& request) {
|
624
|
+
|
625
|
+
return std::find_if(example.requests.begin(),
|
626
|
+
example.requests.end(),
|
627
|
+
std::bind2nd(MatchPayload(), request));
|
628
|
+
}
|
629
|
+
|
630
|
+
/**
|
631
|
+
* \brief Find a response within responses of a given action.
|
632
|
+
* \param transaction A transaction to check.
|
633
|
+
* \param response A response to look for.
|
634
|
+
* \return Iterator pointing to the matching response within given method requests.
|
635
|
+
*/
|
636
|
+
static ResponseIterator findResponse(const TransactionExample& example,
|
637
|
+
const Response& response) {
|
638
|
+
|
639
|
+
return std::find_if(example.responses.begin(),
|
640
|
+
example.responses.end(),
|
641
|
+
std::bind2nd(MatchPayload(), response));
|
642
|
+
}
|
562
643
|
};
|
563
644
|
|
564
645
|
/** Payload Section Parser */
|