bixbite 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.markdown +49 -0
- data/VERSION +1 -0
- data/bin/bixbite +73 -0
- data/lib/bixbite.rb +13 -0
- data/lib/bixbite/command.rb +14 -0
- data/lib/bixbite/create.rb +76 -0
- data/template/Rakefile +25 -0
- data/template/assets/bixbite/Rakefile.rb +297 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
- data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
- data/template/assets/utilities/pngout +0 -0
- data/template/deploy/public_html/.htaccess +0 -0
- data/template/documentation/js/.htaccess +0 -0
- data/template/src/html/.htaccess +76 -0
- data/template/src/html/css/cmn/global.css +96 -0
- data/template/src/html/css/cmn/ie.css +15 -0
- data/template/src/html/css/cmn/ie6.css +15 -0
- data/template/src/html/images/cmn/.htaccess +0 -0
- data/template/src/html/images/tmp/.htaccess +0 -0
- data/template/src/html/includes/debug.inc +5 -0
- data/template/src/html/includes/footer.inc +52 -0
- data/template/src/html/includes/header.inc +61 -0
- data/template/src/html/includes/html.inc +3 -0
- data/template/src/html/includes/namespace.inc +19 -0
- data/template/src/html/includes/page.inc +151 -0
- data/template/src/html/index.html +35 -0
- data/template/src/html/js/cmn/bootstrap.js +74 -0
- data/template/src/html/js/cmn/global.js +142 -0
- data/template/src/html/js/cmn/lib/LAB.js +348 -0
- data/template/src/html/min/.htaccess +4 -0
- data/template/src/html/min/MinifyCLI.php +19 -0
- data/template/src/html/min/README.txt +132 -0
- data/template/src/html/min/builder/_index.js +242 -0
- data/template/src/html/min/builder/bm.js +36 -0
- data/template/src/html/min/builder/index.php +182 -0
- data/template/src/html/min/builder/ocCheck.php +36 -0
- data/template/src/html/min/builder/rewriteTest.js +1 -0
- data/template/src/html/min/config.php +187 -0
- data/template/src/html/min/groupsConfig.php +34 -0
- data/template/src/html/min/index.php +66 -0
- data/template/src/html/min/lib/FirePHP.php +1370 -0
- data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
- data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
- data/template/src/html/min/lib/JSMin.php +314 -0
- data/template/src/html/min/lib/JSMinPlus.php +1872 -0
- data/template/src/html/min/lib/Minify.php +532 -0
- data/template/src/html/min/lib/Minify/Build.php +103 -0
- data/template/src/html/min/lib/Minify/CSS.php +83 -0
- data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
- data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
- data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
- data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
- data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
- data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
- data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
- data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
- data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
- data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
- data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
- data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
- data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
- data/template/src/html/min/lib/Minify/HTML.php +245 -0
- data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
- data/template/src/html/min/lib/Minify/Lines.php +131 -0
- data/template/src/html/min/lib/Minify/Logger.php +45 -0
- data/template/src/html/min/lib/Minify/Packer.php +37 -0
- data/template/src/html/min/lib/Minify/Source.php +187 -0
- data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
- data/template/src/html/min/lib/Solar/Dir.php +199 -0
- data/template/src/html/min/lib/closure-compiler.jar +0 -0
- data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
- data/template/src/html/min/utils.php +90 -0
- data/template/src/templates/css/template.css +7 -0
- data/template/src/templates/js/template.js +72 -0
- data/template/src/templates/template.html +18 -0
- data/template/src/yaml/config.yml +46 -0
- data/template/src/yaml/deploy.yml +35 -0
- data/test/bixbite_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- 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;
|