redsnow 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +16 -16
  3. data/ext/drafter/bin/drafter +0 -0
  4. data/ext/drafter/build/out/Release/drafter +0 -0
  5. data/ext/drafter/build/out/Release/libdrafter.dylib +0 -0
  6. data/ext/drafter/build/out/Release/libmarkdownparser.a +0 -0
  7. data/ext/drafter/build/out/Release/libsnowcrash.a +0 -0
  8. data/ext/drafter/build/out/Release/libsos.a +0 -0
  9. data/ext/drafter/build/out/Release/libsundown.a +0 -0
  10. data/ext/drafter/build/out/Release/obj.target/drafter/src/config.o +0 -0
  11. data/ext/drafter/build/out/Release/obj.target/drafter/src/main.o +0 -0
  12. data/ext/drafter/build/out/Release/obj.target/drafter/src/reporting.o +0 -0
  13. data/ext/drafter/build/out/Release/obj.target/libdrafter/src/Serialize.o +0 -0
  14. data/ext/drafter/build/out/Release/obj.target/libdrafter/src/SerializeAST.o +0 -0
  15. data/ext/drafter/build/out/Release/obj.target/libdrafter/src/SerializeResult.o +0 -0
  16. data/ext/drafter/build/out/Release/obj.target/libdrafter/src/SerializeSourcemap.o +0 -0
  17. data/ext/drafter/build/out/Release/obj.target/libdrafter/src/cdrafter.o +0 -0
  18. data/ext/drafter/build/out/Release/obj.target/libdrafter/src/drafter.o +0 -0
  19. data/ext/drafter/build/out/Release/obj.target/libmarkdownparser/ext/snowcrash/ext/markdown-parser/src/ByteBuffer.o +0 -0
  20. data/ext/drafter/build/out/Release/obj.target/libmarkdownparser/ext/snowcrash/ext/markdown-parser/src/MarkdownNode.o +0 -0
  21. data/ext/drafter/build/out/Release/obj.target/libmarkdownparser/ext/snowcrash/ext/markdown-parser/src/MarkdownParser.o +0 -0
  22. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/Blueprint.o +0 -0
  23. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/BlueprintSourcemap.o +0 -0
  24. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/HTTP.o +0 -0
  25. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/HeadersParser.o +0 -0
  26. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/MSON.o +0 -0
  27. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/MSONOneOfParser.o +0 -0
  28. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/MSONSourcemap.o +0 -0
  29. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/MSONTypeSectionParser.o +0 -0
  30. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/MSONValueMemberParser.o +0 -0
  31. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/Section.o +0 -0
  32. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/Signature.o +0 -0
  33. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/UriTemplateParser.o +0 -0
  34. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/posix/RegexMatch.o +0 -0
  35. data/ext/drafter/build/out/Release/obj.target/libsnowcrash/ext/snowcrash/src/snowcrash.o +0 -0
  36. data/ext/drafter/build/out/Release/obj.target/libsos/ext/sos/src/sos.o +0 -0
  37. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/html/houdini_href_e.o +0 -0
  38. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/html/houdini_html_e.o +0 -0
  39. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/html/html.o +0 -0
  40. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/html/html_smartypants.o +0 -0
  41. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/src/autolink.o +0 -0
  42. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/src/buffer.o +0 -0
  43. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/src/markdown.o +0 -0
  44. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/src/src_map.o +0 -0
  45. data/ext/drafter/build/out/Release/obj.target/libsundown/ext/snowcrash/ext/markdown-parser/ext/sundown/src/stack.o +0 -0
  46. data/ext/drafter/configure +1 -1
  47. data/ext/drafter/ext/snowcrash/configure +1 -1
  48. data/ext/drafter/ext/snowcrash/src/BlueprintParser.h +111 -22
  49. data/ext/drafter/ext/snowcrash/src/MSON.h +5 -1
  50. data/ext/drafter/ext/snowcrash/src/MSONMixinParser.h +8 -0
  51. data/ext/drafter/ext/snowcrash/src/MSONNamedTypeParser.h +12 -1
  52. data/ext/drafter/ext/snowcrash/src/MSONUtility.h +69 -7
  53. data/ext/drafter/ext/snowcrash/src/MSONValueMemberParser.h +23 -0
  54. data/ext/drafter/ext/snowcrash/src/ParameterParser.h +8 -2
  55. data/ext/drafter/ext/snowcrash/src/ResourceParser.h +8 -0
  56. data/ext/drafter/ext/snowcrash/src/SectionParserData.h +6 -0
  57. data/ext/drafter/ext/snowcrash/src/SignatureSectionProcessor.h +9 -3
  58. data/ext/drafter/ext/snowcrash/src/SourceAnnotation.h +2 -1
  59. data/ext/drafter/ext/snowcrash/src/UriTemplateParser.cc +1 -1
  60. data/ext/drafter/ext/snowcrash/src/snowcrash.cc +2 -2
  61. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/__init__.pyc +0 -0
  62. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/common.pyc +0 -0
  63. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/generator/__init__.pyc +0 -0
  64. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/generator/make.pyc +0 -0
  65. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/generator/xcode.pyc +0 -0
  66. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/input.pyc +0 -0
  67. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/xcode_emulation.pyc +0 -0
  68. data/ext/drafter/ext/snowcrash/tools/gyp/pylib/gyp/xcodeproj_file.pyc +0 -0
  69. data/ext/drafter/src/Version.h +1 -1
  70. data/ext/drafter/src/main.cc +6 -6
  71. data/ext/drafter/tools/homebrew/drafter.rb +1 -1
  72. data/lib/redsnow.rb +2 -2
  73. data/lib/redsnow/blueprint.rb +1 -1
  74. data/lib/redsnow/version.rb +1 -1
  75. data/redsnow.gemspec +2 -2
  76. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a7a42395c3a357bc8d783eeafe217eb8169bf802
