jsduck 5.1.0 → 5.2.0

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.
@@ -0,0 +1,51 @@
1
+ require 'jsduck/warning/warn_exception'
2
+
3
+ module JsDuck
4
+ module Warning
5
+
6
+ # A basic warning type.
7
+ class Basic
8
+
9
+ # Creates a simple warning with a message text.
10
+ # The warning is disabled by default.
11
+ def initialize(type, msg)
12
+ @type = type
13
+ @msg = msg
14
+ @enabled = false
15
+ @patterns = []
16
+ end
17
+
18
+ # Enables or disables the warning.
19
+ # Optionally enables/disables it for files matching a path_pattern.
20
+ def set(enabled, path_pattern=nil, params=[])
21
+ if path_pattern
22
+ if @enabled == enabled
23
+ raise WarnException, "Warning rule '#{enabled ? '+' : '-'}#{@type}:#{path_pattern}' has no effect"
24
+ else
25
+ @patterns << Regexp.new(Regexp.escape(path_pattern))
26
+ end
27
+ else
28
+ @enabled = enabled
29
+ @patterns = []
30
+ end
31
+ end
32
+
33
+ # True when warning is enabled for the given filename.
34
+ # (The params parameter is ignored).
35
+ def enabled?(filename="", params=[])
36
+ if @patterns.any? {|re| filename =~ re }
37
+ !@enabled
38
+ else
39
+ @enabled
40
+ end
41
+ end
42
+
43
+ # Documentation for the warning.
44
+ def doc
45
+ " #{@enabled ? '+' : '-'}#{@type} - #{@msg}"
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,40 @@
1
+ require 'jsduck/warning/warn_exception'
2
+
3
+ module JsDuck
4
+ module Warning
5
+
6
+ # A deprecated :no_doc* warning which maps to the new :nodoc
7
+ # warning.
8
+ class Deprecated
9
+
10
+ # Creates a deprecated warning with a mapping to :nodoc warning
11
+ # type with given parameters. The warning is disabled by
12
+ # default.
13
+ def initialize(type, msg, nodoc, params)
14
+ @type = type
15
+ @msg = msg
16
+ @enabled = false
17
+ @nodoc = nodoc
18
+ @params = params
19
+ end
20
+
21
+ # Enables or disables the mapped :nodoc warning.
22
+ def set(enabled, path_pattern=nil, params=[])
23
+ @nodoc.set(enabled, path_pattern, @params)
24
+ raise WarnException, "Warning type #{@type} is deprecated, use nodoc(#{@params.join(',')}) instead"
25
+ end
26
+
27
+ # This method shouldn't be called.
28
+ def enabled?(filename="", params=[])
29
+ raise "Deprecated warning '#{@type}' must not be checked for enabled/disabled"
30
+ end
31
+
32
+ # Documentation for the warning.
33
+ def doc
34
+ " -#{@type} - #{@msg} DEPRECATED"
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,79 @@
1
+ require 'jsduck/warning/warn_exception'
2
+ require 'set'
3
+
4
+ module JsDuck
5
+ module Warning
6
+
7
+ # Missing documentation warning.
8
+ class Nodoc
9
+
10
+ TYPES = Set[nil, :class, :member, :param]
11
+ VISIBILITIES = Set[nil, :public, :protected, :private]
12
+
13
+ # Creates the :nodoc warning type
14
+ def initialize
15
+ @rules = []
16
+ # disable by default
17
+ set(false)
18
+ end
19
+
20
+ # Enables or disables a particular sub-warning
21
+ def set(enabled, path_pattern=nil, params=[])
22
+ type = params[0]
23
+ visibility = params[1]
24
+
25
+ unless TYPES.include?(type) && VISIBILITIES.include?(visibility)
26
+ raise WarnException, "Invalid warning parameters: nodoc(#{type},#{visibility})"
27
+ end
28
+
29
+ @rules << {
30
+ :enabled => enabled,
31
+ :type => type,
32
+ :visibility => visibility,
33
+ :path_re => path_pattern ? Regexp.new(Regexp.escape(path_pattern)) : nil
34
+ }
35
+ end
36
+
37
+ # True when the warning is enabled for the given filename and
38
+ # params combination, where the params contain type and
39
+ # visibility setting.
40
+ def enabled?(filename="", params=[])
41
+ type = params[0]
42
+ visibility = params[1]
43
+
44
+ # Filter out rules that apply to our current item
45
+ matches = @rules.find_all do |r|
46
+ (r[:type].nil? || r[:type] == type) &&
47
+ (r[:visibility].nil? || r[:visibility] == visibility) &&
48
+ (r[:path_re].nil? || r[:path_re] =~ filename)
49
+ end
50
+
51
+ return matches.last[:enabled]
52
+ end
53
+
54
+ # Extensive documentation for :nodoc warning
55
+ def doc
56
+ [
57
+ "",
58
+ " -nodoc(<type>,<visibility>) - Missing documentation",
59
+ "",
60
+ " This warning can take parameters with the following values:",
61
+ "",
62
+ " <type> = class | member | param",
63
+ " <visibility> = public | protected | private",
64
+ "",
65
+ " So, to report missing documentation of public classes:",
66
+ "",
67
+ " --warnings='+nodoc(class,public)'",
68
+ "",
69
+ " Or, to report missing docs of all protected items in /etc:",
70
+ "",
71
+ " --warnings='+nodoc(,protected):/etc/'",
72
+ "",
73
+ ]
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,168 @@
1
+ require 'strscan'
2
+ require 'jsduck/warning/warn_exception'
3
+
4
+ module JsDuck
5
+ module Warning
6
+
7
+ # Parses the warnings passed in from command line
8
+ #
9
+ # Grammar:
10
+ #
11
+ # <warnings> := <warning> [ "," <warning> ]*
12
+ #
13
+ # <warning> := ["+" | "-"] <type> [<params-block>] [<path-block>]
14
+ #
15
+ # <type> := \w+
16
+ #
17
+ # <params-block> := "(" [<params>] ")"
18
+ #
19
+ # <params> := <param> [ "," <param> ]*
20
+ #
21
+ # <param> := \w+ | ""
22
+ #
23
+ # <path-block> := ":" <path>
24
+ #
25
+ # <path> := .*
26
+ #
27
+ class Parser
28
+ def initialize(string)
29
+ @scanner = StringScanner.new(string)
30
+ end
31
+
32
+ # Parses the warnings string.
33
+ #
34
+ # For example the following string:
35
+ #
36
+ # +tag,-nodoc(class,private):/some/path
37
+ #
38
+ # is parsed into the following structure:
39
+ #
40
+ # [
41
+ # {
42
+ # :type => :tag,
43
+ # :enabled => true,
44
+ # :params => [],
45
+ # :path => nil,
46
+ # },
47
+ # {
48
+ # :type => :nodoc,
49
+ # :enabled => false,
50
+ # :params => [:class, :private],
51
+ # :path => "/some/path",
52
+ # },
53
+ # ]
54
+ #
55
+ # When scanning fails, raises an exception with a descriptive
56
+ # message.
57
+ def parse
58
+ results = []
59
+
60
+ while !eos?
61
+ results << warning
62
+ match(/,/)
63
+ end
64
+
65
+ results
66
+ end
67
+
68
+ private
69
+
70
+ def warning
71
+ return {
72
+ :enabled => enabled,
73
+ :type => type,
74
+ :params => params,
75
+ :path => path,
76
+ }
77
+ end
78
+
79
+ def enabled
80
+ if match(/\+/)
81
+ true
82
+ elsif match(/-/)
83
+ false
84
+ else
85
+ true
86
+ end
87
+ end
88
+
89
+ def type
90
+ require(/\w+/).to_sym
91
+ end
92
+
93
+ def params
94
+ if match(/\(/)
95
+ ps = []
96
+
97
+ while !look(/\)/)
98
+ ps << param
99
+ break unless match(/,/)
100
+ end
101
+
102
+ require(/\)/)
103
+
104
+ ps
105
+ else
106
+ []
107
+ end
108
+ end
109
+
110
+ def param
111
+ if p = match(/\w+/)
112
+ p.to_sym
113
+ elsif look(/,/)
114
+ nil
115
+ else
116
+ unexpected_char
117
+ end
118
+ end
119
+
120
+ def path
121
+ if match(/:/)
122
+ match(/[^,]*/).strip
123
+ else
124
+ nil
125
+ end
126
+ end
127
+
128
+ # scans a pattern, throws error on failure
129
+ def require(re)
130
+ if m = match(re)
131
+ m
132
+ else
133
+ unexpected_char
134
+ end
135
+ end
136
+
137
+ # Reports unexpected character
138
+ def unexpected_char
139
+ # do successful empty scan, so we can use #pre_match and #post_match
140
+ @scanner.scan(//)
141
+ raise WarnException, "Unexpected '#{@scanner.peek(1)}' at " +
142
+ "--warnings='#{@scanner.pre_match}<HERE>#{@scanner.post_match}'"
143
+ end
144
+
145
+ # scans a pattern, ignoring the optional whitespace before it
146
+ def match(re)
147
+ skip_ws
148
+ @scanner.scan(re)
149
+ end
150
+
151
+ def look(re)
152
+ skip_ws
153
+ @scanner.check(re)
154
+ end
155
+
156
+ def eos?
157
+ skip_ws
158
+ @scanner.eos?
159
+ end
160
+
161
+ def skip_ws
162
+ @scanner.scan(/\s*/)
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+ end
@@ -0,0 +1,106 @@
1
+ require 'jsduck/warning/basic'
2
+ require 'jsduck/warning/nodoc'
3
+ require 'jsduck/warning/deprecated'
4
+ require 'jsduck/warning/all'
5
+ require 'jsduck/warning/warn_exception'
6
+
7
+ module JsDuck
8
+ module Warning
9
+
10
+ # Warnings management
11
+ class Registry
12
+
13
+ def initialize
14
+ @warnings = []
15
+ @warnings_map = {}
16
+
17
+ # Basic warnings
18
+ [
19
+ [:global, "Member doesn't belong to any class"],
20
+ [:inheritdoc, "@inheritdoc referring to unknown class or member"],
21
+ [:extend, "@extend/mixin/requires/uses referring to unknown class"],
22
+ [:tag, "Use of unsupported @tag"],
23
+ [:tag_repeated, "An @tag used multiple times, but only once allowed"],
24
+ [:tag_syntax, "@tag syntax error"],
25
+ [:link, "{@link} to unknown class or member"],
26
+ [:link_ambiguous, "{@link} is ambiguous"],
27
+ [:link_auto, "Auto-detected link to unknown class or member"],
28
+ [:html, "Unclosed HTML tag"],
29
+
30
+ [:alt_name, "Name used as both classname and alternate classname"],
31
+ [:name_missing, "Member or parameter has no name"],
32
+ [:dup_param, "Method has two parameters with the same name"],
33
+ [:dup_member, "Class has two members with the same name"],
34
+ [:req_after_opt, "Required parameter comes after optional"],
35
+ [:param_count, "Less parameters documented than detected from code"],
36
+ [:subproperty, "@param foo.bar where foo param doesn't exist"],
37
+ [:sing_static, "Singleton class member marked as @static"],
38
+ [:type_syntax, "Syntax error in {type definition}"],
39
+ [:type_name, "Unknown type referenced in {type definition}"],
40
+ [:enum, "Enum with invalid values or no values at all"],
41
+ [:fires, "@fires references unknown event"],
42
+
43
+ [:image, "{@img} referring to missing file"],
44
+ [:image_unused, "An image exists in --images dir that's not used"],
45
+ [:cat_old_format, "Categories file uses old deprecated format"],
46
+ [:cat_no_match, "Class pattern in categories file matches nothing"],
47
+ [:cat_class_missing, "Class is missing from categories file"],
48
+ [:guide, "Guide is missing from --guides dir"],
49
+
50
+ [:aside, "Problem with @aside tag"],
51
+ [:hide, "Problem with @hide tag"],
52
+ ].each do |w|
53
+ register(w[0], Warning::Basic.new(w[0], w[1]))
54
+ end
55
+
56
+ # :nodoc warning
57
+ register(:nodoc, Warning::Nodoc.new)
58
+
59
+ # :all warning (encompasses all other warning types)
60
+ register(:all, Warning::All.new(@warnings.clone))
61
+
62
+ # :deprecated warnings (linking to :nodoc warning)
63
+ [
64
+ {:type => :no_doc, :msg => "Alias for nodoc(class,public)", :params => [:class, :public]},
65
+ {:type => :no_doc_member, :msg => "Alias for nodoc(member,public)", :params => [:member, :public]},
66
+ {:type => :no_doc_param, :msg => "Alias for nodoc(param,public)", :params => [:param, :public]},
67
+ ].each do |w|
68
+ register(w[:type], Warning::Deprecated.new(w[:type], w[:msg], @warnings_map[:nodoc], w[:params]))
69
+ end
70
+
71
+ end
72
+
73
+ def register(type, warning)
74
+ @warnings << warning
75
+ @warnings_map[type] = warning
76
+ end
77
+
78
+ # Enables or disables a particular warning type.
79
+ # Additionally a filename pattern and params for the warning can be specified.
80
+ def set(type, enabled, path_pattern=nil, params=[])
81
+ if @warnings_map[type]
82
+ @warnings_map[type].set(enabled, path_pattern, params)
83
+ else
84
+ raise WarnException, "Warning of type '#{type}' doesn't exist"
85
+ end
86
+ end
87
+
88
+ # get documentation for all warnings
89
+ def doc
90
+ @warnings.map {|w| w.doc }.compact.flatten
91
+ end
92
+
93
+ # True when the warning is enabled for the given type and
94
+ # filename combination.
95
+ def enabled?(type, filename, params=[])
96
+ @warnings_map[type].enabled?(filename, params)
97
+ end
98
+
99
+ def has?(type)
100
+ @warnings_map.has_key?(type)
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,10 @@
1
+ module JsDuck
2
+ module Warning
3
+
4
+ # An exception thrown by JsDuck::Warning classes that is supposed
5
+ # to result in a warning being logged by Logger.
6
+ class WarnException < Exception
7
+ end
8
+
9
+ end
10
+ end