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
@@ -17,14 +17,12 @@ namespace snowcrash {
|
|
17
17
|
|
18
18
|
const char* const GroupHeaderRegex = "^[[:blank:]]*[Gg]roup[[:blank:]]+" SYMBOL_IDENTIFIER "[[:blank:]]*$";
|
19
19
|
|
20
|
-
/**
|
21
|
-
typedef std::pair<Collection<ResourceGroup>::const_iterator, ResourceIterator> ResourceIteratorPair;
|
22
|
-
|
23
|
-
/** Internal type alias for Collection of Resource */
|
24
|
-
typedef Collection<ResourceGroup>::type ResourceGroups;
|
25
|
-
|
20
|
+
/** Internal type alias for Collection iterator of Resource */
|
26
21
|
typedef Collection<ResourceGroup>::const_iterator ResourceGroupIterator;
|
27
22
|
|
23
|
+
/** Resource iterator pair: its containment group and resource iterator itself */
|
24
|
+
typedef std::pair<ResourceGroupIterator, ResourceIterator> ResourceIteratorPair;
|
25
|
+
|
28
26
|
/**
|
29
27
|
* ResourceGroup Section processor
|
30
28
|
*/
|
@@ -35,8 +33,7 @@ namespace snowcrash {
|
|
35
33
|
const MarkdownNodes& siblings,
|
36
34
|
SectionParserData& pd,
|
37
35
|
SectionLayout& layout,
|
38
|
-
|
39
|
-
ResourceGroup& out) {
|
36
|
+
ParseResult<ResourceGroup>& out) {
|
40
37
|
|
41
38
|
MarkdownNodeIterator cur = node;
|
42
39
|
SectionType nestedType = nestedSectionType(cur);
|
@@ -50,8 +47,12 @@ namespace snowcrash {
|
|
50
47
|
CaptureGroups captureGroups;
|
51
48
|
|
52
49
|
if (RegexCapture(node->text, GroupHeaderRegex, captureGroups, 3)) {
|
53
|
-
out.name = captureGroups[1];
|
54
|
-
TrimString(out.name);
|
50
|
+
out.node.name = captureGroups[1];
|
51
|
+
TrimString(out.node.name);
|
52
|
+
}
|
53
|
+
|
54
|
+
if (pd.exportSourceMap() && !out.node.name.empty()) {
|
55
|
+
out.sourceMap.name.sourceMap = node->sourceMap;
|
55
56
|
}
|
56
57
|
|
57
58
|
return ++MarkdownNodeIterator(node);
|
@@ -60,32 +61,35 @@ namespace snowcrash {
|
|
60
61
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
61
62
|
const MarkdownNodes& siblings,
|
62
63
|
SectionParserData& pd,
|
63
|
-
|
64
|
-
ResourceGroup& out) {
|
64
|
+
ParseResult<ResourceGroup>& out) {
|
65
65
|
|
66
66
|
if (pd.sectionContext() == ResourceSectionType) {
|
67
67
|
|
68
|
-
Resource resource;
|
69
|
-
MarkdownNodeIterator cur = ResourceParser::parse(node, siblings, pd,
|
68
|
+
ParseResult<Resource> resource(out.report);
|
69
|
+
MarkdownNodeIterator cur = ResourceParser::parse(node, siblings, pd, resource);
|
70
70
|
|
71
|
-
ResourceIterator duplicate = findResource(out.resources, resource);
|
71
|
+
ResourceIterator duplicate = SectionProcessor<Resource>::findResource(out.node.resources, resource.node);
|
72
72
|
ResourceIteratorPair globalDuplicate;
|
73
73
|
|
74
|
-
if (duplicate == out.resources.end()) {
|
75
|
-
globalDuplicate = findResource(pd.blueprint, resource);
|
74
|
+
if (duplicate == out.node.resources.end()) {
|
75
|
+
globalDuplicate = findResource(pd.blueprint, resource.node);
|
76
76
|
}
|
77
77
|
|
78
|
-
if (duplicate != out.resources.end() ||
|
78
|
+
if (duplicate != out.node.resources.end() ||
|
79
79
|
globalDuplicate.first != pd.blueprint.resourceGroups.end()) {
|
80
80
|
|
81
81
|
// WARN: Duplicate resource
|
82
82
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
83
|
-
report.warnings.push_back(Warning("the resource '" + resource.uriTemplate + "' is already defined",
|
84
|
-
|
85
|
-
|
83
|
+
out.report.warnings.push_back(Warning("the resource '" + resource.node.uriTemplate + "' is already defined",
|
84
|
+
DuplicateWarning,
|
85
|
+
sourceMap));
|
86
86
|
}
|
87
87
|
|
88
|
-
out.resources.push_back(resource);
|
88
|
+
out.node.resources.push_back(resource.node);
|
89
|
+
|
90
|
+
if (pd.exportSourceMap()) {
|
91
|
+
out.sourceMap.resources.collection.push_back(resource.sourceMap);
|
92
|
+
}
|
89
93
|
|
90
94
|
return cur;
|
91
95
|
}
|
@@ -97,11 +101,10 @@ namespace snowcrash {
|
|
97
101
|
const MarkdownNodes& siblings,
|
98
102
|
SectionParserData& pd,
|
99
103
|
SectionType& lastSectionType,
|
100
|
-
|
101
|
-
ResourceGroup& out) {
|
104
|
+
ParseResult<ResourceGroup>& out) {
|
102
105
|
|
103
106
|
if (SectionProcessor<Action>::actionType(node) == DependentActionType &&
|
104
|
-
!out.resources.empty()) {
|
107
|
+
!out.node.resources.empty()) {
|
105
108
|
|
106
109
|
mdp::ByteBuffer method;
|
107
110
|
mdp::ByteBuffer name;
|
@@ -111,17 +114,17 @@ namespace snowcrash {
|
|
111
114
|
|
112
115
|
// WARN: Unexpected action
|
113
116
|
std::stringstream ss;
|
114
|
-
ss << "unexpected action '" << method << "', to define multiple actions for the '" << out.resources.back().uriTemplate;
|
117
|
+
ss << "unexpected action '" << method << "', to define multiple actions for the '" << out.node.resources.back().uriTemplate;
|
115
118
|
ss << "' resource omit the HTTP method in its definition, e.g. '# /resource'";
|
116
119
|
|
117
|
-
report.warnings.push_back(Warning(ss.str(),
|
118
|
-
|
119
|
-
|
120
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
121
|
+
IgnoringWarning,
|
122
|
+
sourceMap));
|
120
123
|
|
121
124
|
return ++MarkdownNodeIterator(node);
|
122
125
|
}
|
123
126
|
|
124
|
-
return SectionProcessorBase<ResourceGroup>::processUnexpectedNode(node, siblings, pd, lastSectionType,
|
127
|
+
return SectionProcessorBase<ResourceGroup>::processUnexpectedNode(node, siblings, pd, lastSectionType, out);
|
125
128
|
}
|
126
129
|
|
127
130
|
static SectionType sectionType(const MarkdownNodeIterator& node) {
|
@@ -179,24 +182,15 @@ namespace snowcrash {
|
|
179
182
|
return SectionProcessorBase<ResourceGroup>::isUnexpectedNode(node, sectionType);
|
180
183
|
}
|
181
184
|
|
182
|
-
/** Finds a resource inside an resources collection */
|
183
|
-
static ResourceIterator findResource(const Resources& resources,
|
184
|
-
const Resource& resource) {
|
185
|
-
|
186
|
-
return std::find_if(resources.begin(),
|
187
|
-
resources.end(),
|
188
|
-
std::bind2nd(MatchResource(), resource));
|
189
|
-
}
|
190
|
-
|
191
185
|
/** Finds a resource in blueprint by its URI template */
|
192
186
|
static ResourceIteratorPair findResource(const Blueprint& blueprint,
|
193
187
|
const Resource& resource) {
|
194
188
|
|
195
|
-
for (
|
189
|
+
for (ResourceGroupIterator it = blueprint.resourceGroups.begin();
|
196
190
|
it != blueprint.resourceGroups.end();
|
197
191
|
++it) {
|
198
192
|
|
199
|
-
ResourceIterator match = findResource(it->resources, resource);
|
193
|
+
ResourceIterator match = SectionProcessor<Resource>::findResource(it->resources, resource);
|
200
194
|
|
201
195
|
if (match != it->resources.end()) {
|
202
196
|
return std::make_pair(it, match);
|
@@ -24,9 +24,7 @@ namespace snowcrash {
|
|
24
24
|
/** Named resource matching regex */
|
25
25
|
const char* const NamedResourceHeaderRegex = "^[[:blank:]]*" SYMBOL_IDENTIFIER "[[:blank:]]+\\[" URI_TEMPLATE "]$";
|
26
26
|
|
27
|
-
/** Internal type alias for Collection of Resource */
|
28
|
-
typedef Collection<Resource>::type Resources;
|
29
|
-
|
27
|
+
/** Internal type alias for Collection iterator of Resource */
|
30
28
|
typedef Collection<Resource>::const_iterator ResourceIterator;
|
31
29
|
|
32
30
|
/**
|
@@ -39,32 +37,46 @@ namespace snowcrash {
|
|
39
37
|
const MarkdownNodes& siblings,
|
40
38
|
SectionParserData& pd,
|
41
39
|
SectionLayout& layout,
|
42
|
-
|
43
|
-
Resource& out) {
|
40
|
+
ParseResult<Resource>& out) {
|
44
41
|
|
45
42
|
CaptureGroups captureGroups;
|
46
43
|
|
47
44
|
// If Abbreviated resource section
|
48
45
|
if (RegexCapture(node->text, ResourceHeaderRegex, captureGroups, 4)) {
|
49
46
|
|
50
|
-
out.uriTemplate = captureGroups[3];
|
47
|
+
out.node.uriTemplate = captureGroups[3];
|
51
48
|
|
52
49
|
// Make this section an action
|
53
50
|
if (!captureGroups[2].empty()) {
|
54
51
|
|
55
|
-
Action action;
|
56
|
-
MarkdownNodeIterator cur = ActionParser::parse(node, node->parent().children(), pd,
|
52
|
+
ParseResult<Action> action(out.report);
|
53
|
+
MarkdownNodeIterator cur = ActionParser::parse(node, node->parent().children(), pd, action);
|
57
54
|
|
58
|
-
out.actions.push_back(action);
|
55
|
+
out.node.actions.push_back(action.node);
|
59
56
|
layout = RedirectSectionLayout;
|
60
57
|
|
58
|
+
if (pd.exportSourceMap()) {
|
59
|
+
out.sourceMap.actions.collection.push_back(action.sourceMap);
|
60
|
+
out.sourceMap.uriTemplate.sourceMap = node->sourceMap;
|
61
|
+
}
|
62
|
+
|
61
63
|
return cur;
|
62
64
|
}
|
63
65
|
} else if (RegexCapture(node->text, NamedResourceHeaderRegex, captureGroups, 4)) {
|
64
66
|
|
65
|
-
out.name = captureGroups[1];
|
66
|
-
TrimString(out.name);
|
67
|
-
out.uriTemplate = captureGroups[2];
|
67
|
+
out.node.name = captureGroups[1];
|
68
|
+
TrimString(out.node.name);
|
69
|
+
out.node.uriTemplate = captureGroups[2];
|
70
|
+
}
|
71
|
+
|
72
|
+
if (pd.exportSourceMap()) {
|
73
|
+
if (!out.node.uriTemplate.empty()) {
|
74
|
+
out.sourceMap.uriTemplate.sourceMap = node->sourceMap;
|
75
|
+
}
|
76
|
+
|
77
|
+
if (!out.node.name.empty()) {
|
78
|
+
out.sourceMap.name.sourceMap = node->sourceMap;
|
79
|
+
}
|
68
80
|
}
|
69
81
|
|
70
82
|
return ++MarkdownNodeIterator(node);
|
@@ -73,22 +85,24 @@ namespace snowcrash {
|
|
73
85
|
static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node,
|
74
86
|
const MarkdownNodes& siblings,
|
75
87
|
SectionParserData& pd,
|
76
|
-
|
77
|
-
Resource& out) {
|
88
|
+
ParseResult<Resource>& out) {
|
78
89
|
|
79
90
|
switch (pd.sectionContext()) {
|
80
91
|
case ActionSectionType:
|
81
|
-
return processAction(node, siblings, pd,
|
92
|
+
return processAction(node, siblings, pd, out);
|
82
93
|
|
83
94
|
case ParametersSectionType:
|
84
|
-
return processParameters(node, siblings, pd,
|
95
|
+
return processParameters(node, siblings, pd, out);
|
85
96
|
|
86
97
|
case ModelSectionType:
|
87
98
|
case ModelBodySectionType:
|
88
|
-
return processModel(node, siblings, pd,
|
99
|
+
return processModel(node, siblings, pd, out);
|
89
100
|
|
90
101
|
case HeadersSectionType:
|
91
|
-
|
102
|
+
{
|
103
|
+
ParseResult<Headers> headers(out.report, out.node.headers, out.sourceMap.headers);
|
104
|
+
return SectionProcessor<Action>::handleDeprecatedHeaders(node, siblings, pd, headers);
|
105
|
+
}
|
92
106
|
|
93
107
|
default:
|
94
108
|
break;
|
@@ -101,27 +115,34 @@ namespace snowcrash {
|
|
101
115
|
const MarkdownNodes& siblings,
|
102
116
|
SectionParserData& pd,
|
103
117
|
SectionType& sectionType,
|
104
|
-
|
105
|
-
Resource& out) {
|
118
|
+
ParseResult<Resource>& out) {
|
106
119
|
|
107
120
|
if ((node->type == mdp::ParagraphMarkdownNodeType ||
|
108
121
|
node->type == mdp::CodeMarkdownNodeType) &&
|
109
122
|
(sectionType == ModelBodySectionType ||
|
110
123
|
sectionType == ModelSectionType)) {
|
111
124
|
|
112
|
-
CodeBlockUtility::addDanglingAsset(node, pd, sectionType, report, out.model.body);
|
125
|
+
mdp::ByteBuffer content = CodeBlockUtility::addDanglingAsset(node, pd, sectionType, out.report, out.node.model.body);
|
126
|
+
|
127
|
+
if (pd.exportSourceMap() && !content.empty()) {
|
128
|
+
out.sourceMap.model.body.sourceMap.append(node->sourceMap);
|
129
|
+
}
|
113
130
|
|
114
131
|
// Update model in the symbol table as well
|
115
|
-
ResourceModelSymbolTable::iterator it = pd.symbolTable.resourceModels.find(out.model.name);
|
132
|
+
ResourceModelSymbolTable::iterator it = pd.symbolTable.resourceModels.find(out.node.model.name);
|
116
133
|
|
117
134
|
if (it != pd.symbolTable.resourceModels.end()) {
|
118
|
-
it->second.body = out.model.body;
|
135
|
+
it->second.body = out.node.model.body;
|
136
|
+
|
137
|
+
if (pd.exportSourceMap()) {
|
138
|
+
pd.symbolSourceMapTable.resourceModels[out.node.model.name].body = out.sourceMap.model.body;
|
139
|
+
}
|
119
140
|
}
|
120
141
|
|
121
142
|
return ++MarkdownNodeIterator(node);
|
122
143
|
}
|
123
144
|
|
124
|
-
return SectionProcessorBase<Resource>::processUnexpectedNode(node, siblings, pd, sectionType,
|
145
|
+
return SectionProcessorBase<Resource>::processUnexpectedNode(node, siblings, pd, sectionType, out);
|
125
146
|
}
|
126
147
|
|
127
148
|
static bool isDescriptionNode(const MarkdownNodeIterator& node,
|
@@ -212,33 +233,39 @@ namespace snowcrash {
|
|
212
233
|
|
213
234
|
static void finalize(const MarkdownNodeIterator& node,
|
214
235
|
SectionParserData& pd,
|
215
|
-
|
216
|
-
Resource& out) {
|
236
|
+
ParseResult<Resource>& out) {
|
217
237
|
|
218
|
-
if (!out.uriTemplate.empty()) {
|
238
|
+
if (!out.node.uriTemplate.empty()) {
|
219
239
|
|
220
240
|
URITemplateParser uriTemplateParser;
|
221
241
|
ParsedURITemplate parsedResult;
|
222
242
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
223
243
|
|
224
|
-
uriTemplateParser.parse(out.uriTemplate, sourceMap, parsedResult);
|
244
|
+
uriTemplateParser.parse(out.node.uriTemplate, sourceMap, parsedResult);
|
225
245
|
|
226
246
|
if (!parsedResult.report.warnings.empty()) {
|
227
|
-
report += parsedResult.report;
|
247
|
+
out.report += parsedResult.report;
|
228
248
|
}
|
229
249
|
}
|
230
250
|
|
231
|
-
// Consolidate
|
232
|
-
if (!out.headers.empty()) {
|
251
|
+
// Consolidate deprecated headers into subsequent payloads
|
252
|
+
if (!out.node.headers.empty()) {
|
233
253
|
|
234
|
-
|
235
|
-
|
236
|
-
++it) {
|
254
|
+
Collection<Action>::iterator actIt = out.node.actions.begin();
|
255
|
+
Collection<SourceMap<Action> >::iterator actSMIt = out.sourceMap.actions.collection.begin();
|
237
256
|
|
238
|
-
|
257
|
+
for (;
|
258
|
+
actIt != out.node.actions.end();
|
259
|
+
++actIt, ++actSMIt) {
|
260
|
+
|
261
|
+
SectionProcessor<Headers>::injectDeprecatedHeaders(pd, out.node.headers, out.sourceMap.headers, actIt->examples, actSMIt->examples);
|
239
262
|
}
|
240
263
|
|
241
|
-
out.headers.clear();
|
264
|
+
out.node.headers.clear();
|
265
|
+
|
266
|
+
if (pd.exportSourceMap()) {
|
267
|
+
out.sourceMap.headers.collection.clear();
|
268
|
+
}
|
242
269
|
}
|
243
270
|
}
|
244
271
|
|
@@ -246,33 +273,36 @@ namespace snowcrash {
|
|
246
273
|
static MarkdownNodeIterator processAction(const MarkdownNodeIterator& node,
|
247
274
|
const MarkdownNodes& siblings,
|
248
275
|
SectionParserData& pd,
|
249
|
-
|
250
|
-
Resource& out) {
|
276
|
+
ParseResult<Resource>& out) {
|
251
277
|
|
252
|
-
Action action;
|
253
|
-
MarkdownNodeIterator cur = ActionParser::parse(node, siblings, pd,
|
278
|
+
ParseResult<Action> action(out.report);
|
279
|
+
MarkdownNodeIterator cur = ActionParser::parse(node, siblings, pd, action);
|
254
280
|
|
255
|
-
ActionIterator duplicate = findAction(out.actions, action);
|
281
|
+
ActionIterator duplicate = SectionProcessor<Action>::findAction(out.node.actions, action.node);
|
256
282
|
|
257
|
-
if (duplicate != out.actions.end()) {
|
283
|
+
if (duplicate != out.node.actions.end()) {
|
258
284
|
|
259
285
|
// WARN: duplicate method
|
260
286
|
std::stringstream ss;
|
261
|
-
ss << "action with method '" << action.method << "' already defined for resource '";
|
262
|
-
ss << out.uriTemplate << "'";
|
287
|
+
ss << "action with method '" << action.node.method << "' already defined for resource '";
|
288
|
+
ss << out.node.uriTemplate << "'";
|
263
289
|
|
264
290
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
265
|
-
report.warnings.push_back(Warning(ss.str(),
|
266
|
-
|
267
|
-
|
291
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
292
|
+
DuplicateWarning,
|
293
|
+
sourceMap));
|
268
294
|
}
|
269
295
|
|
270
|
-
if (!action.parameters.empty()) {
|
296
|
+
if (!action.node.parameters.empty()) {
|
271
297
|
|
272
|
-
checkParametersEligibility(node, pd,
|
298
|
+
checkParametersEligibility(node, pd, action.node.parameters, out);
|
273
299
|
}
|
274
300
|
|
275
|
-
out.actions.push_back(action);
|
301
|
+
out.node.actions.push_back(action.node);
|
302
|
+
|
303
|
+
if (pd.exportSourceMap()) {
|
304
|
+
out.sourceMap.actions.collection.push_back(action.sourceMap);
|
305
|
+
}
|
276
306
|
|
277
307
|
return cur;
|
278
308
|
}
|
@@ -281,16 +311,21 @@ namespace snowcrash {
|
|
281
311
|
static MarkdownNodeIterator processParameters(const MarkdownNodeIterator& node,
|
282
312
|
const MarkdownNodes& siblings,
|
283
313
|
SectionParserData& pd,
|
284
|
-
|
285
|
-
Resource& out) {
|
314
|
+
ParseResult<Resource>& out) {
|
286
315
|
|
287
|
-
Parameters parameters;
|
288
|
-
MarkdownNodeIterator cur = ParametersParser::parse(node, siblings, pd,
|
316
|
+
ParseResult<Parameters> parameters(out.report);
|
317
|
+
MarkdownNodeIterator cur = ParametersParser::parse(node, siblings, pd, parameters);
|
289
318
|
|
290
|
-
if (!parameters.empty()) {
|
319
|
+
if (!parameters.node.empty()) {
|
291
320
|
|
292
|
-
checkParametersEligibility(node, pd,
|
293
|
-
out.parameters.insert(out.parameters.end(), parameters.begin(), parameters.end());
|
321
|
+
checkParametersEligibility(node, pd, parameters.node, out);
|
322
|
+
out.node.parameters.insert(out.node.parameters.end(), parameters.node.begin(), parameters.node.end());
|
323
|
+
|
324
|
+
if (pd.exportSourceMap()) {
|
325
|
+
out.sourceMap.parameters.collection.insert(out.sourceMap.parameters.collection.end(),
|
326
|
+
parameters.sourceMap.collection.begin(),
|
327
|
+
parameters.sourceMap.collection.end());
|
328
|
+
}
|
294
329
|
}
|
295
330
|
|
296
331
|
return cur;
|
@@ -300,69 +335,80 @@ namespace snowcrash {
|
|
300
335
|
static MarkdownNodeIterator processModel(const MarkdownNodeIterator& node,
|
301
336
|
const MarkdownNodes& siblings,
|
302
337
|
SectionParserData& pd,
|
303
|
-
|
304
|
-
Resource& out) {
|
338
|
+
ParseResult<Resource>& out) {
|
305
339
|
|
306
|
-
Payload model;
|
307
|
-
MarkdownNodeIterator cur = PayloadParser::parse(node, siblings, pd,
|
340
|
+
ParseResult<Payload> model(out.report);
|
341
|
+
MarkdownNodeIterator cur = PayloadParser::parse(node, siblings, pd, model);
|
308
342
|
|
309
343
|
// Check whether there isn't a model already
|
310
|
-
if (!out.model.name.empty()) {
|
344
|
+
if (!out.node.model.name.empty()) {
|
311
345
|
|
312
346
|
// WARN: Model already defined
|
313
347
|
std::stringstream ss;
|
314
348
|
ss << "overshadowing previous model definition for '";
|
315
349
|
|
316
|
-
if (!out.name.empty()) {
|
317
|
-
ss << out.name << "(" << out.uriTemplate << ")";
|
350
|
+
if (!out.node.name.empty()) {
|
351
|
+
ss << out.node.name << "(" << out.node.uriTemplate << ")";
|
318
352
|
} else {
|
319
|
-
ss << out.uriTemplate;
|
353
|
+
ss << out.node.uriTemplate;
|
320
354
|
}
|
321
355
|
|
322
356
|
ss << "' resource, a resource can be represented by a single model only";
|
323
357
|
|
324
358
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
325
|
-
report.warnings.push_back(Warning(ss.str(),
|
326
|
-
|
327
|
-
|
359
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
360
|
+
DuplicateWarning,
|
361
|
+
sourceMap));
|
328
362
|
}
|
329
363
|
|
330
|
-
if (model.name.empty()) {
|
364
|
+
if (model.node.name.empty()) {
|
365
|
+
|
366
|
+
if (!out.node.name.empty()) {
|
367
|
+
model.node.name = out.node.name;
|
331
368
|
|
332
|
-
|
333
|
-
|
369
|
+
if (pd.exportSourceMap()) {
|
370
|
+
model.sourceMap.name = out.sourceMap.name;
|
371
|
+
}
|
334
372
|
} else {
|
335
373
|
|
336
374
|
// ERR: No name specified for resource model
|
337
375
|
std::stringstream ss;
|
338
376
|
ss << "resource model can be specified only for a named resource";
|
339
|
-
ss << ", name your resource, e.g. '# <resource name> [" << out.uriTemplate << "]'";
|
377
|
+
ss << ", name your resource, e.g. '# <resource name> [" << out.node.uriTemplate << "]'";
|
340
378
|
|
341
379
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
342
|
-
report.error = Error(ss.str(),
|
343
|
-
|
344
|
-
|
380
|
+
out.report.error = Error(ss.str(),
|
381
|
+
SymbolError,
|
382
|
+
sourceMap);
|
345
383
|
}
|
346
384
|
}
|
347
385
|
|
348
|
-
ResourceModelSymbolTable::iterator it = pd.symbolTable.resourceModels.find(model.name);
|
386
|
+
ResourceModelSymbolTable::iterator it = pd.symbolTable.resourceModels.find(model.node.name);
|
349
387
|
|
350
388
|
if (it == pd.symbolTable.resourceModels.end()) {
|
351
389
|
|
352
|
-
pd.symbolTable.resourceModels[model.name] = model;
|
390
|
+
pd.symbolTable.resourceModels[model.node.name] = model.node;
|
391
|
+
|
392
|
+
if (pd.exportSourceMap()) {
|
393
|
+
pd.symbolSourceMapTable.resourceModels[model.node.name] = model.sourceMap;
|
394
|
+
}
|
353
395
|
} else {
|
354
396
|
|
355
397
|
// ERR: Symbol already defined
|
356
398
|
std::stringstream ss;
|
357
|
-
ss << "symbol '" << model.name << "' already defined";
|
399
|
+
ss << "symbol '" << model.node.name << "' already defined";
|
358
400
|
|
359
401
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
360
|
-
report.error = Error(ss.str(),
|
361
|
-
|
362
|
-
|
402
|
+
out.report.error = Error(ss.str(),
|
403
|
+
SymbolError,
|
404
|
+
sourceMap);
|
363
405
|
}
|
364
406
|
|
365
|
-
out.model = model;
|
407
|
+
out.node.model = model.node;
|
408
|
+
|
409
|
+
if (pd.exportSourceMap()) {
|
410
|
+
out.sourceMap.model = model.sourceMap;
|
411
|
+
}
|
366
412
|
|
367
413
|
return cur;
|
368
414
|
}
|
@@ -370,42 +416,41 @@ namespace snowcrash {
|
|
370
416
|
/** Check Parameters eligibility in URI template */
|
371
417
|
static void checkParametersEligibility(const MarkdownNodeIterator& node,
|
372
418
|
const SectionParserData& pd,
|
373
|
-
Resource& resource,
|
374
419
|
Parameters& parameters,
|
375
|
-
|
420
|
+
ParseResult<Resource>& out) {
|
376
421
|
|
377
422
|
for (ParameterIterator it = parameters.begin();
|
378
423
|
it != parameters.end();
|
379
424
|
++it) {
|
380
425
|
|
381
426
|
// Naive check whether parameter is present in URI Template
|
382
|
-
if (
|
427
|
+
if (out.node.uriTemplate.find(it->name) == std::string::npos) {
|
383
428
|
|
384
429
|
// WARN: parameter name not present
|
385
430
|
std::stringstream ss;
|
386
431
|
ss << "parameter '" << it->name << "' not specified in ";
|
387
432
|
|
388
|
-
if (!
|
389
|
-
ss << "'" <<
|
433
|
+
if (!out.node.name.empty()) {
|
434
|
+
ss << "'" << out.node.name << "' ";
|
390
435
|
}
|
391
436
|
|
392
|
-
ss << "its '" <<
|
437
|
+
ss << "its '" << out.node.uriTemplate << "' URI template";
|
393
438
|
|
394
439
|
mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
|
395
|
-
report.warnings.push_back(Warning(ss.str(),
|
396
|
-
|
397
|
-
|
440
|
+
out.report.warnings.push_back(Warning(ss.str(),
|
441
|
+
LogicalErrorWarning,
|
442
|
+
sourceMap));
|
398
443
|
}
|
399
444
|
}
|
400
445
|
}
|
401
446
|
|
402
|
-
/** Finds
|
403
|
-
static
|
404
|
-
|
447
|
+
/** Finds a resource inside an resources collection */
|
448
|
+
static ResourceIterator findResource(const Resources& resources,
|
449
|
+
const Resource& resource) {
|
405
450
|
|
406
|
-
return std::find_if(
|
407
|
-
|
408
|
-
std::bind2nd(
|
451
|
+
return std::find_if(resources.begin(),
|
452
|
+
resources.end(),
|
453
|
+
std::bind2nd(MatchResource(), resource));
|
409
454
|
}
|
410
455
|
};
|
411
456
|
|