4
- data.tar.gz: c3272147eb4b1ac934b7b675e38f216e5011941b
3
+ metadata.gz: a87a6fa01c627672f57d9c43bd053eb472bf34f5
4
+ data.tar.gz: 50f8b9c504bbb3450a1ec6eaebb261beb92e9e31
5
5
  SHA512:
6
- metadata.gz: d4afc5e2fe580a75423a59ea58a8c5846562f23f73d20a6657d6f09c9c953599af1783304be443daa0619613e2969e66481f8173fac83e64cb19ff75ac284f8d
7
- data.tar.gz: 1125f2f86362bd272e5da418e7b3cca2462a52a05dd0374c91d3042f9341b8b38e769289bc1f85f7d1f5a514502f9827bf629cd682ede49b4b7bc371385d8b70
6
+ metadata.gz: e5a8649d40c41d014156a6d325e9f1fa448f988a6b3a0da550edef1902a2423f1cf5a083caaf3233dea1975fe3065b82eab03822fd7def00a9c8182a98016397
7
+ data.tar.gz: 065df0a1d76038edff0dfe5f6b81b059af0938b4c5ac984777e74270123fa381b372a40be56aea1762bee0ed76e95bd02de356d2bb2ecb9a0ffa9c3f46d06441
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redsnow (0.4.0)
4
+ redsnow (0.4.1)
5
5
  bundler (>= 1.7.0)
6
6
  ffi (~> 1.9.3)
7
7
  rake (>= 10.3.2)
@@ -23,9 +23,9 @@ GEM
23
23
  celluloid (0.16.0)
24
24
  timers (~> 4.0.0)
25
25
  coderay (1.1.0)
26
- ffi (1.9.6)
26
+ ffi (1.9.8)
27
27
  formatador (0.2.5)
28
- guard (2.11.1)
28
+ guard (2.12.5)
29
29
  formatador (>= 0.2.4)
30
30
  listen (~> 2.7)
31
31
  lumberjack (~> 1.0)
@@ -39,8 +39,8 @@ GEM
39
39
  rubocop (~> 0.20)
40
40
  hitimes (1.2.2)
41
41
  i18n (0.7.0)
42
- listen (2.8.5)
43
- celluloid (>= 0.15.2)
42
+ listen (2.10.0)
43
+ celluloid (~> 0.16.0)
44
44
  rb-fsevent (>= 0.9.3)
45
45
  rb-inotify (>= 0.9)
46
46
  lumberjack (1.0.9)
@@ -49,14 +49,14 @@ GEM
49
49
  minitest (4.7.5)
50
50
  mocha (1.1.0)
51
51
  metaclass (~> 0.0.1)
52
- multi_json (1.10.1)
52
+ multi_json (1.11.0)
53
53
  nenv (0.2.0)
54
- notiffany (0.0.3)
54
+ notiffany (0.0.6)
55
55
  nenv (~> 0.1)
56
56
  shellany (~> 0.0)
57
- parser (2.2.0.2)
57
+ parser (2.2.2.1)
58
58
  ast (>= 1.1, < 3.0)
59
- powerpack (0.0.9)
59
+ powerpack (0.1.0)
60
60
  pry (0.10.1)
61
61
  coderay (~> 1.1.0)
62
62
  method_source (~> 0.8.1)
@@ -66,29 +66,29 @@ GEM
66
66
  rb-fsevent (0.9.4)
67
67
  rb-inotify (0.9.5)
68
68
  ffi (>= 0.5.0)
69
- rubocop (0.28.0)
69
+ rubocop (0.30.1)
70
70
  astrolabe (~> 1.3)
71
- parser (>= 2.2.0.pre.7, < 3.0)
72
- powerpack (~> 0.0.6)
71
+ parser (>= 2.2.2.1, < 3.0)
72
+ powerpack (~> 0.1)
73
73
  rainbow (>= 1.99.1, < 3.0)
74
74
  ruby-progressbar (~> 1.4)
75
- ruby-progressbar (1.7.1)
75
+ ruby-progressbar (1.7.5)
76
76
  shellany (0.0.1)
77
77
  shoulda (3.5.0)
78
78
  shoulda-context (~> 1.0, >= 1.0.1)
