bixbite 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +49 -0
  3. data/VERSION +1 -0
  4. data/bin/bixbite +73 -0
  5. data/lib/bixbite.rb +13 -0
  6. data/lib/bixbite/command.rb +14 -0
  7. data/lib/bixbite/create.rb +76 -0
  8. data/template/Rakefile +25 -0
  9. data/template/assets/bixbite/Rakefile.rb +297 -0
  10. data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
  11. data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
  12. data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
  13. data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
  14. data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
  15. data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
  16. data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
  17. data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
  18. data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
  19. data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
  20. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
  21. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
  22. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
  23. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
  24. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
  25. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
  26. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
  27. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
  28. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
  29. data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
  30. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
  31. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
  32. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
  33. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
  34. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
  35. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
  36. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
  37. data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
  38. data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
  39. data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
  40. data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
  41. data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
  42. data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
  43. data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
  44. data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
  45. data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
  46. data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
  47. data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
  48. data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
  49. data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
  50. data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
  51. data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
  52. data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
  53. data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
  54. data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
  55. data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
  56. data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
  57. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
  58. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
  59. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
  60. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
  61. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
  62. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
  63. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
  64. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
  65. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
  66. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
  67. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
  68. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
  69. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
  70. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
  71. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
  72. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
  73. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
  74. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
  75. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
  76. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
  77. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
  78. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
  79. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
  80. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
  81. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
  82. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
  83. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
  84. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
  85. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
  86. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
  87. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
  88. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
  89. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
  90. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
  91. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
  92. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
  93. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
  94. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
  95. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
  96. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
  97. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
  98. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
  99. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
  100. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
  101. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
  102. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
  103. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
  104. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
  105. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
  106. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
  107. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
  108. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
  109. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
  110. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
  111. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
  112. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
  113. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
  114. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
  115. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
  116. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
  117. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
  118. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
  119. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
  120. data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
  121. data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
  122. data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
  123. data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
  124. data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
  125. data/template/assets/utilities/pngout +0 -0
  126. data/template/deploy/public_html/.htaccess +0 -0
  127. data/template/documentation/js/.htaccess +0 -0
  128. data/template/src/html/.htaccess +76 -0
  129. data/template/src/html/css/cmn/global.css +96 -0
  130. data/template/src/html/css/cmn/ie.css +15 -0
  131. data/template/src/html/css/cmn/ie6.css +15 -0
  132. data/template/src/html/images/cmn/.htaccess +0 -0
  133. data/template/src/html/images/tmp/.htaccess +0 -0
  134. data/template/src/html/includes/debug.inc +5 -0
  135. data/template/src/html/includes/footer.inc +52 -0
  136. data/template/src/html/includes/header.inc +61 -0
  137. data/template/src/html/includes/html.inc +3 -0
  138. data/template/src/html/includes/namespace.inc +19 -0
  139. data/template/src/html/includes/page.inc +151 -0
  140. data/template/src/html/index.html +35 -0
  141. data/template/src/html/js/cmn/bootstrap.js +74 -0
  142. data/template/src/html/js/cmn/global.js +142 -0
  143. data/template/src/html/js/cmn/lib/LAB.js +348 -0
  144. data/template/src/html/min/.htaccess +4 -0
  145. data/template/src/html/min/MinifyCLI.php +19 -0
  146. data/template/src/html/min/README.txt +132 -0
  147. data/template/src/html/min/builder/_index.js +242 -0
  148. data/template/src/html/min/builder/bm.js +36 -0
  149. data/template/src/html/min/builder/index.php +182 -0
  150. data/template/src/html/min/builder/ocCheck.php +36 -0
  151. data/template/src/html/min/builder/rewriteTest.js +1 -0
  152. data/template/src/html/min/config.php +187 -0
  153. data/template/src/html/min/groupsConfig.php +34 -0
  154. data/template/src/html/min/index.php +66 -0
  155. data/template/src/html/min/lib/FirePHP.php +1370 -0
  156. data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
  157. data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
  158. data/template/src/html/min/lib/JSMin.php +314 -0
  159. data/template/src/html/min/lib/JSMinPlus.php +1872 -0
  160. data/template/src/html/min/lib/Minify.php +532 -0
  161. data/template/src/html/min/lib/Minify/Build.php +103 -0
  162. data/template/src/html/min/lib/Minify/CSS.php +83 -0
  163. data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
  164. data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
  165. data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
  166. data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
  167. data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
  168. data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
  169. data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
  170. data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
  171. data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
  172. data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
  173. data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
  174. data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
  175. data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
  176. data/template/src/html/min/lib/Minify/HTML.php +245 -0
  177. data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
  178. data/template/src/html/min/lib/Minify/Lines.php +131 -0
  179. data/template/src/html/min/lib/Minify/Logger.php +45 -0
  180. data/template/src/html/min/lib/Minify/Packer.php +37 -0
  181. data/template/src/html/min/lib/Minify/Source.php +187 -0
  182. data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
  183. data/template/src/html/min/lib/Solar/Dir.php +199 -0
  184. data/template/src/html/min/lib/closure-compiler.jar +0 -0
  185. data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
  186. data/template/src/html/min/utils.php +90 -0
  187. data/template/src/templates/css/template.css +7 -0
  188. data/template/src/templates/js/template.js +72 -0
  189. data/template/src/templates/template.html +18 -0
  190. data/template/src/yaml/config.yml +46 -0
  191. data/template/src/yaml/deploy.yml +35 -0
  192. data/test/bixbite_test.rb +7 -0
  193. data/test/test_helper.rb +10 -0
  194. metadata +278 -0
