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,136 +0,0 @@
1
- require 'jsduck/logger'
2
-
3
- module JsDuck
4
-
5
- class Accessors
6
- # Given a class, generates accessor methods to configs with
7
- # @accessor tag. Modifies the class by adding these methods.
8
- # When class already contains a getter or setter, the method is
9
- # not added.
10
- def create(cls)
11
- # Grab all configs tagged as @accessor
12
- accessors = cls[:members].find_all {|m| m[:tagname] == :cfg && m[:accessor] }
13
-
14
- # Build lookup tables of method and event names
15
- methods = build_lookup_table(cls[:members], :method)
16
- events = build_lookup_table(cls[:members], :event)
17
-
18
- accessors.each do |cfg|
19
- # add getter if no method with same name exists
20
- get = create_getter(cfg)
21
- if !methods[get[:name]]
22
- cls[:members] << get
23
- end
24
- # add setter if no method with same name exists
25
- set = create_setter(cfg)
26
- if !methods[set[:name]]
27
- cls[:members] << set
28
- end
29
- # for evented accessors
30
- if cfg[:evented]
31
- # add event if no event with same name exists
32
- ev = create_event(cfg)
33
- if !events[ev[:name]]
34
- cls[:members] << ev
35
- end
36
- end
37
- end
38
- end
39
-
40
- def build_lookup_table(members, tagname)
41
- map = {}
42
- members.each do |m|
43
- map[m[:name]] = m if m[:tagname] == tagname
44
- end
45
- map
46
- end
47
-
48
- def create_getter(cfg)
49
- name = "get" + upcase_first(cfg[:name])
50
- return add_shared({
51
- :tagname => :method,
52
- :name => name,
53
- :doc => "Returns the value of {@link #cfg-#{cfg[:name]}}.",
54
- :params => [],
55
- :return => {
56
- :type => cfg[:type],
57
- :doc => "",
58
- },
59
- :id => "method-" + name,
60
- }, cfg)
61
- end
62
-
63
- def create_setter(cfg)
64
- name = "set" + upcase_first(cfg[:name]);
65
- return add_shared({
66
- :tagname => :method,
67
- :name => name,
68
- :doc => "Sets the value of {@link #cfg-#{cfg[:name]}}.",
69
- :params => [{
70
- :type => cfg[:type],
71
- :name => cfg[:name],
72
- :doc => "",
73
- }],
74
- :return => {
75
- :type => "undefined",
76
- :doc => "",
77
- },
78
- :id => "method-" + name,
79
- }, cfg)
80
- end
81
-
82
- def create_event(cfg)
83
- name = cfg[:name].downcase + "change"
84
- setter_name = "set" + upcase_first(cfg[:name]);
85
- return add_shared({
86
- :tagname => :event,
87
- :name => name,
88
- :doc => "Fires when the {@link ##{cfg[:id]}} configuration is changed by {@link #method-#{setter_name}}.",
89
- :params => [
90
- {
91
- :name => "this",
92
- :type => cfg[:owner],
93
- :doc => "The #{cfg[:owner]} instance."
94
- },
95
- {
96
- :name => "value",
97
- :type => cfg[:type],
98
- :doc => "The new value being set."
99
- },
100
- {
101
- :name => "oldValue",
102
- :type => cfg[:type],
103
- :doc => "The existing value."
104
- },
105
- ],
106
- :id => "event-" + name,
107
- }, cfg)
108
- end
109
-
110
- def add_shared(hash, cfg)
111
- hash.merge!({
112
- :owner => cfg[:owner],
113
- :files => cfg[:files],
114
- :private => cfg[:private],
115
- :autodetected => cfg[:autodetected],
116
- :meta => clone_meta(cfg),
117
- })
118
- end
119
-
120
- def upcase_first(str)
121
- str[0,1].upcase + str[1..-1]
122
- end
123
-
124
- # Create copy of all meta attributes of config, except the
125
- # :required which only applies to configs and must not be
126
- # propagated to methods or events.
127
- def clone_meta(cfg)
128
- h = {}
129
- cfg[:meta].each_pair do |key, value|
130
- h[key] = value unless key == :required
131
- end
132
- h
133
- end
134
- end
135
-
136
- end
data/lib/jsduck/ast.rb DELETED
@@ -1,524 +0,0 @@
1
- require "jsduck/serializer"
2
- require "jsduck/evaluator"
3
- require "jsduck/function_ast"
4
- require "jsduck/ext_patterns"
5
-
6
- module JsDuck
7
-
8
- # Analyzes the AST produced by EsprimaParser.
9
- class Ast
10
- # Should be initialized with EsprimaParser#parse result.
11
- def initialize(docs = [], options = {})
12
- @serializer = JsDuck::Serializer.new
13
- @evaluator = JsDuck::Evaluator.new
14
- @ext_patterns = JsDuck::ExtPatterns.new(options[:ext_namespaces] || ["Ext"])
15
- @docs = docs
16
- end
17
-
18
- # Performs the detection of code in all docsets.
19
- #
20
- # @returns the processed array of docsets. (But it does it
21
- # destructively by modifying the passed-in docsets.)
22
- #
23
- def detect_all!
24
- # First deal only with doc-comments
25
- doc_comments = @docs.find_all {|d| d[:type] == :doc_comment }
26
-
27
- # Detect code in each docset. Sometimes a docset has already
28
- # been detected as part of detecting some previous docset (like
29
- # Class detecting all of its configs) - in such case, skip.
30
- doc_comments.each do |docset|
31
- code = docset[:code]
32
- docset[:code] = detect(code) unless code && code[:tagname]
33
- end
34
-
35
- # Return all doc-comments + other comments for which related
36
- # code was detected.
37
- @docs.find_all {|d| d[:type] == :doc_comment || d[:code] && d[:code][:tagname] }
38
- end
39
-
40
- # Given Esprima-produced syntax tree, detects documentation data.
41
- #
42
- # This method is exposed for testing purposes only, JSDuck itself
43
- # only calls the above #detect_all method.
44
- #
45
- # @param ast :code from Result of EsprimaParser
46
- # @returns Hash consisting of the detected :tagname, :name, and
47
- # other properties relative to the tag. Like so:
48
- #
49
- # { :tagname => :method, :name => "foo", ... }
50
- #
51
- def detect(ast)
52
- ast = ast || {}
53
-
54
- exp = expression?(ast) ? ast["expression"] : nil
55
- var = var?(ast) ? ast["declarations"][0] : nil
56
-
57
- # Ext.define("Class", {})
58
- if exp && ext_define?(exp)
59
- make_class(to_value(exp["arguments"][0]), exp)
60
-
61
- # Ext.override(Class, {})
62
- elsif exp && ext_override?(exp)
63
- make_class("", exp)
64
-
65
- # foo = Ext.extend(Parent, {})
66
- elsif exp && assignment?(exp) && ext_extend?(exp["right"])
67
- make_class(to_s(exp["left"]), exp["right"])
68
-
69
- # Foo = ...
70
- elsif exp && assignment?(exp) && class_name?(to_s(exp["left"]))
71
- make_class(to_s(exp["left"]), exp["right"])
72
-
73
- # var foo = Ext.extend(Parent, {})
74
- elsif var && var["init"] && ext_extend?(var["init"])
75
- make_class(to_s(var["id"]), var["init"])
76
-
77
- # var Foo = ...
78
- elsif var && class_name?(to_s(var["id"]))
79
- make_class(to_s(var["id"]), var["right"])
80
-
81
- # function Foo() {}
82
- elsif function?(ast) && ast["id"] && class_name?(to_s(ast["id"]))
83
- make_class(to_s(ast["id"]))
84
-
85
- # { ... }
86
- elsif object?(ast)
87
- make_class("", ast)
88
-
89
- # function foo() {}
90
- elsif function?(ast)
91
- make_method(ast["id"] ? to_s(ast["id"]) : "", ast)
92
-
93
- # foo = function() {}
94
- elsif exp && assignment?(exp) && function?(exp["right"])
95
- make_method(to_s(exp["left"]), exp["right"])
96
-
97
- # var foo = function() {}
98
- elsif var && var["init"] && function?(var["init"])
99
- make_method(to_s(var["id"]), var["init"])
100
-
101
- # (function() {})
102
- elsif exp && function?(exp)
103
- make_method(exp["id"] ? to_s(exp["id"]) : "", exp)
104
-
105
- # foo: function() {}
106
- elsif property?(ast) && function?(ast["value"])
107
- make_method(key_value(ast["key"]), ast["value"])
108
-
109
- # this.fireEvent("foo", ...)
110
- elsif exp && fire_event?(exp)
111
- make_event(to_value(exp["arguments"][0]))
112
-
113
- # foo = ...
114
- elsif exp && assignment?(exp)
115
- make_property(to_s(exp["left"]), exp["right"])
116
-
117
- # var foo = ...
118
- elsif var
119
- make_property(to_s(var["id"]), var["init"])
120
-
121
- # foo: ...
122
- elsif property?(ast)
123
- make_property(key_value(ast["key"]), ast["value"])
124
-
125
- # foo;
126
- elsif exp && ident?(exp)
127
- make_property(to_s(exp))
128
-
129
- # "foo" (inside some expression)
130
- elsif string?(ast)
131
- make_property(to_value(ast))
132
-
133
- # "foo"; (as a statement of it's own)
134
- elsif exp && string?(exp)
135
- make_property(to_value(exp))
136
-
137
- else
138
- make_property()
139
- end
140
- end
141
-
142
- private
143
-
144
- def expression?(ast)
145
- ast["type"] == "ExpressionStatement"
146
- end
147
-
148
- def call?(ast)
149
- ast["type"] == "CallExpression"
150
- end
151
-
152
- def assignment?(ast)
153
- ast["type"] == "AssignmentExpression"
154
- end
155
-
156
- def ext_define?(ast)
157
- call?(ast) && ext_pattern?("Ext.define", ast["callee"])
158
- end
159
-
160
- def ext_extend?(ast)
161
- call?(ast) && ext_pattern?("Ext.extend", ast["callee"])
162
- end
163
-
164
- def ext_override?(ast)
165
- call?(ast) && ext_pattern?("Ext.override", ast["callee"])
166
- end
167
-
168
- def function?(ast)
169
- ast["type"] == "FunctionDeclaration" || ast["type"] == "FunctionExpression" || empty_fn?(ast)
170
- end
171
-
172
- def empty_fn?(ast)
173
- ast["type"] == "MemberExpression" && ext_pattern?("Ext.emptyFn", ast)
174
- end
175
-
176
- def ext_pattern?(pattern, ast)
177
- @ext_patterns.matches?(pattern, to_s(ast))
178
- end
179
-
180
- def fire_event?(ast)
181
- call?(ast) && to_s(ast["callee"]) == "this.fireEvent"
182
- end
183
-
184
- def var?(ast)
185
- ast["type"] == "VariableDeclaration"
186
- end
187
-
188
- def property?(ast)
189
- ast["type"] == "Property"
190
- end
191
-
192
- def ident?(ast)
193
- ast["type"] == "Identifier"
194
- end
195
-
196
- def string?(ast)
197
- ast["type"] == "Literal" && ast["value"].is_a?(String)
198
- end
199
-
200
- def object?(ast)
201
- ast["type"] == "ObjectExpression"
202
- end
203
-
204
- # Class name begins with upcase char
205
- def class_name?(name)
206
- return name.split(/\./).last =~ /\A[A-Z]/
207
- end
208
-
209
- def make_class(name, ast=nil)
210
- cls = {
211
- :tagname => :class,
212
- :name => name,
213
- }
214
-
215
- # apply information from Ext.extend, Ext.define, or {}
216
- if ast
217
- if ext_define?(ast)
218
- detect_ext_define(cls, ast)
219
- elsif ext_extend?(ast)
220
- detect_ext_something(:extends, cls, ast)
221
- elsif ext_override?(ast)
222
- detect_ext_something(:override, cls, ast)
223
- elsif object?(ast)
224
- detect_class_members_from_object(cls, ast)
225
- elsif ast["type"] == "ArrayExpression"
226
- detect_class_members_from_array(cls, ast)
227
- end
228
- end
229
-
230
- return cls
231
- end
232
-
233
- # Detection of Ext.extend() or Ext.override().
234
- # The type parameter must be correspondingly either :extend or :override.
235
- def detect_ext_something(type, cls, ast)
236
- args = ast["arguments"]
237
- cls[type] = to_s(args[0])
238
- if args.length == 2 && object?(args[1])
239
- detect_class_members_from_object(cls, args[1])
240
- end
241
- end
242
-
243
- # Inspects Ext.define() and copies detected properties over to the
244
- # given cls Hash
245
- def detect_ext_define(cls, ast)
246
- # defaults
247
- cls[:extends] = "Ext.Base"
248
- cls[:requires] = []
249
- cls[:uses] = []
250
- cls[:alternateClassNames] = []
251
- cls[:mixins] = []
252
- cls[:aliases] = []
253
- cls[:members] = []
254
- cls[:code_type] = :ext_define
255
-
256
- each_pair_in_object_expression(ast["arguments"][1]) do |key, value, pair|
257
- case key
258
- when "extend"
259
- cls[:extends] = make_string(value)
260
- when "override"
261
- cls[:override] = make_string(value)
262
- when "requires"
263
- cls[:requires] = make_string_list(value)
264
- when "uses"
265
- cls[:uses] = make_string_list(value)
266
- when "alternateClassName"
267
- cls[:alternateClassNames] = make_string_list(value)
268
- when "mixins"
269
- cls[:mixins] = make_mixins(value)
270
- when "singleton"
271
- cls[:singleton] = make_singleton(value)
272
- when "alias"
273
- cls[:aliases] += make_string_list(value)
274
- when "xtype"
275
- cls[:aliases] += make_string_list(value).map {|xtype| "widget."+xtype }
276
- when "config"
277
- cls[:members] += make_configs(value, {:accessor => true})
278
- when "cachedConfig"
279
- cls[:members] += make_configs(value, {:accessor => true})
280
- when "eventedConfig"
281
- cls[:members] += make_configs(value, {:accessor => true, :evented => true})
282
- when "statics"
283
- cls[:members] += make_statics(value)
284
- when "inheritableStatics"
285
- cls[:members] += make_statics(value, {:inheritable => true})
286
- else
287
- detect_method_or_property(cls, key, value, pair)
288
- end
289
- end
290
- end
291
-
292
- # Detects class members from object literal
293
- def detect_class_members_from_object(cls, ast)
294
- cls[:members] = []
295
- each_pair_in_object_expression(ast) do |key, value, pair|
296
- detect_method_or_property(cls, key, value, pair)
297
- end
298
- end
299
-
300
- # Detects class members from array literal
301
- def detect_class_members_from_array(cls, ast)
302
- cls[:members] = []
303
-
304
- # This will most likely be an @enum class, in which case the
305
- # enum will be for documentation purposes only.
306
- cls[:enum] = {:doc_only => true}
307
-
308
- ast["elements"].each do |el|
309
- detect_method_or_property(cls, key_value(el), el, el)
310
- end
311
- end
312
-
313
- # Detects item in object literal either as method or property
314
- def detect_method_or_property(cls, key, value, pair)
315
- if function?(value)
316
- m = make_method(key, value)
317
- cls[:members] << m if apply_autodetected(m, pair)
318
- else
319
- p = make_property(key, value)
320
- cls[:members] << p if apply_autodetected(p, pair)
321
- end
322
- end
323
-
324
- def make_string(cfg_value)
325
- return nil unless cfg_value
326
-
327
- parent = to_value(cfg_value)
328
-
329
- return parent.is_a?(String) ? parent : nil
330
- end
331
-
332
- def make_string_list(cfg_value)
333
- return [] unless cfg_value
334
-
335
- classes = Array(to_value(cfg_value))
336
-
337
- return classes.all? {|c| c.is_a? String } ? classes : []
338
- end
339
-
340
- def make_mixins(cfg_value)
341
- return [] unless cfg_value
342
-
343
- v = to_value(cfg_value)
344
- classes = v.is_a?(Hash) ? v.values : Array(v)
345
-
346
- return classes.all? {|c| c.is_a? String } ? classes : []
347
- end
348
-
349
- def make_singleton(cfg_value)
350
- cfg_value && to_value(cfg_value) == true
351
- end
352
-
353
- def make_configs(ast, defaults={})
354
- configs = []
355
-
356
- each_pair_in_object_expression(ast) do |name, value, pair|
357
- cfg = make_property(name, value, :cfg)
358
- cfg.merge!(defaults)
359
- configs << cfg if apply_autodetected(cfg, pair)
360
- end
361
-
362
- configs
363
- end
364
-
365
- def make_statics(ast, defaults={})
366
- statics = []
367
-
368
- each_pair_in_object_expression(ast) do |name, value, pair|
369
- if function?(value)
370
- s = make_method(name, value)
371
- else
372
- s = make_property(name, value)
373
- end
374
-
375
- s[:meta] = {:static => true}
376
- s.merge!(defaults)
377
-
378
- statics << s if apply_autodetected(s, pair, defaults[:inheritable])
379
- end
380
-
381
- statics
382
- end
383
-
384
- # Sets auto-detection related properties :autodetected and
385
- # :inheritdoc on the given member Hash.
386
- #
387
- # When member has a comment, adds code to the related docset and
388
- # returns false.
389
- #
390
- # Otherwise detects the line number of member and returns true.
391
- def apply_autodetected(m, ast, inheritable=true)
392
- docset = find_docset(ast)
393
-
394
- if !docset || docset[:type] != :doc_comment
395
- if inheritable
396
- m[:inheritdoc] = {}
397
- else
398
- m[:private] = true
399
- end
400
- m[:autodetected] = true
401
- end
402
-
403
- if docset
404
- docset[:code] = m
405
- return false
406
- else
407
- # Get line number from third place at range array.
408
- # This third item exists in forked EsprimaJS at
409
- # https://github.com/nene/esprima/tree/linenr-in-range
410
- m[:linenr] = ast["range"][2]
411
- return true
412
- end
413
- end
414
-
415
- # Looks up docset associated with given AST node.
416
- # A dead-stupid and -slow implementation, but works.
417
- def find_docset(ast)
418
- @docs.find do |docset|
419
- docset[:code] == ast
420
- end
421
- end
422
-
423
- def make_method(name, ast=nil)
424
- return {
425
- :tagname => :method,
426
- :name => name,
427
- :params => make_params(ast),
428
- :chainable => chainable?(ast) && name != "constructor",
429
- }
430
- end
431
-
432
- def make_params(ast)
433
- if ast && !empty_fn?(ast)
434
- ast["params"].map {|p| {:name => to_s(p)} }
435
- else
436
- []
437
- end
438
- end
439
-
440
- def chainable?(ast)
441
- if function?(ast) && !empty_fn?(ast)
442
- FunctionAst.return_types(ast) == [:this]
443
- else
444
- false
445
- end
446
- end
447
-
448
- def make_event(name)
449
- return {
450
- :tagname => :event,
451
- :name => name,
452
- }
453
- end
454
-
455
- def make_property(name=nil, ast=nil, tagname=:property)
456
- return {
457
- :tagname => tagname,
458
- :name => name,
459
- :type => make_value_type(ast),
460
- :default => make_default(ast),
461
- }
462
- end
463
-
464
- def make_default(ast)
465
- ast && to_value(ast) != nil ? to_s(ast) : nil
466
- end
467
-
468
- def make_value_type(ast)
469
- if ast
470
- v = to_value(ast)
471
- if v.is_a?(String)
472
- "String"
473
- elsif v.is_a?(Numeric)
474
- "Number"
475
- elsif v.is_a?(TrueClass) || v.is_a?(FalseClass)
476
- "Boolean"
477
- elsif v.is_a?(Array)
478
- "Array"
479
- elsif v.is_a?(Hash)
480
- "Object"
481
- elsif v == :regexp
482
- "RegExp"
483
- else
484
- nil
485
- end
486
- else
487
- nil
488
- end
489
- end
490
-
491
- # -- various helper methods --
492
-
493
- # Iterates over keys and values in ObjectExpression. The keys
494
- # are turned into strings, but values are left as is for further
495
- # processing.
496
- def each_pair_in_object_expression(ast)
497
- return unless ast && object?(ast)
498
-
499
- ast["properties"].each do |p|
500
- yield(key_value(p["key"]), p["value"], p)
501
- end
502
- end
503
-
504
- # Converts object expression property key to string value
505
- def key_value(key)
506
- @evaluator.key_value(key)
507
- end
508
-
509
- # Fully serializes the node
510
- def to_s(ast)
511
- @serializer.to_s(ast)
512
- end
513
-
514
- # Converts AST node into a value.
515
- def to_value(ast)
516
- begin
517
- @evaluator.to_value(ast)
518
- rescue
519
- nil
520
- end
521
- end
522
- end
523
-
524
- end