jsduck 4.0.beta → 4.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,7 +16,7 @@ module JsDuck
16
16
 
17
17
  new_cfgs = []
18
18
  cls.all_local_members.each do |member|
19
- if member[:inheritdoc] || member[:autodetected]
19
+ if member[:inheritdoc]
20
20
  resolve(member, new_cfgs)
21
21
  end
22
22
  end
@@ -35,6 +35,10 @@ module JsDuck
35
35
  m[:params] = parent[:params] if parent[:params]
36
36
  m[:return] = parent[:return] if parent[:return]
37
37
 
38
+ if m[:autodetected]
39
+ m[:meta] = parent[:meta].merge(m[:meta])
40
+ end
41
+
38
42
  # remember properties that have changed to configs
39
43
  if m[:tagname] != parent[:tagname]
40
44
  new_cfgs << m
@@ -113,6 +117,7 @@ module JsDuck
113
117
  end
114
118
  end
115
119
 
120
+ #pp parent[:doc]
116
121
  return parent[:inheritdoc] ? find_parent(parent) : parent
117
122
  end
118
123
 
@@ -122,22 +127,28 @@ module JsDuck
122
127
  tagname = inherit[:type] || m[:tagname]
123
128
  static = inherit[:static] || m[:meta][:static]
124
129
 
125
- # Auto-detected properties can override either a property or a
126
- # config. So look for both types.
127
- if m[:autodetected] && tagname == :property
128
- cfg = cls.get_members(name, :cfg, static)[0]
129
- prop = cls.get_members(name, :property, static)[0]
130
-
131
- if cfg && prop
132
- prop
133
- elsif cfg
134
- cfg
135
- elsif prop
136
- prop
130
+ if m[:autodetected]
131
+ # Auto-detected properties can override either a property or a
132
+ # config. So look for both types.
133
+ if tagname == :property
134
+ cfg = cls.get_members(name, :cfg, static || false)[0]
135
+ prop = cls.get_members(name, :property, static || false)[0]
136
+
137
+ if cfg && prop
138
+ prop
139
+ elsif cfg
140
+ cfg
141
+ elsif prop
142
+ prop
143
+ else
144
+ nil
145
+ end
146
+
137
147
  else
138
- nil
148
+ # Unless the auto-detected member is detected as static,
149
+ # look only at instance members.
150
+ cls.get_members(name, tagname, static || false)[0]
139
151
  end
140
-
141
152
  else
142
153
  cls.get_members(name, tagname, static)[0]
143
154
  end
data/lib/jsduck/lint.rb CHANGED
@@ -17,6 +17,7 @@ module JsDuck
17
17
  warn_optional_params
18
18
  warn_duplicate_params
19
19
  warn_duplicate_members
20
+ warn_empty_enums
20
21
  end
21
22
 
22
23
  # print warning for each member or parameter with no name
@@ -94,6 +95,15 @@ module JsDuck
94
95
  end
95
96
  end
96
97
 
98
+ # print warnings for enums with no values
99
+ def warn_empty_enums
100
+ @relations.each do |cls|
101
+ if cls[:enum] && cls[:members][:property].length == 0
102
+ warn(:enum, "Enum #{cls[:name]} defined without values in it", cls)
103
+ end
104
+ end
105
+ end
106
+
97
107
  # Loops through all members of all classes
98
108
  def each_member(&block)
99
109
  @relations.each {|cls| cls.all_local_members.each(&block) }
data/lib/jsduck/logger.rb CHANGED
@@ -31,6 +31,7 @@ module JsDuck
31
31
  [:sing_static, "Singleton class member marked as @static"],
32
32
  [:type_syntax, "Syntax error in {type definition}"],
33
33
  [:type_name, "Unknown type referenced in {type definition}"],
34
+ [:enum, "Enum defined without any values in it"],
34
35
 
35
36
  [:image, "{@img} referring to missing file"],
36
37
  [:image_unused, "An image exists in --images dir that's not used"],
@@ -101,6 +102,8 @@ module JsDuck
101
102
  elsif !@warnings.has_key?(type)
102
103
  warn(nil, "Unknown warning type #{type}")
103
104
  end
105
+
106
+ return false
104
107
  end
