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,1984 @@
1
+ ###############################################################################
2
+ #
3
+ # Package: NaturalDocs::SymbolTable
4
+ #
5
+ ###############################################################################
6
+ #
7
+ # A package that handles all the gory details of managing symbols. It handles where they are defined, which files
8
+ # reference them, if any are undefined or duplicated, and loading and saving them to a file.
9
+ #
10
+ # Usage and Dependencies:
11
+ #
12
+ # - At any time, <RebuildAllIndexes()> can be called.
13
+ #
14
+ # - <NaturalDocs::Settings>, <NaturalDocs::Languages>, and <NaturalDocs::Project> must be initialized before use.
15
+ #
16
+ # - <Load()> must be called to initialize the package. At this point, the <Information Functions> will return the symbol
17
+ # table as of the last time Natural Docs was run.
18
+ #
19
+ # - Note that <Load()> and <Save()> only manage <REFERENCE_TEXT> references. All other reference types must be
20
+ # managed by their respective classes. They should be readded after <Load()> to recreate the state of the last time
21
+ # Natural Docs was run.
22
+ #
23
+ # - <Purge()> must be called, and then <NaturalDocs::Parser->ParseForInformation()> on all files that have changed so it
24
+ # can fully resolve the symbol table via the <Modification Functions>. Afterwards <PurgeResolvingInfo()> can be called
25
+ # to reclaim some memory, and the symbol table will reflect the current state of the code.
26
+ #
27
+ # - <Save()> must be called to commit any changes to the symbol table back to disk.
28
+ #
29
+ ###############################################################################
30
+
31
+ # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
32
+ # Natural Docs is licensed under the GPL
33
+
34
+
35
+ use NaturalDocs::SymbolTable::Symbol;
36
+ use NaturalDocs::SymbolTable::SymbolDefinition;
37
+ use NaturalDocs::SymbolTable::Reference;
38
+ use NaturalDocs::SymbolTable::File;
39
+ use NaturalDocs::SymbolTable::ReferenceTarget;
40
+ use NaturalDocs::SymbolTable::IndexElement;
41
+
42
+ use strict;
43
+ use integer;
44
+
45
+ package NaturalDocs::SymbolTable;
46
+
47
+
48
+
49
+ ###############################################################################
50
+ # Group: Variables
51
+
52
+ #
53
+ # handle: SYMBOLTABLE_FILEHANDLE
54
+ #
55
+ # The file handle used with <SymbolTable.nd>.
56
+ #
57
+
58
+ #
59
+ # hash: symbols
60
+ #
61
+ # A hash of all <SymbolStrings>. The keys are the <SymbolStrings> and the values are <NaturalDocs::SymbolTable::Symbol>
62
+ # objects.
63
+ #
64
+ # Prior to <PurgeResolvingInfo()>, both defined symbols and symbols that are merely potential interpretations of references
65
+ # will be here. Afterwards, only defined symbols will be here.
66
+ #
67
+ my %symbols;
68
+
69
+ #
70
+ # hash: references
71
+ #
72
+ # A hash of all references in the project. The keys are <ReferenceStrings> and the values are
73
+ # <NaturalDocs::SymbolTable::Reference> objects.
74
+ #
75
+ # Prior to <PurgeResolvingInfo()>, all possible interpretations will be stored for each reference. Afterwards, only the current
76
+ # interpretation will be.
77
+ #
78
+ my %references;
79
+
80
+ #
81
+ # hash: files
82
+ #
83
+ # A hash of all the files that define symbols and references in the project. The keys are the <FileNames>, and the values are
84
+ # <NaturalDocs::SymbolTable::File> objects.
85
+ #
86
+ # After <PurgeResolvingInfo()>, this hash will be empty.
87
+ #
88
+ my %files;
89
+
90
+ #
91
+ # object: watchedFile
92
+ #
93
+ # A <NaturalDocs::SymbolTable::File> object of the file being watched for changes. This is compared to the version in <files>
94
+ # to see if anything was changed since the last parse.
95
+ #
96
+ my $watchedFile;
97
+
98
+ #
99
+ # string: watchedFileName
100
+ #
101
+ # The <FileName> of the watched file, if any. If there is no watched file, this will be undef.
102
+ #
103
+ my $watchedFileName;
104
+
105
+ #
106
+ # hash: watchedFileSymbolDefinitions
107
+ #
108
+ # A hashref of the symbol definition information for all the <SymbolStrings> in the watched file. The keys are the symbol strings,
109
+ # and the values are <NaturalDocs::SymbolTable::SymbolDefinition> objects.
110
+ #
111
+ my %watchedFileSymbolDefinitions;
112
+
113
+
114
+ #
115
+ # hash: indexes
116
+ #
117
+ # A hash of generated symbol indexes. The keys are <TopicTypes> and the values are sorted arrayrefs of
118
+ # <NaturalDocs::SymbolTable::IndexElements>, or undef if its empty.
119
+ #
120
+ my %indexes;
121
+
122
+
123
+ #
124
+ # hash: indexChanges
125
+ #
126
+ # A hash of all the indexes that have changed. The keys are the <TopicTypes> and the entries are undef if they have not
127
+ # changed, or 1 if they have. The key will not exist if the <TopicType> has not been checked.
128
+ #
129
+ my %indexChanges;
130
+
131
+
132
+ #
133
+ # hash: indexSectionsWithContent
134
+ #
135
+ # A hash of which sections in an index have content. The keys are the <TopicTypes> of each index, and the values are
136
+ # arrayrefs of bools where the first represents symbols, the second numbers, and the rest A-Z. If there is no information
137
+ # available for an index, it's entry will not exist here.
138
+ #
139
+ my %indexSectionsWithContent;
140
+
141
+
142
+ #
143
+ # bool: rebuildIndexes
144
+ #
145
+ # Whether all indexes should be rebuilt regardless of whether they have been changed.
146
+ #
147
+ my $rebuildIndexes;
148
+
149
+
150
+
151
+ ###############################################################################
152
+ # Group: Files
153
+
154
+
155
+ #
156
+ # File: SymbolTable.nd
157
+ #
158
+ # The storage file for the symbol table.
159
+ #
160
+ # Format:
161
+ #
162
+ # > [BINARY_FORMAT]
163
+ # > [VersionInt: app version]
164
+ #
165
+ # The file starts with the standard <BINARY_FORMAT> <VersionInt> header.
166
+ #
167
+ # The first stage of the file is for symbol definitions, analogous to <symbols>.
168
+ #
169
+ # > [SymbolString: symbol or undef to end] ...
170
+ # >
171
+ # > [UInt16: number of definitions]
172
+ # >
173
+ # > [AString16: global definition file] [AString16: TopicType]
174
+ # > [AString16: prototype] [AString16: summary]
175
+ # >
176
+ # > [AString16: definition file] ...
177
+ # >
178
+ # > ...
179
+ #
180
+ # These blocks continue until the <SymbolString> is undef. Only defined symbols will be included in this file, so
181
+ # number of definitions will never be zero. The first one is always the global definition. If a symbol does not have a
182
+ # prototype or summary, the UInt16 length of the string will be zero.
183
+ #
184
+ # The second stage is for references, which is analogous to <references>. Only <REFERENCE_TEXT> references are
185
+ # stored in this file, and their <Resolving Flags> are implied so they aren't stored either.
186
+ #
187
+ # > [ReferenceString (no type, resolving flags): reference or undef to end]
188
+ # >
189
+ # > [UInt8: number of definition files]
190
+ # > [AString16: definition file] [AString16: definition file] ...
191
+ #
192
+ # These blocks continue until the <ReferenceString> is undef. Since there can be multiple using <SymbolStrings>, those
193
+ # continue until the number of identifiers is zero. Note that all interpretations are rebuilt rather than stored.
194
+ #
195
+ # See Also:
196
+ #
197
+ # <File Format Conventions>
198
+ #
199
+ # Revisions:
200
+ #
201
+ # 1.3:
202
+ #
203
+ # - Symbol <TopicTypes> were changed from UInt8s to AString16s, now that <TopicTypes> are strings instead of
204
+ # integer constants.
205
+ #
206
+ # 1.22:
207
+ #
208
+ # - File format was completely rebuilt to accommodate the new symbol format and to be in binary. To see the plain text
209
+ # format prior to 1.22, check out 1.21's version of this file from CVS. It is too big a change to note here.
210
+ #
211
+
212
+
213
+ #
214
+ # File: IndexInfo.nd
215
+ #
216
+ # The storage file for information about the indexes.
217
+ #
218
+ # Format:
219
+ #
220
+ # > [Standard Header]
221
+ #
222
+ # The standard binary file header.
223
+ #
224
+ # > [AString16: index topic name]
225
+ # > [uint8: symbols have content (0 or 1)]
226
+ # > [uint8: numbers have content (0 or 1)]
227
+ # > [uint8: A has content] [uint8: B has content] ...
228
+ # > ...
229
+ #
230
+ # Every index that has information about it is stored with the topic type name first, then 28 uint8s that say whether that
231
+ # part of the index has content or not. The first is for symbols, the second is for numbers, and the rest are for A-Z. If an
232
+ # index's state is unknown, it won't appear in this file.
233
+ #
234
+ # Revisions:
235
+ #
236
+ # 1.4:
237
+ #
238
+ # - The file is introduced.
239
+ #
240
+
241
+
242
+
243
+ ###############################################################################
244
+ # Group: File Functions
245
+
246
+
247
+ #
248
+ # Function: Load
249
+ #
250
+ # Loads all data files from disk.
251
+ #
252
+ sub Load
253
+ {
254
+ my ($self) = @_;
255
+
256
+ $self->LoadSymbolTable();
257
+ $self->LoadIndexInfo();
258
+ };
259
+
260
+
261
+ #
262
+ # Function: LoadSymbolTable
263
+ #
264
+ # Loads <SymbolTable.nd> from disk.
265
+ #
266
+ sub LoadSymbolTable
267
+ {
268
+ my ($self) = @_;
269
+
270
+ my $fileIsOkay;
271
+
272
+ if (!NaturalDocs::Settings->RebuildData() &&
273
+ open(SYMBOLTABLE_FILEHANDLE, '<' . NaturalDocs::Project->DataFile('SymbolTable.nd')) )
274
+ {
275
+ # See if it's binary.
276
+ binmode(SYMBOLTABLE_FILEHANDLE);
277
+
278
+ my $firstChar;
279
+ read(SYMBOLTABLE_FILEHANDLE, $firstChar, 1);
280
+
281
+ if ($firstChar == ::BINARY_FORMAT())
282
+ {
283
+ my $version = NaturalDocs::Version->FromBinaryFile(\*SYMBOLTABLE_FILEHANDLE);
284
+
285
+ # 1.3 is incompatible with previous versions.
286
+
287
+ if (NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.3') ))
288
+ { $fileIsOkay = 1; }
289
+ else
290
+ { close(SYMBOLTABLE_FILEHANDLE); };
291
+ }
292
+
293
+ else
294
+ { close(SYMBOLTABLE_FILEHANDLE); };
295
+ };
296
+
297
+
298
+ if (!$fileIsOkay)
299
+ {
300
+ NaturalDocs::Project->ReparseEverything();
301
+ return;
302
+ }
303
+
304
+ my $raw;
305
+
306
+
307
+ # Symbols
308
+
309
+ for (;;)
310
+ {
311
+ # [SymbolString: symbol or undef to end]
312
+
313
+ my $symbol = NaturalDocs::SymbolString->FromBinaryFile(\*SYMBOLTABLE_FILEHANDLE);
314
+
315
+ if (!defined $symbol)
316
+ { last; };
317
+
318
+ my $symbolObject = NaturalDocs::SymbolTable::Symbol->New();
319
+ $symbols{$symbol} = $symbolObject;
320
+
321
+ # [UInt16: number of definitions]
322
+
323
+ read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
324
+ my $definitionCount = unpack('n', $raw);
325
+
326
+ do
327
+ {
328
+ # [AString16: (global?) definition file]
329
+
330
+ read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
331
+ my $fileLength = unpack('n', $raw);
332
+
333
+ my $file;
334
+ read(SYMBOLTABLE_FILEHANDLE, $file, $fileLength);
335
+
336
+ # [AString16: TopicType]
337
+
338
+ read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
339
+ my $typeLength = unpack('n', $raw);
340
+
341
+ my $type;
342
+ read(SYMBOLTABLE_FILEHANDLE, $type, $typeLength);
343
+
344
+ # [AString16: prototype]
345
+
346
+ read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
347
+ my $prototypeLength = unpack('n', $raw);
348
+
349
+ my $prototype;
350
+ if ($prototypeLength)
351
+ { read(SYMBOLTABLE_FILEHANDLE, $prototype, $prototypeLength); };
352
+
353
+ # [AString16: summary]
354
+
355
+ read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
356
+ my $summaryLength = unpack('n', $raw);
357
+
358
+ my $summary;
359
+ if ($summaryLength)
360
+ { read(SYMBOLTABLE_FILEHANDLE, $summary, $summaryLength); };
361
+
362
+ $symbolObject->AddDefinition($file, $type, $prototype, $summary);
363
+
364
+ # Add it.
365
+
366
+ if (!exists $files{$file})
367
+ { $files{$file} = NaturalDocs::SymbolTable::File->New(); };
368
+
369
+ $files{$file}->AddSymbol($symbol);
370
+
371
+ $definitionCount--;
372
+ }
373
+ while ($definitionCount);
374
+ };
375
+
376
+
377
+ # References
378
+
379
+ for (;;)
380
+ {
381
+ # [ReferenceString (no type, resolving flags): reference or undef to end]
382
+
383
+ my $referenceString = NaturalDocs::ReferenceString->FromBinaryFile(\*SYMBOLTABLE_FILEHANDLE,
384
+ ::BINARYREF_NOTYPE() |
385
+ ::BINARYREF_NORESOLVINGFLAGS(),
386
+ ::REFERENCE_TEXT(), undef);
387
+
388
+ if (!defined $referenceString)
389
+ { last; };
390
+
391
+ my $referenceObject = NaturalDocs::SymbolTable::Reference->New();
392
+ $references{$referenceString} = $referenceObject;
393
+
394
+ # [UInt8: number of definition files]
395
+
396
+ read(SYMBOLTABLE_FILEHANDLE, $raw, 1);
397
+ my $definitionCount = unpack('C', $raw);
398
+ do
399
+ {
400
+ # [AString16: definition file] [AString16: definition file] ...
401
+
402
+ read(SYMBOLTABLE_FILEHANDLE, $raw, 2);
403
+ my $definitionLength = unpack('n', $raw);
404
+
405
+ my $definition;
406
+ read(SYMBOLTABLE_FILEHANDLE, $definition, $definitionLength);
407
+
408
+ # Add it.
409
+
410
+ $referenceObject->AddDefinition($definition);
411
+
412
+ if (!exists $files{$definition})
413
+ { $files{$definition} = NaturalDocs::SymbolTable::File->New(); };
414
+
415
+ $files{$definition}->AddReference($referenceString);
416
+
417
+ $definitionCount--;
418
+ }
419
+ while ($definitionCount);
420
+
421
+ $self->GenerateInterpretations($referenceString);
422
+ $self->InterpretReference($referenceString);
423
+ };
424
+
425
+ close(SYMBOLTABLE_FILEHANDLE);
426
+ };
427
+
428
+
429
+ #
430
+ # Function: LoadIndexInfo
431
+ #
432
+ # Loads <IndexInfo.nd> from disk.
433
+ #
434
+ sub LoadIndexInfo
435
+ {
436
+ my ($self) = @_;
437
+
438
+ if (NaturalDocs::Settings->RebuildData())
439
+ { return; };
440
+
441
+ my $version = NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('IndexInfo.nd') );
442
+
443
+ if (!defined $version)
444
+ { return; }
445
+
446
+ # The file format hasn't changed since it was introduced.
447
+ if (!NaturalDocs::Version->CheckFileFormat($version))
448
+ {
449
+ NaturalDocs::BinaryFile->Close();
450
+ return;
451
+ };
452
+
453
+ my $topicTypeName;
454
+ while ($topicTypeName = NaturalDocs::BinaryFile->GetAString16())
455
+ {
456
+ my $topicType = NaturalDocs::Topics->TypeFromName($topicTypeName);
457
+ my $content = [ ];
458
+
459
+ for (my $i = 0; $i < 28; $i++)
460
+ { push @$content, NaturalDocs::BinaryFile->GetUInt8(); };
461
+
462
+ if (defined $topicType) # The name in the file could be from a type that was deleted
463
+ { $indexSectionsWithContent{$topicType} = $content; };
464
+ };
465
+
466
+ NaturalDocs::BinaryFile->Close();
467
+ };
468
+
469
+
470
+ #
471
+ # Function: Purge
472
+ #
473
+ # Purges the symbol table of all symbols and references from files that no longer have Natural Docs content.
474
+ #
475
+ sub Purge
476
+ {
477
+ my ($self) = @_;
478
+
479
+ my $filesToPurge = NaturalDocs::Project->FilesToPurge();
480
+
481
+ # We do this in two stages. First we delete all the references, and then we delete all the definitions. This causes us to go
482
+ # through the list twice, but it makes sure no purged files get added to the build list. For example, if we deleted all of
483
+ # Purge File A's references and definitions, and Purge File B had a reference to one of those symbols, Purge File B
484
+ # would be added to the build list because one of its references changed. By removing all the references in all the files
485
+ # before removing the definitions, we avoid this.
486
+
487
+ foreach my $file (keys %$filesToPurge)
488
+ {
489
+ if (exists $files{$file})
490
+ {
491
+ my @references = $files{$file}->References();
492
+ foreach my $reference (@references)
493
+ { $self->DeleteReference($reference, $file); };
494
+ };
495
+ };
496
+
497
+ foreach my $file (keys %$filesToPurge)
498
+ {
499
+ if (exists $files{$file})
500
+ {
501
+ my @symbols = $files{$file}->Symbols();
502
+ foreach my $symbol (@symbols)
503
+ { $self->DeleteSymbol($symbol, $file); };
504
+
505
+ delete $files{$file};
506
+ };
507
+ };
508
+ };
509
+
510
+
511
+ #
512
+ # Function: Save
513
+ #
514
+ # Saves all data files to disk.
515
+ #
516
+ sub Save
517
+ {
518
+ my ($self) = @_;
519
+
520
+ $self->SaveSymbolTable();
521
+ $self->SaveIndexInfo();
522
+ };
523
+
524
+
525
+ #
526
+ # Function: SaveSymbolTable
527
+ #
528
+ # Saves <SymbolTable.nd> to disk.
529
+ #
530
+ sub SaveSymbolTable
531
+ {
532
+ my ($self) = @_;
533
+
534
+ open (SYMBOLTABLE_FILEHANDLE, '>' . NaturalDocs::Project->DataFile('SymbolTable.nd'))
535
+ or die "Couldn't save " . NaturalDocs::Project->DataFile('SymbolTable.nd') . ".\n";
536
+
537
+ binmode(SYMBOLTABLE_FILEHANDLE);
538
+
539
+ print SYMBOLTABLE_FILEHANDLE '' . ::BINARY_FORMAT();
540
+
541
+ NaturalDocs::Version->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, NaturalDocs::Settings->AppVersion());
542
+
543
+
544
+ # Symbols
545
+
546
+ while (my ($symbol, $symbolObject) = each %symbols)
547
+ {
548
+ # Only existing symbols.
549
+ if ($symbolObject->IsDefined())
550
+ {
551
+ # [SymbolString: symbol or undef to end]
552
+
553
+ NaturalDocs::SymbolString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, $symbol);
554
+
555
+ # [UInt16: number of definitions]
556
+
557
+ my @definitions = $symbolObject->Definitions();
558
+ print SYMBOLTABLE_FILEHANDLE pack('n', scalar @definitions);
559
+
560
+ # [AString16: global definition file] [AString16: TopicType]
561
+
562
+ print SYMBOLTABLE_FILEHANDLE pack('nA*nA*', length $symbolObject->GlobalDefinition(),
563
+ $symbolObject->GlobalDefinition(),
564
+ length $symbolObject->GlobalType(),
565
+ $symbolObject->GlobalType());
566
+
567
+ # [AString16: prototype]
568
+
569
+ my $prototype = $symbolObject->GlobalPrototype();
570
+
571
+ if (defined $prototype)
572
+ { print SYMBOLTABLE_FILEHANDLE pack('nA*', length($prototype), $prototype); }
573
+ else
574
+ { print SYMBOLTABLE_FILEHANDLE pack('n', 0); };
575
+
576
+ # [AString16: summary]
577
+
578
+ my $summary = $symbolObject->GlobalSummary();
579
+
580
+ if (defined $summary)
581
+ { print SYMBOLTABLE_FILEHANDLE pack('nA*', length($summary), $summary); }
582
+ else
583
+ { print SYMBOLTABLE_FILEHANDLE pack('n', 0); };
584
+
585
+
586
+ foreach my $definition (@definitions)
587
+ {
588
+ if ($definition ne $symbolObject->GlobalDefinition())
589
+ {
590
+ # [AString16: definition file] [AString16: TopicType]
591
+
592
+ print SYMBOLTABLE_FILEHANDLE pack('nA*nA*', length $definition, $definition,
593
+ length $symbolObject->TypeDefinedIn($definition),
594
+ $symbolObject->TypeDefinedIn($definition));
595
+
596
+ # [AString16: prototype]
597
+
598
+ my $prototype = $symbolObject->PrototypeDefinedIn($definition);
599
+
600
+ if (defined $prototype)
601
+ { print SYMBOLTABLE_FILEHANDLE pack('nA*', length($prototype), $prototype); }
602
+ else
603
+ { print SYMBOLTABLE_FILEHANDLE pack('n', 0); };
604
+
605
+ # [AString16: summary]
606
+
607
+ my $summary = $symbolObject->SummaryDefinedIn($definition);
608
+
609
+ if (defined $summary)
610
+ { print SYMBOLTABLE_FILEHANDLE pack('nA*', length($summary), $summary); }
611
+ else
612
+ { print SYMBOLTABLE_FILEHANDLE pack('n', 0); };
613
+ };
614
+ };
615
+ };
616
+ };
617
+
618
+ # [SymbolString: symbol or undef to end]
619
+
620
+ NaturalDocs::SymbolString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, undef);
621
+
622
+
623
+ # References
624
+
625
+ while (my ($reference, $referenceObject) = each %references)
626
+ {
627
+ my $type = NaturalDocs::ReferenceString->TypeOf($reference);
628
+
629
+ if ($type == ::REFERENCE_TEXT())
630
+ {
631
+ # [ReferenceString (no type, resolving flags): reference or undef to end]
632
+
633
+ NaturalDocs::ReferenceString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, $reference,
634
+ ::BINARYREF_NOTYPE() | ::BINARYREF_NORESOLVINGFLAGS());
635
+
636
+ # [UInt8: number of definition files]
637
+
638
+ my @definitions = $referenceObject->Definitions();
639
+ print SYMBOLTABLE_FILEHANDLE pack('C', scalar @definitions);
640
+
641
+ # [AString16: definition file] [AString16: definition file] ...
642
+
643
+ foreach my $definition (@definitions)
644
+ {
645
+ print SYMBOLTABLE_FILEHANDLE pack('nA*', length($definition), $definition);
646
+ };
647
+ };
648
+ };
649
+
650
+ # [ReferenceString (no type, resolving flags): reference or undef to end]
651
+
652
+ NaturalDocs::ReferenceString->ToBinaryFile(\*SYMBOLTABLE_FILEHANDLE, undef,
653
+ ::BINARYREF_NOTYPE() | ::BINARYREF_NORESOLVINGFLAGS());
654
+
655
+ close(SYMBOLTABLE_FILEHANDLE);
656
+ };
657
+
658
+
659
+ #
660
+ # Function: SaveIndexInfo
661
+ #
662
+ # Saves <IndexInfo.nd> to disk.
663
+ #
664
+ sub SaveIndexInfo
665
+ {
666
+ my ($self) = @_;
667
+
668
+ NaturalDocs::BinaryFile->OpenForWriting( NaturalDocs::Project->DataFile('IndexInfo.nd') );
669
+
670
+ while (my ($topicType, $content) = each %indexSectionsWithContent)
671
+ {
672
+ NaturalDocs::BinaryFile->WriteAString16( NaturalDocs::Topics->NameOfType($topicType) );
673
+
674
+ for (my $i = 0; $i < 28; $i++)
675
+ {
676
+ if ($content->[$i])
677
+ { NaturalDocs::BinaryFile->WriteUInt8(1); }
678
+ else
679
+ { NaturalDocs::BinaryFile->WriteUInt8(0); };
680
+ };
681
+ };
682
+
683
+ NaturalDocs::BinaryFile->Close();
684
+ };
685
+
686
+
687
+
688
+ ###############################################################################
689
+ # Group: Modification Functions
690
+ # These functions should not be called after <PurgeResolvingInfo()>.
691
+
692
+ #
693
+ # Function: AddSymbol
694
+ #
695
+ # Adds a symbol definition to the table, if it doesn't already exist. If the definition changes or otherwise requires the files that
696
+ # reference it to be updated, the function will call <NaturalDocs::Project->RebuildFile()> to make sure that they are.
697
+ #
698
+ # Parameters:
699
+ #
700
+ # symbol - The <SymbolString>.
701
+ # file - The <FileName> where it's defined.
702
+ # type - The symbol's <TopicType>.
703
+ # prototype - The symbol's prototype, if applicable.
704
+ # summary - The symbol's summary, if applicable.
705
+ #
706
+ sub AddSymbol #(symbol, file, type, prototype, summary)
707
+ {
708
+ my ($self, $symbol, $file, $type, $prototype, $summary) = @_;
709
+
710
+
711
+ # If the symbol doesn't exist...
712
+ if (!exists $symbols{$symbol})
713
+ {
714
+ # Create the symbol. There are no references that could be interpreted as this or else it would have existed already.
715
+
716
+ my $newSymbol = NaturalDocs::SymbolTable::Symbol->New();
717
+ $newSymbol->AddDefinition($file, $type, $prototype, $summary);
718
+
719
+ $symbols{$symbol} = $newSymbol;
720
+
721
+ $self->OnIndexChange($type);
722
+ NaturalDocs::Project->RebuildFile($file);
723
+ }
724
+
725
+
726
+ # If the symbol already exists...
727
+ else
728
+ {
729
+ my $symbolObject = $symbols{$symbol};
730
+
731
+ # If the symbol isn't defined, i.e. it was a potential interpretation only...
732
+ if (!$symbolObject->IsDefined())
733
+ {
734
+ $symbolObject->AddDefinition($file, $type, $prototype, $summary);
735
+
736
+ # See if this symbol provides a better interpretation of any references. We can assume this symbol has interpretations
737
+ # because the object won't exist without either that or definitions.
738
+
739
+ my %referencesAndScores = $symbolObject->ReferencesAndScores();
740
+
741
+ while (my ($referenceString, $referenceScore) = each %referencesAndScores)
742
+ {
743
+ my $referenceObject = $references{$referenceString};
744
+
745
+ if (!$referenceObject->HasCurrentInterpretation() ||
746
+ $referenceScore > $referenceObject->CurrentScore())
747
+ {
748
+ $referenceObject->SetCurrentInterpretation($symbol);
749
+ $self->OnInterpretationChange($referenceString);
750
+ };
751
+ };
752
+
753
+ $self->OnIndexChange($type);
754
+ NaturalDocs::Project->RebuildFile($file);
755
+ }
756
+
757
+ # If the symbol is defined but not in this file...
758
+ elsif (!$symbolObject->IsDefinedIn($file))
759
+ {
760
+ $symbolObject->AddDefinition($file, $type, $prototype, $summary);
761
+
762
+ $self->OnIndexChange($type);
763
+ NaturalDocs::Project->RebuildFile($file);
764
+
765
+ # We don't have to check other files because if the symbol is defined it already has a global definiton,
766
+ # and everything else is either using that or its own definition, and thus wouldn't be affected by this.
767
+ };
768
+
769
+ # If the symbol was already defined in this file, ignore it.
770
+
771
+ };
772
+
773
+
774
+ # Add it to the file index.
775
+
776
+ if (!exists $files{$file})
777
+ { $files{$file} = NaturalDocs::SymbolTable::File->New(); };
778
+
779
+ $files{$file}->AddSymbol($symbol);
780
+
781
+
782
+ # Add it to the watched file, if necessary.
783
+
784
+ if (defined $watchedFileName)
785
+ {
786
+ $watchedFile->AddSymbol($symbol);
787
+
788
+ if (!exists $watchedFileSymbolDefinitions{$symbol})
789
+ {
790
+ $watchedFileSymbolDefinitions{$symbol} =
791
+ NaturalDocs::SymbolTable::SymbolDefinition->New($type, $prototype, $summary);
792
+ };
793
+ };
794
+ };
795
+
796
+
797
+ #
798
+ # Function: AddReference
799
+ #
800
+ # Adds a reference to the table, if it doesn't already exist.
801
+ #
802
+ # Parameters:
803
+ #
804
+ # type - The <ReferenceType>.
805
+ # symbol - The reference <SymbolString>.
806
+ # scope - The scope <SymbolString> it appears in.
807
+ # using - An arrayref of scope <SymbolStrings> accessible to the reference via "using" statements, or undef if none.
808
+ # file - The <FileName> where the reference appears. This is not required unless the type is <REFERENCE_TEXT>.
809
+ # resolvingFlags - The <Resolving Flags> of the reference. They will be ignored if the type is <REFERENCE_TEXT>.
810
+ #
811
+ # Alternate Parameters:
812
+ #
813
+ # referenceString - The <ReferenceString> to add.
814
+ # file - The <FileName> where the reference appears. This is not required unless the type is <REFERENCE_TEXT>.
815
+ #
816
+ sub AddReference #(type, symbol, scope, using, file, resolvingFlags) or (referenceString, file)
817
+ {
818
+ my ($self, $referenceString, $file);
819
+
820
+ if (scalar @_ <= 3)
821
+ {
822
+ ($self, $referenceString, $file) = @_;
823
+ }
824
+ else
825
+ {
826
+ my ($type, $symbol, $scope, $using, $resolvingFlags);
827
+ ($self, $type, $symbol, $scope, $using, $file, $resolvingFlags) = @_;
828
+
829
+ $referenceString = NaturalDocs::ReferenceString->MakeFrom($type, $symbol,
830
+ NaturalDocs::Languages->LanguageOf($file)->Name(),
831
+ $scope, $using, $resolvingFlags);
832
+ };
833
+
834
+
835
+ # If the reference doesn't exist...
836
+ if (!exists $references{$referenceString})
837
+ {
838
+ my $referenceObject = NaturalDocs::SymbolTable::Reference->New();
839
+
840
+ $references{$referenceString} = $referenceObject;
841
+
842
+ $self->GenerateInterpretations($referenceString);
843
+ $self->InterpretReference($referenceString);
844
+ }
845
+
846
+
847
+ if (defined $file)
848
+ {
849
+ $references{$referenceString}->AddDefinition($file);
850
+
851
+
852
+ # Add it to the file index.
853
+
854
+ if (!exists $files{$file})
855
+ { $files{$file} = NaturalDocs::SymbolTable::File->New(); };
856
+
857
+ $files{$file}->AddReference($referenceString);
858
+
859
+
860
+ # Add it to the watched file, if necessary.
861
+
862
+ if (defined $watchedFileName)
863
+ { $watchedFile->AddReference($referenceString); };
864
+ };
865
+ };
866
+
867
+
868
+ #
869
+ # Function: WatchFileForChanges
870
+ #
871
+ # Tracks a file to see if any symbols or references were changed or deleted in ways that would require other files to be rebuilt.
872
+ # Assumes that after this function call, the entire file will be parsed again, and thus every symbol and reference will go through
873
+ # <AddSymbol()> and <AddReference()>. Afterwards, call <AnalyzeChanges()> to handle any differences.
874
+ #
875
+ # Parameters:
876
+ #
877
+ # file - The <FileName> to watch.
878
+ #
879
+ sub WatchFileForChanges #(file)
880
+ {
881
+ my ($self, $file) = @_;
882
+
883
+ $watchedFile = NaturalDocs::SymbolTable::File->New();
884
+ $watchedFileName = $file;
885
+ %watchedFileSymbolDefinitions = ( );
886
+ };
887
+
888
+
889
+ #
890
+ # Function: AnalyzeChanges
891
+ #
892
+ # Handles any changes found when reparsing a file using <WatchFileForChanges()>.
893
+ #
894
+ sub AnalyzeChanges
895
+ {
896
+ my ($self) = @_;
897
+
898
+ if (exists $files{$watchedFileName})
899
+ {
900
+
901
+ # Go through the references and remove any that were deleted. Ones that were added will have already been added to
902
+ # the table in AddReference().
903
+
904
+ my @references = $files{$watchedFileName}->References();
905
+ foreach my $reference (@references)
906
+ {
907
+ if (!$watchedFile->DefinesReference($reference))
908
+ { $self->DeleteReference($reference, $watchedFileName); };
909
+ };
910
+ };
911
+
912
+ # We have to check if the watched file exists again because DeleteReference() could have removed it. I'm still not sure how a
913
+ # file could have references without symbols, but apparently it's happened in the real world because it's crashed on people.
914
+ if (exists $files{$watchedFileName})
915
+ {
916
+ # Go through the symbols.
917
+
918
+ my $rebuildFile;
919
+
920
+ my @symbols = $files{$watchedFileName}->Symbols();
921
+ foreach my $symbol (@symbols)
922
+ {
923
+ # Delete symbols that don't exist.
924
+
925
+ if (!$watchedFile->DefinesSymbol($symbol))
926
+ {
927
+ $self->DeleteSymbol($symbol, $watchedFileName);
928
+ $rebuildFile = 1;
929
+ }
930
+
931
+ else
932
+ {
933
+ my $symbolObject = $symbols{$symbol};
934
+ my $newSymbolDef = $watchedFileSymbolDefinitions{$symbol};
935
+
936
+ # Update symbols that changed.
937
+
938
+ if ( $symbolObject->TypeDefinedIn($watchedFileName) ne $newSymbolDef->Type() ||
939
+ $symbolObject->PrototypeDefinedIn($watchedFileName) ne $newSymbolDef->Prototype() ||
940
+ $symbolObject->SummaryDefinedIn($watchedFileName) ne $newSymbolDef->Summary() )
941
+ {
942
+ $self->OnIndexChange($symbolObject->TypeDefinedIn($watchedFileName));
943
+ $self->OnIndexChange($newSymbolDef->Type());
944
+ $rebuildFile = 1;
945
+
946
+ $symbolObject->ChangeDefinition($watchedFileName, $newSymbolDef->Type(), $newSymbolDef->Prototype(),
947
+ $newSymbolDef->Summary());
948
+
949
+ # If the symbol definition was the global one, we need to update all files that reference it. If it wasn't, the only file
950
+ # that could references it is itself, and the only way the symbol definition could change in the first place was if it was
951
+ # itself changed.
952
+ if ($symbolObject->GlobalDefinition() eq $watchedFileName)
953
+ {
954
+ # Rebuild the files that have references to this symbol
955
+ my @references = $symbolObject->References();
956
+ foreach my $reference (@references)
957
+ {
958
+ if ($references{$reference}->CurrentInterpretation() eq $symbol)
959
+ { $self->OnTargetSymbolChange($reference); };
960
+ }; # While references
961
+ }; # If global definition is watched file
962
+ }; # If the symbol definition changed
963
+ }; # If the symbol still exists
964
+ }; # foreach symbol in watched file
965
+
966
+ if ($rebuildFile)
967
+ { NaturalDocs::Project->RebuildFile($watchedFileName); };
968
+
969
+ };
970
+
971
+
972
+ $watchedFile = undef;
973
+ $watchedFileName = undef;
974
+ %watchedFileSymbolDefinitions = ( );
975
+ };
976
+
977
+
978
+ #
979
+ # Function: DeleteReference
980
+ #
981
+ # Deletes a reference from the table.
982
+ #
983
+ # Be careful with this function, as deleting a reference means there are no more of them in the file at all. The tables do not
984
+ # keep track of how many times references appear in a file. In these cases you should instead call <WatchFileForChanges()>,
985
+ # reparse the file, thus readding all the references, and call <AnalyzeChanges()>.
986
+ #
987
+ # <REFERENCE_TEXT> references should *always* be managed with <WatchFileForChanges()> and <AnalyzeChanges()>.
988
+ # This function should only be used externally for other types of references.
989
+ #
990
+ # Parameters:
991
+ #
992
+ # referenceString - The <ReferenceString>.
993
+ # file - The <FileName> where the reference is. This is not required unless the type is <REFERENCE_TEXT>.
994
+ #
995
+ sub DeleteReference #(referenceString, file)
996
+ {
997
+ my ($self, $referenceString, $file) = @_;
998
+
999
+
1000
+ # If the reference exists...
1001
+ if (exists $references{$referenceString})
1002
+ {
1003
+ my $referenceObject = $references{$referenceString};
1004
+
1005
+ if (defined $file)
1006
+ { $referenceObject->DeleteDefinition($file); };
1007
+
1008
+ # If there are no other definitions, or it doesn't use file definitions to begin with...
1009
+ if (!$referenceObject->IsDefined())
1010
+ {
1011
+ my @interpretations = $referenceObject->Interpretations();
1012
+ foreach my $interpretation (@interpretations)
1013
+ {
1014
+ $symbols{$interpretation}->DeleteReference($referenceString);
1015
+ };
1016
+
1017
+ delete $references{$referenceString};
1018
+ };
1019
+
1020
+
1021
+ if (defined $file)
1022
+ {
1023
+ # Remove it from the file index.
1024
+
1025
+ $files{$file}->DeleteReference($referenceString);
1026
+
1027
+ if (!$files{$file}->HasAnything())
1028
+ { delete $files{$file}; };
1029
+
1030
+ # We don't need to worry about the watched file, since this function will only be called by AnalyzeChanges() and
1031
+ # LoadAndPurge().
1032
+ };
1033
+ };
1034
+ };
1035
+
1036
+
1037
+ #
1038
+ # Function: RebuildAllIndexes
1039
+ #
1040
+ # When called, it makes sure all indexes are listed as changed by <IndexChanged()>, regardless of whether they actually did
1041
+ # or not.
1042
+ #
1043
+ # This can be called at any time.
1044
+ #
1045
+ sub RebuildAllIndexes
1046
+ {
1047
+ my $self = shift;
1048
+ $rebuildIndexes = 1;
1049
+ };
1050
+
1051
+
1052
+ #
1053
+ # Function: PurgeResolvingInfo
1054
+ #
1055
+ # Purges unnecessary information from the symbol table after it is fully resolved. This will reduce the memory footprint for the
1056
+ # build stage. After calling this function, you can only call the <Information Functions> and <Save()>.
1057
+ #
1058
+ sub PurgeResolvingInfo
1059
+ {
1060
+ my ($self) = @_;
1061
+
1062
+ # Go through the symbols. We don't need to keep around potential symbols anymore, nor do we need what references can
1063
+ # be interpreted as the defined ones.
1064
+
1065
+ while (my ($symbol, $symbolObject) = each %symbols)
1066
+ {
1067
+ if ($symbolObject->IsDefined())
1068
+ { $symbolObject->DeleteAllReferences(); }
1069
+ else
1070
+ { delete $symbols{$symbol}; };
1071
+ };
1072
+
1073
+
1074
+ # Go through the references. We don't need any of the interpretations except for the current.
1075
+
1076
+ foreach my $referenceObject (values %references)
1077
+ { $referenceObject->DeleteAllInterpretationsButCurrent(); };
1078
+
1079
+
1080
+ # We don't need the information by file at all.
1081
+
1082
+ %files = ( );
1083
+ };
1084
+
1085
+
1086
+ #
1087
+ # Function: PurgeIndexes
1088
+ #
1089
+ # Clears all generated indexes.
1090
+ #
1091
+ sub PurgeIndexes
1092
+ {
1093
+ my ($self) = @_;
1094
+ %indexes = ( );
1095
+ };
1096
+
1097
+
1098
+ ###############################################################################
1099
+ # Group: Information Functions
1100
+ # These functions should not be called until the symbol table is fully resolved.
1101
+
1102
+
1103
+ #
1104
+ # Function: References
1105
+ #
1106
+ # Returns what the passed reference information resolve to, if anything. Note that this only works if the reference had
1107
+ # been previously added to the table via <AddReference()> with the exact same parameters.
1108
+ #
1109
+ # Parameters:
1110
+ #
1111
+ # type - The <ReferenceType>.
1112
+ # symbol - The reference <SymbolString>.
1113
+ # scope - The scope <SymbolString> the reference appears in, or undef if none.
1114
+ # using - An arrayref of scope <SymbolStrings> available to the reference via using statements.
1115
+ # file - The source <FileName> the reference appears in, or undef if none.
1116
+ # resolvingFlags - The <Resolving Flags> of the reference. Ignored if the type is <REFERENCE_TEXT>.
1117
+ #
1118
+ # Alternate Parameters:
1119
+ #
1120
+ # referenceString - The <ReferenceString> to resolve.
1121
+ # file - The source <FileName> the reference appears in, or undef if none.
1122
+ #
1123
+ # Returns:
1124
+ #
1125
+ # A <NaturalDocs::SymbolTable::ReferenceTarget> object, or undef if the reference doesn't resolve to anything.
1126
+ #
1127
+ sub References #(type, symbol, scope, using, file, resolvingFlags) or (referenceString, file)
1128
+ {
1129
+ my ($self, $referenceString, $file);
1130
+
1131
+ if (scalar @_ <= 3)
1132
+ { ($self, $referenceString, $file) = @_; }
1133
+ else
1134
+ {
1135
+ my ($type, $symbol, $scope, $using, $resolvingFlags);
1136
+ ($self, $type, $symbol, $scope, $using, $file, $resolvingFlags) = @_;
1137
+
1138
+ $referenceString = NaturalDocs::ReferenceString->MakeFrom($type, $symbol,
1139
+ NaturalDocs::Languages->LanguageOf($file)->Name(),
1140
+ $scope, $using, $resolvingFlags);
1141
+ };
1142
+
1143
+ if (exists $references{$referenceString} && $references{$referenceString}->HasCurrentInterpretation())
1144
+ {
1145
+ my $targetSymbol = $references{$referenceString}->CurrentInterpretation();
1146
+ my $targetObject = $symbols{$targetSymbol};
1147
+
1148
+ my $targetFile;
1149
+ my $targetType;
1150
+ my $targetPrototype;
1151
+ my $targetSummary;
1152
+
1153
+ if (defined $file && $targetObject->IsDefinedIn($file))
1154
+ {
1155
+ $targetFile = $file;
1156
+ $targetType = $targetObject->TypeDefinedIn($file);
1157
+ $targetPrototype = $targetObject->PrototypeDefinedIn($file);
1158
+ $targetSummary = $targetObject->SummaryDefinedIn($file);
1159
+ }
1160
+ else
1161
+ {
1162
+ $targetFile = $targetObject->GlobalDefinition();
1163
+ $targetType = $targetObject->GlobalType();
1164
+ $targetPrototype = $targetObject->GlobalPrototype();
1165
+ $targetSummary = $targetObject->GlobalSummary();
1166
+ };
1167
+
1168
+ return NaturalDocs::SymbolTable::ReferenceTarget->New($targetSymbol, $targetFile, $targetType, $targetPrototype,
1169
+ $targetSummary);
1170
+ }
1171
+
1172
+ else
1173
+ { return undef; };
1174
+ };
1175
+
1176
+
1177
+ #
1178
+ # Function: Lookup
1179
+ #
1180
+ # Returns information on the passed <SymbolString>, if it exists. Note that the symbol must be fully resolved.
1181
+ #
1182
+ # Parameters:
1183
+ #
1184
+ # symbol - The <SymbolString>.
1185
+ # file - The source <FileName> the reference appears in, or undef if none.
1186
+ #
1187
+ # Returns:
1188
+ #
1189
+ # A <NaturalDocs::SymbolTable::ReferenceTarget> object, or undef if the symbol isn't defined.
1190
+ #
1191
+ sub Lookup #(symbol, file)
1192
+ {
1193
+ my ($self, $symbol, $file) = @_;
1194
+
1195
+ my $symbolObject = $symbols{$symbol};
1196
+
1197
+ if (defined $symbolObject)
1198
+ {
1199
+ my $targetFile;
1200
+ my $targetType;
1201
+ my $targetPrototype;
1202
+ my $targetSummary;
1203
+
1204
+ if (defined $file && $symbolObject->IsDefinedIn($file))
1205
+ {
1206
+ $targetFile = $file;
1207
+ $targetType = $symbolObject->TypeDefinedIn($file);
1208
+ $targetPrototype = $symbolObject->PrototypeDefinedIn($file);
1209
+ $targetSummary = $symbolObject->SummaryDefinedIn($file);
1210
+ }
1211
+ else
1212
+ {
1213
+ $targetFile = $symbolObject->GlobalDefinition();
1214
+ $targetType = $symbolObject->GlobalType();
1215
+ $targetPrototype = $symbolObject->GlobalPrototype();
1216
+ $targetSummary = $symbolObject->GlobalSummary();
1217
+ };
1218
+
1219
+ return NaturalDocs::SymbolTable::ReferenceTarget->New($symbol, $targetFile, $targetType, $targetPrototype,
1220
+ $targetSummary);
1221
+ }
1222
+
1223
+ else
1224
+ { return undef; };
1225
+ };
1226
+
1227
+
1228
+ #
1229
+ # Function: Index
1230
+ #
1231
+ # Returns a symbol index.
1232
+ #
1233
+ # Indexes are generated on demand, but they are stored so subsequent calls for the same index will be fast. Call
1234
+ # <PurgeIndexes()> to clear the generated indexes.
1235
+ #
1236
+ # Parameters:
1237
+ #
1238
+ # type - The <TopicType> of symbol to limit the index to, or undef for none.
1239
+ #
1240
+ # Returns:
1241
+ #
1242
+ # An arrayref of sections. The first represents all the symbols, the second the numbers, and the rest A through Z.
1243
+ # Each section is a sorted arrayref of <NaturalDocs::SymbolTable::IndexElement> objects. If a section has no content,
1244
+ # it will be undef.
1245
+ #
1246
+ sub Index #(type)
1247
+ {
1248
+ my ($self, $type) = @_;
1249
+
1250
+ if (!exists $indexes{$type})
1251
+ { $indexes{$type} = $self->MakeIndex($type); };
1252
+
1253
+ return $indexes{$type};
1254
+ };
1255
+
1256
+
1257
+ #
1258
+ # Function: HasIndexes
1259
+ #
1260
+ # Determines which indexes out of a list actually have content.
1261
+ #
1262
+ # Parameters:
1263
+ #
1264
+ # types - An existence hashref of the <TopicTypes> to check for indexes.
1265
+ #
1266
+ # Returns:
1267
+ #
1268
+ # An existence hashref of all the specified indexes that have content. Will return an empty hashref if none.
1269
+ #
1270
+ sub HasIndexes #(types)
1271
+ {
1272
+ my ($self, $types) = @_;
1273
+
1274
+ # EliminationHash is a copy of all the types, and the types will be deleted as they are found. This allows us to quit early if
1275
+ # we've found all the types because the hash will be empty. We'll later return the original hash minus what was left over
1276
+ # in here, which are the ones that weren't found.
1277
+ my %eliminationHash = %$types;
1278
+
1279
+ finddefs:
1280
+ foreach my $symbolObject (values %symbols)
1281
+ {
1282
+ foreach my $definition ($symbolObject->Definitions())
1283
+ {
1284
+ delete $eliminationHash{ $symbolObject->TypeDefinedIn($definition) };
1285
+ delete $eliminationHash{ ::TOPIC_GENERAL() };
1286
+
1287
+ if (!scalar keys %eliminationHash)
1288
+ { last finddefs; };
1289
+ };
1290
+ };
1291
+
1292
+ my $result = { %$types };
1293
+
1294
+ foreach my $type (keys %eliminationHash)
1295
+ { delete $result->{$type}; };
1296
+
1297
+ return $result;
1298
+ };
1299
+
1300
+
1301
+ #
1302
+ # Function: IndexChanged
1303
+ #
1304
+ # Returns whether the specified index has changed.
1305
+ #
1306
+ # Parameters:
1307
+ #
1308
+ # type - The <TopicType> to limit the index to.
1309
+ #
1310
+ sub IndexChanged #(TopicType type)
1311
+ {
1312
+ my ($self, $type) = @_;
1313
+ return ($rebuildIndexes || defined $indexChanges{$type});
1314
+ };
1315
+
1316
+
1317
+ #
1318
+ # Function: IndexSectionsWithContent
1319
+ #
1320
+ # Returns an arrayref of whether each section of the specified index has content. The first entry will be for symbols, the second
1321
+ # for numbers, and the rest A-Z. Do not change the arrayref.
1322
+ #
1323
+ sub IndexSectionsWithContent #(TopicType type)
1324
+ {
1325
+ my ($self, $type) = @_;
1326
+
1327
+ if (!exists $indexSectionsWithContent{$type})
1328
+ {
1329
+ # This is okay because Index() stores generated indexes. It's not an expensive operation unless the index was never asked
1330
+ # for before or it will never be asked for otherwise, and this shouldn't be the case.
1331
+
1332
+ my $index = $self->Index($type);
1333
+ my $content = [ ];
1334
+
1335
+ for (my $i = 0; $i < 28; $i++)
1336
+ {
1337
+ push @$content, (defined $index->[$i] ? 1 : 0);
1338
+ };
1339
+
1340
+ $indexSectionsWithContent{$type} = $content;
1341
+ };
1342
+
1343
+ return $indexSectionsWithContent{$type};
1344
+ };
1345
+
1346
+
1347
+
1348
+ ###############################################################################
1349
+ # Group: Event Handlers
1350
+
1351
+
1352
+ #
1353
+ # Function: OnIndexChange
1354
+ #
1355
+ # Called whenever a change happens to a symbol that would cause an index to be regenerated.
1356
+ #
1357
+ # Parameters:
1358
+ #
1359
+ # type - The <TopicType> of the symbol that caused the change.
1360
+ #
1361
+ sub OnIndexChange #(TopicType type)
1362
+ {
1363
+ my ($self, $type) = @_;
1364
+
1365
+ $indexChanges{$type} = 1;
1366
+ $indexChanges{::TOPIC_GENERAL()} = 1;
1367
+ delete $indexSectionsWithContent{$type};
1368
+ };
1369
+
1370
+
1371
+ #
1372
+ # Function: OnInterpretationChange
1373
+ #
1374
+ # Called whenever the current interpretation of a reference changes, meaning it switched from one symbol to another.
1375
+ #
1376
+ # Parameters:
1377
+ #
1378
+ # referenceString - The <ReferenceString> whose current interpretation changed.
1379
+ #
1380
+ sub OnInterpretationChange #(referenceString)
1381
+ {
1382
+ my ($self, $referenceString) = @_;
1383
+ my $referenceType = NaturalDocs::ReferenceString->TypeOf($referenceString);
1384
+
1385
+ if ($referenceType == ::REFERENCE_TEXT())
1386
+ {
1387
+ my @referenceDefinitions = $references{$referenceString}->Definitions();
1388
+
1389
+ foreach my $referenceDefinition (@referenceDefinitions)
1390
+ {
1391
+ NaturalDocs::Project->RebuildFile($referenceDefinition);
1392
+ };
1393
+ }
1394
+
1395
+ elsif (NaturalDocs::Constants->IsClassHierarchyReference($referenceType))
1396
+ {
1397
+ NaturalDocs::ClassHierarchy->OnInterpretationChange($referenceString);
1398
+ };
1399
+ };
1400
+
1401
+
1402
+ #
1403
+ # Function: OnTargetSymbolChange
1404
+ #
1405
+ # Called whenever the symbol that serves as the interpretation of a reference changes, but the reference still resolves to
1406
+ # the same symbol. This would happen if the type, prototype, summary, or which file serves as global definition of the symbol
1407
+ # changes.
1408
+ #
1409
+ # Parameters:
1410
+ #
1411
+ # referenceString - The <ReferenceString> whose interpretation's symbol changed.
1412
+ #
1413
+ sub OnTargetSymbolChange #(referenceString)
1414
+ {
1415
+ my ($self, $referenceString) = @_;
1416
+ my $referenceType = NaturalDocs::ReferenceString->TypeOf($referenceString);
1417
+
1418
+ if ($referenceType == ::REFERENCE_TEXT())
1419
+ {
1420
+ my @referenceDefinitions = $references{$referenceString}->Definitions();
1421
+
1422
+ foreach my $referenceDefinition (@referenceDefinitions)
1423
+ {
1424
+ NaturalDocs::Project->RebuildFile($referenceDefinition);
1425
+ };
1426
+ }
1427
+
1428
+ elsif (NaturalDocs::Constants->IsClassHierarchyReference($referenceType))
1429
+ {
1430
+ NaturalDocs::ClassHierarchy->OnTargetSymbolChange($referenceString);
1431
+ };
1432
+ };
1433
+
1434
+
1435
+
1436
+ ###############################################################################
1437
+ # Group: Support Functions
1438
+
1439
+
1440
+ #
1441
+ # Function: DeleteSymbol
1442
+ #
1443
+ # Removes a symbol definition from the table. It will call <OnInterpretationChange()> for all references that have it as their
1444
+ # current interpretation.
1445
+ #
1446
+ # External code should not attempt to delete symbols using this function. Instead it should call <WatchFileFoChanges()>,
1447
+ # reparse the file, and call <AnalyzeChanges()>.
1448
+ #
1449
+ # Parameters:
1450
+ #
1451
+ # symbol - The <SymbolString>.
1452
+ # file - The <FileName> where the definition is.
1453
+ #
1454
+ sub DeleteSymbol #(symbol, file)
1455
+ {
1456
+ my ($self, $symbol, $file) = @_;
1457
+
1458
+
1459
+ # If the symbol and definition exist...
1460
+ if (exists $symbols{$symbol} && $symbols{$symbol}->IsDefinedIn($file))
1461
+ {
1462
+ my $symbolObject = $symbols{$symbol};
1463
+ my $wasGlobal = ($symbolObject->GlobalDefinition() eq $file);
1464
+
1465
+ $self->OnIndexChange($symbolObject->TypeDefinedIn($file));
1466
+
1467
+ $symbolObject->DeleteDefinition($file);
1468
+
1469
+ # If this was one definition of many...
1470
+ if ($symbolObject->IsDefined())
1471
+ {
1472
+
1473
+ # If this was the global definition...
1474
+ if ($wasGlobal)
1475
+ {
1476
+ # Update every file that referenced the global symbol; i.e. every file that doesn't have its own definition.
1477
+
1478
+ my @references = $symbolObject->References();
1479
+
1480
+ foreach my $reference (@references)
1481
+ {
1482
+ if ($references{$reference}->CurrentInterpretation() eq $symbol)
1483
+ {
1484
+ $self->OnTargetSymbolChange($reference);
1485
+ };
1486
+ };
1487
+ }
1488
+
1489
+ # If this wasn't the global definition...
1490
+ else
1491
+ {
1492
+ # It's a safe bet that we don't need to do anything here. The only thing that we even need to look for here is if the
1493
+ # file referenced its own symbol and thus should be rebuilt. However, if the file is having a symbol deleted, it either
1494
+ # changed or was itself deleted. If it changed and still has other Natural Docs content, it should already be on the
1495
+ # rebuild list. If it was deleted or no longer has Natural Docs content, we certainly don't want to add it to the rebuild
1496
+ # list.
1497
+ };
1498
+ }
1499
+
1500
+ # If this is the only definition...
1501
+ else
1502
+ {
1503
+ # If this symbol is the interpretation of any references...
1504
+ if ($symbolObject->HasReferences())
1505
+ {
1506
+ # If this was the current interpretation of any references, reinterpret them and rebuild their files.
1507
+
1508
+ my @references = $symbolObject->References();
1509
+
1510
+ foreach my $reference (@references)
1511
+ {
1512
+ if ($references{$reference}->CurrentInterpretation() eq $symbol)
1513
+ {
1514
+ $self->InterpretReference($reference);
1515
+ $self->OnInterpretationChange($reference);
1516
+ };
1517
+ };
1518
+ }
1519
+
1520
+ # If there are no interpretations of the symbol...
1521
+ else
1522
+ {
1523
+ # Delete the symbol entirely.
1524
+ delete $symbols{$symbol};
1525
+ };
1526
+ };
1527
+
1528
+ # Remove it from the file index.
1529
+
1530
+ $files{$file}->DeleteSymbol($symbol);
1531
+
1532
+ if (!$files{$file}->HasAnything())
1533
+ { delete $files{$file}; };
1534
+
1535
+
1536
+ # We don't need to worry about the watched file, since this function will only be called by AnalyzeChanges() and
1537
+ # LoadAndPurge().
1538
+ };
1539
+ };
1540
+
1541
+
1542
+ #
1543
+ # Function: GenerateInterpretations
1544
+ #
1545
+ # Generates the list of interpretations for the passed reference. Also creates potential symbols as necessary.
1546
+ #
1547
+ # Parameters:
1548
+ #
1549
+ # referenceString - The <ReferenceString> to generate the interpretations of.
1550
+ #
1551
+ sub GenerateInterpretations #(referenceString)
1552
+ {
1553
+ my ($self, $referenceString) = @_;
1554
+
1555
+ my ($type, $symbol, $languageName, $scope, $using, $resolvingFlags) =
1556
+ NaturalDocs::ReferenceString->InformationOf($referenceString);
1557
+
1558
+ # RESOLVE_NOPLURAL is handled by having @singulars be empty.
1559
+ my @singulars;
1560
+ if (!($resolvingFlags & ::RESOLVE_NOPLURAL()))
1561
+ { @singulars = $self->SingularInterpretationsOf($symbol); };
1562
+
1563
+ # Since higher scores are better, we'll start at a high number and decrement.
1564
+ my $score = 50000;
1565
+
1566
+
1567
+ # If RESOLVE_RELATIVE is set, we do all the scope relatives before the global.
1568
+ if ($resolvingFlags & ::RESOLVE_RELATIVE())
1569
+ {
1570
+ $score = $self->GenerateRelativeInterpretations($referenceString, $symbol, \@singulars, $scope, $score);
1571
+ }
1572
+
1573
+ # If neither RESOLVE_RELATIVE nor RESOLVE_ABSOLUTE is set, we only do the local before the global.
1574
+ elsif (!($resolvingFlags & ::RESOLVE_ABSOLUTE()))
1575
+ {
1576
+ $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($scope, $symbol), $score);
1577
+ $score--;
1578
+
1579
+ foreach my $singular (@singulars)
1580
+ {
1581
+ $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($scope, $singular), $score);
1582
+ $score--;
1583
+ };
1584
+ };
1585
+
1586
+
1587
+ # Do the global.
1588
+
1589
+ $self->AddInterpretation($referenceString, $symbol, $score);
1590
+ $score--;
1591
+
1592
+ foreach my $singular (@singulars)
1593
+ {
1594
+ $self->AddInterpretation($referenceString, $singular, $score);
1595
+ $score--;
1596
+ };
1597
+
1598
+
1599
+ # If neither RESOLVE_RELATIVE nor RESOLVE_ABSOLUTE is set, we need to do the rest of the scope relatives after the global.
1600
+ if (!($resolvingFlags & ::RESOLVE_RELATIVE()) && !($resolvingFlags & ::RESOLVE_ABSOLUTE()))
1601
+ {
1602
+ $score = $self->GenerateRelativeInterpretations($referenceString, $symbol, \@singulars, $scope, $score, 1);
1603
+ };
1604
+
1605
+
1606
+ # Finally, if RESOLVE_NOUSING isn't set, go through the using scopes.
1607
+ if (!($resolvingFlags & ::RESOLVE_NOUSING()) && defined $using)
1608
+ {
1609
+ foreach my $usingScope (@$using)
1610
+ {
1611
+ if ($resolvingFlags & ::RESOLVE_ABSOLUTE())
1612
+ {
1613
+ $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($usingScope, $symbol), $score);
1614
+ $score--;
1615
+
1616
+ foreach my $singular (@singulars)
1617
+ {
1618
+ $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join($usingScope, $singular), $score);
1619
+ $score--;
1620
+ };
1621
+ }
1622
+ else
1623
+ {
1624
+ $score = $self->GenerateRelativeInterpretations($referenceString, $symbol, \@singulars, $usingScope, $score);
1625
+ };
1626
+ };
1627
+ };
1628
+ };
1629
+
1630
+
1631
+ #
1632
+ # Function: GenerateRelativeInterpretations
1633
+ #
1634
+ # Generates the list of relative interpretations for the passed reference and packages. Also creates potential symbols as
1635
+ # necessary.
1636
+ #
1637
+ # This function will _not_ create global interpretations. It _will_ create a local interpretations (symbol + all packages) unless
1638
+ # you set dontUseFull.
1639
+ #
1640
+ # Parameters:
1641
+ #
1642
+ # referenceString - The <ReferenceString> to generate interpretations for.
1643
+ # symbol - The <SymbolString> to generate interpretations of.
1644
+ # singulars - A reference to an array of singular <SymbolStrings> to also generate interpretations of. Set to an empty array
1645
+ # if none.
1646
+ # package - The package <SymbolString> to use. May be undef.
1647
+ # score - The starting score to apply.
1648
+ # dontUseFull - Whether to not generate an interpretation including the full package identifier. If set, generated interpretations
1649
+ # will start one level down.
1650
+ #
1651
+ # Returns:
1652
+ #
1653
+ # The next unused score. This is basically the passed score minus the number of interpretations created.
1654
+ #
1655
+ sub GenerateRelativeInterpretations #(referenceString, symbol, singulars, package, score, dontUseFull)
1656
+ {
1657
+ my ($self, $referenceString, $symbol, $singulars, $package, $score, $dontUseFull) = @_;
1658
+
1659
+ my @packages = NaturalDocs::SymbolString->IdentifiersOf($package);
1660
+
1661
+ # The last package index to include. This number is INCLUSIVE!
1662
+ my $packageLevel = scalar @packages - 1;
1663
+
1664
+ if ($dontUseFull)
1665
+ { $packageLevel--; };
1666
+
1667
+ while ($packageLevel >= 0)
1668
+ {
1669
+ $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join(@packages[0..$packageLevel], $symbol),
1670
+ $score);
1671
+ $score--;
1672
+
1673
+ foreach my $singular (@$singulars)
1674
+ {
1675
+ $self->AddInterpretation($referenceString, NaturalDocs::SymbolString->Join(@packages[0..$packageLevel], $singular),
1676
+ $score);
1677
+ $score--;
1678
+ };
1679
+
1680
+ $packageLevel--;
1681
+ };
1682
+
1683
+ return $score;
1684
+ };
1685
+
1686
+
1687
+ #
1688
+ # Function: SingularInterpretationsOf
1689
+ #
1690
+ # Generates singular interpretations of a <SymbolString> if it can be interpreted as a plural. Not all of them will be valid singular
1691
+ # forms, but that doesn't matter since it's incredibly unlikely an invalid form would exist as a symbol. What matters is that the
1692
+ # legimate singular is present on the list.
1693
+ #
1694
+ # Parameters:
1695
+ #
1696
+ # symbol - The <SymbolString>.
1697
+ #
1698
+ # Returns:
1699
+ #
1700
+ # An array of potential singular interpretations as <SymbolStrings>, in no particular order. If the symbol can't be interpreted
1701
+ # as a plural, returns an empty array.
1702
+ #
1703
+ sub SingularInterpretationsOf #(symbol)
1704
+ {
1705
+ my ($self, $symbol) = @_;
1706
+
1707
+ my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
1708
+ my $lastIdentifier = pop @identifiers;
1709
+ my $preIdentifiers = NaturalDocs::SymbolString->Join(@identifiers);
1710
+
1711
+ my @results;
1712
+
1713
+ # First cut off any 's or ' at the end, since they can appear after other plural forms.
1714
+ if ($lastIdentifier =~ s/\'s?$//i)
1715
+ {
1716
+ push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $lastIdentifier);
1717
+ };
1718
+
1719
+ # See http://www.gsu.edu/~wwwesl/egw/crump.htm for a good list of potential plural forms. There are a couple more than
1720
+ # listed below, but they're fairly rare and this is already seriously over-engineered. This is split by suffix length to make
1721
+ # comparisons more efficient.
1722
+
1723
+ # The fact that this will generate some impossible combinations (leaves => leave, leav, leaf, leafe) doesn't matter. It's very
1724
+ # unlikely that more than one will manage to match a defined symbol. Even if they do (leave, leaf), it's incredibly unlikely
1725
+ # that someone has defined an impossible one (leav, leafe). So it's not so important that we remove impossible combinations,
1726
+ # just that we include all the possible ones.
1727
+
1728
+ my @suffixGroups = ( [ 's', undef, # boys => boy
1729
+ 'i', 'us', # alumni => alumnus
1730
+ 'a', 'um', # errata => erratum
1731
+ 'a', 'on' ], # phenomena => phenomenon
1732
+
1733
+ [ 'es', undef, # foxes => fox
1734
+ 'ae', 'a' ], # amoebae => amoeba
1735
+
1736
+ [ 'ies', 'y', # pennies => penny
1737
+ 'ves', 'f', # calves => calf
1738
+ 'ves', 'fe', # knives => knife
1739
+ 'men', 'man', # women => woman
1740
+ 'ice', 'ouse', # mice => mouse
1741
+ 'oes', 'o', # vetoes => veto
1742
+ 'ces', 'x', # matrices => matrix
1743
+ 'xen', 'x' ], # oxen => ox
1744
+
1745
+ [ 'ices', 'ex', # indices => index
1746
+ 'feet', 'foot', # feet => foot
1747
+ 'eese', 'oose', # geese => goose
1748
+ 'eeth', 'ooth', # teeth => tooth
1749
+ 'dren', 'd' ] ); # children => child
1750
+
1751
+ my $suffixLength = 1;
1752
+
1753
+ foreach my $suffixGroup (@suffixGroups)
1754
+ {
1755
+ my $identifierSuffix = lc( substr($lastIdentifier, 0 - $suffixLength) );
1756
+ my $cutIdentifier = substr($lastIdentifier, 0, 0 - $suffixLength);
1757
+
1758
+ for (my $i = 0; $i + 1 < scalar @$suffixGroup; $i += 2)
1759
+ {
1760
+ my $suffix = $suffixGroup->[$i];
1761
+ my $replacement = $suffixGroup->[$i + 1];
1762
+
1763
+ if ($identifierSuffix eq $suffix)
1764
+ {
1765
+ if (defined $replacement)
1766
+ {
1767
+ push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $cutIdentifier . $replacement);
1768
+ push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $cutIdentifier . uc($replacement));
1769
+ }
1770
+ else
1771
+ {
1772
+ push @results, NaturalDocs::SymbolString->Join($preIdentifiers, $cutIdentifier);
1773
+ };
1774
+ };
1775
+ };
1776
+
1777
+ $suffixLength++;
1778
+ };
1779
+
1780
+ return @results;
1781
+ };
1782
+
1783
+
1784
+ #
1785
+ # Function: AddInterpretation
1786
+ #
1787
+ # Adds an interpretation to an existing reference. Creates potential symbols as necessary.
1788
+ #
1789
+ # Parameters:
1790
+ #
1791
+ # referenceString - The <ReferenceString> to add the interpretation to.
1792
+ # symbol - The <SymbolString> the reference can be interpreted as.
1793
+ # score - The score of the interpretation.
1794
+ #
1795
+ sub AddInterpretation #(referenceString, symbol, score)
1796
+ {
1797
+ my ($self, $referenceString, $symbol, $score) = @_;
1798
+
1799
+ $references{$referenceString}->AddInterpretation($symbol, $score);
1800
+
1801
+ # Create a potential symbol if it doesn't exist.
1802
+
1803
+ if (!exists $symbols{$symbol})
1804
+ { $symbols{$symbol} = NaturalDocs::SymbolTable::Symbol->New(); };
1805
+
1806
+ $symbols{$symbol}->AddReference($referenceString, $score);
1807
+ };
1808
+
1809
+
1810
+ #
1811
+ # Function: InterpretReference
1812
+ #
1813
+ # Interprets the passed reference, matching it to the defined symbol with the highest score. If the symbol is already
1814
+ # interpreted, it will reinterpret it. If there are no matches, it will make it an undefined reference.
1815
+ #
1816
+ # Parameters:
1817
+ #
1818
+ # referenceString - The <ReferenceString> to interpret.
1819
+ #
1820
+ sub InterpretReference #(referenceString)
1821
+ {
1822
+ my ($self, $referenceString) = @_;
1823
+
1824
+ my $interpretation;
1825
+ my $currentInterpretation;
1826
+ my $score;
1827
+ my $currentScore = -1;
1828
+
1829
+ my $referenceObject = $references{$referenceString};
1830
+
1831
+ my %interpretationsAndScores = $referenceObject->InterpretationsAndScores();
1832
+ while ( ($interpretation, $score) = each %interpretationsAndScores )
1833
+ {
1834
+ if ($score > $currentScore && $symbols{$interpretation}->IsDefined())
1835
+ {
1836
+ $currentScore = $score;
1837
+ $currentInterpretation = $interpretation;
1838
+ };
1839
+ };
1840
+
1841
+ if ($currentScore > -1)
1842
+ { $referenceObject->SetCurrentInterpretation($currentInterpretation); }
1843
+ else
1844
+ { $referenceObject->SetCurrentInterpretation(undef); };
1845
+ };
1846
+
1847
+
1848
+ #
1849
+ # Function: MakeIndex
1850
+ #
1851
+ # Generates a symbol index.
1852
+ #
1853
+ # Parameters:
1854
+ #
1855
+ # type - The <TopicType> to limit the index to.
1856
+ #
1857
+ # Returns:
1858
+ #
1859
+ # An arrayref of sections. The first represents all the symbols, the second the numbers, and the rest A through Z.
1860
+ # Each section is a sorted arrayref of <NaturalDocs::SymbolTable::IndexElement> objects. If a section has no content,
1861
+ # it will be undef.
1862
+ #
1863
+ sub MakeIndex #(type)
1864
+ {
1865
+ my ($self, $type) = @_;
1866
+
1867
+
1868
+ # Go through the symbols and generate IndexElements for any that belong in the index.
1869
+
1870
+ # Keys are the symbol strings, values are IndexElements.
1871
+ my %indexSymbols;
1872
+
1873
+ while (my ($symbolString, $object) = each %symbols)
1874
+ {
1875
+ my ($symbol, $package) = $self->SplitSymbolForIndex($symbolString, $object->GlobalType());
1876
+ my @definitions = $object->Definitions();
1877
+
1878
+ foreach my $definition (@definitions)
1879
+ {
1880
+ my $definitionType = $object->TypeDefinedIn($definition);
1881
+
1882
+ if ($type eq ::TOPIC_GENERAL() || $type eq $definitionType)
1883
+ {
1884
+ if (!exists $indexSymbols{$symbol})
1885
+ {
1886
+ $indexSymbols{$symbol} =
1887
+ NaturalDocs::SymbolTable::IndexElement->New($symbol, $package, $definition, $definitionType,
1888
+ $object->PrototypeDefinedIn($definition),
1889
+ $object->SummaryDefinedIn($definition) );
1890
+ }
1891
+ else
1892
+ {
1893
+ $indexSymbols{$symbol}->Merge($package, $definition, $definitionType,
1894
+ $object->PrototypeDefinedIn($definition),
1895
+ $object->SummaryDefinedIn($definition) );
1896
+ };
1897
+ }; # If type matches
1898
+ }; # Each definition
1899
+ }; # Each symbol
1900
+
1901
+
1902
+ # Generate sortable symbols for each IndexElement, sort them internally, and divide them into sections.
1903
+
1904
+ my $sections = [ ];
1905
+
1906
+ foreach my $indexElement (values %indexSymbols)
1907
+ {
1908
+ $indexElement->Sort();
1909
+ $indexElement->MakeSortableSymbol();
1910
+
1911
+ my $sectionNumber;
1912
+
1913
+ if ($indexElement->SortableSymbol() =~ /^([a-z])/i)
1914
+ { $sectionNumber = ord(lc($1)) - ord('a') + 2; }
1915
+ elsif ($indexElement->SortableSymbol() =~ /^[0-9]/)
1916
+ { $sectionNumber = 1; }
1917
+ else
1918
+ { $sectionNumber = 0; };
1919
+
1920
+ if (!defined $sections->[$sectionNumber])
1921
+ { $sections->[$sectionNumber] = [ ]; };
1922
+
1923
+ push @{$sections->[$sectionNumber]}, $indexElement;
1924
+ };
1925
+
1926
+
1927
+ # Sort each section.
1928
+
1929
+ for (my $i = 0; $i < scalar @$sections; $i++)
1930
+ {
1931
+ if (defined $sections->[$i])
1932
+ {
1933
+ @{$sections->[$i]} = sort
1934
+ {
1935
+ my $result = ::StringCompare($a->SortableSymbol(), $b->SortableSymbol());
1936
+
1937
+ if ($result == 0)
1938
+ { $result = ::StringCompare($a->IgnoredPrefix(), $b->IgnoredPrefix()); };
1939
+
1940
+ return $result;
1941
+ }
1942
+ @{$sections->[$i]};
1943
+ };
1944
+ };
1945
+
1946
+ return $sections;
1947
+ };
1948
+
1949
+
1950
+ #
1951
+ # Function: SplitSymbolForIndex
1952
+ #
1953
+ # Splits a <SymbolString> into its symbol and package portions for indexing.
1954
+ #
1955
+ # Parameters:
1956
+ #
1957
+ # symbol - The <SymbolString>.
1958
+ # type - Its <TopicType>.
1959
+ #
1960
+ # Returns:
1961
+ #
1962
+ # The array ( symbol, package ), which are both <SymbolStrings>. If the symbol is global, package will be undef.
1963
+ #
1964
+ sub SplitSymbolForIndex #(symbol, type)
1965
+ {
1966
+ my ($self, $symbol, $type) = @_;
1967
+
1968
+ my $scope = NaturalDocs::Topics->TypeInfo($type)->Scope();
1969
+
1970
+ if ($scope == ::SCOPE_START() || $scope == ::SCOPE_ALWAYS_GLOBAL())
1971
+ { return ( $symbol, undef ); }
1972
+ else
1973
+ {
1974
+ my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
1975
+
1976
+ $symbol = pop @identifiers;
1977
+ my $package = NaturalDocs::SymbolString->Join(@identifiers);
1978
+
1979
+ return ( $symbol, $package );
1980
+ };
1981
+ };
1982
+
1983
+
1984
+ 1;