jsduck 5.0.0.beta2 → 5.0.0.beta3
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/Rakefile +14 -4
- data/bin/jsduck +3 -1
- data/jsduck.gemspec +2 -2
- data/lib/jsduck/app.rb +8 -0
- data/lib/jsduck/assets.rb +3 -0
- data/lib/jsduck/batch_processor.rb +2 -0
- data/lib/jsduck/categories/class_name.rb +2 -26
- data/lib/jsduck/categories/factory.rb +5 -43
- data/lib/jsduck/columns.rb +56 -0
- data/lib/jsduck/doc/delimited_parser.rb +105 -0
- data/lib/jsduck/doc/scanner.rb +2 -1
- data/lib/jsduck/doc/standard_tag_parser.rb +37 -71
- data/lib/jsduck/guide_anchors.rb +32 -0
- data/lib/jsduck/guide_toc.rb +49 -0
- data/lib/jsduck/guides.rb +14 -32
- data/lib/jsduck/inline/video.rb +2 -8
- data/lib/jsduck/js/ast.rb +13 -305
- data/lib/jsduck/js/class.rb +245 -0
- data/lib/jsduck/js/event.rb +34 -0
- data/lib/jsduck/js/fires.rb +42 -0
- data/lib/jsduck/js/method.rb +94 -0
- data/lib/jsduck/js/method_calls.rb +40 -0
- data/lib/jsduck/js/node.rb +29 -0
- data/lib/jsduck/js/property.rb +64 -0
- data/lib/jsduck/js/{function.rb → returns.rb} +8 -3
- data/lib/jsduck/js/scoped_traverser.rb +42 -0
- data/lib/jsduck/logger.rb +13 -1
- data/lib/jsduck/merger.rb +34 -27
- data/lib/jsduck/news.rb +128 -0
- data/lib/jsduck/options.rb +59 -2
- data/lib/jsduck/params_merger.rb +47 -0
- data/lib/jsduck/process/accessors.rb +8 -2
- data/lib/jsduck/process/fires.rb +71 -0
- data/lib/jsduck/process/importer.rb +19 -1
- data/lib/jsduck/render/class.rb +11 -4
- data/lib/jsduck/render/signature_util.rb +14 -0
- data/lib/jsduck/tag/alias.rb +0 -20
- data/lib/jsduck/tag/alternate_class_names.rb +0 -5
- data/lib/jsduck/tag/cfg.rb +30 -5
- data/lib/jsduck/tag/class.rb +45 -2
- data/lib/jsduck/tag/css_mixin.rb +8 -4
- data/lib/jsduck/tag/css_var.rb +26 -5
- data/lib/jsduck/tag/default.rb +2 -8
- data/lib/jsduck/tag/enum.rb +7 -10
- data/lib/jsduck/tag/event.rb +12 -4
- data/lib/jsduck/tag/extends.rb +0 -6
- data/lib/jsduck/tag/fires.rb +53 -0
- data/lib/jsduck/tag/icons/cfg.png +0 -0
- data/lib/jsduck/tag/icons/css_mixin.png +0 -0
- data/lib/jsduck/tag/icons/css_var.png +0 -0
- data/lib/jsduck/tag/icons/event.png +0 -0
- data/lib/jsduck/tag/icons/method.png +0 -0
- data/lib/jsduck/tag/icons/property.png +0 -0
- data/lib/jsduck/tag/member_tag.rb +130 -0
- data/lib/jsduck/tag/method.rb +44 -4
- data/lib/jsduck/tag/param.rb +8 -60
- data/lib/jsduck/tag/property.rb +28 -5
- data/lib/jsduck/tag/tag.rb +3 -75
- data/lib/jsduck/tag/type.rb +1 -11
- data/lib/jsduck/tag_registry.rb +6 -48
- data/lib/jsduck/web/css.rb +8 -1
- data/lib/jsduck/web/data.rb +2 -1
- data/lib/jsduck/web/index_html.rb +1 -0
- data/lib/jsduck/web/member_icons.rb +43 -0
- data/lib/jsduck/web/search.rb +3 -2
- data/lib/jsduck/web/writer.rb +8 -0
- metadata +31 -27
- data/lib/jsduck/docs_code_comparer.rb +0 -44
- data/lib/jsduck/render/signature.rb +0 -94
- data/lib/jsduck/tag/autodetected.rb +0 -21
- data/lib/jsduck/tag/name.rb +0 -36
@@ -0,0 +1,32 @@
|
|
1
|
+
module JsDuck
|
2
|
+
|
3
|
+
# Transforms in-page links so they won't break docs app #!-navigation.
|
4
|
+
#
|
5
|
+
# For example a link to "#automation" in testing guide will be
|
6
|
+
# replaced with "#!/guide/testing-section-automation" and the link
|
7
|
+
# target ID will be transformed into "testing-section-automation".
|
8
|
+
class GuideAnchors
|
9
|
+
|
10
|
+
def self.transform(html, guide_name)
|
11
|
+
html.gsub(/(<a\s+(?:[^<>]*\s+)?href=['"]#)([^!\/].*?)(['"])/i) do |m|
|
12
|
+
"#{$1}!/guide/#{guide_name}-section-#{$2}#{$3}"
|
13
|
+
|
14
|
+
end.gsub(/(<a\s+(?:[^<>]*\s+)?name=['"])(.*?)(['"])/i) do |m|
|
15
|
+
$1 + transform_id($2, guide_name) + $3
|
16
|
+
|
17
|
+
end.gsub(/(<\w+\s+(?:[^<>]*\s+)?id=['"])(.*?)(['"])/i) do |m|
|
18
|
+
$1 + transform_id($2, guide_name) + $3
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.transform_id(id, guide_name)
|
23
|
+
if id =~ /^#{guide_name}-section-/
|
24
|
+
id
|
25
|
+
else
|
26
|
+
"#{guide_name}-section-#{id}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'jsduck/util/html'
|
2
|
+
|
3
|
+
module JsDuck
|
4
|
+
|
5
|
+
# Adds Table of Contents section to guide HTML.
|
6
|
+
class GuideToc
|
7
|
+
|
8
|
+
# Inserts table of contents at the top of guide HTML by looking
|
9
|
+
# for <h2> elements.
|
10
|
+
def self.inject(html, guide_name)
|
11
|
+
toc = []
|
12
|
+
new_html = []
|
13
|
+
|
14
|
+
html.each_line do |line|
|
15
|
+
if line =~ /^\s*<(h[1-6])>(.*?)<\/h[1-6]>$/
|
16
|
+
tag = $1
|
17
|
+
text = Util::HTML.strip_tags($2)
|
18
|
+
id = guide_name + "-section-" + title_to_id(text)
|
19
|
+
if tag == "h2"
|
20
|
+
toc << "<li><a href='#!/guide/#{id}'>#{text}</a></li>\n"
|
21
|
+
end
|
22
|
+
new_html << "<#{tag} id='#{id}'>#{text}</#{tag}>\n"
|
23
|
+
else
|
24
|
+
new_html << line
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Inject TOC below first heading if at least 2 items in TOC
|
29
|
+
if toc.length >= 2
|
30
|
+
new_html.insert(1, [
|
31
|
+
"<div class='toc'>\n",
|
32
|
+
"<p><strong>Contents</strong></p>\n",
|
33
|
+
"<ol>\n",
|
34
|
+
toc,
|
35
|
+
"</ol>\n",
|
36
|
+
"</div>\n",
|
37
|
+
])
|
38
|
+
end
|
39
|
+
|
40
|
+
new_html.flatten.join
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.title_to_id(title)
|
44
|
+
title.downcase.gsub(/[^\w]+/, "-")
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/lib/jsduck/guides.rb
CHANGED
@@ -4,7 +4,8 @@ require 'jsduck/util/io'
|
|
4
4
|
require 'jsduck/util/null_object'
|
5
5
|
require 'jsduck/logger'
|
6
6
|
require 'jsduck/grouped_asset'
|
7
|
-
require 'jsduck/
|
7
|
+
require 'jsduck/guide_toc'
|
8
|
+
require 'jsduck/guide_anchors'
|
8
9
|
require 'jsduck/img/dir'
|
9
10
|
require 'fileutils'
|
10
11
|
|
@@ -55,6 +56,10 @@ module JsDuck
|
|
55
56
|
def load_guide(guide)
|
56
57
|
return Logger.warn(:guide, "Guide not found", guide["url"]) unless File.exists?(guide["url"])
|
57
58
|
return Logger.warn(:guide, "Guide not found", guide[:filename]) unless File.exists?(guide[:filename])
|
59
|
+
unless js_ident?(guide["name"])
|
60
|
+
# Guide name is also used as JSONP callback method name.
|
61
|
+
return Logger.warn(:guide, "Guide name is not valid JS identifier: #{guide["name"]}", guide[:filename])
|
62
|
+
end
|
58
63
|
|
59
64
|
begin
|
60
65
|
return format_guide(guide)
|
@@ -67,7 +72,9 @@ module JsDuck
|
|
67
72
|
def format_guide(guide)
|
68
73
|
@formatter.doc_context = {:filename => guide[:filename], :linenr => 0}
|
69
74
|
@formatter.images = Img::Dir.new(guide["url"], "guides/#{guide["name"]}")
|
70
|
-
html =
|
75
|
+
html = @formatter.format(Util::IO.read(guide[:filename]))
|
76
|
+
html = GuideToc.inject(html, guide['name'])
|
77
|
+
html = GuideAnchors.transform(html, guide['name'])
|
71
78
|
|
72
79
|
# Report unused images (but ignore the icon files)
|
73
80
|
@formatter.images.get("icon.png")
|
@@ -102,6 +109,11 @@ module JsDuck
|
|
102
109
|
end
|
103
110
|
end
|
104
111
|
|
112
|
+
# True when string is valid JavaScript identifier
|
113
|
+
def js_ident?(str)
|
114
|
+
/\A[$\w]+\z/ =~ str
|
115
|
+
end
|
116
|
+
|
105
117
|
# Ensures the guide dir contains icon.png.
|
106
118
|
# When there isn't looks for icon-lg.png and renames it to icon.png.
|
107
119
|
# When neither exists, copies over default icon.
|
@@ -115,36 +127,6 @@ module JsDuck
|
|
115
127
|
end
|
116
128
|
end
|
117
129
|
|
118
|
-
# Creates table of contents at the top of guide by looking for <h2> elements in HTML.
|
119
|
-
def add_toc(guide, html)
|
120
|
-
toc = [
|
121
|
-
"<div class='toc'>\n",
|
122
|
-
"<p><strong>Contents</strong></p>\n",
|
123
|
-
"<ol>\n",
|
124
|
-
]
|
125
|
-
new_html = []
|
126
|
-
i = 0
|
127
|
-
html.each_line do |line|
|
128
|
-
if line =~ /^<h2>(.*)<\/h2>$/
|
129
|
-
i += 1
|
130
|
-
text = Util::HTML.strip_tags($1)
|
131
|
-
toc << "<li><a href='#!/guide/#{guide['name']}-section-#{i}'>#{text}</a></li>\n"
|
132
|
-
new_html << "<h2 id='#{guide['name']}-section-#{i}'>#{text}</h2>\n"
|
133
|
-
else
|
134
|
-
new_html << line
|
135
|
-
end
|
136
|
-
end
|
137
|
-
toc << "</ol>\n"
|
138
|
-
toc << "</div>\n"
|
139
|
-
# Inject TOC at below first heading if at least 2 items in TOC
|
140
|
-
if i >= 2
|
141
|
-
new_html.insert(1, toc)
|
142
|
-
new_html.flatten.join
|
143
|
-
else
|
144
|
-
html
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
130
|
# Returns HTML listing of guides
|
149
131
|
def to_html(style="")
|
150
132
|
html = @groups.map do |group|
|
data/lib/jsduck/inline/video.rb
CHANGED
@@ -16,14 +16,8 @@ module JsDuck
|
|
16
16
|
@templates = {
|
17
17
|
"html5" => '<video src="%u">%a</video>',
|
18
18
|
"vimeo" => [
|
19
|
-
'<p><
|
20
|
-
|
21
|
-
'<param name="allowscriptaccess" value="always" />',
|
22
|
-
'<param name="flashvars" value="api=1" />',
|
23
|
-
'<param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=%u&server=vimeo.com&color=4CC208&fullscreen=1" />',
|
24
|
-
'<embed src="http://vimeo.com/moogaloop.swf?clip_id=%u&server=vimeo.com&color=4CC208&fullscreen=1" ',
|
25
|
-
'type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="360"></embed>',
|
26
|
-
'</object></p>',
|
19
|
+
'<p><iframe src="http://player.vimeo.com/video/%u" width="640" height="360" frameborder="0" ',
|
20
|
+
'webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>'
|
27
21
|
].join
|
28
22
|
}
|
29
23
|
|
data/lib/jsduck/js/ast.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
require "jsduck/js/
|
1
|
+
require "jsduck/js/class"
|
2
|
+
require "jsduck/js/method"
|
3
|
+
require "jsduck/js/event"
|
4
|
+
require "jsduck/js/property"
|
2
5
|
require "jsduck/js/node"
|
3
|
-
require "jsduck/tag_registry"
|
4
6
|
|
5
7
|
module JsDuck
|
6
8
|
module Js
|
@@ -48,313 +50,19 @@ module JsDuck
|
|
48
50
|
def detect(node)
|
49
51
|
ast = Js::Node.create(node)
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
elsif exp && exp.ext_override?
|
60
|
-
make_class("", exp)
|
61
|
-
|
62
|
-
# foo = Ext.extend(Parent, {})
|
63
|
-
elsif exp && exp.assignment_expression? && exp["right"].ext_extend?
|
64
|
-
make_class(exp["left"].to_s, exp["right"])
|
65
|
-
|
66
|
-
# Foo = ...
|
67
|
-
elsif exp && exp.assignment_expression? && class_name?(exp["left"].to_s)
|
68
|
-
make_class(exp["left"].to_s, exp["right"])
|
69
|
-
|
70
|
-
# var foo = Ext.extend(Parent, {})
|
71
|
-
elsif var && var["init"].ext_extend?
|
72
|
-
make_class(var["id"].to_s, var["init"])
|
73
|
-
|
74
|
-
# var Foo = ...
|
75
|
-
elsif var && class_name?(var["id"].to_s)
|
76
|
-
make_class(var["id"].to_s, var["right"])
|
77
|
-
|
78
|
-
# function Foo() {}
|
79
|
-
elsif ast.function? && class_name?(ast["id"].to_s || "")
|
80
|
-
make_class(ast["id"].to_s)
|
81
|
-
|
82
|
-
# { ... }
|
83
|
-
elsif ast.object_expression?
|
84
|
-
make_class("", ast)
|
85
|
-
|
86
|
-
# function foo() {}
|
87
|
-
elsif ast.function?
|
88
|
-
make_method(ast["id"].to_s || "", ast)
|
89
|
-
|
90
|
-
# foo = function() {}
|
91
|
-
elsif exp && exp.assignment_expression? && exp["right"].function?
|
92
|
-
make_method(exp["left"].to_s, exp["right"])
|
93
|
-
|
94
|
-
# var foo = function() {}
|
95
|
-
elsif var && var["init"] && var["init"].function?
|
96
|
-
make_method(var["id"].to_s, var["init"])
|
97
|
-
|
98
|
-
# (function() {})
|
99
|
-
elsif exp && exp.function?
|
100
|
-
make_method(exp["id"].to_s || "", exp)
|
101
|
-
|
102
|
-
# foo: function() {}
|
103
|
-
elsif ast.property? && ast["value"].function?
|
104
|
-
make_method(ast["key"].key_value, ast["value"])
|
105
|
-
|
106
|
-
# this.fireEvent("foo", ...)
|
107
|
-
elsif exp && exp.fire_event?
|
108
|
-
make_event(exp["arguments"][0].to_value)
|
109
|
-
|
110
|
-
# foo = ...
|
111
|
-
elsif exp && exp.assignment_expression?
|
112
|
-
make_property(exp["left"].to_s, exp["right"])
|
113
|
-
|
114
|
-
# var foo = ...
|
115
|
-
elsif var
|
116
|
-
make_property(var["id"].to_s, var["init"])
|
117
|
-
|
118
|
-
# foo: ...
|
119
|
-
elsif ast.property?
|
120
|
-
make_property(ast["key"].key_value, ast["value"])
|
121
|
-
|
122
|
-
# foo;
|
123
|
-
elsif exp && exp.identifier?
|
124
|
-
make_property(exp.to_s)
|
125
|
-
|
126
|
-
# "foo" (inside some expression)
|
127
|
-
elsif ast.string?
|
128
|
-
make_property(ast.to_value)
|
129
|
-
|
130
|
-
# "foo"; (as a statement of it's own)
|
131
|
-
elsif exp && exp.string?
|
132
|
-
make_property(exp.to_value)
|
133
|
-
|
53
|
+
if doc = Js::Class.detect(ast, @docs)
|
54
|
+
doc
|
55
|
+
elsif doc = Js::Method.detect(ast)
|
56
|
+
doc
|
57
|
+
elsif doc = Js::Event.detect(ast)
|
58
|
+
doc
|
59
|
+
elsif doc = Js::Property.detect(ast)
|
60
|
+
doc
|
134
61
|
else
|
135
|
-
|
62
|
+
Js::Property.make()
|
136
63
|
end
|
137
64
|
end
|
138
65
|
|
139
|
-
private
|
140
|
-
|
141
|
-
# Class name begins with upcase char
|
142
|
-
def class_name?(name)
|
143
|
-
return name.split(/\./).last =~ /\A[A-Z]/
|
144
|
-
end
|
145
|
-
|
146
|
-
def make_class(name, ast=nil)
|
147
|
-
cls = {
|
148
|
-
:tagname => :class,
|
149
|
-
:name => name,
|
150
|
-
}
|
151
|
-
|
152
|
-
# apply information from Ext.extend, Ext.define, or {}
|
153
|
-
if ast
|
154
|
-
if ast.ext_define?
|
155
|
-
detect_ext_define(cls, ast)
|
156
|
-
elsif ast.ext_extend?
|
157
|
-
detect_ext_something(:extends, cls, ast)
|
158
|
-
elsif ast.ext_override?
|
159
|
-
detect_ext_something(:override, cls, ast)
|
160
|
-
elsif ast.object_expression?
|
161
|
-
detect_class_members_from_object(cls, ast)
|
162
|
-
elsif ast.array_expression?
|
163
|
-
detect_class_members_from_array(cls, ast)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
return cls
|
168
|
-
end
|
169
|
-
|
170
|
-
# Detection of Ext.extend() or Ext.override().
|
171
|
-
# The type parameter must be correspondingly either :extend or :override.
|
172
|
-
def detect_ext_something(type, cls, ast)
|
173
|
-
args = ast["arguments"]
|
174
|
-
cls[type] = args[0].to_s
|
175
|
-
if args.length == 2 && args[1].object_expression?
|
176
|
-
detect_class_members_from_object(cls, args[1])
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
# Inspects Ext.define() and copies detected properties over to the
|
181
|
-
# given cls Hash
|
182
|
-
def detect_ext_define(cls, ast)
|
183
|
-
# defaults
|
184
|
-
cls.merge!(TagRegistry.ext_define_defaults)
|
185
|
-
cls[:members] = []
|
186
|
-
cls[:code_type] = :ext_define
|
187
|
-
|
188
|
-
ast["arguments"][1].each_property do |key, value, pair|
|
189
|
-
if tag = TagRegistry.get_by_ext_define_pattern(key)
|
190
|
-
tag.parse_ext_define(cls, value)
|
191
|
-
else
|
192
|
-
case key
|
193
|
-
when "config"
|
194
|
-
cls[:members] += make_configs(value, {:accessor => true})
|
195
|
-
when "cachedConfig"
|
196
|
-
cls[:members] += make_configs(value, {:accessor => true})
|
197
|
-
when "eventedConfig"
|
198
|
-
cls[:members] += make_configs(value, {:accessor => true, :evented => true})
|
199
|
-
when "statics"
|
200
|
-
cls[:members] += make_statics(value)
|
201
|
-
when "inheritableStatics"
|
202
|
-
cls[:members] += make_statics(value, {:inheritable => true})
|
203
|
-
else
|
204
|
-
detect_method_or_property(cls, key, value, pair)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
# Detects class members from object literal
|
211
|
-
def detect_class_members_from_object(cls, ast)
|
212
|
-
cls[:members] = []
|
213
|
-
ast.each_property do |key, value, pair|
|
214
|
-
detect_method_or_property(cls, key, value, pair)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
# Detects class members from array literal
|
219
|
-
def detect_class_members_from_array(cls, ast)
|
220
|
-
cls[:members] = []
|
221
|
-
|
222
|
-
# This will most likely be an @enum class, in which case the
|
223
|
-
# enum will be for documentation purposes only.
|
224
|
-
cls[:enum] = {:doc_only => true}
|
225
|
-
|
226
|
-
ast["elements"].each do |el|
|
227
|
-
detect_method_or_property(cls, el.key_value, el, el)
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
# Detects item in object literal either as method or property
|
232
|
-
def detect_method_or_property(cls, key, value, pair)
|
233
|
-
if value.function?
|
234
|
-
m = make_method(key, value)
|
235
|
-
cls[:members] << m if apply_autodetected(m, pair)
|
236
|
-
else
|
237
|
-
p = make_property(key, value)
|
238
|
-
cls[:members] << p if apply_autodetected(p, pair)
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
def make_configs(ast, defaults={})
|
243
|
-
configs = []
|
244
|
-
|
245
|
-
ast.each_property do |name, value, pair|
|
246
|
-
cfg = make_property(name, value, :cfg)
|
247
|
-
cfg.merge!(defaults)
|
248
|
-
configs << cfg if apply_autodetected(cfg, pair)
|
249
|
-
end
|
250
|
-
|
251
|
-
configs
|
252
|
-
end
|
253
|
-
|
254
|
-
def make_statics(ast, defaults={})
|
255
|
-
statics = []
|
256
|
-
|
257
|
-
ast.each_property do |name, value, pair|
|
258
|
-
if value.function?
|
259
|
-
s = make_method(name, value)
|
260
|
-
else
|
261
|
-
s = make_property(name, value)
|
262
|
-
end
|
263
|
-
|
264
|
-
s[:static] = true
|
265
|
-
s.merge!(defaults)
|
266
|
-
|
267
|
-
statics << s if apply_autodetected(s, pair, defaults[:inheritable])
|
268
|
-
end
|
269
|
-
|
270
|
-
statics
|
271
|
-
end
|
272
|
-
|
273
|
-
# Sets auto-detection related properties :autodetected and
|
274
|
-
# :inheritdoc on the given member Hash.
|
275
|
-
#
|
276
|
-
# When member has a comment, adds code to the related docset and
|
277
|
-
# returns false.
|
278
|
-
#
|
279
|
-
# Otherwise detects the line number of member and returns true.
|
280
|
-
def apply_autodetected(m, ast, inheritable=true)
|
281
|
-
docset = find_docset(ast.raw)
|
282
|
-
|
283
|
-
if !docset || docset[:type] != :doc_comment
|
284
|
-
if inheritable
|
285
|
-
m[:inheritdoc] = {}
|
286
|
-
else
|
287
|
-
m[:private] = true
|
288
|
-
end
|
289
|
-
m[:autodetected] = {:tagname => m[:tagname]}
|
290
|
-
end
|
291
|
-
|
292
|
-
if docset
|
293
|
-
docset[:code] = m
|
294
|
-
return false
|
295
|
-
else
|
296
|
-
m[:linenr] = ast.linenr
|
297
|
-
return true
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
# Looks up docset associated with given AST node.
|
302
|
-
# A dead-stupid and -slow implementation, but works.
|
303
|
-
#
|
304
|
-
# The comparison needs to be done between raw AST nodes - multiple
|
305
|
-
# Node instances can be created to wrap a single raw AST node,
|
306
|
-
# and they will then not be equal.
|
307
|
-
def find_docset(raw_ast)
|
308
|
-
@docs.find do |docset|
|
309
|
-
docset[:code] == raw_ast
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
def make_method(name, ast)
|
314
|
-
return {
|
315
|
-
:tagname => :method,
|
316
|
-
:name => name,
|
317
|
-
:params => make_params(ast),
|
318
|
-
:chainable => chainable?(ast) && name != "constructor",
|
319
|
-
}
|
320
|
-
end
|
321
|
-
|
322
|
-
def make_params(ast)
|
323
|
-
if ast.function? && !ast.ext_empty_fn?
|
324
|
-
ast["params"].map {|p| {:name => p.to_s} }
|
325
|
-
else
|
326
|
-
[]
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
def chainable?(ast)
|
331
|
-
if ast.function? && !ast.ext_empty_fn?
|
332
|
-
Js::Function.return_types(ast.raw) == [:this]
|
333
|
-
else
|
334
|
-
false
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
def make_event(name)
|
339
|
-
return {
|
340
|
-
:tagname => :event,
|
341
|
-
:name => name,
|
342
|
-
}
|
343
|
-
end
|
344
|
-
|
345
|
-
def make_property(name=nil, ast=nil, tagname=:property)
|
346
|
-
return {
|
347
|
-
:tagname => tagname,
|
348
|
-
:name => name,
|
349
|
-
:type => ast && ast.value_type,
|
350
|
-
:default => ast && make_default(ast),
|
351
|
-
}
|
352
|
-
end
|
353
|
-
|
354
|
-
def make_default(ast)
|
355
|
-
ast.to_value != nil ? ast.to_s : nil
|
356
|
-
end
|
357
|
-
|
358
66
|
end
|
359
67
|
|
360
68
|
end
|