105
108
 
106
109
  # Formats filename and line number for output
@@ -0,0 +1,46 @@
1
+
2
+ module JsDuck
3
+
4
+ # Wrapper which chooses the available Markdown implementation and
5
+ # provides a uniform interface to it.
6
+ #
7
+ # Possible engines in order of preference:
8
+ #
9
+ # - rdiscount
10
+ # - kramdown
11
+ #
12
+ class Markdown
13
+
14
+ if RUBY_PLATFORM == "java"
15
+ require "kramdown"
16
+ begin
17
+ @@engine = :kramdown
18
+ rescue LoadError
19
+ throw "ERROR: Kramdown gem not available."
20
+ end
21
+ else
22
+ begin
23
+ require "rdiscount"
24
+ @@engine = :rdiscount
25
+ rescue LoadError
26
+ begin
27
+ require "kramdown"
28
+ @@engine = :kramdown
29
+ rescue LoadError
30
+ throw "ERROR: Neither RDiscount nor Kramdown gem available."
31
+ end
32
+ end
33
+ end
34
+
35
+ # Converts Markdown text into HTML
36
+ def self.to_html(input)
37
+ if @@engine == :rdiscount
38
+ RDiscount.new(input).to_html
39
+ else
40
+ Kramdown::Document.new(input).to_html
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
data/lib/jsduck/merger.rb CHANGED
@@ -44,8 +44,10 @@ module JsDuck
44
44
  h[:extends] = nil if h[:extends] == "Object"
45
45
 
46
46
  h[:aliases] = build_aliases_hash(h[:aliases] || [])
47
+
47
48
  # Used by Aggregator to determine if we're dealing with Ext4 code
48
- h[:code_type] = code[:tagname]
49
+ h[:code_type] = code[:code_type] if code[:code_type]
50
+
49
51
  h[:members] = Class.default_members_hash
50
52
  h[:statics] = Class.default_members_hash
51
53
 
@@ -44,6 +44,7 @@ module JsDuck
44
44
  attr_accessor :local_storage_db
45
45
  attr_accessor :touch_examples_ui
46
46
  attr_accessor :ext_namespaces
47
+ attr_accessor :imports
47
48
 
48
49
  def initialize
49
50
  @input_files = []
@@ -75,11 +76,11 @@ module JsDuck
75
76
  ]
76
77
  @meta_tag_paths = []
77
78
 
78
- @version = "4.0.beta"
79
+ @version = "4.0.beta2"
79
80
 
80
81
  # Customizing output
81
- @title = "Sencha Docs - Ext JS"
82
- @header = "<strong>Sencha Docs</strong> Ext JS"
82
+ @title = "Ext JS - Sencha Docs"
83
+ @header = "<strong>Ext JS</strong> Sencha Docs"
83
84
  @footer = "Generated with <a href='https://github.com/senchalabs/jsduck'>JSDuck</a> #{@version}."
84
85
  @head_html = ""
85
86
  @body_html = ""
@@ -112,6 +113,7 @@ module JsDuck
112
113
  @local_storage_db = "docs"
113
114
  @touch_examples_ui = false
114
115
  @ext_namespaces = ["Ext"]
116
+ @imports = []
115
117
 
116
118
  # enable all warnings except :link_auto
117
119
  Logger.instance.set_warning(:all, true)
@@ -181,7 +183,7 @@ module JsDuck
181
183
 
182
184
  opts.on('--title=TEXT',
183
185
  "Custom title text for the documentation.",
184
- "Defaults to 'Sencha Docs - Ext JS'", " ") do |text|
186
+ "Defaults to 'Ext JS - Sencha Docs'", " ") do |text|
185
187
  @title = text
186
188
  @header = text.sub(/^(.*?) +- +/, "<strong>\\1 </strong>")
187
189
  end
@@ -360,6 +362,17 @@ module JsDuck
360
362
  @ext_namespaces = ns
361
363
  end
362
364
 
