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
@@ -20,9 +20,6 @@ namespace snowcrash {
|
|
20
20
|
/** Headers matching regex */
|
21
21
|
const char* const HeadersRegex = "^[[:blank:]]*[Hh]eaders?[[:blank:]]*$";
|
22
22
|
|
23
|
-
/** Internal type alias for collection of HTTP headers */
|
24
|
-
typedef Collection<Header>::type Headers;
|
25
|
-
|
26
23
|
/** Header Iterator in its containment group */
|
27
24
|
typedef Collection<Header>::const_iterator HeaderIterator;
|
28
25
|
|
@@ -36,13 +33,12 @@ namespace snowcrash {
|
|
36
33
|
const MarkdownNodes& siblings,
|
37
34
|
SectionParserData& pd,
|
38
35
|
SectionLayout& layout,
|
39
|
-
|
40
|
-
Headers& out) {
|
36
|
+
ParseResult<Headers>& out) {
|
41
37
|
|
42
38
|
mdp::ByteBuffer content;
|
43
|
-
CodeBlockUtility::signatureContentAsCodeBlock(node, pd, report, content);
|
39
|
+
CodeBlockUtility::signatureContentAsCodeBlock(node, pd, out.report, content);
|
44
40
|
|
45
|
-
headersFromContent(node, content, pd,
|
41
|
+
headersFromContent(node, content, pd, out);
|
46
42
|
|
47
43
|
return ++MarkdownNodeIterator(node);
|
48
44
|
}
|
@@ -50,21 +46,20 @@ namespace snowcrash {
|
|
50
46
|
static MarkdownNodeIterator processDescription(const MarkdownNodeIterator& node,
|
51
47
|
const MarkdownNodes& siblings,
|
52
48
|
SectionParserData& pd,
|
53
|
-
|
54
|
-
|
49
|
+
ParseResult<Headers>& out) {
|
50
|
+
|
55
51
|
return node;
|
56
52
|
}
|
57
53
|
|
58
54
|
static MarkdownNodeIterator processContent(const MarkdownNodeIterator& node,
|
59
55
|
const MarkdownNodes& siblings,
|
60
56
|
SectionParserData& pd,
|
61
|
-
|
62
|
-
Headers& out) {
|
57
|
+
ParseResult<Headers>& out) {
|
63
58
|
|
64
59
|
mdp::ByteBuffer content;
|
65
|
-
CodeBlockUtility::contentAsCodeBlock(node, pd, report, content);
|
60
|
+
CodeBlockUtility::contentAsCodeBlock(node, pd, out.report, content);
|
66
61
|
|
67
|
-
headersFromContent(node, content, pd,
|
62
|
+
headersFromContent(node, content, pd, out);
|
68
63
|
|
69
64
|
return ++MarkdownNodeIterator(node);
|
70
65
|
}
|
@@ -101,16 +96,15 @@ namespace snowcrash {
|
|
101
96
|
|
102
97
|
static void finalize(const MarkdownNodeIterator& node,
|
103
98
|
SectionParserData& pd,
|
104
|
-
|
105
|
-
Headers& out) {
|
99
|
+
ParseResult<Headers>& out) {
|
106
100
|
|
107
|
-
if (out.empty()) {
|
101
|
+
if (out.node.empty()) {
|
108
102
|
|
109
103
|
// WARN: No headers defined
|
110
104
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
111
|
-
report.warnings.push_back(Warning("no headers specified",
|
112
|
-
|
113
|
-
|
105
|
+
out.report.warnings.push_back(Warning("no headers specified",
|
106
|
+
FormattingWarning,
|
107
|
+
sourceMap));
|
114
108
|
}
|
115
109
|
}
|
116
110
|
|
@@ -118,13 +112,14 @@ namespace snowcrash {
|
|
118
112
|
static void headersFromContent(const MarkdownNodeIterator& node,
|
119
113
|
const mdp::ByteBuffer& content,
|
120
114
|
SectionParserData& pd,
|
121
|
-
|
122
|
-
|
115
|
+
ParseResult<Headers>& out) {
|
116
|
+
|
123
117
|
std::vector<std::string> lines = Split(content, '\n');
|
124
118
|
|
125
119
|
for (std::vector<std::string>::iterator line = lines.begin();
|
126
120
|
line != lines.end();
|
127
121
|
++line) {
|
122
|
+
|
128
123
|
if (TrimString(*line).empty()) {
|
129
124
|
continue;
|
130
125
|
}
|
@@ -132,51 +127,97 @@ namespace snowcrash {
|
|
132
127
|
Header header;
|
133
128
|
|
134
129
|
if (CodeBlockUtility::keyValueFromLine(*line, header)) {
|
135
|
-
if (findHeader(
|
130
|
+
if (findHeader(out.node, header) != out.node.end()) {
|
136
131
|
// WARN: duplicate header on this level
|
137
132
|
std::stringstream ss;
|
138
133
|
|
139
134
|
ss << "duplicate definition of '" << header.first << "' header";
|
140
135
|
|
141
136
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
142
|
-
report.warnings.push_back(Warning(ss.str(),
|
143
|
-
|
144
|
-
|
137
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
138
|
+
DuplicateWarning,
|
139
|
+
sourceMap));
|
145
140
|
}
|
146
141
|
|
147
|
-
|
142
|
+
out.node.push_back(header);
|
143
|
+
|
144
|
+
if (pd.exportSourceMap()) {
|
145
|
+
SourceMap<Header> headerSM;
|
146
|
+
headerSM.sourceMap = node->sourceMap;
|
147
|
+
out.sourceMap.collection.push_back(headerSM);
|
148
|
+
}
|
148
149
|
} else {
|
149
150
|
// WARN: unable to parse header
|
150
151
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
151
|
-
report.warnings.push_back(Warning("unable to parse HTTP header, expected '<header name> : <header value>', one header per line",
|
152
|
-
|
153
|
-
|
152
|
+
out.report.warnings.push_back(Warning("unable to parse HTTP header, expected '<header name> : <header value>', one header per line",
|
153
|
+
FormattingWarning,
|
154
|
+
sourceMap));
|
154
155
|
}
|
155
156
|
}
|
156
157
|
}
|
157
158
|
|
158
159
|
/** Inject headers into transaction examples requests and responses */
|
159
|
-
static void injectDeprecatedHeaders(
|
160
|
-
|
160
|
+
static void injectDeprecatedHeaders(SectionParserData& pd,
|
161
|
+
const Headers& headers,
|
162
|
+
const SourceMap<Headers>& headersSM,
|
163
|
+
TransactionExamples& examples,
|
164
|
+
SourceMap<TransactionExamples>& examplesSM) {
|
165
|
+
|
166
|
+
Collection<TransactionExample>::iterator exampleIt = examples.begin();
|
167
|
+
Collection<SourceMap<TransactionExample> >::iterator exampleSourceMapIt;
|
168
|
+
|
169
|
+
if (pd.exportSourceMap()) {
|
170
|
+
exampleSourceMapIt = examplesSM.collection.begin();
|
171
|
+
}
|
172
|
+
|
173
|
+
while (exampleIt != examples.end()) {
|
161
174
|
|
162
|
-
|
163
|
-
|
164
|
-
|
175
|
+
Collection<Request>::iterator requestIt = exampleIt->requests.begin();
|
176
|
+
Collection<SourceMap<Request> >::iterator requestSourceMapIt;
|
177
|
+
|
178
|
+
if (pd.exportSourceMap()) {
|
179
|
+
requestSourceMapIt = exampleSourceMapIt->requests.collection.begin();
|
180
|
+
}
|
165
181
|
|
166
182
|
// Requests
|
167
|
-
|
168
|
-
|
169
|
-
|
183
|
+
while (requestIt != exampleIt->requests.end()) {
|
184
|
+
|
185
|
+
requestIt->headers.insert(requestIt->headers.begin(), headers.begin(), headers.end());
|
186
|
+
++requestIt;
|
187
|
+
|
188
|
+
if (pd.exportSourceMap()) {
|
189
|
+
requestSourceMapIt->headers.collection.insert(requestSourceMapIt->headers.collection.begin(),
|
190
|
+
headersSM.collection.begin(),
|
191
|
+
headersSM.collection.end());
|
192
|
+
++requestSourceMapIt;
|
193
|
+
}
|
194
|
+
}
|
170
195
|
|
171
|
-
|
196
|
+
Collection<Response>::iterator responseIt = exampleIt->responses.begin();
|
197
|
+
Collection<SourceMap<Response> >::iterator responseSourceMapIt;
|
198
|
+
|
199
|
+
if (pd.exportSourceMap()) {
|
200
|
+
responseSourceMapIt = exampleSourceMapIt->responses.collection.begin();
|
172
201
|
}
|
173
202
|
|
174
203
|
// Responses
|
175
|
-
|
176
|
-
|
177
|
-
|
204
|
+
while(responseIt != exampleIt->responses.end()) {
|
205
|
+
|
206
|
+
responseIt->headers.insert(responseIt->headers.begin(), headers.begin(), headers.end());
|
207
|
+
++responseIt;
|
178
208
|
|
179
|
-
|
209
|
+
if (pd.exportSourceMap()) {
|
210
|
+
responseSourceMapIt->headers.collection.insert(responseSourceMapIt->headers.collection.begin(),
|
211
|
+
headersSM.collection.begin(),
|
212
|
+
headersSM.collection.end());
|
213
|
+
++responseSourceMapIt;
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
++exampleIt;
|
218
|
+
|
219
|
+
if (pd.exportSourceMap()) {
|
220
|
+
++exampleSourceMapIt;
|
180
221
|
}
|
181
222
|
}
|
182
223
|
}
|
@@ -184,6 +225,7 @@ namespace snowcrash {
|
|
184
225
|
/** Finds a header in its containment group by its key (first) */
|
185
226
|
static HeaderIterator findHeader(const Headers& headers,
|
186
227
|
const Header& header) {
|
228
|
+
|
187
229
|
return std::find_if(headers.begin(),
|
188
230
|
headers.end(),
|
189
231
|
std::bind2nd(MatchFirsts<Header>(), header));
|
@@ -59,16 +59,19 @@ namespace snowcrash {
|
|
59
59
|
const MarkdownNodes& siblings,
|
60
60
|
SectionParserData& pd,
|
61
61
|
SectionLayout& layout,
|
62
|
-
|
63
|
-
Parameter& out) {
|
62
|
+
ParseResult<Parameter>& out) {
|
64
63
|
|
65
64
|
mdp::ByteBuffer signature, remainingContent;
|
66
65
|
signature = GetFirstLine(node->text, remainingContent);
|
67
66
|
|
68
|
-
parseSignature(node, pd, signature,
|
67
|
+
parseSignature(node, pd, signature, out);
|
69
68
|
|
70
69
|
if (!remainingContent.empty()) {
|
71
|
-
out.description += "\n" + remainingContent + "\n";
|
70
|
+
out.node.description += "\n" + remainingContent + "\n";
|
71
|
+
|
72
|
+
if (pd.exportSourceMap()) {
|
73
|
+
out.sourceMap.description.sourceMap.append(node->sourceMap);
|
74
|
+
}
|
72
75
|
}
|
73
76
|
|
74
77
|
return ++MarkdownNodeIterator(node);
|
@@ -78,46 +81,50 @@ namespace snowcrash {
|
|
78
81
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
79
82
|
const MarkdownNodes& siblings,
|
80
83
|
SectionParserData& pd,
|
81
|
-
|
82
|
-
Parameter& out) {
|
84
|
+
ParseResult<Parameter>& out) {
|
83
85
|
|
84
86
|
if (pd.sectionContext() != ValuesSectionType) {
|
85
87
|
return node;
|
86
88
|
}
|
87
89
|
|
88
90
|
// Check redefinition
|
89
|
-
if (!out.values.empty()) {
|
91
|
+
if (!out.node.values.empty()) {
|
90
92
|
// WARN: parameter values are already defined
|
91
93
|
std::stringstream ss;
|
92
94
|
ss << "overshadowing previous 'values' definition";
|
93
|
-
ss << " for parameter '" << out.name << "'";
|
95
|
+
ss << " for parameter '" << out.node.name << "'";
|
94
96
|
|
95
97
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
96
|
-
report.warnings.push_back(Warning(ss.str(),
|
97
|
-
|
98
|
-
|
98
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
99
|
+
RedefinitionWarning,
|
100
|
+
sourceMap));
|
99
101
|
}
|
100
102
|
|
101
103
|
// Clear any previous values
|
102
|
-
out.values.clear();
|
104
|
+
out.node.values.clear();
|
105
|
+
|
106
|
+
if (pd.exportSourceMap()) {
|
107
|
+
out.sourceMap.values.collection.clear();
|
108
|
+
}
|
103
109
|
|
104
|
-
|
110
|
+
ParseResult<Values> values(out.report, out.node.values, out.sourceMap.values);
|
111
|
+
ValuesParser::parse(node, siblings, pd, values);
|
105
112
|
|
106
|
-
if (out.values.empty()) {
|
113
|
+
if (out.node.values.empty()) {
|
107
114
|
// WARN: empty definition
|
108
115
|
std::stringstream ss;
|
109
|
-
ss << "no possible values specified for parameter '" << out.name << "'";
|
116
|
+
ss << "no possible values specified for parameter '" << out.node.name << "'";
|
110
117
|
|
111
118
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
112
|
-
report.warnings.push_back(Warning(ss.str(),
|
113
|
-
|
114
|
-
|
119
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
120
|
+
EmptyDefinitionWarning,
|
121
|
+
sourceMap));
|
115
122
|
}
|
116
123
|
|
117
|
-
if ((!out.exampleValue.empty() || !out.defaultValue.empty()) &&
|
118
|
-
!out.values.empty()) {
|
124
|
+
if ((!out.node.exampleValue.empty() || !out.node.defaultValue.empty()) &&
|
125
|
+
!out.node.values.empty()) {
|
119
126
|
|
120
|
-
checkExampleAndDefaultValue(node, pd,
|
127
|
+
checkExampleAndDefaultValue(node, pd, out);
|
121
128
|
}
|
122
129
|
|
123
130
|
return ++MarkdownNodeIterator(node);
|
@@ -156,10 +163,9 @@ namespace snowcrash {
|
|
156
163
|
static void parseSignature(const mdp::MarkdownNodeIterator& node,
|
157
164
|
SectionParserData& pd,
|
158
165
|
mdp::ByteBuffer& signature,
|
159
|
-
|
160
|
-
Parameter& parameter) {
|
166
|
+
ParseResult<Parameter>& out) {
|
161
167
|
|
162
|
-
|
168
|
+
out.node.use = UndefinedParameterUse;
|
163
169
|
|
164
170
|
TrimString(signature);
|
165
171
|
|
@@ -174,17 +180,19 @@ namespace snowcrash {
|
|
174
180
|
|
175
181
|
if (firstSpace == std::string::npos) {
|
176
182
|
// Name
|
177
|
-
|
183
|
+
out.node.name = signature;
|
178
184
|
}
|
179
185
|
else {
|
180
|
-
|
186
|
+
out.node.name = innerSignature.substr(0, firstSpace);
|
181
187
|
innerSignature = innerSignature.substr(firstSpace + 1);
|
188
|
+
|
182
189
|
size_t descriptionPos = innerSignature.find(snowcrash::DescriptionIdentifier);
|
183
190
|
|
184
191
|
if (descriptionPos != std::string::npos) {
|
185
192
|
// Description
|
186
|
-
|
187
|
-
|
193
|
+
out.node.description = innerSignature.substr(descriptionPos);
|
194
|
+
out.node.description = TrimString(out.node.description.replace(0, snowcrash::DescriptionIdentifier.length(), ""));
|
195
|
+
|
188
196
|
innerSignature = innerSignature.substr(0, descriptionPos);
|
189
197
|
innerSignature = TrimString(innerSignature);
|
190
198
|
}
|
@@ -197,7 +205,9 @@ namespace snowcrash {
|
|
197
205
|
if (endOfAttributesPos - attributesPos > 1) {
|
198
206
|
std::string attributes = innerSignature.substr(attributesPos, endOfAttributesPos - attributesPos);
|
199
207
|
attributes = attributes.substr(1);
|
200
|
-
|
208
|
+
|
209
|
+
parseAdditionalTraits(node, pd, attributes, out);
|
210
|
+
|
201
211
|
innerSignature = innerSignature.substr(0, attributesPos);
|
202
212
|
innerSignature = TrimString(innerSignature);
|
203
213
|
}
|
@@ -205,41 +215,56 @@ namespace snowcrash {
|
|
205
215
|
|
206
216
|
if (innerSignature.length() > 0) {
|
207
217
|
// Remove =
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
218
|
+
out.node.defaultValue = innerSignature;
|
219
|
+
|
220
|
+
out.node.defaultValue.erase(std::remove(out.node.defaultValue.begin(), out.node.defaultValue.end(), '='), out.node.defaultValue.end());
|
221
|
+
out.node.defaultValue.erase(std::remove(out.node.defaultValue.begin(), out.node.defaultValue.end(), '`'), out.node.defaultValue.end());
|
222
|
+
|
223
|
+
out.node.defaultValue = TrimString(out.node.defaultValue);
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
if (pd.exportSourceMap()) {
|
228
|
+
if (!out.node.name.empty()) {
|
229
|
+
out.sourceMap.name.sourceMap = node->sourceMap;
|
230
|
+
}
|
231
|
+
|
232
|
+
if (!out.node.description.empty()) {
|
233
|
+
out.sourceMap.description.sourceMap = node->sourceMap;
|
234
|
+
}
|
235
|
+
|
236
|
+
if (!out.node.defaultValue.empty()) {
|
237
|
+
out.sourceMap.defaultValue.sourceMap = node->sourceMap;
|
212
238
|
}
|
213
239
|
}
|
214
240
|
|
215
241
|
// Check possible required vs default clash
|
216
|
-
if (
|
217
|
-
!
|
218
|
-
|
242
|
+
if (out.node.use != OptionalParameterUse &&
|
243
|
+
!out.node.defaultValue.empty()) {
|
244
|
+
|
219
245
|
// WARN: Required vs default clash
|
220
246
|
std::stringstream ss;
|
221
|
-
ss << "specifying parameter '" <<
|
247
|
+
ss << "specifying parameter '" << out.node.name << "' as required supersedes its default value"\
|
222
248
|
", declare the parameter as 'optional' to specify its default value";
|
223
249
|
|
224
250
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
225
|
-
report.warnings.push_back(Warning(ss.str(),
|
226
|
-
|
227
|
-
|
251
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
252
|
+
LogicalErrorWarning,
|
253
|
+
sourceMap));
|
228
254
|
}
|
229
255
|
} else {
|
230
256
|
// ERR: unable to parse
|
231
257
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
232
|
-
report.error = Error("unable to parse parameter specification",
|
233
|
-
|
234
|
-
|
258
|
+
out.report.error = Error("unable to parse parameter specification",
|
259
|
+
BusinessError,
|
260
|
+
sourceMap);
|
235
261
|
}
|
236
262
|
}
|
237
263
|
|
238
264
|
static void parseAdditionalTraits(const mdp::MarkdownNodeIterator& node,
|
239
265
|
SectionParserData& pd,
|
240
266
|
mdp::ByteBuffer& traits,
|
241
|
-
|
242
|
-
Parameter& parameter) {
|
267
|
+
ParseResult<Parameter>& out) {
|
243
268
|
|
244
269
|
TrimString(traits);
|
245
270
|
|
@@ -249,13 +274,17 @@ namespace snowcrash {
|
|
249
274
|
if (RegexCapture(traits, AdditionalTraitsExampleRegex, captureGroups) &&
|
250
275
|
captureGroups.size() > 1) {
|
251
276
|
|
252
|
-
|
277
|
+
out.node.exampleValue = captureGroups[1];
|
253
278
|
std::string::size_type pos = traits.find(captureGroups[0]);
|
254
279
|
|
255
280
|
if (pos != std::string::npos) {
|
256
281
|
traits.replace(pos, captureGroups[0].length(), std::string());
|
257
282
|
}
|
258
|
-
|
283
|
+
|
284
|
+
if (pd.exportSourceMap()) {
|
285
|
+
out.sourceMap.exampleValue.sourceMap = node->sourceMap;
|
286
|
+
}
|
287
|
+
}
|
259
288
|
|
260
289
|
captureGroups.clear();
|
261
290
|
|
@@ -263,12 +292,16 @@ namespace snowcrash {
|
|
263
292
|
if (RegexCapture(traits, AdditionalTraitsUseRegex, captureGroups) &&
|
264
293
|
captureGroups.size() > 1) {
|
265
294
|
|
266
|
-
|
295
|
+
out.node.use = RegexMatch(captureGroups[1], ParameterOptionalRegex) ? OptionalParameterUse : RequiredParameterUse;
|
267
296
|
std::string::size_type pos = traits.find(captureGroups[0]);
|
268
297
|
|
269
298
|
if (pos != std::string::npos) {
|
270
299
|
traits.replace(pos, captureGroups[0].length(), std::string());
|
271
300
|
}
|
301
|
+
|
302
|
+
if (pd.exportSourceMap()) {
|
303
|
+
out.sourceMap.use.sourceMap = node->sourceMap;
|
304
|
+
}
|
272
305
|
}
|
273
306
|
|
274
307
|
captureGroups.clear();
|
@@ -277,12 +310,16 @@ namespace snowcrash {
|
|
277
310
|
if (RegexCapture(traits, AdditionalTraitsTypeRegex, captureGroups) &&
|
278
311
|
captureGroups.size() > 1) {
|
279
312
|
|
280
|
-
|
313
|
+
out.node.type = captureGroups[1];
|
281
314
|
std::string::size_type pos = traits.find(captureGroups[0]);
|
282
315
|
|
283
316
|
if (pos != std::string::npos) {
|
284
317
|
traits.replace(pos, captureGroups[0].length(), std::string());
|
285
318
|
}
|
319
|
+
|
320
|
+
if (pd.exportSourceMap()) {
|
321
|
+
out.sourceMap.type.sourceMap = node->sourceMap;
|
322
|
+
}
|
286
323
|
}
|
287
324
|
|
288
325
|
// Check what is left
|
@@ -296,20 +333,25 @@ namespace snowcrash {
|
|
296
333
|
ss << ", e.g. '(optional, string, `Hello World`)'";
|
297
334
|
|
298
335
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
299
|
-
report.warnings.push_back(Warning(ss.str(),
|
300
|
-
|
301
|
-
|
336
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
337
|
+
FormattingWarning,
|
338
|
+
sourceMap));
|
302
339
|
|
303
|
-
|
304
|
-
|
305
|
-
|
340
|
+
out.node.type.clear();
|
341
|
+
out.node.exampleValue.clear();
|
342
|
+
out.node.use = UndefinedParameterUse;
|
343
|
+
|
344
|
+
if (pd.exportSourceMap()) {
|
345
|
+
out.sourceMap.type.sourceMap.clear();
|
346
|
+
out.sourceMap.exampleValue.sourceMap.clear();
|
347
|
+
out.sourceMap.use.sourceMap.clear();
|
348
|
+
}
|
306
349
|
}
|
307
350
|
}
|
308
351
|
|
309
352
|
static void checkExampleAndDefaultValue(const mdp::MarkdownNodeIterator& node,
|
310
353
|
SectionParserData& pd,
|
311
|
-
|
312
|
-
Parameter& parameter) {
|
354
|
+
ParseResult<Parameter>& out) {
|
313
355
|
|
314
356
|
bool isExampleFound = false;
|
315
357
|
bool isDefaultFound = false;
|
@@ -317,40 +359,40 @@ namespace snowcrash {
|
|
317
359
|
std::stringstream ss;
|
318
360
|
bool printWarning = false;
|
319
361
|
|
320
|
-
for (Collection<Value>::iterator it =
|
321
|
-
it !=
|
362
|
+
for (Collection<Value>::iterator it = out.node.values.begin();
|
363
|
+
it != out.node.values.end();
|
322
364
|
++it) {
|
323
365
|
|
324
|
-
if (
|
366
|
+
if (out.node.exampleValue == *it) {
|
325
367
|
isExampleFound = true;
|
326
368
|
}
|
327
369
|
|
328
|
-
if (
|
370
|
+
if (out.node.defaultValue == *it) {
|
329
371
|
isDefaultFound = true;
|
330
372
|
}
|
331
373
|
}
|
332
374
|
|
333
|
-
if(!
|
375
|
+
if(!out.node.exampleValue.empty() &&
|
334
376
|
!isExampleFound) {
|
335
377
|
|
336
378
|
// WARN: missing example in values.
|
337
|
-
ss << "the example value '" <<
|
379
|
+
ss << "the example value '" << out.node.exampleValue << "' of parameter '"<< out.node.name <<"' is not in its list of expected values";
|
338
380
|
printWarning = true;
|
339
381
|
}
|
340
382
|
|
341
|
-
if(!
|
383
|
+
if(!out.node.defaultValue.empty() &&
|
342
384
|
!isDefaultFound) {
|
343
385
|
|
344
386
|
// WARN: missing default in values.
|
345
|
-
ss << "the default value '" <<
|
387
|
+
ss << "the default value '" << out.node.defaultValue << "' of parameter '"<< out.node.name <<"' is not in its list of expected values";
|
346
388
|
printWarning = true;
|
347
389
|
}
|
348
390
|
|
349
391
|
if (printWarning) {
|
350
392
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
351
|
-
report.warnings.push_back(Warning(ss.str(),
|
352
|
-
|
353
|
-
|
393
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
394
|
+
LogicalErrorWarning,
|
395
|
+
sourceMap));
|
354
396
|
}
|
355
397
|
}
|
356
398
|
|