ext/snowcrash/src/BlueprintParser.h in redsnow-0.2.0 vs ext/snowcrash/src/BlueprintParser.h in redsnow-0.2.1

- old
+ new

@@ -17,13 +17,11 @@ namespace snowcrash { const char* const ExpectedAPINameMessage = "expected API name, e.g. '# <API Name>'"; - /** Internal type alias for Collection of Metadata */ - typedef Collection<Metadata>::type MetadataCollection; - + /** Internal type alias for Collection iterator of Metadata */ typedef Collection<Metadata>::iterator MetadataCollectionIterator; /** * Blueprint processor */ @@ -32,26 +30,31 @@ static MarkdownNodeIterator processSignature(const MarkdownNodeIterator& node, const MarkdownNodes& siblings, SectionParserData& pd, SectionLayout& layout, - Report& report, - Blueprint& out) { + ParseResult<Blueprint>& out) { MarkdownNodeIterator cur = node; while (cur != siblings.end() && cur->type == mdp::ParagraphMarkdownNodeType) { - MetadataCollection metadata; - parseMetadata(cur, pd, report, metadata); + ParseResult<MetadataCollection> metadata(out.report); + parseMetadata(cur, pd, metadata); // First block is paragraph and is not metadata (no API name) - if (metadata.empty()) { - return processDescription(cur, siblings, pd, report, out); + if (metadata.node.empty()) { + return processDescription(cur, siblings, pd, out); } else { - out.metadata.insert(out.metadata.end(), metadata.begin(), metadata.end()); + out.node.metadata.insert(out.node.metadata.end(), metadata.node.begin(), metadata.node.end()); + + if (pd.exportSourceMap()) { + out.sourceMap.metadata.collection.insert(out.sourceMap.metadata.collection.end(), + metadata.sourceMap.collection.begin(), + metadata.sourceMap.collection.end()); + } } cur++; } @@ -68,56 +71,63 @@ if (nestedType != UndefinedSectionType) { layout = ExclusiveNestedSectionLayout; return cur; } - out.name = cur->text; - TrimString(out.name); + out.node.name = cur->text; + TrimString(out.node.name); + + if (pd.exportSourceMap() && !out.node.name.empty()) { + out.sourceMap.name.sourceMap = cur->sourceMap; + } } else { // Any other type of block, add to description - return processDescription(cur, siblings, pd, report, out); + return processDescription(cur, siblings, pd, out); } return ++MarkdownNodeIterator(cur); } static MarkdownNodeIterator processNestedSection(const MarkdownNodeIterator& node, const MarkdownNodes& siblings, SectionParserData& pd, - Report& report, - Blueprint& out) { + ParseResult<Blueprint>& out) { if (pd.sectionContext() == ResourceGroupSectionType || pd.sectionContext() == ResourceSectionType) { - ResourceGroup resourceGroup; - MarkdownNodeIterator cur = ResourceGroupParser::parse(node, siblings, pd, report, resourceGroup); + ParseResult<ResourceGroup> resourceGroup(out.report); + MarkdownNodeIterator cur = ResourceGroupParser::parse(node, siblings, pd, resourceGroup); - ResourceGroupIterator duplicate = findResourceGroup(out.resourceGroups, resourceGroup); + ResourceGroupIterator duplicate = findResourceGroup(out.node.resourceGroups, resourceGroup.node); - if (duplicate != out.resourceGroups.end()) { + if (duplicate != out.node.resourceGroups.end()) { // WARN: duplicate resource group std::stringstream ss; - if (resourceGroup.name.empty()) { + if (resourceGroup.node.name.empty()) { ss << "anonymous group"; } else { - ss << "group '" << resourceGroup.name << "'"; + ss << "group '" << resourceGroup.node.name << "'"; } ss << " is already defined"; mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData); - report.warnings.push_back(Warning(ss.str(), - DuplicateWarning, - sourceMap)); + out.report.warnings.push_back(Warning(ss.str(), + DuplicateWarning, + sourceMap)); } - out.resourceGroups.push_back(resourceGroup); + out.node.resourceGroups.push_back(resourceGroup.node); + if (pd.exportSourceMap()) { + out.sourceMap.resourceGroups.collection.push_back(resourceGroup.sourceMap); + } + return cur; } return node; } @@ -159,30 +169,29 @@ return nested; } static void finalize(const MarkdownNodeIterator& node, SectionParserData& pd, - Report& report, - Blueprint& out) { + ParseResult<Blueprint>& out) { - if (!out.name.empty()) + if (!out.node.name.empty()) return; if (pd.options & RequireBlueprintNameOption) { // ERR: No API name specified mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData); - report.error = Error(ExpectedAPINameMessage, - BusinessError, - sourceMap); + out.report.error = Error(ExpectedAPINameMessage, + BusinessError, + sourceMap); } - else if (!out.description.empty()) { + else if (!out.node.description.empty()) { mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData); - report.warnings.push_back(Warning(ExpectedAPINameMessage, - APINameWarning, - sourceMap)); + out.report.warnings.push_back(Warning(ExpectedAPINameMessage, + APINameWarning, + sourceMap)); } } static bool isUnexpectedNode(const MarkdownNodeIterator& node, SectionType sectionType) { @@ -192,12 +201,11 @@ } static void parseMetadata(const MarkdownNodeIterator& node, SectionParserData& pd, - Report& report, - MetadataCollection& out) { + ParseResult<MetadataCollection>& out) { mdp::ByteBuffer content = node->text; TrimStringEnd(content); std::vector<mdp::ByteBuffer> lines = Split(content, '\n'); @@ -207,53 +215,59 @@ ++it) { Metadata metadata; if (CodeBlockUtility::keyValueFromLine(*it, metadata)) { - out.push_back(metadata); + out.node.push_back(metadata); + + if (pd.exportSourceMap()) { + SourceMap<Metadata> metadataSM; + metadataSM.sourceMap = node->sourceMap; + out.sourceMap.collection.push_back(metadataSM); + } } } - if (lines.size() == out.size()) { + if (lines.size() == out.node.size()) { // Check duplicates std::vector<mdp::ByteBuffer> duplicateKeys; - for (MetadataCollectionIterator it = out.begin(); - it != out.end(); + for (MetadataCollectionIterator it = out.node.begin(); + it != out.node.end(); ++it) { MetadataCollectionIterator from = it; - if (++from == out.end()) + if (++from == out.node.end()) break; MetadataCollectionIterator duplicate = std::find_if(from, - out.end(), + out.node.end(), std::bind2nd(MatchFirsts<Metadata>(), *it)); - if (duplicate != out.end() && + if (duplicate != out.node.end() && std::find(duplicateKeys.begin(), duplicateKeys.end(), it->first) == duplicateKeys.end()) { duplicateKeys.push_back(it->first); // WARN: duplicate metadata definition std::stringstream ss; ss << "duplicate definition of '" << it->first << "'"; mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData); - report.warnings.push_back(Warning(ss.str(), - DuplicateWarning, - sourceMap)); + out.report.warnings.push_back(Warning(ss.str(), + DuplicateWarning, + sourceMap)); } } } - else if (!out.empty()) { + else if (!out.node.empty()) { // WARN: malformed metadata block mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData); - report.warnings.push_back(Warning("ignoring possible metadata, expected '<key> : <value>', one one per line", - FormattingWarning, - sourceMap)); + out.report.warnings.push_back(Warning("ignoring possible metadata, expected '<key> : <value>', one one per line", + FormattingWarning, + sourceMap)); } } /** Finds a resource group inside an resource groups collection */ static ResourceGroupIterator findResourceGroup(const ResourceGroups& resourceGroups,