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.
- data/.travis.yml +0 -1
- data/README.md +32 -6
- data/Rakefile +10 -18
- data/bin/compare +5 -5
- data/bin/jsduck +2 -3
- data/jsduck.gemspec +3 -4
- data/lib/jsduck/aggregator.rb +21 -80
- data/lib/jsduck/app.rb +7 -14
- data/lib/jsduck/app_data.rb +4 -5
- data/lib/jsduck/assets.rb +4 -7
- data/lib/jsduck/base_type.rb +53 -0
- data/lib/jsduck/batch_parser.rb +8 -87
- data/lib/jsduck/batch_processor.rb +77 -0
- data/lib/jsduck/categories/auto.rb +83 -0
- data/lib/jsduck/categories/class_name.rb +63 -0
- data/lib/jsduck/categories/factory.rb +113 -0
- data/lib/jsduck/categories/file.rb +75 -0
- data/lib/jsduck/class.rb +3 -9
- data/lib/jsduck/class_doc_expander.rb +1 -1
- data/lib/jsduck/css/lexer.rb +203 -0
- data/lib/jsduck/css/parser.rb +121 -0
- data/lib/jsduck/doc/comment.rb +40 -0
- data/lib/jsduck/doc/map.rb +23 -0
- data/lib/jsduck/doc/parser.rb +128 -0
- data/lib/jsduck/doc/processor.rb +52 -0
- data/lib/jsduck/doc/scanner.rb +76 -0
- data/lib/jsduck/doc/standard_tag_parser.rb +154 -0
- data/lib/jsduck/doc/subproperties.rb +64 -0
- data/lib/jsduck/docs_code_comparer.rb +31 -0
- data/lib/jsduck/export_writer.rb +2 -2
- data/lib/jsduck/exporter/app.rb +16 -4
- data/lib/jsduck/exporter/full.rb +2 -2
- data/lib/jsduck/format/batch.rb +58 -0
- data/lib/jsduck/format/class.rb +62 -0
- data/lib/jsduck/format/doc.rb +172 -0
- data/lib/jsduck/format/html_stack.rb +109 -0
- data/lib/jsduck/format/shortener.rb +55 -0
- data/lib/jsduck/format/subproperties.rb +64 -0
- data/lib/jsduck/guides.rb +32 -14
- data/lib/jsduck/index_html.rb +3 -1
- data/lib/jsduck/inline/auto_link.rb +2 -2
- data/lib/jsduck/inline/link.rb +4 -3
- data/lib/jsduck/inline/link_renderer.rb +2 -2
- data/lib/jsduck/inline/video.rb +8 -2
- data/lib/jsduck/js/ast.rb +361 -0
- data/lib/jsduck/js/esprima.rb +39 -0
- data/lib/jsduck/{esprima → js/esprima}/esprima.js +0 -0
- data/lib/jsduck/js/evaluator.rb +70 -0
- data/lib/jsduck/js/ext_patterns.rb +70 -0
- data/lib/jsduck/js/function.rb +206 -0
- data/lib/jsduck/js/node.rb +194 -0
- data/lib/jsduck/js/node_array.rb +36 -0
- data/lib/jsduck/js/parser.rb +223 -0
- data/lib/jsduck/js/serializer.rb +263 -0
- data/lib/jsduck/js/utils.rb +21 -0
- data/lib/jsduck/logger.rb +3 -13
- data/lib/jsduck/members_index.rb +3 -4
- data/lib/jsduck/merger.rb +25 -145
- data/lib/jsduck/options.rb +29 -132
- data/lib/jsduck/parser.rb +76 -0
- data/lib/jsduck/process/accessors.rb +133 -0
- data/lib/jsduck/process/circular_deps.rb +58 -0
- data/lib/jsduck/process/enums.rb +91 -0
- data/lib/jsduck/process/ext4_events.rb +43 -0
- data/lib/jsduck/process/global_members.rb +36 -0
- data/lib/jsduck/process/ignored_classes.rb +16 -0
- data/lib/jsduck/process/importer.rb +58 -0
- data/lib/jsduck/process/inherit_doc.rb +197 -0
- data/lib/jsduck/process/lint.rb +135 -0
- data/lib/jsduck/process/overrides.rb +99 -0
- data/lib/jsduck/process/return_values.rb +72 -0
- data/lib/jsduck/process/versions.rb +102 -0
- data/lib/jsduck/relations.rb +5 -0
- data/lib/jsduck/render/class.rb +144 -0
- data/lib/jsduck/render/sidebar.rb +97 -0
- data/lib/jsduck/render/signature.rb +94 -0
- data/lib/jsduck/render/subproperties.rb +99 -0
- data/lib/jsduck/render/tags.rb +38 -0
- data/lib/jsduck/search_data.rb +19 -13
- data/lib/jsduck/source/file.rb +8 -17
- data/lib/jsduck/tag/abstract.rb +4 -7
- data/lib/jsduck/tag/accessor.rb +10 -0
- data/lib/jsduck/tag/alias.rb +61 -0
- data/lib/jsduck/tag/alternate_class_names.rb +17 -0
- data/lib/jsduck/tag/aside.rb +28 -31
- data/lib/jsduck/tag/author.rb +9 -5
- data/lib/jsduck/tag/boolean_tag.rb +24 -0
- data/lib/jsduck/tag/cfg.rb +45 -0
- data/lib/jsduck/tag/chainable.rb +5 -7
- data/lib/jsduck/tag/class.rb +28 -0
- data/lib/jsduck/tag/class_list_tag.rb +40 -0
- data/lib/jsduck/tag/constructor.rb +24 -0
- data/lib/jsduck/tag/css_mixin.rb +17 -0
- data/lib/jsduck/tag/css_var.rb +29 -0
- data/lib/jsduck/tag/default.rb +31 -0
- data/lib/jsduck/tag/deprecated.rb +13 -27
- data/lib/jsduck/tag/deprecated_tag.rb +58 -0
- data/lib/jsduck/tag/doc.rb +32 -0
- data/lib/jsduck/tag/docauthor.rb +4 -5
- data/lib/jsduck/tag/enum.rb +70 -0
- data/lib/jsduck/tag/event.rb +28 -0
- data/lib/jsduck/tag/evented.rb +10 -0
- data/lib/jsduck/tag/extends.rb +45 -0
- data/lib/jsduck/tag/ftype.rb +18 -0
- data/lib/jsduck/tag/hide.rb +4 -11
- data/lib/jsduck/tag/ignore.rb +6 -7
- data/lib/jsduck/tag/inheritable.rb +10 -0
- data/lib/jsduck/tag/inheritdoc.rb +48 -0
- data/lib/jsduck/tag/markdown.rb +8 -6
- data/lib/jsduck/tag/member.rb +24 -0
- data/lib/jsduck/tag/method.rb +35 -0
- data/lib/jsduck/tag/mixins.rb +26 -0
- data/lib/jsduck/tag/name.rb +36 -0
- data/lib/jsduck/tag/new.rb +13 -27
- data/lib/jsduck/tag/override.rb +37 -0
- data/lib/jsduck/tag/overrides.rb +29 -0
- data/lib/jsduck/tag/param.rb +87 -0
- data/lib/jsduck/tag/preventable.rb +19 -10
- data/lib/jsduck/tag/private.rb +28 -13
- data/lib/jsduck/tag/property.rb +39 -0
- data/lib/jsduck/tag/protected.rb +5 -7
- data/lib/jsduck/tag/ptype.rb +18 -0
- data/lib/jsduck/tag/readonly.rb +4 -7
- data/lib/jsduck/tag/removed.rb +21 -29
- data/lib/jsduck/tag/required.rb +11 -9
- data/lib/jsduck/tag/requires.rb +12 -0
- data/lib/jsduck/tag/return.rb +47 -0
- data/lib/jsduck/tag/since.rb +19 -11
- data/lib/jsduck/tag/singleton.rb +15 -0
- data/lib/jsduck/tag/static.rb +5 -7
- data/lib/jsduck/tag/subproperties.rb +23 -0
- data/lib/jsduck/tag/tag.rb +208 -0
- data/lib/jsduck/tag/template.rb +14 -9
- data/lib/jsduck/tag/throws.rb +38 -0
- data/lib/jsduck/tag/type.rb +48 -0
- data/lib/jsduck/tag/uses.rb +12 -0
- data/lib/jsduck/tag/xtype.rb +30 -0
- data/lib/jsduck/tag_loader.rb +39 -0
- data/lib/jsduck/tag_registry.rb +189 -0
- data/lib/jsduck/type_parser.rb +3 -3
- data/lib/jsduck/web_writer.rb +2 -2
- data/lib/jsduck/welcome.rb +1 -1
- metadata +578 -538
- data/lib/jsduck/accessors.rb +0 -136
- data/lib/jsduck/ast.rb +0 -524
- data/lib/jsduck/auto_categories.rb +0 -80
- data/lib/jsduck/batch_formatter.rb +0 -60
- data/lib/jsduck/categories.rb +0 -73
- data/lib/jsduck/categories_class_name.rb +0 -37
- data/lib/jsduck/circular_deps.rb +0 -56
- data/lib/jsduck/class_formatter.rb +0 -102
- data/lib/jsduck/columns.rb +0 -56
- data/lib/jsduck/css_lexer.rb +0 -201
- data/lib/jsduck/css_parser.rb +0 -119
- data/lib/jsduck/doc_ast.rb +0 -319
- data/lib/jsduck/doc_formatter.rb +0 -142
- data/lib/jsduck/doc_parser.rb +0 -611
- data/lib/jsduck/doc_type.rb +0 -59
- data/lib/jsduck/enum.rb +0 -73
- data/lib/jsduck/esprima.rb +0 -51
- data/lib/jsduck/evaluator.rb +0 -69
- data/lib/jsduck/ext_patterns.rb +0 -58
- data/lib/jsduck/file_categories.rb +0 -76
- data/lib/jsduck/function_ast.rb +0 -206
- data/lib/jsduck/guide_anchors.rb +0 -32
- data/lib/jsduck/guide_toc.rb +0 -49
- data/lib/jsduck/html_stack.rb +0 -105
- data/lib/jsduck/importer.rb +0 -121
- data/lib/jsduck/inherit_doc.rb +0 -193
- data/lib/jsduck/js_parser.rb +0 -221
- data/lib/jsduck/lint.rb +0 -133
- data/lib/jsduck/meta_tag.rb +0 -88
- data/lib/jsduck/meta_tag_loader.rb +0 -67
- data/lib/jsduck/meta_tag_registry.rb +0 -111
- data/lib/jsduck/meta_tag_renderer.rb +0 -34
- data/lib/jsduck/news.rb +0 -128
- data/lib/jsduck/override.rb +0 -87
- data/lib/jsduck/renderer.rb +0 -361
- data/lib/jsduck/return_values.rb +0 -72
- data/lib/jsduck/serializer.rb +0 -262
- data/lib/jsduck/shortener.rb +0 -58
- data/lib/jsduck/signature_renderer.rb +0 -91
- data/lib/jsduck/source/file_parser.rb +0 -72
data/lib/jsduck/guide_anchors.rb
DELETED
@@ -1,32 +0,0 @@
|
|
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
|
data/lib/jsduck/guide_toc.rb
DELETED
@@ -1,49 +0,0 @@
|
|
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/html_stack.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
require 'jsduck/logger'
|
2
|
-
|
3
|
-
module JsDuck
|
4
|
-
|
5
|
-
# Tracks opening and closing of HTML tags, with the purpose of
|
6
|
-
# closing down the unfinished tags.
|
7
|
-
class HtmlStack
|
8
|
-
|
9
|
-
# Initializes the stack with two optional parameters:
|
10
|
-
#
|
11
|
-
# @param ignore_html A hash of additional HTML tags that don't need closing.
|
12
|
-
# @param doc_context Filename and linenr of the current doc-comment.
|
13
|
-
def initialize(ignore_html={}, doc_context={})
|
14
|
-
@ignore_html = ignore_html
|
15
|
-
@doc_context = doc_context
|
16
|
-
@open_tags = []
|
17
|
-
end
|
18
|
-
|
19
|
-
# Scans an opening tag in HTML using the passed in StringScanner.
|
20
|
-
def open(s)
|
21
|
-
s.scan(/</) + push_tag(s.scan(/\w+/)) + s.scan_until(/>|\Z/)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Scans a closing tag in HTML using the passed in StringScanner.
|
25
|
-
def close(s)
|
26
|
-
s.scan(/<\//)
|
27
|
-
tag = s.scan(/\w+/)
|
28
|
-
s.scan(/>/)
|
29
|
-
|
30
|
-
pop_tags(tag).map {|t| "</#{t}>" }.join
|
31
|
-
end
|
32
|
-
|
33
|
-
# Registers opening of a tag. Returns the tag.
|
34
|
-
def push_tag(tag)
|
35
|
-
@open_tags.push(tag) unless void?(tag)
|
36
|
-
tag
|
37
|
-
end
|
38
|
-
|
39
|
-
# True when the tag is currently open.
|
40
|
-
def open?(tag)
|
41
|
-
@open_tags.include?(tag)
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
# Registers closing of a tag. Returns all the tags that need to
|
47
|
-
# be closed at that point.
|
48
|
-
def pop_tags(tag)
|
49
|
-
if !@open_tags.include?(tag)
|
50
|
-
if @ignore_html[tag]
|
51
|
-
return [tag]
|
52
|
-
else
|
53
|
-
warn_unopened(tag)
|
54
|
-
return []
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
popped = []
|
59
|
-
begin
|
60
|
-
popped << t = @open_tags.pop
|
61
|
-
if t != tag
|
62
|
-
warn_unclosed(t)
|
63
|
-
end
|
64
|
-
end until t == tag
|
65
|
-
|
66
|
-
popped
|
67
|
-
end
|
68
|
-
|
69
|
-
def warn_unopened(*tags)
|
70
|
-
warn("Unopened HTML tag", tags)
|
71
|
-
end
|
72
|
-
|
73
|
-
def warn_unclosed(*tags)
|
74
|
-
warn("Unclosed HTML tag", tags)
|
75
|
-
end
|
76
|
-
|
77
|
-
def warn(msg, tags)
|
78
|
-
ctx = @doc_context
|
79
|
-
tag_list = tags.map {|tag| "<#{tag}>" }.join(", ")
|
80
|
-
Logger.warn(:html, "#{msg}: #{tag_list}", ctx[:filename], ctx[:linenr])
|
81
|
-
end
|
82
|
-
|
83
|
-
def void?(tag)
|
84
|
-
VOID_TAGS[tag] || @ignore_html[tag]
|
85
|
-
end
|
86
|
-
|
87
|
-
# Tags that don't require closing
|
88
|
-
VOID_TAGS = {
|
89
|
-
"base" => true,
|
90
|
-
"link" => true,
|
91
|
-
"meta" => true,
|
92
|
-
"hr" => true,
|
93
|
-
"br" => true,
|
94
|
-
"wbr" => true,
|
95
|
-
"area" => true,
|
96
|
-
"img" => true,
|
97
|
-
"param" => true,
|
98
|
-
"input" => true,
|
99
|
-
"isindex" => true,
|
100
|
-
"option" => true,
|
101
|
-
}
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
data/lib/jsduck/importer.rb
DELETED
@@ -1,121 +0,0 @@
|
|
1
|
-
require 'jsduck/util/json'
|
2
|
-
require 'jsduck/util/null_object'
|
3
|
-
require 'jsduck/logger'
|
4
|
-
require 'jsduck/util/parallel'
|
5
|
-
|
6
|
-
module JsDuck
|
7
|
-
|
8
|
-
# Reads in JSDuck exports of different versions of docs.
|
9
|
-
module Importer
|
10
|
-
module_function
|
11
|
-
|
12
|
-
# Loads in exported docs and generates @since and @new tags based on that data.
|
13
|
-
def import(imports, relations, new_since=nil)
|
14
|
-
if imports.length > 0
|
15
|
-
generate_since_tags(read_all(imports), relations, new_since)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Reads in data for all versions, returning array of
|
20
|
-
# version/class-data pairs. We don't use a hash to preserve the
|
21
|
-
# order of versions (from oldest to newest).
|
22
|
-
def read_all(imports)
|
23
|
-
imports.map do |ver|
|
24
|
-
{
|
25
|
-
:version => ver[:version],
|
26
|
-
:classes => ver[:path] ? read(ver) : current_version,
|
27
|
-
}
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def current_version
|
32
|
-
Util::NullObject.new(:[] => Util::NullObject.new(:[] => true))
|
33
|
-
end
|
34
|
-
|
35
|
-
# Reads in data from all .json files in directory
|
36
|
-
def read(ver)
|
37
|
-
# Map list of files into pairs of (classname, members-hash)
|
38
|
-
pairs = Util::Parallel.map(Dir[ver[:path] + "/*.json"]) do |filename|
|
39
|
-
JsDuck::Logger.log("Importing #{ver[:version]}", filename)
|
40
|
-
json = Util::Json.read(filename)
|
41
|
-
[json["name"], members_id_index(json)]
|
42
|
-
end
|
43
|
-
|
44
|
-
# Turn key-value pairs array into hash
|
45
|
-
return Hash[ pairs ]
|
46
|
-
end
|
47
|
-
|
48
|
-
# creates index of all class members
|
49
|
-
def members_id_index(json)
|
50
|
-
index = {}
|
51
|
-
["members", "statics"].each do |group_name|
|
52
|
-
json[group_name].each_pair do |tagname, members|
|
53
|
-
members.each do |m|
|
54
|
-
index[m["id"]] = true
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
index
|
59
|
-
end
|
60
|
-
|
61
|
-
# Using the imported versions data, adds @since tags to all
|
62
|
-
# classes/members.
|
63
|
-
def generate_since_tags(versions, relations, new_since=nil)
|
64
|
-
new_versions = build_new_versions_map(versions, new_since)
|
65
|
-
|
66
|
-
relations.each do |cls|
|
67
|
-
v = cls[:meta][:since] || class_since(versions, cls)
|
68
|
-
cls[:meta][:since] = v
|
69
|
-
cls[:meta][:new] = true if new_versions[v]
|
70
|
-
|
71
|
-
cls.all_local_members.each do |m|
|
72
|
-
v = m[:meta][:since] || member_since(versions, cls, m)
|
73
|
-
m[:meta][:since] = v
|
74
|
-
m[:meta][:new] = true if new_versions[v]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# Generates a lookup table of versions that we are going to label
|
80
|
-
# with @new tags. By default we use the latest version, otherwise
|
81
|
-
# use all versions since the latest.
|
82
|
-
def build_new_versions_map(versions, new_since=nil)
|
83
|
-
new_versions = {}
|
84
|
-
|
85
|
-
if new_since
|
86
|
-
versions.map {|v| v[:version] }.each do |v|
|
87
|
-
if v == new_since || !new_versions.empty?
|
88
|
-
new_versions[v] = true
|
89
|
-
end
|
90
|
-
end
|
91
|
-
else
|
92
|
-
new_versions[versions.last[:version]] = true
|
93
|
-
end
|
94
|
-
|
95
|
-
new_versions
|
96
|
-
end
|
97
|
-
|
98
|
-
def member_since(versions, cls, m)
|
99
|
-
versions.each do |ver|
|
100
|
-
c = ver[:classes][cls[:name]]
|
101
|
-
return ver[:version] if c && c[m[:id]]
|
102
|
-
cls[:alternateClassNames].each do |name|
|
103
|
-
c = ver[:classes][name]
|
104
|
-
return ver[:version] if c && c[m[:id]]
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
# Returns name of the version since which the class is available
|
110
|
-
def class_since(versions, cls)
|
111
|
-
versions.each do |ver|
|
112
|
-
return ver[:version] if ver[:classes][cls[:name]]
|
113
|
-
cls[:alternateClassNames].each do |name|
|
114
|
-
return ver[:version] if ver[:classes][name]
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
end
|
data/lib/jsduck/inherit_doc.rb
DELETED
@@ -1,193 +0,0 @@
|
|
1
|
-
require 'jsduck/logger'
|
2
|
-
require 'jsduck/class'
|
3
|
-
|
4
|
-
module JsDuck
|
5
|
-
|
6
|
-
# Deals with inheriting documentation
|
7
|
-
class InheritDoc
|
8
|
-
def initialize(relations)
|
9
|
-
@relations = relations
|
10
|
-
end
|
11
|
-
|
12
|
-
# Performs all inheriting
|
13
|
-
def resolve_all
|
14
|
-
@relations.each do |cls|
|
15
|
-
resolve_class(cls) if cls[:inheritdoc]
|
16
|
-
|
17
|
-
new_cfgs = []
|
18
|
-
cls.all_local_members.each do |member|
|
19
|
-
if member[:inheritdoc]
|
20
|
-
resolve(member, new_cfgs)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
move_cfgs(cls, new_cfgs) if new_cfgs.length > 0
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
# Copy over doc/params/return from parent member.
|
30
|
-
def resolve(m, new_cfgs)
|
31
|
-
parent = find_parent(m)
|
32
|
-
|
33
|
-
if m[:inheritdoc] && parent
|
34
|
-
m[:doc] = (m[:doc] + "\n\n" + parent[:doc]).strip
|
35
|
-
m[:params] = parent[:params] if parent[:params]
|
36
|
-
m[:return] = parent[:return] if parent[:return]
|
37
|
-
m[:type] = parent[:type] if parent[:type]
|
38
|
-
|
39
|
-
if m[:autodetected]
|
40
|
-
m[:meta] = parent[:meta].merge(m[:meta])
|
41
|
-
end
|
42
|
-
|
43
|
-
# remember properties that have changed to configs
|
44
|
-
if m[:autodetected] && m[:tagname] != parent[:tagname]
|
45
|
-
new_cfgs << m
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
resolve_visibility(m, parent)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Changes given properties into configs within class
|
53
|
-
def move_cfgs(cls, members)
|
54
|
-
members.each do |m|
|
55
|
-
m[:tagname] = :cfg
|
56
|
-
end
|
57
|
-
# Ask class to update its internal caches for these members
|
58
|
-
cls.update_members!(members)
|
59
|
-
end
|
60
|
-
|
61
|
-
# For auto-detected members/classes (which have @private == :inherit)
|
62
|
-
# Use the visibility from parent class (defaulting to private when no parent).
|
63
|
-
def resolve_visibility(m, parent)
|
64
|
-
if m[:autodetected] && !JsDuck::Class.constructor?(m)
|
65
|
-
if !parent || parent[:private]
|
66
|
-
m[:meta][:private] = m[:private] = true
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Finds parent member of the given member. When @inheritdoc names
|
72
|
-
# a member to inherit from, finds that member instead.
|
73
|
-
#
|
74
|
-
# If the parent also has @inheritdoc, continues recursively.
|
75
|
-
def find_parent(m)
|
76
|
-
|
77
|
-
inherit = m[:inheritdoc] || {}
|
78
|
-
if inherit[:cls]
|
79
|
-
# @inheritdoc MyClass#member
|
80
|
-
parent_cls = @relations[m[:inheritdoc][:cls]]
|
81
|
-
return warn("class not found", m) unless parent_cls
|
82
|
-
|
83
|
-
parent = lookup_member(parent_cls, m)
|
84
|
-
return warn("member not found", m) unless parent
|
85
|
-
|
86
|
-
elsif inherit[:member]
|
87
|
-
# @inheritdoc #member
|
88
|
-
parent = lookup_member(@relations[m[:owner]], m)
|
89
|
-
return warn("member not found", m) unless parent
|
90
|
-
|
91
|
-
else
|
92
|
-
# @inheritdoc
|
93
|
-
parent_cls = @relations[m[:owner]].parent
|
94
|
-
mixins = @relations[m[:owner]].mixins
|
95
|
-
|
96
|
-
# Warn when no parent or mixins at all
|
97
|
-
if !parent_cls && mixins.length == 0
|
98
|
-
warn("parent class not found", m) unless m[:autodetected]
|
99
|
-
return nil
|
100
|
-
end
|
101
|
-
|
102
|
-
# First check for the member in all mixins, because members
|
103
|
-
# from mixins override those from parent class. Looking first
|
104
|
-
# from mixins is probably a bit slower, but it's the correct
|
105
|
-
# order to do things.
|
106
|
-
if mixins.length > 0
|
107
|
-
parent = mixins.map {|mix| lookup_member(mix, m) }.compact.first
|
108
|
-
end
|
109
|
-
|
110
|
-
# When not found, try looking from parent class
|
111
|
-
if !parent && parent_cls
|
112
|
-
parent = lookup_member(parent_cls, m)
|
113
|
-
end
|
114
|
-
|
115
|
-
# Only when both parent and mixins fail, throw warning
|
116
|
-
if !parent
|
117
|
-
warn("parent member not found", m) unless m[:autodetected]
|
118
|
-
return nil
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
return parent[:inheritdoc] ? find_parent(parent) : parent
|
123
|
-
end
|
124
|
-
|
125
|
-
def lookup_member(cls, m)
|
126
|
-
inherit = m[:inheritdoc] || {}
|
127
|
-
name = inherit[:member] || m[:name]
|
128
|
-
tagname = inherit[:type] || m[:tagname]
|
129
|
-
static = inherit[:static] || m[:meta][:static]
|
130
|
-
|
131
|
-
if m[:autodetected]
|
132
|
-
# Auto-detected properties can override either a property or a
|
133
|
-
# config. So look for both types.
|
134
|
-
if tagname == :property
|
135
|
-
cfg = cls.find_members(:name => name, :tagname => :cfg, :static => static || false)[0]
|
136
|
-
prop = cls.find_members(:name => name, :tagname => :property, :static => static || false)[0]
|
137
|
-
|
138
|
-
if cfg && prop
|
139
|
-
prop
|
140
|
-
elsif cfg
|
141
|
-
cfg
|
142
|
-
elsif prop
|
143
|
-
prop
|
144
|
-
else
|
145
|
-
nil
|
146
|
-
end
|
147
|
-
|
148
|
-
else
|
149
|
-
# Unless the auto-detected member is detected as static,
|
150
|
-
# look only at instance members.
|
151
|
-
cls.find_members(:name => name, :tagname => tagname, :static => static || false)[0]
|
152
|
-
end
|
153
|
-
else
|
154
|
-
cls.find_members(:name => name, :tagname => tagname, :static => static)[0]
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
# Copy over doc from parent class.
|
159
|
-
def resolve_class(cls)
|
160
|
-
parent = find_class_parent(cls)
|
161
|
-
|
162
|
-
if parent
|
163
|
-
cls[:doc] = (cls[:doc] + "\n\n" + parent[:doc]).strip
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def find_class_parent(cls)
|
168
|
-
if cls[:inheritdoc][:cls]
|
169
|
-
# @inheritdoc MyClass
|
170
|
-
parent = @relations[cls[:inheritdoc][:cls]]
|
171
|
-
return warn("class not found", cls) unless parent
|
172
|
-
else
|
173
|
-
# @inheritdoc
|
174
|
-
parent = cls.parent
|
175
|
-
return warn("parent class not found", cls) unless parent
|
176
|
-
end
|
177
|
-
|
178
|
-
return parent[:inheritdoc] ? find_class_parent(parent) : parent
|
179
|
-
end
|
180
|
-
|
181
|
-
def warn(msg, item)
|
182
|
-
context = item[:files][0]
|
183
|
-
i_member = item[:inheritdoc][:member]
|
184
|
-
|
185
|
-
msg = "@inheritdoc #{item[:inheritdoc][:cls]}"+ (i_member ? "#" + i_member : "") + " - " + msg
|
186
|
-
Logger.warn(:inheritdoc, msg, context[:filename], context[:linenr])
|
187
|
-
|
188
|
-
return nil
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
192
|
-
|
193
|
-
end
|