jsduck 4.10.4 → 5.0.0.beta01

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. data/.travis.yml +0 -1
  2. data/README.md +32 -6
  3. data/Rakefile +10 -18
  4. data/bin/compare +5 -5
  5. data/bin/jsduck +2 -3
  6. data/jsduck.gemspec +3 -4
  7. data/lib/jsduck/aggregator.rb +21 -80
  8. data/lib/jsduck/app.rb +7 -14
  9. data/lib/jsduck/app_data.rb +4 -5
  10. data/lib/jsduck/assets.rb +4 -7
  11. data/lib/jsduck/base_type.rb +53 -0
  12. data/lib/jsduck/batch_parser.rb +8 -87
  13. data/lib/jsduck/batch_processor.rb +77 -0
  14. data/lib/jsduck/categories/auto.rb +83 -0
  15. data/lib/jsduck/categories/class_name.rb +63 -0
  16. data/lib/jsduck/categories/factory.rb +113 -0
  17. data/lib/jsduck/categories/file.rb +75 -0
  18. data/lib/jsduck/class.rb +3 -9
  19. data/lib/jsduck/class_doc_expander.rb +1 -1
  20. data/lib/jsduck/css/lexer.rb +203 -0
  21. data/lib/jsduck/css/parser.rb +121 -0
  22. data/lib/jsduck/doc/comment.rb +40 -0
  23. data/lib/jsduck/doc/map.rb +23 -0
  24. data/lib/jsduck/doc/parser.rb +128 -0
  25. data/lib/jsduck/doc/processor.rb +52 -0
  26. data/lib/jsduck/doc/scanner.rb +76 -0
  27. data/lib/jsduck/doc/standard_tag_parser.rb +154 -0
  28. data/lib/jsduck/doc/subproperties.rb +64 -0
  29. data/lib/jsduck/docs_code_comparer.rb +31 -0
  30. data/lib/jsduck/export_writer.rb +2 -2
  31. data/lib/jsduck/exporter/app.rb +16 -4
  32. data/lib/jsduck/exporter/full.rb +2 -2
  33. data/lib/jsduck/format/batch.rb +58 -0
  34. data/lib/jsduck/format/class.rb +62 -0
  35. data/lib/jsduck/format/doc.rb +172 -0
  36. data/lib/jsduck/format/html_stack.rb +109 -0
  37. data/lib/jsduck/format/shortener.rb +55 -0
  38. data/lib/jsduck/format/subproperties.rb +64 -0
  39. data/lib/jsduck/guides.rb +32 -14
  40. data/lib/jsduck/index_html.rb +3 -1
  41. data/lib/jsduck/inline/auto_link.rb +2 -2
  42. data/lib/jsduck/inline/link.rb +4 -3
  43. data/lib/jsduck/inline/link_renderer.rb +2 -2
  44. data/lib/jsduck/inline/video.rb +8 -2
  45. data/lib/jsduck/js/ast.rb +361 -0
  46. data/lib/jsduck/js/esprima.rb +39 -0
  47. data/lib/jsduck/{esprima → js/esprima}/esprima.js +0 -0
  48. data/lib/jsduck/js/evaluator.rb +70 -0
  49. data/lib/jsduck/js/ext_patterns.rb +70 -0
  50. data/lib/jsduck/js/function.rb +206 -0
  51. data/lib/jsduck/js/node.rb +194 -0
  52. data/lib/jsduck/js/node_array.rb +36 -0
  53. data/lib/jsduck/js/parser.rb +223 -0
  54. data/lib/jsduck/js/serializer.rb +263 -0
  55. data/lib/jsduck/js/utils.rb +21 -0
  56. data/lib/jsduck/logger.rb +3 -13
  57. data/lib/jsduck/members_index.rb +3 -4
  58. data/lib/jsduck/merger.rb +25 -145
  59. data/lib/jsduck/options.rb +29 -132
  60. data/lib/jsduck/parser.rb +76 -0
  61. data/lib/jsduck/process/accessors.rb +133 -0
  62. data/lib/jsduck/process/circular_deps.rb +58 -0
  63. data/lib/jsduck/process/enums.rb +91 -0
  64. data/lib/jsduck/process/ext4_events.rb +43 -0
  65. data/lib/jsduck/process/global_members.rb +36 -0
  66. data/lib/jsduck/process/ignored_classes.rb +16 -0
  67. data/lib/jsduck/process/importer.rb +58 -0
  68. data/lib/jsduck/process/inherit_doc.rb +197 -0
  69. data/lib/jsduck/process/lint.rb +135 -0
  70. data/lib/jsduck/process/overrides.rb +99 -0
  71. data/lib/jsduck/process/return_values.rb +72 -0
  72. data/lib/jsduck/process/versions.rb +102 -0
  73. data/lib/jsduck/relations.rb +5 -0
  74. data/lib/jsduck/render/class.rb +144 -0
  75. data/lib/jsduck/render/sidebar.rb +97 -0
  76. data/lib/jsduck/render/signature.rb +94 -0
  77. data/lib/jsduck/render/subproperties.rb +99 -0
  78. data/lib/jsduck/render/tags.rb +38 -0
  79. data/lib/jsduck/search_data.rb +19 -13
  80. data/lib/jsduck/source/file.rb +8 -17
  81. data/lib/jsduck/tag/abstract.rb +4 -7
  82. data/lib/jsduck/tag/accessor.rb +10 -0
  83. data/lib/jsduck/tag/alias.rb +61 -0
  84. data/lib/jsduck/tag/alternate_class_names.rb +17 -0
  85. data/lib/jsduck/tag/aside.rb +28 -31
  86. data/lib/jsduck/tag/author.rb +9 -5
  87. data/lib/jsduck/tag/boolean_tag.rb +24 -0
  88. data/lib/jsduck/tag/cfg.rb +45 -0
  89. data/lib/jsduck/tag/chainable.rb +5 -7
  90. data/lib/jsduck/tag/class.rb +28 -0
  91. data/lib/jsduck/tag/class_list_tag.rb +40 -0
  92. data/lib/jsduck/tag/constructor.rb +24 -0
  93. data/lib/jsduck/tag/css_mixin.rb +17 -0
  94. data/lib/jsduck/tag/css_var.rb +29 -0
  95. data/lib/jsduck/tag/default.rb +31 -0
  96. data/lib/jsduck/tag/deprecated.rb +13 -27
  97. data/lib/jsduck/tag/deprecated_tag.rb +58 -0
  98. data/lib/jsduck/tag/doc.rb +32 -0
  99. data/lib/jsduck/tag/docauthor.rb +4 -5
  100. data/lib/jsduck/tag/enum.rb +70 -0
  101. data/lib/jsduck/tag/event.rb +28 -0
  102. data/lib/jsduck/tag/evented.rb +10 -0
  103. data/lib/jsduck/tag/extends.rb +45 -0
  104. data/lib/jsduck/tag/ftype.rb +18 -0
  105. data/lib/jsduck/tag/hide.rb +4 -11
  106. data/lib/jsduck/tag/ignore.rb +6 -7
  107. data/lib/jsduck/tag/inheritable.rb +10 -0
  108. data/lib/jsduck/tag/inheritdoc.rb +48 -0
  109. data/lib/jsduck/tag/markdown.rb +8 -6
  110. data/lib/jsduck/tag/member.rb +24 -0
  111. data/lib/jsduck/tag/method.rb +35 -0
  112. data/lib/jsduck/tag/mixins.rb +26 -0
  113. data/lib/jsduck/tag/name.rb +36 -0
  114. data/lib/jsduck/tag/new.rb +13 -27
  115. data/lib/jsduck/tag/override.rb +37 -0
  116. data/lib/jsduck/tag/overrides.rb +29 -0
  117. data/lib/jsduck/tag/param.rb +87 -0
  118. data/lib/jsduck/tag/preventable.rb +19 -10
  119. data/lib/jsduck/tag/private.rb +28 -13
  120. data/lib/jsduck/tag/property.rb +39 -0
  121. data/lib/jsduck/tag/protected.rb +5 -7
  122. data/lib/jsduck/tag/ptype.rb +18 -0
  123. data/lib/jsduck/tag/readonly.rb +4 -7
  124. data/lib/jsduck/tag/removed.rb +21 -29
  125. data/lib/jsduck/tag/required.rb +11 -9
  126. data/lib/jsduck/tag/requires.rb +12 -0
  127. data/lib/jsduck/tag/return.rb +47 -0
  128. data/lib/jsduck/tag/since.rb +19 -11
  129. data/lib/jsduck/tag/singleton.rb +15 -0
  130. data/lib/jsduck/tag/static.rb +5 -7
  131. data/lib/jsduck/tag/subproperties.rb +23 -0
  132. data/lib/jsduck/tag/tag.rb +208 -0
  133. data/lib/jsduck/tag/template.rb +14 -9
  134. data/lib/jsduck/tag/throws.rb +38 -0
  135. data/lib/jsduck/tag/type.rb +48 -0
  136. data/lib/jsduck/tag/uses.rb +12 -0
  137. data/lib/jsduck/tag/xtype.rb +30 -0
  138. data/lib/jsduck/tag_loader.rb +39 -0
  139. data/lib/jsduck/tag_registry.rb +189 -0
  140. data/lib/jsduck/type_parser.rb +3 -3
  141. data/lib/jsduck/web_writer.rb +2 -2
  142. data/lib/jsduck/welcome.rb +1 -1
  143. metadata +578 -538
  144. data/lib/jsduck/accessors.rb +0 -136
  145. data/lib/jsduck/ast.rb +0 -524
  146. data/lib/jsduck/auto_categories.rb +0 -80
  147. data/lib/jsduck/batch_formatter.rb +0 -60
  148. data/lib/jsduck/categories.rb +0 -73
  149. data/lib/jsduck/categories_class_name.rb +0 -37
  150. data/lib/jsduck/circular_deps.rb +0 -56
  151. data/lib/jsduck/class_formatter.rb +0 -102
  152. data/lib/jsduck/columns.rb +0 -56
  153. data/lib/jsduck/css_lexer.rb +0 -201
  154. data/lib/jsduck/css_parser.rb +0 -119
  155. data/lib/jsduck/doc_ast.rb +0 -319
  156. data/lib/jsduck/doc_formatter.rb +0 -142
  157. data/lib/jsduck/doc_parser.rb +0 -611
  158. data/lib/jsduck/doc_type.rb +0 -59
  159. data/lib/jsduck/enum.rb +0 -73
  160. data/lib/jsduck/esprima.rb +0 -51
  161. data/lib/jsduck/evaluator.rb +0 -69
  162. data/lib/jsduck/ext_patterns.rb +0 -58
  163. data/lib/jsduck/file_categories.rb +0 -76
  164. data/lib/jsduck/function_ast.rb +0 -206
  165. data/lib/jsduck/guide_anchors.rb +0 -32
  166. data/lib/jsduck/guide_toc.rb +0 -49
  167. data/lib/jsduck/html_stack.rb +0 -105
  168. data/lib/jsduck/importer.rb +0 -121
  169. data/lib/jsduck/inherit_doc.rb +0 -193
  170. data/lib/jsduck/js_parser.rb +0 -221
  171. data/lib/jsduck/lint.rb +0 -133
  172. data/lib/jsduck/meta_tag.rb +0 -88
  173. data/lib/jsduck/meta_tag_loader.rb +0 -67
  174. data/lib/jsduck/meta_tag_registry.rb +0 -111
  175. data/lib/jsduck/meta_tag_renderer.rb +0 -34
  176. data/lib/jsduck/news.rb +0 -128
  177. data/lib/jsduck/override.rb +0 -87
  178. data/lib/jsduck/renderer.rb +0 -361
  179. data/lib/jsduck/return_values.rb +0 -72
  180. data/lib/jsduck/serializer.rb +0 -262
  181. data/lib/jsduck/shortener.rb +0 -58
  182. data/lib/jsduck/signature_renderer.rb +0 -91
  183. data/lib/jsduck/source/file_parser.rb +0 -72