365
+ opts.on('--import=VERSION:PATH',
366
+ "Imports docs of a particular version generating @since tags.",
367
+ "Several versions can be imported using the option multiple times.",
368
+ "To specify the current version, leave the :PATH portion off.", " ") do |v|
369
+ if v =~ /\A(.*?):(.*)\Z/
370
+ @imports << {:version => $1, :path => canonical($2)}
371
+ else
372
+ @imports << {:version => v}
373
+ end
374
+ end
375
+
363
376
  opts.on('--config=PATH',
364
377
  "Loads config options from JSON file.", " ") do |path|
365
378
  path = canonical(path)
@@ -5,25 +5,26 @@ module JsDuck
5
5
  # Wrapper around the parallel gem that falls back to simple
6
6
  # Array#map and Array#each when :in_processes => 0 specified.
7
7
  class ParallelWrap
8
+ @@in_processes = nil
8
9
 
9
- # Takes config object for parallel
10
- def initialize(cfg = {})
11
- @cfg = cfg
10
+ # Sets globally the nr of processes to use.
11
+ def self.in_processes=(n)
12
+ @@in_processes = n
12
13
  end
13
14
 
14
- def each(arr, &block)
15
- if @cfg[:in_processes] == 0
15
+ def self.each(arr, &block)
16
+ if @@in_processes == 0
16
17
  arr.each &block
17
18
  else
18
- Parallel.each(arr, @cfg, &block)
19
+ Parallel.each(arr, {:in_processes => @@in_processes}, &block)
19
20
  end
20
21
  end
21
22
 
22
- def map(arr, &block)
23
- if @cfg[:in_processes] == 0
23
+ def self.map(arr, &block)
24
+ if @@in_processes == 0
24
25
  arr.map &block
25
26
  else
26
- Parallel.map(arr, @cfg, &block)
27
+ Parallel.map(arr, {:in_processes => @@in_processes}, &block)
27
28
  end
28
29
  end
29
30
  end
@@ -20,6 +20,7 @@ module JsDuck
20
20
  render_meta_data(@cls[:html_meta], :top),
21
21
  render_private_class_notice,
22
22
  @cls[:doc],
23
+ render_enum_class_notice,
23
24
  render_meta_data(@cls[:html_meta], :bottom),
24
25
  "</div>",
25
26
  "<div class='members'>",
@@ -38,6 +39,26 @@ module JsDuck
38
39
  ]
39
40
  end
40
41
 
42
+ def render_enum_class_notice
43
+ return if !@cls[:enum]
44
+
45
+ if @cls[:enum][:type] == "String"
46
+ first = @cls[:members][:property][0] || {:name => 'foo', :default => '"foo"'}
47
+ [
48
+ "<p class='enum'><strong>ENUM:</strong> ",
49
+ "This enumeration defines a set of String values. ",
50
+ "It exists primarily for documentation purposes - ",
51
+ "in code use the actual string values like #{first[:default]}, ",
52
+ "don't reference them through this class like #{@cls[:name]}.#{first[:name]}.</p>",
53
+ ]
54
+ else
55
+ [
56
+ "<p class='enum'><strong>ENUM:</strong> ",
57
+ "This enumeration defines a set of #{@cls[:enum][:type]} values.</p>",
58
+ ]
59
+ end
60
+ end
61
+
41
62
  def render_meta_data(meta_data, position)
42
63
  return if meta_data.size == 0
43
64
 
@@ -19,7 +19,7 @@ module JsDuck
19
19
  @html_filename = ""
20
20
  @links = {}
21
21
 
22
- @docs = SourceFileParser.instance.parse(@contents, @filename, options)
22
+ @docs = SourceFileParser.new.parse(@contents, @filename, options)
23
23
 
24
24
  @docs.map do |docset|
25
25
  link(docset[:linenr], docset)
@@ -1,4 +1,3 @@
1
- require 'singleton'
2
1
  require 'jsduck/js_parser'
3
2
  require 'jsduck/css_parser'
4
3
  require 'jsduck/doc_parser'
@@ -15,7 +14,6 @@ module JsDuck
15
14
  # This is the class that brings together all the different steps of
16
15
  # parsing the source.
17
16
  class SourceFileParser
18
- include Singleton
19
17
 
20
18
  def initialize
21
19
  @doc_type = DocType.new
@@ -1,13 +1,13 @@
1
1
  require 'jsduck/logger'
2
+ require 'jsduck/parallel_wrap'
2
3
  require 'fileutils'