79
79
  shoulda-matchers (>= 1.4.1, < 3.0)
80
80
  shoulda-context (1.2.1)
81
- shoulda-matchers (2.7.0)
81
+ shoulda-matchers (2.8.0)
82
82
  activesupport (>= 3.0.0)
83
83
  slop (3.6.0)
84
84
  thor (0.19.1)
85
- thread_safe (0.3.4)
85
+ thread_safe (0.3.5)
86
86
  timers (4.0.1)
87
87
  hitimes
88
88
  turn (0.9.7)
89
89
  ansi
90
90
  minitest (~> 4)
91
- tzinfo (0.3.42)
91
+ tzinfo (0.3.43)
92
92
  unindent (1.0)
93
93
  yard (0.8.7.6)
94
94
 
Binary file
@@ -8,7 +8,7 @@
8
8
  import sys
9
9
 
10
10
 
11
- if sys.version_info.major != 2:
11
+ if sys.version_info[0] != 2:
12
12
  # Since various Linux distros and OS X doesn't properly follow PEP 394,
13
13
  # We've set the shebang line to `python` and erroring when it isn't
14
14
  # Python 2.
@@ -9,7 +9,7 @@
9
9
  import sys
10
10
 
11
11
 
12
- if sys.version_info.major != 2:
12
+ if sys.version_info[0] != 2:
13
13
  # Since various Linux distros and OS X doesn't properly follow PEP 394,
14
14
  # We've set the shebang line to `python` and erroring when it isn't
15
15
  # Python 2.
@@ -9,6 +9,8 @@
9
9
  #ifndef SNOWCRASH_BLUEPRINTPARSER_H
10
10
  #define SNOWCRASH_BLUEPRINTPARSER_H
11
11
 
12
+ #include <iterator>
13
+ #include <algorithm>
12
14
  #include "ResourceParser.h"
13
15
  #include "ResourceGroupParser.h"
14
16
  #include "DataStructureGroupParser.h"
@@ -284,16 +286,14 @@ namespace snowcrash {
284
286
 
285
287
  // ERR: No API name specified
286
288
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
287
- out.report.error = Error(ExpectedAPINameMessage,
288
- BusinessError,
289
- sourceMap);
289
+ out.report.error = Error(ExpectedAPINameMessage, BusinessError, sourceMap);
290
290
 
291
291
  }
292
292
  else if (!out.node.description.empty()) {
293
+
294
+ // WARN: No API name specified
293
295
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
294
- out.report.warnings.push_back(Warning(ExpectedAPINameMessage,
295
- APINameWarning,
296
- sourceMap));
296
+ out.report.warnings.push_back(Warning(ExpectedAPINameMessage, APINameWarning, sourceMap));
297
297
  }
298
298
  }
299
299
 
@@ -343,21 +343,47 @@ namespace snowcrash {
343
343
  identifier = signature.identifier;
344
344
  }
345
345
 