@@ -0,0 +1,1484 @@
1
+ ###############################################################################
2
+ #
3
+ # Class: NaturalDocs::Languages::CSharp
4
+ #
5
+ ###############################################################################
6
+ #
7
+ # A subclass to handle the language variations of C#.
8
+ #
9
+ #
10
+ # Topic: Language Support
11
+ #
12
+ # Supported:
13
+ #
14
+ # - Classes
15
+ # - Namespaces (no topic generated)
16
+ # - Functions
17
+ # - Constructors and Destructors
18
+ # - Properties
19
+ # - Indexers
20
+ # - Operators
21
+ # - Delegates
22
+ # - Variables
23
+ # - Constants
24
+ # - Events
25
+ # - Enums
26
+ #
27
+ # Not supported yet:
28
+ #
29
+ # - Autodocumenting enum members
30
+ # - Using alias
31
+ #
32
+ ###############################################################################
33
+
34
+ # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
35
+ # Natural Docs is licensed under the GPL
36
+
37
+ use strict;
38
+ use integer;
39
+
40
+ package NaturalDocs::Languages::CSharp;
41
+
42
+ use base 'NaturalDocs::Languages::Advanced';
43
+
44
+
45
+ ###############################################################################
46
+ # Group: Package Variables
47
+
48
+ #
49
+ # hash: classKeywords
50
+ # An existence hash of all the acceptable class keywords. The keys are in all lowercase.
51
+ #
52
+ my %classKeywords = ( 'class' => 1,
53
+ 'struct' => 1,
54
+ 'interface' => 1 );
55
+
56
+ #
57
+ # hash: classModifiers
58
+ # An existence hash of all the acceptable class modifiers. The keys are in all lowercase.
59
+ #
60
+ my %classModifiers = ( 'new' => 1,
61
+ 'public' => 1,
62
+ 'protected' => 1,
63
+ 'internal' => 1,
64
+ 'private' => 1,
65
+ 'abstract' => 1,
66
+ 'sealed' => 1,
67
+ 'unsafe' => 1,
68
+ 'static' => 1 );
69
+
70
+ #
71
+ # hash: functionModifiers
72
+ # An existence hash of all the acceptable function modifiers. Also applies to properties. Also encompasses those for operators
73
+ # and indexers, but have more than are valid for them. The keys are in all lowercase.
74
+ #
75
+ my %functionModifiers = ( 'new' => 1,
76
+ 'public' => 1,
77
+ 'protected' => 1,
78
+ 'internal' => 1,
79
+ 'private' => 1,
80
+ 'static' => 1,
81
+ 'virtual' => 1,
82
+ 'sealed' => 1,
83
+ 'override' => 1,
84
+ 'abstract' => 1,
85
+ 'extern' => 1,
86
+ 'unsafe' => 1 );
87
+
88
+ #
89
+ # hash: variableModifiers
90
+ # An existence hash of all the acceptable variable modifiers. The keys are in all lowercase.
91
+ #
92
+ my %variableModifiers = ( 'new' => 1,
93
+ 'public' => 1,
94
+ 'protected' => 1,
95
+ 'internal' => 1,
96
+ 'private' => 1,
97
+ 'static' => 1,
98
+ 'readonly' => 1,
99
+ 'volatile' => 1,
100
+ 'unsafe' => 1 );
101
+
102
+ #
103
+ # hash: enumTypes
104
+ # An existence hash of all the possible enum types. The keys are in all lowercase.
105
+ #
106
+ my %enumTypes = ( 'sbyte' => 1,
107
+ 'byte' => 1,
108
+ 'short' => 1,
109
+ 'ushort' => 1,
110
+ 'int' => 1,
111
+ 'uint' => 1,
112
+ 'long' => 1,
113
+ 'ulong' => 1 );
114
+
115
+ #
116
+ # hash: impossibleTypeWords
117
+ # An existence hash of all the reserved words that cannot be in a type. This includes 'enum' and all modifiers. The keys are in
118
+ # all lowercase.
119
+ #
120
+ my %impossibleTypeWords = ( 'abstract' => 1, 'as' => 1, 'base' => 1, 'break' => 1, 'case' => 1, 'catch' => 1,
121
+ 'checked' => 1, 'class' => 1, 'const' => 1, 'continue' => 1, 'default' => 1, 'delegate' => 1,
122
+ 'do' => 1, 'else' => 1, 'enum' => 1, 'event' => 1, 'explicit' => 1, 'extern' => 1,
123
+ 'false' => 1, 'finally' => 1, 'fixed' => 1, 'for' => 1, 'foreach' => 1, 'goto' => 1, 'if' => 1,
124
+ 'implicit' => 1, 'in' => 1, 'interface' => 1, 'internal' => 1, 'is' => 1, 'lock' => 1,
125
+ 'namespace' => 1, 'new' => 1, 'null' => 1, 'operator' => 1, 'out' => 1, 'override' => 1,
126
+ 'params' => 1, 'private' => 1, 'protected' => 1, 'public' => 1, 'readonly' => 1, 'ref' => 1,
127
+ 'return' => 1, 'sealed' => 1, 'sizeof' => 1, 'stackalloc' => 1, 'static' => 1,
128
+ 'struct' => 1, 'switch' => 1, 'this' => 1, 'throw' => 1, 'true' => 1, 'try' => 1, 'typeof' => 1,
129
+ 'unchecked' => 1, 'unsafe' => 1, 'using' => 1, 'virtual' => 1, 'volatile' => 1, 'while' => 1 );
130
+ # Deleted from the list: object, string, bool, decimal, sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, void
131
+
132
+
133
+
134
+ ###############################################################################
135
+ # Group: Interface Functions
136
+
137
+
138
+ #
139
+ # Function: PackageSeparator
140
+ # Returns the package separator symbol.
141
+ #
142
+ sub PackageSeparator
143
+ { return '.'; };
144
+
145
+
146
+ #
147
+ # Function: EnumValues
148
+ # Returns the <EnumValuesType> that describes how the language handles enums.
149
+ #
150
+ sub EnumValues
151
+ { return ::ENUM_UNDER_TYPE(); };
152
+
153
+
154
+ #
155
+ # Function: ParseFile
156
+ #
157
+ # Parses the passed source file, sending comments acceptable for documentation to <NaturalDocs::Parser->OnComment()>.
158
+ #
159
+ # Parameters:
160
+ #
161
+ # sourceFile - The <FileName> to parse.
162
+ # topicList - A reference to the list of <NaturalDocs::Parser::ParsedTopics> being built by the file.
163
+ #
164
+ # Returns:
165
+ #
166
+ # The array ( autoTopics, scopeRecord ).
167
+ #
168
+ # autoTopics - An arrayref of automatically generated topics from the file, or undef if none.
169
+ # scopeRecord - An arrayref of <NaturalDocs::Languages::Advanced::ScopeChanges>, or undef if none.
170
+ #
171
+ sub ParseFile #(sourceFile, topicsList)
172
+ {
173
+ my ($self, $sourceFile, $topicsList) = @_;
174
+
175
+ $self->ParseForCommentsAndTokens($sourceFile, [ '//' ], [ '/*', '*/' ], [ '///' ], [ '/**', '*/' ] );
176
+
177
+ my $tokens = $self->Tokens();
178
+ my $index = 0;
179
+ my $lineNumber = 1;
180
+
181
+ while ($index < scalar @$tokens)
182
+ {
183
+ if ($self->TryToSkipWhitespace(\$index, \$lineNumber) ||
184
+ $self->TryToGetNamespace(\$index, \$lineNumber) ||
185
+ $self->TryToGetUsing(\$index, \$lineNumber) ||
186
+ $self->TryToGetClass(\$index, \$lineNumber) ||
187
+ $self->TryToGetFunction(\$index, \$lineNumber) ||
188
+ $self->TryToGetOverloadedOperator(\$index, \$lineNumber) ||
189
+ $self->TryToGetVariable(\$index, \$lineNumber) ||
190
+ $self->TryToGetEnum(\$index, \$lineNumber) )
191
+ {
192
+ # The functions above will handle everything.
193
+ }
194
+
195
+ elsif ($tokens->[$index] eq '{')
196
+ {
197
+ $self->StartScope('}', $lineNumber, undef, undef, undef);
198
+ $index++;
199
+ }
200
+
201
+ elsif ($tokens->[$index] eq '}')
202
+ {
203
+ if ($self->ClosingScopeSymbol() eq '}')
204
+ { $self->EndScope($lineNumber); };
205
+
206
+ $index++;
207
+ }
208
+
209
+ else
210
+ {
211
+ $self->SkipRestOfStatement(\$index, \$lineNumber);
212
+ };
213
+ };
214
+
215
+
216
+ # Don't need to keep these around.
217
+ $self->ClearTokens();
218
+
219
+
220
+ my $autoTopics = $self->AutoTopics();
221
+
222
+ my $scopeRecord = $self->ScopeRecord();
223
+ if (defined $scopeRecord && !scalar @$scopeRecord)
224
+ { $scopeRecord = undef; };
225
+
226
+ return ( $autoTopics, $scopeRecord );
227
+ };
228
+
229
+
230
+
231
+ ###############################################################################
232
+ # Group: Statement Parsing Functions
233
+ # All functions here assume that the current position is at the beginning of a statement.
234
+ #
235
+ # Note for developers: I am well aware that the code in these functions do not check if we're past the end of the tokens as
236
+ # often as it should. We're making use of the fact that Perl will always return undef in these cases to keep the code simpler.
237
+
238
+
239
+ #
240
+ # Function: TryToGetNamespace
241
+ #
242
+ # Determines whether the position is at a namespace declaration statement, and if so, adjusts the scope, skips it, and returns
243
+ # true.
244
+ #
245
+ # Why no topic?:
246
+ #
247
+ # The main reason we don't create a Natural Docs topic for a namespace is because in order to declare class A.B.C in C#,
248
+ # you must do this:
249
+ #
250
+ # > namespace A.B
251
+ # > {
252
+ # > class C
253
+ # > { ... }
254
+ # > }
255
+ #
256
+ # That would result in a namespace topic whose only purpose is really to qualify C. It would take the default page title, and
257
+ # thus the default menu title. So if you have files for A.B.X, A.B.Y, and A.B.Z, they all will appear as A.B on the menu.
258
+ #
259
+ # If something actually appears in the namespace besides a class, it will be handled by
260
+ # <NaturalDocs::Parser->AddPackageDelineators()>. That function will add a package topic to correct the scope.
261
+ #
262
+ # If the user actually documented it, it will still appear because of the manual topic.
263
+ #
264
+ sub TryToGetNamespace #(indexRef, lineNumberRef)
265
+ {
266
+ my ($self, $indexRef, $lineNumberRef) = @_;
267
+ my $tokens = $self->Tokens();
268
+
269
+ if (lc($tokens->[$$indexRef]) ne 'namespace')
270
+ { return undef; };
271
+
272
+ my $index = $$indexRef + 1;
273
+ my $lineNumber = $$lineNumberRef;
274
+
275
+ if (!$self->TryToSkipWhitespace(\$index, \$lineNumber))
276
+ { return undef; };
277
+
278
+ my $name;
279
+
280
+ while ($tokens->[$index] =~ /^[a-z_\.\@]/i)
281
+ {
282
+ $name .= $tokens->[$index];
283
+ $index++;
284
+ };
285
+
286
+ if (!defined $name)
287
+ { return undef; };
288
+
289
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
290
+
291
+ if ($tokens->[$index] ne '{')
292
+ { return undef; };
293
+
294
+ $index++;
295
+
296
+
297
+ # We found a valid one if we made it this far.
298
+
299
+ my $autoTopic = NaturalDocs::Parser::ParsedTopic->New(::TOPIC_CLASS(), $name,
300
+ $self->CurrentScope(), $self->CurrentUsing(),
301
+ undef,
302
+ undef, undef, $$lineNumberRef);
303
+
304
+ # We don't add an auto-topic for namespaces. See the function documentation above.
305
+
306
+ NaturalDocs::Parser->OnClass($autoTopic->Package());
307
+
308
+ $self->StartScope('}', $lineNumber, $autoTopic->Package());
309
+
310
+ $$indexRef = $index;
311
+ $$lineNumberRef = $lineNumber;
312
+
313
+ return 1;
314
+ };
315
+
316
+
317
+ #
318
+ # Function: TryToGetClass
319
+ #
320
+ # Determines whether the position is at a class declaration statement, and if so, generates a topic for it, skips it, and
321
+ # returns true.
322
+ #
323
+ # Supported Syntaxes:
324
+ #
325
+ # - Classes
326
+ # - Structs
327
+ # - Interfaces
328
+ #
329
+ sub TryToGetClass #(indexRef, lineNumberRef)
330
+ {
331
+ my ($self, $indexRef, $lineNumberRef) = @_;
332
+ my $tokens = $self->Tokens();
333
+
334
+ my $index = $$indexRef;
335
+ my $lineNumber = $$lineNumberRef;
336
+
337
+ my $startIndex = $index;
338
+ my $startLine = $lineNumber;
339
+ my $needsPrototype = 0;
340
+
341
+ if ($self->TryToSkipAttributes(\$index, \$lineNumber))
342
+ { $self->TryToSkipWhitespace(\$index, \$lineNumber); }
343
+
344
+ my @modifiers;
345
+
346
+ while ($tokens->[$index] =~ /^[a-z]/i &&
347
+ !exists $classKeywords{lc($tokens->[$index])} &&
348
+ exists $classModifiers{lc($tokens->[$index])} )
349
+ {
350
+ push @modifiers, lc($tokens->[$index]);
351
+ $index++;
352
+
353
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
354
+ };
355
+
356
+ if (!exists $classKeywords{lc($tokens->[$index])})
357
+ { return undef; };
358
+
359
+ my $lcClassKeyword = lc($tokens->[$index]);
360
+
361
+ $index++;
362
+
363
+ if (!$self->TryToSkipWhitespace(\$index, \$lineNumber))
364
+ { return undef; };
365
+
366
+ my $name;
367
+
368
+ while ($tokens->[$index] =~ /^[a-z_\@]/i)
369
+ {
370
+ $name .= $tokens->[$index];
371
+ $index++;
372
+ };
373
+
374
+ if (!defined $name)
375
+ { return undef; };
376
+
377
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
378
+
379
+ if ($tokens->[$index] eq '<')
380
+ {
381
+ # XXX: This is half-assed.
382
+ $index++;
383
+ $needsPrototype = 1;
384
+
385
+ while ($index < scalar @$tokens && $tokens->[$index] ne '>')
386
+ {
387
+ $index++;
388
+ }
389
+
390
+ if ($index < scalar @$tokens)
391
+ {
392
+ $index++;
393
+ }
394
+ else
395
+ { return undef; }
396
+
397
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
398
+ }
399
+
400
+ my @parents;
401
+
402
+ if ($tokens->[$index] eq ':')
403
+ {
404
+ do
405
+ {
406
+ $index++;
407
+
408
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
409
+
410
+ my $parentName;
411
+
412
+ while ($tokens->[$index] =~ /^[a-z_\.\@]/i)
413
+ {
414
+ $parentName .= $tokens->[$index];
415
+ $index++;
416
+ };
417
+
418
+ if ($tokens->[$index] eq '<')
419
+ {
420
+ # XXX: This is still half-assed.
421
+ $index++;
422
+ $needsPrototype = 1;
423
+
424
+ while ($index < scalar @$tokens && $tokens->[$index] ne '>')
425
+ {
426
+ $index++;
427
+ }
428
+
429
+ if ($index < scalar @$tokens)
430
+ {
431
+ $index++;
432
+ }
433
+ else
434
+ { return undef; }
435
+
436
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
437
+ }
438
+
439
+ if (!defined $parentName)
440
+ { return undef; };
441
+
442
+ push @parents, NaturalDocs::SymbolString->FromText($parentName);
443
+
444
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
445
+ }
446
+ while ($tokens->[$index] eq ',')
447
+ };
448
+
449
+ if (lc($tokens->[$index]) eq 'where')
450
+ {
451
+ # XXX: This is also half-assed
452
+ $index++;
453
+
454
+ while ($index < scalar @$tokens && $tokens->[$index] ne '{')
455
+ {
456
+ $index++;
457
+ }
458
+ }
459
+
460
+ if ($tokens->[$index] ne '{')
461
+ { return undef; };
462
+
463
+
464
+ # If we made it this far, we have a valid class declaration.
465
+
466
+ my @scopeIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($self->CurrentScope());
467
+ $name = join('.', @scopeIdentifiers, $name);
468
+
469
+ my $topicType;
470
+
471
+ if ($lcClassKeyword eq 'interface')
472
+ { $topicType = ::TOPIC_INTERFACE(); }
473
+ else
474
+ { $topicType = ::TOPIC_CLASS(); };
475
+
476
+ my $prototype;
477
+
478
+ if ($needsPrototype)
479
+ {
480
+ $prototype = $self->CreateString($startIndex, $index);
481
+ }
482
+
483
+ my $autoTopic = NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
484
+ undef, $self->CurrentUsing(),
485
+ $prototype,
486
+ undef, undef, $$lineNumberRef);
487
+
488
+ $self->AddAutoTopic($autoTopic);
489
+ NaturalDocs::Parser->OnClass($autoTopic->Package());
490
+
491
+ foreach my $parent (@parents)
492
+ {
493
+ NaturalDocs::Parser->OnClassParent($autoTopic->Package(), $parent, $self->CurrentScope(), undef,
494
+ ::RESOLVE_RELATIVE());
495
+ };
496
+
497
+ $self->StartScope('}', $lineNumber, $autoTopic->Package());
498
+
499
+ $index++;
500
+
501
+ $$indexRef = $index;
502
+ $$lineNumberRef = $lineNumber;
503
+
504
+ return 1;
505
+ };
506
+
507
+
508
+ #
509
+ # Function: TryToGetUsing
510
+ #
511
+ # Determines whether the position is at a using statement, and if so, adds it to the current scope, skips it, and returns
512
+ # true.
513
+ #
514
+ # Supported:
515
+ #
516
+ # - Using
517
+ #
518
+ # Unsupported:
519
+ #
520
+ # - Using with alias
521
+ #
522
+ sub TryToGetUsing #(indexRef, lineNumberRef)
523
+ {
524
+ my ($self, $indexRef, $lineNumberRef) = @_;
525
+ my $tokens = $self->Tokens();
526
+
527
+ my $index = $$indexRef;
528
+ my $lineNumber = $$lineNumberRef;
529
+
530
+ if (lc($tokens->[$index]) ne 'using')
531
+ { return undef; };
532
+
533
+ $index++;
534
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
535
+
536
+ my $name;
537
+
538
+ while ($tokens->[$index] =~ /^[a-z_\@\.]/i)
539
+ {
540
+ $name .= $tokens->[$index];
541
+ $index++;
542
+ };
543
+
544
+ if ($tokens->[$index] ne ';' ||
545
+ !defined $name)
546
+ { return undef; };
547
+
548
+ $index++;
549
+
550
+
551
+ $self->AddUsing( NaturalDocs::SymbolString->FromText($name) );
552
+
553
+ $$indexRef = $index;
554
+ $$lineNumberRef = $lineNumber;
555
+
556
+ return 1;
557
+ };
558
+
559
+
560
+
561
+ #
562
+ # Function: TryToGetFunction
563
+ #
564
+ # Determines if the position is on a function declaration, and if so, generates a topic for it, skips it, and returns true.
565
+ #
566
+ # Supported Syntaxes:
567
+ #
568
+ # - Functions
569
+ # - Constructors
570
+ # - Destructors
571
+ # - Properties
572
+ # - Indexers
573
+ # - Delegates
574
+ # - Events
575
+ #
576
+ sub TryToGetFunction #(indexRef, lineNumberRef)
577
+ {
578
+ my ($self, $indexRef, $lineNumberRef) = @_;
579
+ my $tokens = $self->Tokens();
580
+
581
+ my $index = $$indexRef;
582
+ my $lineNumber = $$lineNumberRef;
583
+
584
+ if ($self->TryToSkipAttributes(\$index, \$lineNumber))
585
+ { $self->TryToSkipWhitespace(\$index, \$lineNumber); };
586
+
587
+ my $startIndex = $index;
588
+ my $startLine = $lineNumber;
589
+
590
+ my @modifiers;
591
+
592
+ while ($tokens->[$index] =~ /^[a-z]/i &&
593
+ exists $functionModifiers{lc($tokens->[$index])} )
594
+ {
595
+ push @modifiers, lc($tokens->[$index]);
596
+ $index++;
597
+
598
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
599
+ };
600
+
601
+ my $isDelegate;
602
+ my $isEvent;
603
+
604
+ if (lc($tokens->[$index]) eq 'delegate')
605
+ {
606
+ $isDelegate = 1;
607
+ $index++;
608
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
609
+ }
610
+ elsif (lc($tokens->[$index]) eq 'event')
611
+ {
612
+ $isEvent = 1;
613
+ $index++;
614
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
615
+ };
616
+
617
+ my $returnType = $self->TryToGetType(\$index, \$lineNumber);
618
+
619
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
620
+
621
+ my $name;
622
+ my $lastNameWord;
623
+
624
+ while ($tokens->[$index] =~ /^[a-z\_\@\.\~\<]/i)
625
+ {
626
+ $name .= $tokens->[$index];
627
+
628
+ # Ugly hack, but what else is new? For explicit generic interface definitions, such as:
629
+ # IDObjectType System.Collections.Generic.IEnumerator<IDObjectType>.Current
630
+
631
+ if ($tokens->[$index] eq '<')
632
+ {
633
+ do
634
+ {
635
+ $index++;
636
+ $name .= $tokens->[$index];
637
+ }
638
+ while ($index < @$tokens && $tokens->[$index] ne '>');
639
+ }
640
+
641
+ $lastNameWord = $tokens->[$index];
642
+ $index++;
643
+ };
644
+
645
+ if (!defined $name)
646
+ {
647
+ # Constructors and destructors don't have return types. It's possible their names were mistaken for the return type.
648
+ if (defined $returnType)
649
+ {
650
+ $name = $returnType;
651
+ $returnType = undef;
652
+
653
+ $name =~ /([a-z0-9_]+)$/i;
654
+ $lastNameWord = $1;
655
+ }
656
+ else
657
+ { return undef; };
658
+ };
659
+
660
+ # If there's no return type, make sure it's a constructor or destructor.
661
+ if (!defined $returnType)
662
+ {
663
+ my @identifiers = NaturalDocs::SymbolString->IdentifiersOf( $self->CurrentScope() );
664
+
665
+ if ($lastNameWord ne $identifiers[-1])
666
+ { return undef; };
667
+ };
668
+
669
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
670
+
671
+
672
+ # Skip the brackets on indexers.
673
+ if ($tokens->[$index] eq '[' && lc($lastNameWord) eq 'this')
674
+ {
675
+ # This should jump the brackets completely.
676
+ $self->GenericSkip(\$index, \$lineNumber);
677
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
678
+
679
+ $name .= '[]';
680
+ };
681
+
682
+
683
+ # Properties, indexers, events with braces
684
+
685
+ if ($tokens->[$index] eq '{')
686
+ {
687
+ my $prototype = $self->CreateString($startIndex, $index);
688
+
689
+ $index++;
690
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
691
+
692
+ my ($aWord, $bWord, $hasA, $hasB);
693
+
694
+ if ($isEvent)
695
+ {
696
+ $aWord = 'add';
697
+ $bWord = 'remove';
698
+ }
699
+ else
700
+ {
701
+ $aWord = 'get';
702
+ $bWord = 'set';
703
+ };
704
+
705
+ while ($index < scalar @$tokens)
706
+ {
707
+ if ($self->TryToSkipAttributes(\$index, \$lineNumber))
708
+ { $self->TryToSkipWhitespace(\$index, \$lineNumber); };
709
+
710
+ if (lc($tokens->[$index]) eq $aWord)
711
+ { $hasA = 1; }
712
+ elsif (lc($tokens->[$index]) eq $bWord)
713
+ { $hasB = 1; }
714
+ elsif ($tokens->[$index] eq '}')
715
+ {
716
+ $index++;
717
+ last;
718
+ };
719
+
720
+ $self->SkipRestOfStatement(\$index, \$lineNumber);
721
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
722
+ };
723
+
724
+ if ($hasA && $hasB)
725
+ { $prototype .= ' { ' . $aWord . ', ' . $bWord . ' }'; }
726
+ elsif ($hasA)
727
+ { $prototype .= ' { ' . $aWord . ' }'; }
728
+ elsif ($hasB)
729
+ { $prototype .= ' { ' . $bWord . ' }'; };
730
+
731
+ $prototype = $self->NormalizePrototype($prototype);
732
+
733
+ my $topicType = ( $isEvent ? ::TOPIC_EVENT() : ::TOPIC_PROPERTY() );
734
+
735
+ $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
736
+ $self->CurrentScope(), $self->CurrentUsing(),
737
+ $prototype,
738
+ undef, undef, $startLine));
739
+ }
740
+
741
+
742
+ # Functions, constructors, destructors, delegates.
743
+
744
+ elsif ($tokens->[$index] eq '(')
745
+ {
746
+ # This should jump the parenthesis completely.
747
+ $self->GenericSkip(\$index, \$lineNumber);
748
+
749
+ my $topicType = ( $isDelegate ? ::TOPIC_DELEGATE() : ::TOPIC_FUNCTION() );
750
+ my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
751
+
752
+ $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($topicType, $name,
753
+ $self->CurrentScope(), $self->CurrentUsing(),
754
+ $prototype,
755
+ undef, undef, $startLine));
756
+
757
+ $self->SkipRestOfStatement(\$index, \$lineNumber);
758
+ }
759
+
760
+
761
+ # Events without braces
762
+
763
+ elsif ($isEvent && $tokens->[$index] eq ';')
764
+ {
765
+ my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
766
+
767
+ $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_EVENT(), $name,
768
+ $self->CurrentScope(), $self->CurrentUsing(),
769
+ $prototype,
770
+ undef, undef, $startLine));
771
+ $index++;
772
+ }
773
+
774
+ else
775
+ { return undef; };
776
+
777
+
778
+ # We succeeded if we got this far.
779
+
780
+ $$indexRef = $index;
781
+ $$lineNumberRef = $lineNumber;
782
+
783
+ return 1;
784
+ };
785
+
786
+
787
+ #
788
+ # Function: TryToGetOverloadedOperator
789
+ #
790
+ # Determines if the position is on an operator overload declaration, and if so, generates a topic for it, skips it, and returns true.
791
+ #
792
+ sub TryToGetOverloadedOperator #(indexRef, lineNumberRef)
793
+ {
794
+ my ($self, $indexRef, $lineNumberRef) = @_;
795
+ my $tokens = $self->Tokens();
796
+
797
+ my $index = $$indexRef;
798
+ my $lineNumber = $$lineNumberRef;
799
+
800
+ if ($self->TryToSkipAttributes(\$index, \$lineNumber))
801
+ { $self->TryToSkipWhitespace(\$index, \$lineNumber); };
802
+
803
+ my $startIndex = $index;
804
+ my $startLine = $lineNumber;
805
+
806
+ my @modifiers;
807
+
808
+ while ($tokens->[$index] =~ /^[a-z]/i &&
809
+ exists $functionModifiers{lc($tokens->[$index])} )
810
+ {
811
+ push @modifiers, lc($tokens->[$index]);
812
+ $index++;
813
+
814
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
815
+ };
816
+
817
+
818
+ my $name;
819
+
820
+
821
+ # Casting operators.
822
+
823
+ if (lc($tokens->[$index]) eq 'implicit' || lc($tokens->[$index]) eq 'explicit')
824
+ {
825
+ $index++;
826
+
827
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
828
+
829
+ if (lc($tokens->[$index]) ne 'operator')
830
+ { return undef; };
831
+
832
+ $index++;
833
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
834
+
835
+ $name = $self->TryToGetType(\$index, \$lineNumber);
836
+
837
+ if (!defined $name)
838
+ { return undef; };
839
+ }
840
+
841
+
842
+ # Symbol operators.
843
+
844
+ else
845
+ {
846
+ if (!$self->TryToGetType(\$index, \$lineNumber))
847
+ { return undef; };
848
+
849
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
850
+
851
+ if (lc($tokens->[$index]) ne 'operator')
852
+ { return undef; };
853
+
854
+ $index++;
855
+
856
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
857
+
858
+ if (lc($tokens->[$index]) eq 'true' || lc($tokens->[$index]) eq 'false')
859
+ {
860
+ $name = $tokens->[$index];
861
+ $index++;
862
+ }
863
+ else
864
+ {
865
+ while ($tokens->[$index] =~ /^[\+\-\!\~\*\/\%\&\|\^\<\>\=]$/)
866
+ {
867
+ $name .= $tokens->[$index];
868
+ $index++;
869
+ };
870
+ };
871
+ };
872
+
873
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
874
+
875
+ if ($tokens->[$index] ne '(')
876
+ { return undef; };
877
+
878
+ # This should skip the parenthesis completely.
879
+ $self->GenericSkip(\$index, \$lineNumber);
880
+
881
+ my $prototype = $self->NormalizePrototype( $self->CreateString($startIndex, $index) );
882
+
883
+ $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_FUNCTION(), 'operator ' . $name,
884
+ $self->CurrentScope(), $self->CurrentUsing(),
885
+ $prototype,
886
+ undef, undef, $startLine));
887
+
888
+ $self->SkipRestOfStatement(\$index, \$lineNumber);
889
+
890
+
891
+ # We succeeded if we got this far.
892
+
893
+ $$indexRef = $index;
894
+ $$lineNumberRef = $lineNumber;
895
+
896
+ return 1;
897
+ };
898
+
899
+
900
+ #
901
+ # Function: TryToGetVariable
902
+ #
903
+ # Determines if the position is on a variable declaration statement, and if so, generates a topic for each variable, skips the
904
+ # statement, and returns true.
905
+ #
906
+ # Supported Syntaxes:
907
+ #
908
+ # - Variables
909
+ # - Constants
910
+ #
911
+ sub TryToGetVariable #(indexRef, lineNumberRef)
912
+ {
913
+ my ($self, $indexRef, $lineNumberRef) = @_;
914
+ my $tokens = $self->Tokens();
915
+
916
+ my $index = $$indexRef;
917
+ my $lineNumber = $$lineNumberRef;
918
+
919
+ if ($self->TryToSkipAttributes(\$index, \$lineNumber))
920
+ { $self->TryToSkipWhitespace(\$index, \$lineNumber); };
921
+
922
+ my $startIndex = $index;
923
+ my $startLine = $lineNumber;
924
+
925
+ my @modifiers;
926
+
927
+ while ($tokens->[$index] =~ /^[a-z]/i &&
928
+ exists $variableModifiers{lc($tokens->[$index])} )
929
+ {
930
+ push @modifiers, lc($tokens->[$index]);
931
+ $index++;
932
+
933
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
934
+ };
935
+
936
+ my $type;
937
+ if (lc($tokens->[$index]) eq 'const')
938
+ {
939
+ $type = ::TOPIC_CONSTANT();
940
+ $index++;
941
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
942
+ }
943
+ else
944
+ {
945
+ $type = ::TOPIC_VARIABLE();
946
+ };
947
+
948
+ if (!$self->TryToGetType(\$index, \$lineNumber))
949
+ { return undef; };
950
+
951
+ my $endTypeIndex = $index;
952
+
953
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
954
+
955
+ my @names;
956
+
957
+ for (;;)
958
+ {
959
+ my $name;
960
+
961
+ while ($tokens->[$index] =~ /^[a-z\@\_]/i)
962
+ {
963
+ $name .= $tokens->[$index];
964
+ $index++;
965
+ };
966
+
967
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
968
+
969
+ if ($tokens->[$index] eq '=')
970
+ {
971
+ do
972
+ {
973
+ $self->GenericSkip(\$index, \$lineNumber);
974
+ }
975
+ while ($tokens->[$index] ne ',' && $tokens->[$index] ne ';');
976
+ };
977
+
978
+ push @names, $name;
979
+
980
+ if ($tokens->[$index] eq ';')
981
+ {
982
+ $index++;
983
+ last;
984
+ }
985
+ elsif ($tokens->[$index] eq ',')
986
+ {
987
+ $index++;
988
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
989
+ }
990
+ else
991
+ { return undef; };
992
+ };
993
+
994
+
995
+ # We succeeded if we got this far.
996
+
997
+ my $prototypePrefix = $self->CreateString($startIndex, $endTypeIndex);
998
+
999
+ foreach my $name (@names)
1000
+ {
1001
+ my $prototype = $self->NormalizePrototype( $prototypePrefix . ' ' . $name );
1002
+
1003
+ $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New($type, $name,
1004
+ $self->CurrentScope(), $self->CurrentUsing(),
1005
+ $prototype,
1006
+ undef, undef, $startLine));
1007
+ };
1008
+
1009
+ $$indexRef = $index;
1010
+ $$lineNumberRef = $lineNumber;
1011
+
1012
+ return 1;
1013
+ };
1014
+
1015
+
1016
+ #
1017
+ # Function: TryToGetEnum
1018
+ #
1019
+ # Determines if the position is on an enum declaration statement, and if so, generates a topic for it.
1020
+ #
1021
+ # Supported Syntaxes:
1022
+ #
1023
+ # - Enums
1024
+ # - Enums with declared types
1025
+ #
1026
+ # Unsupported:
1027
+ #
1028
+ # - Documenting the members automatically
1029
+ #
1030
+ sub TryToGetEnum #(indexRef, lineNumberRef)
1031
+ {
1032
+ my ($self, $indexRef, $lineNumberRef) = @_;
1033
+ my $tokens = $self->Tokens();
1034
+
1035
+ my $index = $$indexRef;
1036
+ my $lineNumber = $$lineNumberRef;
1037
+
1038
+ if ($self->TryToSkipAttributes(\$index, \$lineNumber))
1039
+ { $self->TryToSkipWhitespace(\$index, \$lineNumber); };
1040
+
1041
+ my $startIndex = $index;
1042
+ my $startLine = $lineNumber;
1043
+
1044
+ my @modifiers;
1045
+
1046
+ while ($tokens->[$index] =~ /^[a-z]/i &&
1047
+ exists $variableModifiers{lc($tokens->[$index])} )
1048
+ {
1049
+ push @modifiers, lc($tokens->[$index]);
1050
+ $index++;
1051
+
1052
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1053
+ };
1054
+
1055
+ if (lc($tokens->[$index]) ne 'enum')
1056
+ { return undef; }
1057
+
1058
+ $index++;
1059
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1060
+
1061
+ my $name;
1062
+
1063
+ while ($tokens->[$index] =~ /^[a-z\@\_]/i)
1064
+ {
1065
+ $name .= $tokens->[$index];
1066
+ $index++;
1067
+ };
1068
+
1069
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1070
+
1071
+ if ($tokens->[$index] eq ':')
1072
+ {
1073
+ $index++;
1074
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1075
+
1076
+ if (!exists $enumTypes{ lc($tokens->[$index]) })
1077
+ { return undef; }
1078
+
1079
+ $index++;
1080
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1081
+ }
1082
+
1083
+ if ($tokens->[$index] ne '{')
1084
+ { return undef; }
1085
+
1086
+ # We succeeded if we got this far.
1087
+
1088
+ my $prototype = $self->CreateString($startIndex, $index);
1089
+ $prototype = $self->NormalizePrototype( $prototype );
1090
+
1091
+ $self->SkipRestOfStatement(\$index, \$lineNumber);
1092
+
1093
+ $self->AddAutoTopic(NaturalDocs::Parser::ParsedTopic->New(::TOPIC_ENUMERATION(), $name,
1094
+ $self->CurrentScope(), $self->CurrentUsing(),
1095
+ $prototype,
1096
+ undef, undef, $startLine));
1097
+
1098
+ $$indexRef = $index;
1099
+ $$lineNumberRef = $lineNumber;
1100
+
1101
+ return 1;
1102
+ };
1103
+
1104
+
1105
+ #
1106
+ # Function: TryToGetType
1107
+ #
1108
+ # Determines if the position is on a type identifier, and if so, skips it and returns it as a string. This function does _not_ allow
1109
+ # modifiers. You must take care of those beforehand.
1110
+ #
1111
+ sub TryToGetType #(indexRef, lineNumberRef)
1112
+ {
1113
+ my ($self, $indexRef, $lineNumberRef) = @_;
1114
+ my $tokens = $self->Tokens();
1115
+
1116
+ my $name;
1117
+ my $index = $$indexRef;
1118
+ my $lineNumber = $$lineNumberRef;
1119
+
1120
+ while ($tokens->[$index] =~ /^[a-z\@\.\_]/i)
1121
+ {
1122
+ if (exists $impossibleTypeWords{ lc($tokens->[$index]) } && $name !~ /\@$/)
1123
+ { return undef; };
1124
+
1125
+ $name .= $tokens->[$index];
1126
+ $index++;
1127
+ };
1128
+
1129
+ if (!defined $name)
1130
+ { return undef; };
1131
+
1132
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1133
+
1134
+ if ($tokens->[$index] eq '?')
1135
+ {
1136
+ $name .= '?';
1137
+ $index++;
1138
+
1139
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1140
+ }
1141
+
1142
+ if ($tokens->[$index] eq '<')
1143
+ {
1144
+ # XXX: This is half-assed.
1145
+ $name .= '<';
1146
+ $index++;
1147
+
1148
+ while ($index < scalar @$tokens && $tokens->[$index] ne '>')
1149
+ {
1150
+ $name .= $tokens->[$index];
1151
+ $index++;
1152
+ }
1153
+
1154
+ if ($index < scalar @$tokens)
1155
+ {
1156
+ $name .= '>';
1157
+ $index++;
1158
+ }
1159
+ else
1160
+ { return undef; }
1161
+
1162
+ $self->TryToSkipWhitespace(\$index, \$lineNumber);
1163
+ }
1164
+
1165
+ while ($tokens->[$index] eq '[')
1166
+ {
1167
+ $name .= '[';
1168
+ $index++;
1169
+
1170
+ while ($tokens->[$index] eq ',')
1171
+ {
1172
+ $name .= ',';
1173
+ $index++;
1174
+ };
1175
+
1176
+ if ($tokens->[$index] eq ']')
1177
+ {
1178
+ $name .= ']';
1179
+ $index++;
1180
+ }
1181
+ else
1182
+ { return undef; }
1183
+ };
1184
+
1185
+ $$indexRef = $index;
1186
+ $$lineNumberRef = $lineNumber;
1187
+
1188
+ return $name;
1189
+ };
1190
+
1191
+
1192
+
1193
+ ###############################################################################
1194
+ # Group: Low Level Parsing Functions
1195
+
1196
+
1197
+ #
1198
+ # Function: GenericSkip
1199
+ #
1200
+ # Advances the position one place through general code.
1201
+ #
1202
+ # - If the position is on a string, it will skip it completely.
1203
+ # - If the position is on an opening symbol, it will skip until the past the closing symbol.
1204
+ # - If the position is on whitespace (including comments and preprocessing directives), it will skip it completely.
1205
+ # - Otherwise it skips one token.
1206
+ #
1207
+ # Parameters:
1208
+ #
1209
+ # indexRef - A reference to the current index.
1210
+ # lineNumberRef - A reference to the current line number.
1211
+ #
1212
+ sub GenericSkip #(indexRef, lineNumberRef)
1213
+ {
1214
+ my ($self, $indexRef, $lineNumberRef) = @_;
1215
+ my $tokens = $self->Tokens();
1216
+
1217
+ # We can ignore the scope stack because we're just skipping everything without parsing, and we need recursion anyway.
1218
+ if ($tokens->[$$indexRef] eq '{')
1219
+ {
1220
+ $$indexRef++;
1221
+ $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, '}');
1222
+ }
1223
+ elsif ($tokens->[$$indexRef] eq '(')
1224
+ {
1225
+ $$indexRef++;
1226
+ $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ')');
1227
+ }
1228
+ elsif ($tokens->[$$indexRef] eq '[')
1229
+ {
1230
+ $$indexRef++;
1231
+ $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']');
1232
+ }
1233
+
1234
+ elsif ($self->TryToSkipWhitespace($indexRef, $lineNumberRef) ||
1235
+ $self->TryToSkipString($indexRef, $lineNumberRef))
1236
+ {
1237
+ }
1238
+
1239
+ else
1240
+ { $$indexRef++; };
1241
+ };
1242
+
1243
+
1244
+ #
1245
+ # Function: GenericSkipUntilAfter
1246
+ #
1247
+ # Advances the position via <GenericSkip()> until a specific token is reached and passed.
1248
+ #
1249
+ sub GenericSkipUntilAfter #(indexRef, lineNumberRef, token)
1250
+ {
1251
+ my ($self, $indexRef, $lineNumberRef, $token) = @_;
1252
+ my $tokens = $self->Tokens();
1253
+
1254
+ while ($$indexRef < scalar @$tokens && $tokens->[$$indexRef] ne $token)
1255
+ { $self->GenericSkip($indexRef, $lineNumberRef); };
1256
+
1257
+ if ($tokens->[$$indexRef] eq "\n")
1258
+ { $$lineNumberRef++; };
1259
+ $$indexRef++;
1260
+ };
1261
+
1262
+
1263
+ #
1264
+ # Function: SkipRestOfStatement
1265
+ #
1266
+ # Advances the position via <GenericSkip()> until after the end of the current statement, which is defined as a semicolon or
1267
+ # a brace group. Of course, either of those appearing inside parenthesis, a nested brace group, etc. don't count.
1268
+ #
1269
+ sub SkipRestOfStatement #(indexRef, lineNumberRef)
1270
+ {
1271
+ my ($self, $indexRef, $lineNumberRef) = @_;
1272
+ my $tokens = $self->Tokens();
1273
+
1274
+ while ($$indexRef < scalar @$tokens &&
1275
+ $tokens->[$$indexRef] ne ';' &&
1276
+ $tokens->[$$indexRef] ne '{')
1277
+ {
1278
+ $self->GenericSkip($indexRef, $lineNumberRef);
1279
+ };
1280
+
1281
+ if ($tokens->[$$indexRef] eq ';')
1282
+ { $$indexRef++; }
1283
+ elsif ($tokens->[$$indexRef] eq '{')
1284
+ { $self->GenericSkip($indexRef, $lineNumberRef); };
1285
+ };
1286
+
1287
+
1288
+ #
1289
+ # Function: TryToSkipString
1290
+ # If the current position is on a string delimiter, skip past the string and return true.
1291
+ #
1292
+ # Parameters:
1293
+ #
1294
+ # indexRef - A reference to the index of the position to start at.
1295
+ # lineNumberRef - A reference to the line number of the position.
1296
+ #
1297
+ # Returns:
1298
+ #
1299
+ # Whether the position was at a string.
1300
+ #
1301
+ # Syntax Support:
1302
+ #
1303
+ # - Supports quotes, apostrophes, and at-quotes.
1304
+ #
1305
+ sub TryToSkipString #(indexRef, lineNumberRef)
1306
+ {
1307
+ my ($self, $indexRef, $lineNumberRef) = @_;
1308
+ my $tokens = $self->Tokens();
1309
+
1310
+ # The three string delimiters. All three are Perl variables when preceded by a dollar sign.
1311
+ if ($self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '\'') ||
1312
+ $self->SUPER::TryToSkipString($indexRef, $lineNumberRef, '"') )
1313
+ {
1314
+ return 1;
1315
+ }
1316
+ elsif ($tokens->[$$indexRef] eq '@' && $tokens->[$$indexRef+1] eq '"')
1317
+ {
1318
+ $$indexRef += 2;
1319
+
1320
+ # We need to do at-strings manually because backslash characters are accepted as regular characters, and two consecutive
1321
+ # quotes are accepted as well.
1322
+
1323
+ while ($$indexRef < scalar @$tokens && !($tokens->[$$indexRef] eq '"' && $tokens->[$$indexRef+1] ne '"') )
1324
+ {
1325
+ if ($tokens->[$$indexRef] eq '"')
1326
+ {
1327
+ # This is safe because the while condition will only let through quote pairs.
1328
+ $$indexRef += 2;
1329
+ }
1330
+ elsif ($tokens->[$$indexRef] eq "\n")
1331
+ {
1332
+ $$indexRef++;
1333
+ $$lineNumberRef++;
1334
+ }
1335
+ else
1336
+ {
1337
+ $$indexRef++;
1338
+ };
1339
+ };
1340
+
1341
+ # Skip the closing quote.
1342
+ if ($$indexRef < scalar @$tokens)
1343
+ { $$indexRef++; };
1344
+
1345
+ return 1;
1346
+ }
1347
+ else
1348
+ { return undef; };
1349
+ };
1350
+
1351
+
1352
+ #
1353
+ # Function: TryToSkipAttributes
1354
+ # If the current position is on an attribute section, skip it and return true. Skips multiple attribute sections if they appear
1355
+ # consecutively.
1356
+ #
1357
+ sub TryToSkipAttributes #(indexRef, lineNumberRef)
1358
+ {
1359
+ my ($self, $indexRef, $lineNumberRef) = @_;
1360
+ my $tokens = $self->Tokens();
1361
+
1362
+ my $success;
1363
+
1364
+ while ($tokens->[$$indexRef] eq '[')
1365
+ {
1366
+ $success = 1;
1367
+ $$indexRef++;
1368
+ $self->GenericSkipUntilAfter($indexRef, $lineNumberRef, ']');
1369
+ $self->TryToSkipWhitespace($indexRef, $lineNumberRef);
1370
+ };
1371
+
1372
+ return $success;
1373
+ };
1374
+
1375
+
1376
+ #
1377
+ # Function: TryToSkipWhitespace
1378
+ # If the current position is on a whitespace token, a line break token, a comment, or a preprocessing directive, it skips them
1379
+ # and returns true. If there are a number of these in a row, it skips them all.
1380
+ #
1381
+ sub TryToSkipWhitespace #(indexRef, lineNumberRef)
1382
+ {
1383
+ my ($self, $indexRef, $lineNumberRef) = @_;
1384
+ my $tokens = $self->Tokens();
1385
+
1386
+ my $result;
1387
+
1388
+ while ($$indexRef < scalar @$tokens)
1389
+ {
1390
+ if ($tokens->[$$indexRef] =~ /^[ \t]/)
1391
+ {
1392
+ $$indexRef++;
1393
+ $result = 1;
1394
+ }
1395
+ elsif ($tokens->[$$indexRef] eq "\n")
1396
+ {
1397
+ $$indexRef++;
1398
+ $$lineNumberRef++;
1399
+ $result = 1;
1400
+ }
1401
+ elsif ($self->TryToSkipComment($indexRef, $lineNumberRef) ||
1402
+ $self->TryToSkipPreprocessingDirective($indexRef, $lineNumberRef))
1403
+ {
1404
+ $result = 1;
1405
+ }
1406
+ else
1407
+ { last; };
1408
+ };
1409
+
1410
+ return $result;
1411
+ };
1412
+
1413
+
1414
+ #
1415
+ # Function: TryToSkipComment
1416
+ # If the current position is on a comment, skip past it and return true.
1417
+ #
1418
+ sub TryToSkipComment #(indexRef, lineNumberRef)
1419
+ {
1420
+ my ($self, $indexRef, $lineNumberRef) = @_;
1421
+
1422
+ return ( $self->TryToSkipLineComment($indexRef, $lineNumberRef) ||
1423
+ $self->TryToSkipMultilineComment($indexRef, $lineNumberRef) );
1424
+ };
1425
+
1426
+
1427
+ #
1428
+ # Function: TryToSkipLineComment
1429
+ # If the current position is on a line comment symbol, skip past it and return true.
1430
+ #
1431
+ sub TryToSkipLineComment #(indexRef, lineNumberRef)
1432
+ {
1433
+ my ($self, $indexRef, $lineNumberRef) = @_;
1434
+ my $tokens = $self->Tokens();
1435
+
1436
+ if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '/')
1437
+ {
1438
+ $self->SkipRestOfLine($indexRef, $lineNumberRef);
1439
+ return 1;
1440
+ }
1441
+ else
1442
+ { return undef; };
1443
+ };
1444
+
1445
+
1446
+ #
1447
+ # Function: TryToSkipMultilineComment
1448
+ # If the current position is on an opening comment symbol, skip past it and return true.
1449
+ #
1450
+ sub TryToSkipMultilineComment #(indexRef, lineNumberRef)
1451
+ {
1452
+ my ($self, $indexRef, $lineNumberRef) = @_;
1453
+ my $tokens = $self->Tokens();
1454
+
1455
+ if ($tokens->[$$indexRef] eq '/' && $tokens->[$$indexRef+1] eq '*')
1456
+ {
1457
+ $self->SkipUntilAfter($indexRef, $lineNumberRef, '*', '/');
1458
+ return 1;
1459
+ }
1460
+ else
1461
+ { return undef; };
1462
+ };
1463
+
1464
+
1465
+ #
1466
+ # Function: TryToSkipPreprocessingDirective
1467
+ # If the current position is on a preprocessing directive, skip past it and return true.
1468
+ #
1469
+ sub TryToSkipPreprocessingDirective #(indexRef, lineNumberRef)
1470
+ {
1471
+ my ($self, $indexRef, $lineNumberRef) = @_;
1472
+ my $tokens = $self->Tokens();
1473
+
1474
+ if ($tokens->[$$indexRef] eq '#' && $self->IsFirstLineToken($$indexRef))
1475
+ {
1476
+ $self->SkipRestOfLine($indexRef, $lineNumberRef);
1477
+ return 1;
1478
+ }
1479
+ else
1480
+ { return undef; };
1481
+ };
1482
+
1483
+
1484
+ 1;