jsduck 5.0.0.beta2 → 5.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|