346
- // If named type already exists, do nothing
347
- mson::NamedTypeBaseTable::iterator it = pd.namedTypeBaseTable.find(identifier);
346
+ // If named type already exists, return error
347
+ if (pd.namedTypeDependencyTable.find(identifier) != pd.namedTypeDependencyTable.end()) {
348
348
 
349
- if (it != pd.namedTypeBaseTable.end()) {
349
+ // ERR: Named type is defined more than once
350
+ std::stringstream ss;
351
+ ss << "named type '" << identifier << "' is defined more than once";
352
+
353
+ mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
354
+ report.error = Error(ss.str(), MSONError, sourceMap);
350
355
  return;
351
356
  }
352
357
 
353
- // Otherwise, add the respective entries to the tables
354
- if (typeDefinition.typeSpecification.name.base != mson::UndefinedTypeName) {
358
+ mson::BaseTypeName baseTypeName = typeDefinition.typeSpecification.name.base;
359
+
360
+ // Initialize an entry in the dependency table
361
+ pd.namedTypeDependencyTable[identifier] = std::set<mson::Literal>();
362
+
363
+ // Add the respective entries to the tables
364
+ if (baseTypeName != mson::UndefinedTypeName) {
355
365
  pd.namedTypeBaseTable[identifier] = mson::parseBaseType(typeDefinition.typeSpecification.name.base);
366
+
367
+ // Add nested types as dependents
368
+ if (baseTypeName == mson::ArrayTypeName || baseTypeName == mson::EnumTypeName) {
369
+
370
+ for (mson::TypeNames::iterator it = typeDefinition.typeSpecification.nestedTypes.begin();
371
+ it != typeDefinition.typeSpecification.nestedTypes.end();
372
+ ++it) {
373
+
374
+ if (!it->symbol.literal.empty() && !it->symbol.variable) {
375
+ pd.namedTypeDependencyTable[identifier].insert(it->symbol.literal);
376
+ }
377
+ }
378
+ }
356
379
  }
357
380
  else if (!typeDefinition.typeSpecification.name.symbol.literal.empty() &&
358
381
  !typeDefinition.typeSpecification.name.symbol.variable) {
359
382
 
360
- pd.namedTypeInheritanceTable[identifier] = typeDefinition.typeSpecification.name.symbol.literal;
383
+ pd.namedTypeInheritanceTable[identifier] = std::make_pair(typeDefinition.typeSpecification.name.symbol.literal, node->sourceMap);
384
+
385
+ // Make the sub type dependent on super type
386
+ pd.namedTypeDependencyTable[identifier].insert(typeDefinition.typeSpecification.name.symbol.literal);
361
387
  }
362
388
  else if (typeDefinition.typeSpecification.name.empty()) {
363
389
 
@@ -376,16 +402,62 @@ namespace snowcrash {
376
402
  Report& report) {
377
403
 
378
404
  mson::NamedTypeInheritanceTable::iterator it;
379
- mson::NamedTypeBaseTable::iterator baseIt;
405
+ mson::NamedTypeDependencyTable::iterator depIt;
406
+
407
+ // First resolve dependency tables
408
+ for (depIt = pd.namedTypeDependencyTable.begin();
409
+ depIt != pd.namedTypeDependencyTable.end();
410
+ depIt++) {
411
+
412
+ resolveNamedTypeDependencyTableEntry(pd, depIt->first, report);
413
+ }
380
414
 
381
415
  for (it = pd.namedTypeInheritanceTable.begin();
382
416
  it != pd.namedTypeInheritanceTable.end();
383
417
  it++) {
384
418
 
385
- resolveNamedTypeTableEntry(pd, it->first, it->second, report);
419
+ resolveNamedTypeBaseTableEntry(pd, it->first, it->second.first, it->second.second, report);
420
+
421
+ if (report.error.code != Error::OK) {
422
+ return;
423
+ }
386
424
  }
387
425
  }
388
426
 
427
+ /**
428
+ * \brief Resolve the inheritance dependencies of the current named type
429
+ * (Does not include mixin or member dependencies)
430
+ *
431
+ * \param pd Section parser data
432
+ * \param identifier The named type whose dependents need to be resolved
433
+ * \param report Parse report
434
+ */
435
+ static void resolveNamedTypeDependencyTableEntry(SectionParserData& pd,
436
+ const mson::Literal& identifier,
437
+ Report& report) {
438
+
439
+ std::set<mson::Literal> diffDeps, finalDeps, initialDeps;
440
+
441
+ do {
442
+ initialDeps = pd.namedTypeDependencyTable[identifier];
443
+ diffDeps.clear();
444
+
445
+ for (std::set<mson::Literal>::iterator it = initialDeps.begin();
446
+ it != initialDeps.end();
447
+ it++) {
448
+
449
+ std::set<mson::Literal> superTypeDeps = pd.namedTypeDependencyTable[*it];
450
+ pd.namedTypeDependencyTable[identifier].insert(superTypeDeps.begin(), superTypeDeps.end());
451
+ }
452
+
453
+ // Check if the list of dependents has grown
454
+ finalDeps = pd.namedTypeDependencyTable[identifier];
455
+ std::set_difference(finalDeps.begin(), finalDeps.end(), initialDeps.begin(), initialDeps.end(),
456
+ std::inserter(diffDeps, diffDeps.end()));
457
+
458
+ } while (!diffDeps.empty());
459
+ };
460
+
389
461
  /**
390
462
  * \brief For each entry in the named type inheritance table, resolve the sub-type's base type recursively
391
463
  *
@@ -394,10 +466,11 @@ namespace snowcrash {
394
466
  * \param superType The super named type between the two
395
467
  * \param report Parse report
396
468
  */
397
- static void resolveNamedTypeTableEntry(SectionParserData& pd,
398
- const mson::Literal& subType,
399
- const mson::Literal& superType,
400
- Report& report) {
469
+ static void resolveNamedTypeBaseTableEntry(SectionParserData& pd,
470
+ const mson::Literal& subType,
471
+ const mson::Literal& superType,
472
+ const mdp::BytesRangeSet& nodeSourceMap,
473
+ Report& report) {
401
474
 
402
475
  mson::BaseType baseType;
403
476
  mson::NamedTypeBaseTable::iterator it = pd.namedTypeBaseTable.find(subType);
@@ -407,6 +480,20 @@ namespace snowcrash {
407
480
  return;
408
481
  }
409
482
 
483
+ // Check for circular references
484
+ std::set<mson::Literal> deps = pd.namedTypeDependencyTable[subType];
485
+
486
+ if (deps.find(subType) != deps.end()) {
487
+
488
+ // ERR: A named type is circularly referenced
489
+ std::stringstream ss;
490
+ ss << "base type '" << subType << "' circularly referencing itself";
491
+
492
+ mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(nodeSourceMap, pd.sourceData);
493
+ report.error = Error(ss.str(), MSONError, sourceMap);
494
+ return;
495
+ }
496
+
410
497
  // Otherwise, get the base type from super type
411
498
  it = pd.namedTypeBaseTable.find(superType);
412
499
 
@@ -416,19 +503,21 @@ namespace snowcrash {
416
503
  // Try to get the super type of the current super type
417
504
  mson::NamedTypeInheritanceTable::iterator inhIt = pd.namedTypeInheritanceTable.find(superType);
418
505
 
506
+ // Check for recursive MSON definitions
419
507
  if (inhIt == pd.namedTypeInheritanceTable.end()) {
420
508
 
421
- // We cannot find the super type in inheritance table at all
509
+ // ERR: We cannot find the super type in inheritance table at all
422
510
  // and there is not base type table entry for it, so, the blueprint is wrong
423
511
  std::stringstream ss;
424
- ss << "unable to find named type '" << superType << "' in the whole document";
512
+ ss << "base type '" << superType << "' is not defined in the document";
425
513
 
426
- report.error = Error(ss.str(), BusinessError, mdp::CharactersRangeSet());
514
+ mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(nodeSourceMap, pd.sourceData);
515
+ report.error = Error(ss.str(), MSONError, sourceMap);
427
516
  return;
428
517
  }
429
518
 
430
519
  // Recursively, try to get a base type for the current super type
431
- resolveNamedTypeTableEntry(pd, superType, inhIt->second, report);
520
+ resolveNamedTypeBaseTableEntry(pd, superType, inhIt->second.first, inhIt->second.second, report);
432
521
 
433
522
  if (report.error.code != Error::OK) {
434
523
  return;
@@ -11,6 +11,7 @@
11
11
 
12
12
  #include <vector>
13
13
  #include <string>
14
+ #include <set>
14
15
  #include <map>
15
16
  #include <stdexcept>
16
17
 
@@ -54,7 +55,10 @@ namespace mson {
54
55
  typedef std::map<Literal, BaseType> NamedTypeBaseTable;
55
56
 
56
57
  /** Named Types inheritance table */
57
- typedef std::map<Literal, Literal> NamedTypeInheritanceTable;
58
+ typedef std::map<Literal, std::pair<Literal, mdp::BytesRangeSet> > NamedTypeInheritanceTable;
59
+
60
+ /** Named Types dependency table */
61
+ typedef std::map<Literal, std::set<Literal> > NamedTypeDependencyTable;
58
62
 
59
63
  /** A simple or actual value */
60
64
  struct Value {
@@ -65,6 +65,14 @@ namespace snowcrash {
65
65
  sourceMap));
66
66
  }
67
67
 
68
+ // Check circular references
69
+ if (out.node.typeSpecification.name.base == mson::UndefinedTypeName &&
70
+ !out.node.typeSpecification.name.symbol.literal.empty() &&
71
+ !out.node.typeSpecification.name.symbol.variable) {
72
+
73
+ mson::addDependency(node, pd, out.node.typeSpecification.name.symbol.literal, pd.namedTypeContext, out.report);
74
+ }
75
+
68
76
  return ++MarkdownNodeIterator(node);
69
77
  }
70
78
 
@@ -34,7 +34,7 @@ namespace snowcrash {
34
34
  const Signature& signature,
35
35
  const ParseResultRef<mson::NamedType>& out) {
36
36
 
37
- mson::parseTypeName(signature.identifier, out.node.name);
37
+ mson::parseTypeName(signature.identifier, out.node.name, false);
38
38
  mson::parseTypeDefinition(node, pd, signature.attributes, out.report, out.node.typeDefinition);
39
39
 
40
40
  if (pd.exportSourceMap()) {
@@ -53,6 +53,9 @@ namespace snowcrash {
53
53
  out.node.typeDefinition.baseType = mson::ImplicitObjectBaseType;
54
54
  }
55
55
 
56
+ // Setup named type context
57
+ pd.namedTypeContext = out.node.name.symbol.literal;
58
+
56
59
  return ++MarkdownNodeIterator(node);
57
60
  }
58
61
 
@@ -99,6 +102,14 @@ namespace snowcrash {
99
102
 
100
103
  return SectionProcessor<mson::ValueMember>::nestedSectionType(node);
101
104
  }
105
+
106
+ static void finalize(const MarkdownNodeIterator& node,
107
+ SectionParserData& pd,
108
+ const ParseResultRef<mson::NamedType>& out) {
109
+
110
+ // Clear named type context
111
+ pd.namedTypeContext.clear();
112
+ }
102
113
  };
103
114
 
104
115
  /** MSON Named Type Section Parser */
@@ -121,26 +121,28 @@ namespace mson {
121
121
  *
122
122
  * \param subject String which represents the type name
123
123
  * \param typeName MSON Type Name
124
+ * \param isBaseType If false, will be parsed as a symbol
124
125
  */
125
126
  inline void parseTypeName(const std::string& subject,
126
- TypeName& typeName) {
127
+ TypeName& typeName,
128
+ bool isBaseType = true) {
127
129
 
128
- if (subject == "boolean") {
130
+ if (isBaseType && subject == "boolean") {
129
131
  typeName.base = BooleanTypeName;
130
132
  }
131
- else if (subject == "string") {
133
+ else if (isBaseType && subject == "string") {
132
134
  typeName.base = StringTypeName;
133
135
  }
134
- else if (subject == "number") {
136
+ else if (isBaseType && subject == "number") {
135
137
  typeName.base = NumberTypeName;
136
138
  }
137
- else if (subject == "array") {
139
+ else if (isBaseType && subject == "array") {
138
140
  typeName.base = ArrayTypeName;
139
141
  }
140
- else if (subject == "enum") {
142
+ else if (isBaseType && subject == "enum") {
141
143
  typeName.base = EnumTypeName;
142
144
  }
143
- else if (subject == "object") {
145
+ else if (isBaseType && subject == "object") {
144
146
  typeName.base = ObjectTypeName;
145
147
  }
146
148
  else {
@@ -418,6 +420,66 @@ namespace mson {
418
420
  propertyName.literal = subject;
419
421
  }
420
422
  }
423
+
424
+ /**
425
+ * \brief Add a dependency to the dependency list of the dependents while checking for circular references
426
+ *
427
+ * \param node Current markdown node iterator
428
+ * \param pd Section parser data
429
+ * \param dependency The named type which should be added to the dependency list
430
+ * \param dependent The named type to which the dependency should be added
431
+ * \param report Parse result report
432
+ */
433
+ inline void addDependency(const mdp::MarkdownNodeIterator& node,
434
+ snowcrash::SectionParserData& pd,
435
+ const mson::Literal dependency,
436
+ const mson::Literal dependent,
437
+ snowcrash::Report& report) {
438
+
439
+ // First, check if the type exists
440
+ if (pd.namedTypeDependencyTable.find(dependency) == pd.namedTypeDependencyTable.end()) {
441
+
442
+ // ERR: We cannot find the dependency type
443
+ std::stringstream ss;
444
+ ss << "base type '" << dependency << "' is not defined in the document";
445
+
446
+ mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
447
+ report.error = snowcrash::Error(ss.str(), snowcrash::MSONError, sourceMap);
448
+ return;
449
+ }
450
+
451
+ std::set<mson::Literal> dependencyDeps = pd.namedTypeDependencyTable[dependency];
452
+
453
+ // Second, check if it is circular reference between them
454
+ if (dependent == dependency ||
455
+ dependencyDeps.find(dependent) != dependencyDeps.end()) {
456
+
457
+ // ERR: Dependency named type circular references itself
458
+ std::stringstream ss;
459
+ ss << "base type '" << dependent << "' circularly referencing itself";
460
+
461
+ mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
462
+ report.error = snowcrash::Error(ss.str(), snowcrash::MSONError, sourceMap);
463
+ return;
464
+ }
465
+
466
+ // Third, check if the dependency is already in the list
467
+ if (pd.namedTypeDependencyTable[dependent].find(dependency) != pd.namedTypeDependencyTable[dependent].end()) {
468
+ return;
469
+ }
470
+
471
+ for (mson::NamedTypeDependencyTable::iterator it = pd.namedTypeDependencyTable.begin();
472
+ it != pd.namedTypeDependencyTable.end();
473
+ ++it) {
474
+
475
+ // If the entry is dependent itself or contain dependent in its list
476
+ if (it->first == dependent || it->second.find(dependent) != it->second.end()) {
477
+
478
+ it->second.insert(dependency);
479
+ it->second.insert(dependencyDeps.begin(), dependencyDeps.end());
480
+ }
481
+ }
482
+ }
421
483
  }
422
484
 
423
485
  #endif
@@ -111,6 +111,29 @@ namespace snowcrash {
111
111
  mson::parseTypeDefinition(node, pd, signature.attributes, report, valueMember.valueDefinition.typeDefinition);
112
112
  parseRemainingContent(node, pd, signature.remainingContent, valueMember.sections, sourceMap.sections);
113
113
 
114
+ // Check for circular references
115
+ mson::TypeSpecification typeSpecification = valueMember.valueDefinition.typeDefinition.typeSpecification;
116
+
117
+ if (typeSpecification.name.base == mson::ArrayTypeName ||
118
+ typeSpecification.name.base == mson::EnumTypeName) {
119
+
120
+ for (mson::TypeNames::iterator it = typeSpecification.nestedTypes.begin();
121
+ it != typeSpecification.nestedTypes.end();
122
+ ++it) {
123
+
124
+ if (!it->symbol.literal.empty() && !it->symbol.variable) {
125
+ mson::addDependency(node, pd, it->symbol.literal, pd.namedTypeContext, report);
126
+ }
127
+ }
128
+ }
129
+ else if (typeSpecification.name.base == mson::UndefinedTypeName &&
130
+ !typeSpecification.name.symbol.literal.empty() &&
131
+ !typeSpecification.name.symbol.variable) {
132
+
133
+ mson::addDependency(node, pd, typeSpecification.name.symbol.literal, pd.namedTypeContext, report);
134
+ }
135
+
136
+ // Properly parse the values in the signature
114
137
  if (signature.values.size() > 1) {
115
138
 
116
139
  if (valueMember.valueDefinition.typeDefinition.baseType == mson::PrimitiveBaseType) {
@@ -255,7 +255,7 @@ namespace snowcrash {
255
255
  // ERR: unable to parse
256
256
  mdp::CharactersRangeSet sourceMap = mdp::BytesRangeSetToCharactersRangeSet(node->sourceMap, pd.sourceData);
257
257
  out.report.error = Error("unable to parse parameter specification",
258
- BusinessError,
258
+ ApplicationError,
259
259
  sourceMap);
260
260
  }
261
261
  }
@@ -470,7 +470,13 @@ namespace snowcrash {
470
470
  std::string first = innerSignature.substr(0, 1);
471
471
 
472
472
  if (first == "`") {
473
- RetrieveEscaped(innerSignature);
473
+ std::string escaped = RetrieveEscaped(innerSignature);
474
+
475
+ // If empty value is returned
476
+ if (escaped.empty()) {
477
+ innerSignature.clear();
478
+ }
479
+
474
480
  TrimString(innerSignature);
475
481
  }
476
482
  else if (first == "(") {
@@ -105,9 +105,17 @@ namespace snowcrash {
105
105
 
106
106
  case AttributesSectionType:
107
107
  {
108
+ // Set up named type context
109
+ if (!out.node.name.empty()) {
110
+ pd.namedTypeContext = out.node.name;
111
+ }
112
+
108
113
  ParseResultRef<Attributes> attributes(out.report, out.node.attributes, out.sourceMap.attributes);
109
114
  MarkdownNodeIterator cur = AttributesParser::parse(node, siblings, pd, attributes);
110
115
 
116
+ // Clear named type context
117
+ pd.namedTypeContext.clear();
118
+
111
119
  if (!out.node.name.empty()) {
112
120
 
113
121
  if (SectionProcessor<DataStructureGroup>::isNamedTypeDuplicate(pd.blueprint, out.node.name)) {
@@ -51,6 +51,12 @@ namespace snowcrash {
51
51
  /** Table mapping named type to sub types */
52
52
  mson::NamedTypeInheritanceTable namedTypeInheritanceTable;
53
53
 
54
+ /** Table mapping named types to their dependent named types */
55
+ mson::NamedTypeDependencyTable namedTypeDependencyTable;
56
+
57
+ /** Variable to store the current named type */
58
+ mson::Literal namedTypeContext;
59
+
54
60
  /** Model Table */
55
61
  ModelTable modelTable;
56
62
 
@@ -371,13 +371,15 @@ namespace scpl {
371
371
  * \param begin Character index representing the beginning of the bracket that needs to be matched
372
372
  * \param endBracket The type of bracket that needs to be matched
373
373
  * \param splitByAttribute If this is true, we need to return when we find a top-level attribute delimiter
374
+ * \param clearAtEnd If this is true, the string will be cleared at the end of parsing
374
375
  *
375
376
  * \return String inside the given brackets. If not splitting by comma, append the brackets too
376
377
  */
377
378
  static mdp::ByteBuffer matchBrackets(mdp::ByteBuffer& subject,
378
379
  size_t begin,
379
380
  const char endBracket,
380
- const bool splitByAttribute = false) {
381
+ const bool splitByAttribute = false,
382
+ const bool clearAtEnd = false) {
381
383
 
382
384
  size_t i = begin + 1;
383
385
  mdp::ByteBuffer returnString;
@@ -403,11 +405,11 @@ namespace scpl {
403
405
  }
404
406
  } else if (subject[i] == '[') {
405
407
 
406
- returnString += matchBrackets(subject, i, ']');
408
+ returnString += matchBrackets(subject, i, ']', false, true);
407
409
  i = 0;
408
410
  } else if (subject[i] == '(') {
409
411
 
410
- returnString += matchBrackets(subject, i, ')');
412
+ returnString += matchBrackets(subject, i, ')', false, true);
411
413
  i = 0;
412
414
  } else if (subject[i] == endBracket) {
413
415
 
@@ -431,6 +433,10 @@ namespace scpl {
431
433
  }
432
434
  }
433
435
 
436
+ if (i == subject.length() && clearAtEnd) {
437
+ subject.clear();
438
+ }
439
+
434
440
  return returnString;
435
441
  }
436
442
  };
@@ -101,7 +101,8 @@ namespace snowcrash {
101
101
  NoError = 0,
102
102
  ApplicationError = 1,
103
103
  BusinessError = 2,
104
- ModelError = 3
104
+ ModelError = 3,
105
+ MSONError = 4
105
106
  };
106
107
 
107
108
  /**
@@ -188,7 +188,7 @@ void URITemplateParser::parse(const URITemplate& uri, const mdp::CharactersRange
188
188
  }
189
189
  }
190
190
  else{
191
- result.report.error = Error("Failed to parse URI Template", URIWarning);
191
+ result.report.error = Error("Failed to parse URI Template", ApplicationError);
192
192
  }
193
193
 
194
194
  }
@@ -76,11 +76,11 @@ int snowcrash::parse(const mdp::ByteBuffer& source,
76
76
 
77
77
  std::stringstream ss;
78
78
  ss << "parser exception: '" << e.what() << "'";
79
- out.report.error = Error(ss.str(), 1);
79
+ out.report.error = Error(ss.str(), ApplicationError);
80
80
  }
81
81
  catch (...) {
82
82
 
83
- out.report.error = Error("parser exception has occured", 1);
83
+ out.report.error = Error("parser exception has occured", ApplicationError);
84
84
  }
85
85
 
86
86
  return out.report.error.code;
@@ -15,7 +15,7 @@
15
15
 
16
16
  #define DRAFTER_MAJOR_VERSION 0
17
17
  #define DRAFTER_MINOR_VERSION 1
18
- #define DRAFTER_PATCH_VERSION 0
18
+ #define DRAFTER_PATCH_VERSION 5
19
19
 
20
20
  #define DRAFTER_VERSION_IS_RELEASE 1
21
21
 
@@ -72,14 +72,14 @@ int main(int argc, const char *argv[])
72
72
  if (!config.validate) { // not just validate -> we will serialize
73
73
  sos::Serialize* serializer = CreateSerializer(config.format);
74
74
 
75
- Serialization(CreateStreamFromName<std::ostream>(config.output),
76
- drafter::WrapBlueprint(blueprint.node),
77
- serializer);
75
+ std::ostream *out = CreateStreamFromName<std::ostream>(config.output);
76
+ Serialization(out, drafter::WrapBlueprint(blueprint.node), serializer);
77
+ delete out;
78
78
 
79
79
  if (options & snowcrash::ExportSourcemapOption) {
80
- Serialization(CreateStreamFromName<std::ostream>(config.sourceMap),
81
- drafter::WrapBlueprintSourcemap(blueprint.sourceMap),
82
- serializer);
80
+ std::ostream *sourcemap = CreateStreamFromName<std::ostream>(config.sourceMap);
81
+ Serialization(sourcemap, drafter::WrapBlueprintSourcemap(blueprint.sourceMap), serializer);
82
+ delete sourcemap;
83
83
  }
84
84
 
85
85
  delete serializer;
@@ -2,7 +2,7 @@ require 'formula'
2
2
 
3
3
  class Drafter < Formula
4
4
  homepage 'http://apiblueprint.org'
5
- head 'https://github.com/apiaryio/drafter.git', :tag => 'v0.1.0'
5
+ head 'https://github.com/apiaryio/drafter.git', :tag => 'v0.1.5'
6
6
 
7
7
  def install
8
8
  system "./configure"
@@ -10,8 +10,8 @@ module RedSnow
10
10
  include Binding
11
11
 
12
12
  # Options
13
- EXPORT_SOURCEMAP_OPTION_KEY = :'exportSourcemap'
14
- REQUIRE_BLUEPRINT_NAME_OPTION_KEY = :'requireBlueprintName'
13
+ EXPORT_SOURCEMAP_OPTION_KEY = :exportSourcemap
14
+ REQUIRE_BLUEPRINT_NAME_OPTION_KEY = :requireBlueprintName
15
15
 
16
16
  # Parse options
17
17
  attr_accessor :options
@@ -80,7 +80,7 @@ module RedSnow
80
80
  end
81
81
 
82
82
  def get_item(key)
83
- @collection.select { |item| item[:name].downcase == key.downcase }.first
83
+ @collection.find { |item| item[:name].downcase == key.downcase }
84
84
  end
85
85
  end
86
86
 
@@ -1,5 +1,5 @@
1
1
  # Module RedSnow
2
2
  module RedSnow
3
3
  # Gem version
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.1'
5
5
  end
@@ -13,8 +13,8 @@ Gem::Specification.new do |gem|
13
13
  gem.homepage = 'https://github.com/apiaryio/redsnow'
14
14
  gem.license = 'MIT'
15
15
  gem.files = Dir['lib/**/*']
16
- gem.files << Dir['*']
17
- gem.files << Dir['ext/drafter/**/*'].reject { |f| f =~ /cmdline|test|features|README*|LICENSE|Gemfile*|\.xcode*/ }
16
+ gem.files << Dir['*']
17
+ gem.files << Dir['ext/drafter/**/*'].reject { |f| f =~ /cmdline|test|features|README*|LICENSE|Gemfile*|\.xcode*/ }
18
18
  gem.executables = gem.files.grep(/^bin/).map { |f| File.basename(f) }
19
19
  gem.test_files = gem.files.grep(/^(test|spec|features)/)
20
20
  gem.require_paths = %w(lib ext)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redsnow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ladislav Prskavec
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-30 00:00:00.000000000 Z
11
+ date: 2015-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -443,7 +443,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
443
443
  version: '0'
444
444
  requirements: []
445
445
  rubyforge_project:
446
- rubygems_version: 2.2.2
446
+ rubygems_version: 2.4.5
447
447
  signing_key:
448
448
  specification_version: 4
449
449
  summary: Ruby bindings for Snow Crash