jsduck 3.1.0 → 3.2.1

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.
Files changed (41) hide show
  1. data/README.md +14 -9
  2. data/Rakefile +31 -230
  3. data/jsduck.gemspec +2 -2
  4. data/lib/jsduck/accessors.rb +14 -6
  5. data/lib/jsduck/aggregator.rb +9 -4
  6. data/lib/jsduck/app.rb +1 -0
  7. data/lib/jsduck/app_data.rb +14 -7
  8. data/lib/jsduck/app_exporter.rb +3 -3
  9. data/lib/jsduck/class.rb +8 -5
  10. data/lib/jsduck/class_formatter.rb +1 -3
  11. data/lib/jsduck/css_parser.rb +1 -1
  12. data/lib/jsduck/doc_formatter.rb +140 -36
  13. data/lib/jsduck/doc_parser.rb +27 -44
  14. data/lib/jsduck/index_html.rb +0 -3
  15. data/lib/jsduck/inherit_doc.rb +20 -4
  16. data/lib/jsduck/js_parser.rb +1 -1
  17. data/lib/jsduck/lint.rb +15 -0
  18. data/lib/jsduck/logger.rb +9 -7
  19. data/lib/jsduck/merger.rb +18 -16
  20. data/lib/jsduck/meta_tag.rb +28 -5
  21. data/lib/jsduck/meta_tag_loader.rb +38 -21
  22. data/lib/jsduck/meta_tag_registry.rb +79 -0
  23. data/lib/jsduck/options.rb +69 -12
  24. data/lib/jsduck/renderer.rb +10 -38
  25. data/lib/jsduck/search_data.rb +53 -3
  26. data/lib/jsduck/tag/abstract.rb +14 -0
  27. data/lib/jsduck/{author_tag.rb → tag/author.rb} +2 -2
  28. data/lib/jsduck/tag/deprecated.rb +33 -0
  29. data/lib/jsduck/{doc_author_tag.rb → tag/docauthor.rb} +2 -2
  30. data/lib/jsduck/tag/markdown.rb +12 -0
  31. data/lib/jsduck/tag/preventable.rb +28 -0
  32. data/lib/jsduck/tag/protected.rb +14 -0
  33. data/lib/jsduck/tag/readonly.rb +14 -0
  34. data/lib/jsduck/tag/required.rb +21 -0
  35. data/lib/jsduck/tag/static.rb +14 -0
  36. data/lib/jsduck/tag/template.rb +23 -0
  37. data/opt/example.js +149 -0
  38. metadata +17 -9
  39. data/opt/extjs-welcome.html +0 -74
  40. data/opt/touch-iframe.html +0 -85
  41. data/opt/touch-welcome.html +0 -122
@@ -85,15 +85,19 @@ module JsDuck
85
85
  # Merges new class-doc into old one.
86
86
  def merge_classes(old, new)
87
87
  # Merge booleans
88
- [:extends, :singleton, :private, :protected].each do |tag|
88
+ [:extends, :singleton, :private].each do |tag|
89
89
  old[tag] = old[tag] || new[tag]
90
90
  end
91
91
  # Merge arrays
92
92
  [:mixins, :alternateClassNames, :files].each do |tag|
93
93
  old[tag] = old[tag] + new[tag]
94
94
  end
95
+ # Merge meta hashes
96
+ new[:meta].each_pair do |name, value|
97
+ old[:meta][name] = old[:meta][name] || value
98
+ end
95
99
  # Merge hashes of arrays
96
- [:aliases, :meta].each do |tag|
100
+ [:aliases].each do |tag|
97
101
  new[tag].each_pair do |key, contents|
98
102
  old[tag][key] = (old[tag][key] || []) + contents
99
103
  end
@@ -129,7 +133,7 @@ module JsDuck
129
133
  end
130
134
 
131
135
  def add_to_class(cls, member)
132
- cls[member[:static] ? :statics : :members][member[:tagname]] << member
136
+ cls[member[:meta][:static] ? :statics : :members][member[:tagname]] << member
133
137
  end