3
4
 
4
5
  module JsDuck
5
6
 
6
7
  # Writes HTML JavaScript/CSS source into HTML files.
7
8
  class SourceWriter
8
- def initialize(source_files, parallel)
9
+ def initialize(source_files)
9
10
  @source_files = source_files
10
- @parallel = parallel
11
11
  end
12
12
 
13
13
  # Writes all source files as HTML files into destination dir.
@@ -15,7 +15,7 @@ module JsDuck
15
15
  generate_html_filenames
16
16
 
17
17
  FileUtils.mkdir(destination)
18
- @parallel.each(@source_files) do |file|
18
+ ParallelWrap.each(@source_files) do |file|
19
19
  Logger.instance.log("Writing source", file.html_filename)
20
20
  write_single(destination + "/" + file.html_filename, file.to_html)
21
21
  end
@@ -0,0 +1,20 @@
1
+ require "jsduck/meta_tag"
2
+ require "jsduck/logger"
3
+
4
+ module JsDuck::Tag
5
+ # Implementation of @new tag.
6
+ class New < JsDuck::MetaTag
7
+ def initialize
8
+ @name = "new"
9
+ @key = :new
10
+ @signature = {:long => "&#9733;", :short => "&#9733;"} # unicode black star char
11
+ @boolean = true
12
+ end
13
+
14
+ def to_value(contents)
15
+ true
16
+ end
17
+
18
+ end
19
+ end
20
+
@@ -0,0 +1,26 @@
1
+ require "jsduck/meta_tag"
2
+ require "jsduck/logger"
3
+
4
+ module JsDuck::Tag
5
+ # Implementation of @since tag.
6
+ class Since < JsDuck::MetaTag
7
+ def initialize
8
+ @name = "since"
9
+ @key = :since
10
+ end
11
+
12
+ def to_value(contents)
13
+ if contents.length > 1
14
+ JsDuck::Logger.instance.warn(nil, "Only one @since tag allowed per class/member.")
15
+ end
16
+ contents[0]
17
+ end
18
+
19
+ def to_html(version)
20
+ <<-EOHTML
21
+ <p>Available since: <b>#{version}</b></p>
22
+ EOHTML
23
+ end
24
+ end
25
+ end
26
+
@@ -8,6 +8,8 @@ module JsDuck
8
8
  #
9
9
  # 1. Traditional type expressions found in ExtJS code:
10
10
  #
11
+ # "string"
12
+ # 3.14
11
13
  # SomeType
12
14
  # Name.spaced.Type
13
15
  # Number[]
@@ -141,7 +143,7 @@ module JsDuck
141
143
  #
142
144
  # <array-type> ::= <atomic-type> [ "[]" ]*
143
145
  #
144
- # <atomic-type> ::= <union-type> | <record-type> | <function-type> | <type-name>
146
+ # <atomic-type> ::= <union-type> | <record-type> | <function-type> | <string-literal> | <type-name>
145
147
  #
146
148
  def null_type
147
149
  if nullability = @input.scan(/[?!]/)
@@ -154,6 +156,10 @@ module JsDuck
154
156
  return false unless record_type
155
157
  elsif @input.check(/function\(/)
156
158
  return false unless function_type
159
+ elsif @input.check(/['"]/)
160
+ return false unless string_literal
161
+ elsif @input.check(/\d/)
162
+ return false unless number_literal
157
163
  else
158
164
  return false unless type_name
159
165
  end
@@ -289,6 +295,24 @@ module JsDuck
289
295
  true
290
296
  end
291
297
 
298
+ #
299
+ # <string-literal> ::= '.*' | ".*"
300
+ #
301
+ def string_literal
302
+ @out << @input.scan(/"([^\\"]|\\.)*?"|'([^\\']|\\.)*?'/)
303
+
304
+ true
305
+ end
306
+
307
+ #
308
+ # <number-literal> ::= <digit>+ [ "." <digit>+ ]
309
+ #
310
+ def number_literal
311
+ @out << @input.scan(/\d+(\.\d+)?/)
312
+
313
+ true
314
+ end
315
+
292
316
  #
293
317
  # <type-name> ::= <type-application> | "*"
294
318
  #