@@ -1,201 +0,0 @@
1
- require 'strscan'
2
-
3
- module JsDuck
4
-
5
- # Tokenizes CSS or SCSS code into lexical tokens.
6
- #
7
- # Each token has a type and value.
8
- # Types and possible values for them are as follows:
9
- #
10
- # - :number -- "25.8"
11
- # - :percentage -- "25%"
12
- # - :dimension -- "2em"
13
- # - :string -- '"Hello world"'
14
- # - :ident -- "foo-bar"
15
- # - :at_keyword -- "@mixin"
16
- # - :hash -- "#00FF66"
17
- # - :delim -- "{"
18
- # - :doc_comment -- "/** My comment */"
19
- #
20
- # Notice that doc-comments are recognized as tokens while normal
21
- # comments are ignored just as whitespace.
22
- #
23
- class CssLexer
24
- # Initializes lexer with input string.
25
- def initialize(input)
26
- @input = StringScanner.new(input)
27
- @buffer = []
28
- end
29
-
30
- # Tests if given pattern matches the tokens that follow at current
31
- # position.
32
- #
33
- # Takes list of strings and symbols. Symbols are compared to
34
- # token type, while strings to token value. For example:
35
- #
36
- # look(:ident, ":", :dimension)
37
- #
38
- def look(*tokens)
39
- buffer_tokens(tokens.length)
40
- i = 0
41
- tokens.all? do |t|
42
- tok = @buffer[i]
43
- i += 1
44
- if !tok
45
- false
46
- elsif t.instance_of?(Symbol)
47
- tok[:type] == t
48
- else
49
- tok[:value] == t
50
- end
51
- end
52
- end
53
-
54
- # Returns the value of next token, moving the current token cursor
55
- # also to next token.
56
- #
57
- # When full=true, returns full token as hash like so:
58
- #
59
- # {:type => :ident, :value => "foo"}
60
- #
61
- # For doc-comments the full token also contains the field :linenr,
62
- # pointing to the line where the doc-comment began.
63
- #
64
- def next(full=false)
65
- buffer_tokens(1)
66
- tok = @buffer.shift
67
- # advance the scanpointer to the position after this token
68
- @input.pos = tok[:pos]
69
- full ? tok : tok[:value]
70
- end
71
-
72
- # True when no more tokens.
73
- def empty?
74
- buffer_tokens(1)
75
- return !@buffer.first
76
- end
77
-
78
- # Ensures next n tokens are read in buffer
79
- #
80
- # At the end of buffering the initial position scanpointer is
81
- # restored. Only the #next method will advance the scanpointer in
82
- # a way that's visible outside this class.
83
- def buffer_tokens(n)
84
- prev_pos = @input.pos
85
- @input.pos = @buffer.last[:pos] if @buffer.last
86
- (n - @buffer.length).times do
87
- @previous_token = tok = next_token
88
- if tok
89
- # remember scanpointer position after each token
90
- tok[:pos] = @input.pos
91
- @buffer << tok
92
- end
93
- end
94
- @input.pos = prev_pos
95
- end
96
-
97
- # Parses out next token from input stream.
98
- def next_token
99
- while !@input.eos? do
100
- skip_white
101
- if @input.check(IDENT)
102
- return {
103
- :type => :ident,
104
- :value => @input.scan(IDENT)
105
- }
106
- elsif @input.check(/'/)
107
- return {
108
- :type => :string,
109
- :value => @input.scan(/'([^'\\]|\\.)*('|\Z)/m)
110
- }
111
- elsif @input.check(/"/)
112
- return {
113
- :type => :string,
114
- :value => @input.scan(/"([^"\\]|\\.)*("|\Z)/m)
115
- }
116
- elsif @input.check(/\//)
117
- # Several things begin with dash:
118
- # - comments, regexes, division-operators
119
- if @input.check(/\/\*\*[^\/]/)
120
- return {
121
- :type => :doc_comment,
122
- # Calculate current line number, starting with 1
123
- :linenr => @input.string[0...@input.pos].count("\n") + 1,
124
- :value => @input.scan_until(/\*\/|\Z/).sub(/\A\/\*\*/, "").sub(/\*\/\Z/, "")
125
- }
126
- elsif @input.check(/\/\*/)
127
- # skip multiline comment
128
- @input.scan_until(/\*\/|\Z/)
129
- elsif @input.check(/\/\//)
130
- # skip line comment
131
- @input.scan_until(/\n|\Z/)
132
- else
133
- return {
134
- :type => :operator,
135
- :value => @input.scan(/\//)
136
- }
137
- end
138
- elsif @input.check(NUM)
139
- nr = @input.scan(NUM)
140
- if @input.check(/%/)
141
- return {
142
- :type => :percentage,
143
- :value => nr + @input.scan(/%/)
144
- }
145
- elsif @input.check(IDENT)
146
- return {
147
- :type => :dimension,
148
- :value => nr + @input.scan(IDENT)
149
- }
150
- else
151
- return {
152
- :type => :number,
153
- :value => nr
154
- }
155
- end
156
- elsif @input.check(/@/)
157
- return maybe(:at_keyword, /@/, IDENT)
158
- elsif @input.check(/#/)
159
- return maybe(:hash, /#/, NAME)
160
- elsif @input.check(/\$/)
161
- return maybe(:var, /\$/, IDENT)
162
- elsif @input.check(/./)
163
- return {
164
- :type => :delim,
165
- :value => @input.scan(/./)
166
- }
167
- end
168
- end
169
- end
170
-
171
- # Returns token of given type when both regexes match.
172
- # Otherwise returns :delim token with value of first regex match.
173
- # First regex must always match.
174
- def maybe(token_type, before_re, after_re)
175
- before = @input.scan(before_re)
176
- if @input.check(after_re)
177
- return {
178
- :type => token_type,
179
- :value => before + @input.scan(after_re)
180
- }
181
- else
182
- return {
183
- :type => :delim,
184
- :value => before
185
- }
186
- end
187
- end
188
-
189
- def skip_white
190
- @input.scan(/\s+/)
191
- end
192
-
193
- # Simplified token syntax based on:
194
- # http://www.w3.org/TR/CSS21/syndata.html
195
- IDENT = /-?[_a-z][_a-z0-9-]*/i
196
- NAME = /[_a-z0-9-]+/i
197
- NUM = /[0-9]*\.[0-9]+|[0-9]+/
198
-
199
- end
200
-
201
- end
@@ -1,119 +0,0 @@
1
- require 'jsduck/css_lexer'
2
-
3
- module JsDuck
4
-
5
- class CssParser
6
- def initialize(input, options = {})
7
- @lex = CssLexer.new(input)
8
- @docs = []
9
- end
10
-
11
- # Parses the whole CSS block and returns same kind of structure
12
- # that JavaScript parser does.
13
- def parse
14
- while !@lex.empty? do
15
- if look(:doc_comment)
16
- comment = @lex.next(true)
17
- @docs << {
18
- :comment => comment[:value],
19
- :linenr => comment[:linenr],
20
- :code => code_block,
21
- :type => :doc_comment,
22
- }
23
- else
24
- @lex.next
25
- end
26
- end
27
- @docs
28
- end
29
-
30
- # <code-block> := <mixin-declaration> | <var-declaration> | <property>
31
- def code_block
32
- if look("@mixin")
33
- mixin_declaration
34
- elsif look(:var, ":")
35
- var_declaration
36
- else
37
- # Default to property like in JsParser.
38
- {:tagname => :property}
39
- end
40
- end
41
-
42
- # <mixin-declaration> := "@mixin" <ident>
43
- def mixin_declaration
44
- match("@mixin")
45
- return {
46
- :tagname => :css_mixin,
47
- :name => look(:ident) ? match(:ident) : nil,
48
- }
49
- end
50
-
51
- # <var-declaration> := <var> ":" <css-value>
52
- def var_declaration
53
- name = match(:var)
54
- match(":")
55
- value_list = css_value
56
- return {
57
- :tagname => :css_var,
58
- :name => name,
59
- :default => value_list.map {|v| v[:value] }.join(" "),
60
- :type => value_type(value_list),
61
- }
62
- end
63
-
64
- # <css-value> := ...anything up to... [ ";" | "}" | "!default" ]
65
- def css_value
66
- val = []
67
- while !look(";") && !look("}") && !look("!", "default")
68
- val << @lex.next(true)
69
- end
70
- val
71
- end
72
-
73
- # Determines type of CSS value
74
- def value_type(val)
75
- case val[0][:type]
76
- when :number
77
- "number"
78
- when :dimension
79
- "length"
80
- when :percentage
81
- "percentage"
82
- when :string
83
- "string"
84
- when :hash
85
- "color"
86
- when :ident
87
- case val[0][:value]
88
- when "true", "false"
89
- return "boolean"
90
- when "rgb", "rgba", "hsl", "hsla"
91
- return "color"
92
- when "black", "silver", "gray", "white", "maroon",
93
- "red", "purple", "fuchsia", "green", "lime", "olive",
94
- "yellow", "navy", "blue", "teal", "aqua", "orange"
95
- return "color"
96
- when "transparent"
97
- return "color"
98
- end
99
- end
100
- end
101
-
102
- # Matches all arguments, returns the value of last match
103
- # When the whole sequence doesn't match, throws exception
104
- def match(*args)
105
- if look(*args)
106
- last = nil
107
- args.length.times { last = @lex.next }
108
- last
109
- else
110
- throw "Expected: " + args.join(", ")
111
- end
112
- end
113
-
114
- def look(*args)
115
- @lex.look(*args)
116
- end
117
- end
118
-
119
- end
@@ -1,319 +0,0 @@
1
- require 'jsduck/logger'
2
- require 'jsduck/meta_tag_registry'
3
-
4
- module JsDuck
5
-
6
- # Detects docs info directly from comment.
7
- class DocAst
8
- # Allow passing in filename and line for error reporting
9
- attr_accessor :filename
10
- attr_accessor :linenr
11
-
12
- def initialize
13
- @filename = ""
14
- @linenr = 0
15
- @meta_tags = MetaTagRegistry.instance
16
- end
17
-
18
- # Given tagname and array of tags from DocParser, produces docs
19
- # of the type determined by tagname.
20
- def detect(tagname, docs)
21
- case tagname
22
- when :class
23
- create_class(docs)
24
- when :event
25
- create_event(docs)
26
- when :method
27
- create_method(docs)
28
- when :cfg
29
- create_cfg(docs)
30
- when :property
31
- create_property(docs)
32
- when :css_var
33
- create_css_var(docs)
34
- when :css_mixin
35
- create_css_mixin(docs)
36
- end
37
- end
38
-
39
- private
40
-
41
- def create_class(docs)
42
- doc_map = build_doc_map(docs)
43
- return add_shared({
44
- :tagname => :class,
45
- :name => detect_name(:class, doc_map),
46
- :doc => detect_doc(docs),
47
- :extends => detect_extends(doc_map),
48
- :mixins => detect_list(:mixins, doc_map),
49
- :alternateClassNames => detect_list(:alternateClassNames, doc_map),
50
- :aliases => detect_aliases(doc_map),
51
- :singleton => !!doc_map[:singleton],
52
- :requires => detect_list(:requires, doc_map),
53
- :uses => detect_list(:uses, doc_map),
54
- :enum => detect_enum(doc_map),
55
- :override => extract(doc_map, :override, :class),
56
- }, doc_map)
57
- end
58
-
59
- def create_method(docs)
60
- doc_map = build_doc_map(docs)
61
- return add_shared({
62
- :tagname => :method,
63
- :name => detect_name(:method, doc_map),
64
- :owner => detect_owner(doc_map),
65
- :doc => detect_doc(docs),
66
- :params => detect_params(doc_map),
67
- :return => detect_return(doc_map),
68
- :throws => detect_throws(doc_map),
69
- }, doc_map)
70
- end
71
-
72
- def create_event(docs)
73
- doc_map = build_doc_map(docs)
74
- return add_shared({
75
- :tagname => :event,
76
- :name => detect_name(:event, doc_map),
77
- :owner => detect_owner(doc_map),
78
- :doc => detect_doc(docs),
79
- :params => detect_params(doc_map),
80
- }, doc_map)
81
- end
82
-
83
- def create_cfg(docs)
84
- doc_map = build_doc_map(docs)
85
- return add_shared({
86
- :tagname => :cfg,
87
- :name => detect_name(:cfg, doc_map),
88
- :owner => detect_owner(doc_map),
89
- :type => detect_type(:cfg, doc_map),
90
- :doc => detect_doc(docs),
91
- :default => detect_default(:cfg, doc_map),
92
- :properties => detect_subproperties(:cfg, docs),
93
- :accessor => !!doc_map[:accessor],
94
- :evented => !!doc_map[:evented],
95
- }, doc_map)
96
- end
97
-
98
- def create_property(docs)
99
- doc_map = build_doc_map(docs)
100
- return add_shared({
101
- :tagname => :property,
102
- :name => detect_name(:property, doc_map),
103
- :owner => detect_owner(doc_map),
104
- :type => detect_type(:property, doc_map),
105
- :doc => detect_doc(docs),
106
- :default => detect_default(:property, doc_map),
107
- :properties => detect_subproperties(:property, docs),
108
- }, doc_map)
109
- end
110
-
111
- def create_css_var(docs)
112
- doc_map = build_doc_map(docs)
113
- return add_shared({
114
- :tagname => :css_var,
115
- :name => detect_name(:css_var, doc_map),
116
- :owner => detect_owner(doc_map),
117
- :type => detect_type(:css_var, doc_map),
118
- :default => detect_default(:css_var, doc_map),
119
- :doc => detect_doc(docs),
120
- }, doc_map)
121
- end
122
-
123
- def create_css_mixin(docs)
124
- doc_map = build_doc_map(docs)
125
- return add_shared({
126
- :tagname => :css_mixin,
127
- :name => detect_name(:css_mixin, doc_map),
128
- :owner => detect_owner(doc_map),
129
- :doc => detect_doc(docs),
130
- :params => detect_params(doc_map),
131
- }, doc_map)
132
- end
133
-
134
- # Detects properties common for each doc-object and adds them
135
- def add_shared(hash, doc_map)
136
- hash.merge!({
137
- :inheritable => !!doc_map[:inheritable],
138
- :inheritdoc => extract(doc_map, :inheritdoc),
139
- :meta => detect_meta(doc_map),
140
- })
141
-
142
- # copy :private also to main hash
143
- hash[:private] = hash[:meta][:private] ? true : nil
144
-
145
- return hash
146
- end
147
-
148
- def detect_name(tagname, doc_map)
149
- name = extract(doc_map, tagname, :name)
150
- if name
151
- name
152
- else
153
- doc_map[:constructor] ? "constructor" : nil
154
- end
155
- end
156
-
157
- def extract(doc_map, tagname, propname = nil)
158
- tag = doc_map[tagname] ? doc_map[tagname].first : nil
159
- if tag && propname
160
- tag[propname]
161
- else
162
- tag
163
- end
164
- end
165
-
166
- def detect_owner(doc_map)
167
- extract(doc_map, :member, :member)
168
- end
169
-
170
- def detect_type(tagname, doc_map)
171
- extract(doc_map, tagname, :type) || extract(doc_map, :type, :type)
172
- end
173
-
174
- def detect_extends(doc_map)
175
- extract(doc_map, :extends, :extends)
176
- end
177
-
178
- def detect_default(tagname, doc_map)
179
- extract(doc_map, tagname, :default)
180
- end
181
-
182
- # for detecting mixins and alternateClassNames
183
- def detect_list(type, doc_map)
184
- if doc_map[type]
185
- doc_map[type].map {|d| d[type] }.flatten
186
- else
187
- nil
188
- end
189
- end
190
-
191
- def detect_aliases(doc_map)
192
- if doc_map[:alias]
193
- doc_map[:alias].map {|tag| tag[:name] }
194
- else
195
- nil
196
- end
197
- end
198
-
199
- def detect_meta(doc_map)
200
- meta = {}
201
- (doc_map[:meta] || []).map do |tag|
202
- meta[tag[:name]] = [] unless meta[tag[:name]]
203
- meta[tag[:name]] << tag[:doc]
204
- end
205
-
206
- meta.each_pair do |key, value|
207
- tag = @meta_tags[key]
208
- meta[key] = tag.to_value(tag.boolean ? true : value)
209
- end
210
-
211
- meta[:required] = true if detect_required(doc_map)
212
- meta
213
- end
214
-
215
- def detect_required(doc_map)
216
- doc_map[:cfg] && doc_map[:cfg].first[:optional] == false
217
- end
218
-
219
- def detect_params(doc_map)
220
- combine_properties(doc_map[:param] || [])
221
- end
222
-
223
- def detect_subproperties(tagname, docs)
224
- prop_docs = docs.find_all {|tag| tag[:tagname] == tagname}
225
- prop_docs.length > 0 ? combine_properties(prop_docs)[0][:properties] : []
226
- end
227
-
228
- def combine_properties(raw_items)
229
- # First item can't be namespaced, if it is ignore the rest.
230
- if raw_items[0] && raw_items[0][:name] =~ /\./
231
- return [raw_items[0]]
232
- end
233
-
234
- # build name-index of all items
235
- index = {}
236
- raw_items.each {|it| index[it[:name]] = it }
237
-
238
- # If item name has no dots, add it directly to items array.
239
- # Otherwise look up the parent of item and add it as the
240
- # property of that parent.
241
- items = []
242
- raw_items.each do |it|
243
- if it[:name] =~ /^(.+)\.([^.]+)$/
244
- it[:name] = $2
245
- parent = index[$1]
246
- if parent
247
- parent[:properties] = [] unless parent[:properties]
248
- parent[:properties] << it
249
- else
250
- Logger.warn(:subproperty, "Ignoring subproperty #{$1}.#{$2}, no parent found with name '#{$1}'.", @filename, @linenr)
251
- end
252
- else
253
- items << it
254
- end
255
- end
256
- items
257
- end
258
-
259
- def detect_return(doc_map)
260
- has_return_tag = !!extract(doc_map, :return)
261
- ret = extract(doc_map, :return) || {}
262
- return {
263
- :type => ret[:type] || (has_return_tag ? "Object" : "undefined"),
264
- :name => ret[:name] || "return",
265
- :doc => ret[:doc] || "",
266
- :properties => doc_map[:return] ? detect_subproperties(:return, doc_map[:return]) : []
267
- }
268
- end
269
-
270
- def detect_throws(doc_map)
271
- return unless doc_map[:throws]
272
-
273
- doc_map[:throws].map do |throws|
274
- {
275
- :type => throws[:type] || "Object",
276
- :doc => throws[:doc] || "",
277
- }
278
- end
279
- end
280
-
281
- def detect_enum(doc_map)
282
- return nil unless extract(doc_map, :class, :enum)
283
-
284
- default = extract(doc_map, :class, :default)
285
-
286
- return {
287
- :type => extract(doc_map, :class, :type),
288
- :default => default,
289
- :doc_only => !!default,
290
- }
291
- end
292
-
293
- # Combines :doc-s of most tags
294
- # Ignores tags that have doc comment themselves and subproperty tags
295
- def detect_doc(docs)
296
- ignore_tags = [:param, :return, :throws, :meta]
297
- doc_tags = docs.find_all { |tag| !ignore_tags.include?(tag[:tagname]) && !subproperty?(tag) }
298
- doc_tags.map { |tag| tag[:doc] }.compact.join(" ")
299
- end
300
-
301
- def subproperty?(tag)
302
- (tag[:tagname] == :cfg || tag[:tagname] == :property) && tag[:name] =~ /\./
303
- end
304
-
305
- # Build map of at-tags for quick lookup
306
- def build_doc_map(docs)
307
- map = {}
308
- docs.each do |tag|
309
- if map[tag[:tagname]]
310
- map[tag[:tagname]] << tag
311
- else
312
- map[tag[:tagname]] = [tag]
313
- end
314
- end
315
- map
316
- end
317
- end
318
-
319
- end