redsnow 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 */
|