134
138
 
135
139
  def add_orphan(node)
@@ -182,8 +186,9 @@ module JsDuck
182
186
  :alternateClassNames => [],
183
187
  :members => Class.default_members_hash,
184
188
  :statics => Class.default_members_hash,
189
+ :aliases => {},
185
190
  :meta => {},
186
- :files => [{:filename => "", :linenr => 0}],
191
+ :files => [{:filename => "", :linenr => 0, :href => ""}],
187
192
  })
188
193
  end
189
194
 
data/lib/jsduck/app.rb CHANGED
@@ -143,6 +143,7 @@ module JsDuck
143
143
  class_formatter.include_types = !@opts.export
144
144
  # Format all doc-objects in parallel
145
145
  formatted_classes = @parallel.map(@relations.classes) do |cls|
146
+ Logger.instance.log("Markdown formatting #{cls[:name]}")
146
147
  {
147
148
  :doc => class_formatter.format(cls.internal_doc),
148
149
  :images => doc_formatter.images
@@ -2,6 +2,7 @@ require 'jsduck/json_duck'
2
2
  require 'jsduck/icons'
3
3
  require 'jsduck/search_data'
4
4
  require 'jsduck/stats'
5
+ require 'jsduck/meta_tag_registry'
5
6
 
6
7
  module JsDuck
7
8
 
@@ -18,13 +19,19 @@ module JsDuck
18
19
 
19
20
  # Writes classes, guides, videos, and search data to one big .js file
20
21
  def write(filename)
21
- js = "Docs.data = " + JsonDuck.generate({
22
- :classes => Icons.new.create(@relations.classes),
23
- :guides => @guides.to_array,
24
- :videos => @videos.to_array,
25
- :examples => @examples.to_array,
26
- :search => SearchData.new.create(@relations.classes),
27
- :stats => @opts.stats ? Stats.new.create(@relations.classes) : [],
22
+ js = "Docs = " + JsonDuck.generate({
23
+ :data => {
24
+ :classes => Icons.new.create(@relations.classes),
25
+ :guides => @guides.to_array,
26
+ :videos => @videos.to_array,
27
+ :examples => @examples.to_array,
28
+ :search => SearchData.new.create(@relations.classes),
29
+ :stats => @opts.stats ? Stats.new.create(@relations.classes) : [],
30
+ :signatures => MetaTagRegistry.instance.signatures,
31
+ :localStorageDb => @opts.local_storage_db,
32
+ :showPrintButton => @opts.seo,
33
+ :touchExamplesUi => @opts.touch_examples_ui,
34
+ }
28
35
  }) + ";\n"
29
36
  File.open(filename, 'w') {|f| f.write(js) }
30
37
  end
@@ -1,6 +1,7 @@
1
1
  require 'jsduck/full_exporter'
2
2
  require 'jsduck/renderer'
3
3
  require 'jsduck/doc_formatter'
4
+ require 'jsduck/meta_tag_registry'
4
5
 
5
6
  module JsDuck
6
7
 
@@ -12,8 +13,7 @@ module JsDuck
12
13
  @renderer = Renderer.new
13
14
  # Inject formatter to all meta-tags.
14
15
  doc_formatter = DocFormatter.new(relations, opts)
15
- opts.meta_tags.each {|tag| tag.formatter = doc_formatter }
16
- @renderer.meta_tags = opts.meta_tags
16
+ MetaTagRegistry.instance.formatter = doc_formatter
17
17
  end
18
18
 
19
19
  # Returns compacted class data hash which contains an additional
@@ -45,7 +45,7 @@ module JsDuck
45
45
 
46
46
  def compact_member(m)
47
47
  m_copy = {}
48
- [:name, :tagname, :owner, :protected, :static, :deprecated, :required, :template, :id].each do |key|
48
+ [:name, :tagname, :owner, :meta, :id].each do |key|
49
49
  m_copy[key] = m[key]
50
50
  end
51
51
  m_copy
data/lib/jsduck/class.rb CHANGED
@@ -154,25 +154,28 @@ module JsDuck
154
154
  local_members
155
155
  end
156
156
 
157
- # Returns member by name.
157
+ # Returns members by name. An array of one or more members, or
158
+ # empty array when nothing matches.
158
159
  #
159
160
  # Optionally one can also specify type name to differenciate
160
161
  # between different types of members.
161
- def get_member(name, type_name=nil)
162
+ def get_members(name, type_name=nil, static=false)
162
163
  # build hash of all members
163
164
  unless @members_map
164
165
  @members_map = {}
165
166
  [:members, :statics].each do |group|
166
167
  @doc[group].each_key do |type|
167
168
  members_hash(type, group).each_pair do |key, member|
168
- @members_map["#{type}-#{key}"] = member
169
- @members_map[key] = member
169
+ @members_map[key] = (@members_map[key] || []) + [member]
170
170
  end
171
171
  end
172
172
  end
173
173
  end
174
174
 
175
- @members_map[type_name ? "#{type_name}-#{name}" : name]
175
+ ms = @members_map[name] || []
176
+ ms = ms.find_all {|m| m[:tagname] == type_name } if type_name
177
+ ms = ms.find_all {|m| m[:meta][:static] } if static
178
+ return ms
176
179
  end
177
180
 
178
181
  # Returns all public members of class, including the inherited and mixed in ones
@@ -14,7 +14,6 @@ module JsDuck
14
14
  @relations = relations
15
15
  @formatter = formatter
16
16
  @include_types = true
17
- @meta_tags = []
18
17
  end
19
18
 
20
19
  # Runs the formatter on doc object of a class.
@@ -36,7 +35,6 @@ module JsDuck
36
35
  def format_member(m)
37
36
  @formatter.doc_context = m[:files][0]
38
37
  m[:doc] = @formatter.format(m[:doc]) if m[:doc]
39
- m[:deprecated][:text] = @formatter.format(m[:deprecated][:text]) if m[:deprecated]
40
38
  if expandable?(m) || @formatter.too_long?(m[:doc])
41
39
  m[:shortDoc] = @formatter.shorten(m[:doc])
42
40
  end
@@ -52,7 +50,7 @@ module JsDuck
52
50
  end
53
51
 
54
52
  def expandable?(m)
55
- m[:params] || (m[:properties] && m[:properties].length > 0) || m[:default] || m[:deprecated] || m[:template]
53
+ m[:params] || (m[:properties] && m[:properties].length > 0) || m[:default] || m[:meta][:deprecated] || m[:meta][:template]
56
54
  end
57
55
 
58
56
  def format_item(it, is_css_tag)
@@ -6,7 +6,7 @@ module JsDuck
6
6
  class CssParser
7
7
  def initialize(input, options = {})
8
8
  @lex = Lexer.new(input)
9
- @doc_parser = DocParser.new(:css, options[:meta_tags])
9
+ @doc_parser = DocParser.new
10
10
  @docs = []
11
11
  end
12
12
 
@@ -78,27 +78,48 @@ module JsDuck
78
78
  #
79
79
  # Adds 'inline-example' class to code examples beginning with @example.
80
80
  #
81
- # Additionally replaces strings recognized as ClassNames with
82
- # links to these classes. So one doesn even need to use the @link
83
- # tag to create a link.
81
+ # Additionally replaces strings recognized as ClassNames or
82
+ # #members with links to these classes or members. So one doesn't
83
+ # even need to use the @link tag to create a link.
84
84
  def replace(input)
85
85
  s = StringScanner.new(input)
86
86
  out = ""
87
+
88
+ # Keep track of the nesting level of <a> tags. We're not
89
+ # auto-detecting class names when inside <a>. Normally links
90
+ # shouldn't be nested, but just to be extra safe.
91
+ open_a_tags = 0
92
+
87
93
  while !s.eos? do
88
94
  if s.check(@link_re)
89
95
  out += replace_link_tag(s.scan(@link_re))
90
96
  elsif s.check(@img_re)
91
97
  out += replace_img_tag(s.scan(@img_re))
98
+ elsif s.check(/[{]/)
99
+ # There might still be "{" that doesn't begin {@link} or {@img} - ignore it
100
+ out += s.scan(/[{]/)
92
101
  elsif s.check(@example_annotation_re)
93
102
  # Match possible classnames following @example and add them
94
103
  # as CSS classes inside <pre> element.
95
104
  s.scan(@example_annotation_re) =~ @example_annotation_re
96
105
  css_classes = ($1 || "").strip
97
106
  out += "<pre class='inline-example #{css_classes}'><code>"
98
- elsif s.check(/[{<]/)
99
- out += s.scan(/[{<]/)
107
+ elsif s.check(/<a\b/)
108
+ # Increment number of open <a> tags.
109
+ open_a_tags += 1
110
+ out += s.scan_until(/>|\Z/)
111
+ elsif s.check(/<\/a>/)
112
+ # <a> closed, auto-detection may continue when no more <a> tags open.
113
+ open_a_tags -= 1
114
+ out += s.scan(/<\/a>/)
115
+ elsif s.check(/</)
116
+ # Ignore all other HTML tags
117
+ out += s.scan_until(/>|\Z/)
100
118
  else
101
- out += replace_class_names(s.scan(/[^{<]+/))
119
+ # Replace class names in the following text up to next "<" or "{"
120
+ # but only when we're not inside <a>...</a>
121
+ text = s.scan(/[^{<]+/)
122
+ out += open_a_tags > 0 ? text : create_magic_links(text)
102
123
  end
103
124
  end
104
125
  out
@@ -108,12 +129,14 @@ module JsDuck
108
129
  input.sub(@link_re) do
109
130
  target = $1
110
131
  text = $2
111
- if target =~ /^(.*)#(?:(.*)-)?(.*)$/
132
+ if target =~ /^(.*)#(static-)?(?:(cfg|property|method|event|css_var|css_mixin)-)?(.*)$/
112
133
  cls = $1.empty? ? @class_context : $1
113
- type = $2 ? $2.intern : nil
114
- member = $3
134
+ static = !!$2
135
+ type = $3 ? $3.intern : nil
136
+ member = $4
115
137
  else
116
138
  cls = target
139
+ static = false
117
140
  type = false
118
141
  member = false
119
142
  end
@@ -131,15 +154,39 @@ module JsDuck
131
154
  line = @doc_context[:linenr]
132
155
  if !@relations[cls]
133
156
  Logger.instance.warn(:link, "#{input} links to non-existing class", file, line)
134
- text
135
- elsif member && !get_member(cls, member, type)
136
- Logger.instance.warn(:link, "#{input} links to non-existing member", file, line)
137
- text
138
- elsif member && !public_member?(cls, member, type)
139
- Logger.instance.warn(:link, "#{input} links to private member", file, line)
140
- text
157
+ return text
158
+ elsif member
159
+ ms = get_members(cls, member, type, static)
160
+ if ms.length == 0
161
+ Logger.instance.warn(:link, "#{input} links to non-existing member", file, line)
162
+ return text
163
+ end
164
+
165
+ ms = ms.find_all {|m| !m[:private] }
166
+ if ms.length == 0
167
+ Logger.instance.warn(:link_private, "#{input} links to private member", file, line)
168
+ return text
169
+ end
170
+
171
+ if ms.length > 1
172
+ # When multiple public members, see if there remains just
173
+ # one when we ignore the static members. If there's more,
174
+ # report ambiguity. If there's only static members, also
175
+ # report ambiguity.
176
+ instance_ms = ms.find_all {|m| !m[:meta][:static] }
177
+ if instance_ms.length > 1
178
+ alternatives = instance_ms.map {|m| m[:tagname].to_s }.join(", ")
179
+ Logger.instance.warn(:link_ambiguous, "#{input} is ambiguous: "+alternatives, file, line)
180
+ elsif instance_ms.length == 0
181
+ static_ms = ms.find_all {|m| m[:meta][:static] }
182
+ alternatives = static_ms.map {|m| "static " + m[:tagname].to_s }.join(", ")
183
+ Logger.instance.warn(:link_ambiguous, "#{input} is ambiguous: "+alternatives, file, line)
184
+ end
185
+ end
186
+
187
+ return link(cls, member, text, type, static)
141
188
  else
142
- link(cls, member, text, type)
189
+ return link(cls, false, text)
143
190
  end
144
191
  end
145
192
  end
@@ -148,21 +195,73 @@ module JsDuck
148
195
  input.sub(@img_re) { img($1, $2) }
149
196
  end
150
197
 
151
- def replace_class_names(input)
152
- input.gsub(/(\A|\s)([A-Z][A-Za-z0-9.]*[A-Za-z0-9])(?:(#)([A-Za-z0-9]+))?([.,]?(?:\s|\Z))/m) do
153
- before = $1
154
- cls = $2
155
- hash = $3
156
- member = $4
157
- after = $5
158
-
159
- if @relations[cls] && (member ? public_member?(cls, member) : cls =~ /\./)
160
- label = member ? cls+"."+member : cls
161
- before + link(cls, member, label) + after
198
+ # Looks input text for patterns like:
199
+ #
200
+ # My.ClassName
201
+ # MyClass#method
202
+ # #someProperty
203
+ #
204
+ # and converts them to links, as if they were surrounded with
205
+ # {@link} tag. One notable exception is that Foo is not created to
206
+ # link, even when Foo class exists, but Foo.Bar is. This is to
207
+ # avoid turning normal words into links. For example:
208
+ #
209
+ # Math involves a lot of numbers. Ext JS is a JavaScript framework.
210
+ #
211
+ # In these sentences we don't want to link "Math" and "Ext" to the
212
+ # corresponding JS classes. And that's why we auto-link only
213
+ # class names containing a dot "."
214
+ #
215
+ def create_magic_links(input)
216
+ cls_re = "([A-Z][A-Za-z0-9.]*[A-Za-z0-9])"
217
+ member_re = "(?:#([A-Za-z0-9]+))"
218
+
219
+ input.gsub(/\b#{cls_re}#{member_re}?\b|#{member_re}\b/m) do
220
+ replace_magic_link($1, $2 || $3)
221
+ end
222
+ end
223
+
224
+ def replace_magic_link(cls, member)
225
+ if cls && member
226
+ if @relations[cls] && get_matching_member(cls, member)
227
+ return link(cls, member, cls+"."+member)
228
+ else
229
+ warn_magic_link("#{cls}##{member} links to non-existing " + (@relations[cls] ? "member" : "class"))
230
+ end
231
+ elsif cls && cls =~ /\./
232
+ if @relations[cls]
233
+ return link(cls, nil, cls)
162
234
  else
163
- before + cls + (hash || "") + (member || "") + after
235
+ cls2, member2 = split_to_cls_and_member(cls)
236
+ if @relations[cls2] && get_matching_member(cls2, member2)
237
+ return link(cls2, member2, cls2+"."+member2)
238
+ elsif cls =~ /\.(js|css|html|php)\Z/
239
+ # Ignore common filenames
240
+ else
241
+ warn_magic_link("#{cls} links to non-existing class")
242
+ end
243
+ end
244
+ elsif !cls && member
245
+ if get_matching_member(@class_context, member)
246
+ return link(@class_context, member, member)
247
+ elsif member =~ /\A([A-F0-9]{3}|[A-F0-9]{6})\Z/i || member =~ /\A[0-9]/
248
+ # Ignore HEX color codes and
249
+ # member names beginning with number
250
+ else
251
+ warn_magic_link("##{member} links to non-existing member")
164
252
  end
165
253
  end
254
+
255
+ return "#{cls}#{member ? '#' : ''}#{member}"
256
+ end
257
+
258
+ def split_to_cls_and_member(str)
259
+ parts = str.split(/\./)
260
+ return [parts.slice(0, parts.length-1).join("."), parts.last]
261
+ end
262
+
263
+ def warn_magic_link(msg)
264
+ Logger.instance.warn(:link_auto, msg, @doc_context[:filename], @doc_context[:linenr])
166
265
  end
167
266
 
168
267
  # applies the image template
@@ -181,11 +280,11 @@ module JsDuck
181
280
  end
182
281
 
183
282
  # applies the link template
184
- def link(cls, member, anchor_text, type=nil)
283
+ def link(cls, member, anchor_text, type=nil, static=false)
185
284
  # Use the canonical class name for link (not some alternateClassName)
186
285
  cls = @relations[cls].full_name
187
286
  # prepend type name to member name
188
- member = member && get_member(cls, member, type)
287
+ member = member && get_matching_member(cls, member, type, static)
189
288
 
190
289
  @link_tpl.gsub(/(%[\w#-])/) do
191
290
  case $1
@@ -205,13 +304,18 @@ module JsDuck
205
304
  end
206
305
  end
207
306
 
208
- def public_member?(cls, member, type=nil)
209
- m = get_member(cls, member, type)
210
- return m && !m[:private]
307
+ def get_matching_member(cls, member, type=nil, static=false)
308
+ ms = get_members(cls, member, type, static).find_all {|m| !m[:private] }
309
+ if ms.length > 1
310
+ instance_ms = ms.find_all {|m| !m[:meta][:static] }
311
+ instance_ms.length > 0 ? instance_ms[0] : ms.find_all {|m| m[:meta][:static] }[0]
312
+ else
313
+ ms[0]
314
+ end
211
315
  end
212
316
 
213
- def get_member(cls, member, type=nil)
214
- return @relations[cls] && @relations[cls].get_member(member, type)
317
+ def get_members(cls, member, type=nil, static=false)
318
+ @relations[cls] ? @relations[cls].get_members(member, type, static) : []
215
319
  end
216
320
 
217
321
  # Formats doc-comment for placement into HTML.
@@ -1,6 +1,7 @@
1
1
  require 'strscan'
2
2
  require 'jsduck/js_literal_parser'
3
3
  require 'jsduck/js_literal_builder'
4
+ require 'jsduck/meta_tag_registry'
4
5
 
5
6
  module JsDuck
6
7
 
@@ -23,15 +24,10 @@ module JsDuck
23
24
  # @see and {@link} are parsed separately in JsDuck::DocFormatter.
24
25
  #
25
26
  class DocParser
26
- # Pass in :css to be able to parse CSS doc-comments
27
- def initialize(mode = :js, meta_tags = nil)
28
- @ident_pattern = (mode == :css) ? /\$?[\w-]+/ : /[$\w]\w*/
29
- @ident_chain_pattern = (mode == :css) ? /\$?[\w-]+(\.[\w-]+)*/ : /[$\w]\w*(\.\w+)*/
30
-
31
- @meta_tags_map = {}
32
- (meta_tags || []).each do |tag|
33
- @meta_tags_map[tag.name] = tag
34
- end
27
+ def initialize
28
+ @ident_pattern = /[$\w-]+/
29
+ @ident_chain_pattern = /[$\w-]+(\.[$\w-]+)*/
30
+ @meta_tags = MetaTagRegistry.instance
35
31
  end
36
32
 
37
33
  def parse(input)
@@ -134,33 +130,19 @@ module JsDuck
134
130
  at_inheritdoc
135
131
  elsif look(/@alias/)
136
132
  at_alias
137
- elsif look(/@deprecated\b/)
138
- at_deprecated
139
133
  elsif look(/@var\b/)
140
134
  at_var
141
- elsif look(/@static\b/)
142
- boolean_at_tag(/@static/, :static)
143
135
  elsif look(/@inheritable\b/)
144
136
  boolean_at_tag(/@inheritable/, :inheritable)
145
137
  elsif look(/@(private|ignore|hide)\b/)
146
138
  boolean_at_tag(/@(private|ignore|hide)/, :private)
147
- elsif look(/@protected\b/)
148
- boolean_at_tag(/@protected/, :protected)
149
139
  elsif look(/@accessor\b/)
150
140
  boolean_at_tag(/@accessor/, :accessor)
151
141
  elsif look(/@evented\b/)
152
142
  boolean_at_tag(/@evented/, :evented)
153
- elsif look(/@template\b/)
154
- boolean_at_tag(/@template/, :template)
155
- elsif look(/@markdown\b/)
156
- # this is detected just to be ignored
157
- boolean_at_tag(/@markdown/, :markdown)
158
- elsif look(/@abstract\b/)
159
- # this is detected just to be ignored
160
- boolean_at_tag(/@abstract/, :abstract)
161
143
  elsif look(/@/)
162
144
  @input.scan(/@/)
163
- tag = @meta_tags_map[look(/\w+/)]
145
+ tag = @meta_tags[look(/\w+/)]
164
146
  if tag
165
147
  meta_at_tag(tag)
166
148
  else
@@ -177,13 +159,21 @@ module JsDuck
177
159
  prev_tag = @current_tag
178
160
 
179
161
  add_tag(:meta)
180
- @current_tag[:name] = match(/\w+/)
162
+ @current_tag[:name] = tag.key
163
+ match(/\w+/)
181
164
  skip_horiz_white
182
165
 
183
- # Fors singleline tags, scan to the end of line and finish the
184
- # tag. For multiline tags we leave the tag open for :doc
185
- # addition just like with built-in multiline tags.
186
- unless tag.multiline
166
+ if tag.boolean
167
+ # For boolean tags, only scan the tag name and switch context
168
+ # back to previous tag.
169
+ skip_white
170
+ @current_tag = prev_tag
171
+ elsif tag.multiline
172
+ # For multiline tags we leave the tag open for :doc addition
173
+ # just like with built-in multiline tags.
174
+ else
175
+ # Fors singleline tags, scan to the end of line and finish the
176
+ # tag.
187
177
  @current_tag[:doc] = @input.scan(/.*$/).strip
188
178
  skip_white
189
179
  @current_tag = prev_tag
@@ -275,7 +265,7 @@ module JsDuck
275
265
  match(/@property/)
276
266
  add_tag(:property)
277
267
  maybe_type
278
- maybe_ident_chain(:name)
268
+ maybe_name_with_default
279
269
  skip_white
280
270
  end
281
271
 
@@ -331,7 +321,7 @@ module JsDuck
331
321
  skip_white
332
322
  end
333
323
 
334
- # matches @inheritdoc class.name#type-member
324
+ # matches @inheritdoc class.name#static-type-member
335
325
  def at_inheritdoc
336
326
  match(/@inherit[dD]oc|@alias/)
337
327
 
@@ -341,8 +331,12 @@ module JsDuck
341
331
  @current_tag[:cls] = ident_chain
342
332
  if look(/#\w/)
343
333
  @input.scan(/#/)
344
- if look(/\w+-\w+/)
345
- @current_tag[:type] = ident
334
+ if look(/static-/)
335
+ @current_tag[:static] = true
336
+ @input.scan(/static-/)
337
+ end
338
+ if look(/(cfg|property|method|event|css_var|css_mixin)-/)
339
+ @current_tag[:type] = ident.to_sym
346
340
  @input.scan(/-/)
347
341
  end
348
342
  @current_tag[:member] = ident
@@ -351,17 +345,6 @@ module JsDuck
351
345
  skip_white
352
346
  end
353
347
 
354
- # matches @deprecated <version> some text ... newline
355
- def at_deprecated
356
- match(/@deprecated/)
357
- add_tag(:deprecated)
358
- skip_horiz_white
359
- @current_tag[:version] = @input.scan(/[0-9.]+/)
360
- skip_horiz_white
361
- @current_tag[:text] = @input.scan(/.*$/)
362
- skip_white
363
- end
364
-
365
348
  # Used to match @private, @ignore, @hide, ...
366
349
  def boolean_at_tag(regex, propname)
367
350
  match(regex)