Loading lib/jsduck/batch_processor.rb +2 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ require 'jsduck/process/versions' require 'jsduck/process/return_values' require 'jsduck/process/fires' require 'jsduck/process/lint' require 'jsduck/process/no_doc' require 'jsduck/process/circular_deps' module JsDuck Loading Loading @@ -71,6 +72,7 @@ module JsDuck Process::ReturnValues.new(relations).process_all! Process::Fires.new(relations).process_all! Process::Lint.new(relations).process_all! Process::NoDoc.new(relations).process_all! relations end Loading lib/jsduck/logger.rb +51 −98 Original line number Diff line number Diff line require 'jsduck/util/singleton' require 'jsduck/util/os' require 'jsduck/warning/registry' require 'jsduck/warning/warn_exception' module JsDuck Loading @@ -18,51 +20,7 @@ module JsDuck @verbose = false @colors = nil @warning_docs = [ [:global, "Member doesn't belong to any class"], [:inheritdoc, "@inheritdoc referring to unknown class or member"], [:extend, "@extend/mixin/requires/uses referring to unknown class"], [:tag, "Use of unsupported @tag"], [:tag_repeated, "An @tag used multiple times, but only once allowed"], [:tag_syntax, "@tag syntax error"], [:link, "{@link} to unknown class or member"], [:link_ambiguous, "{@link} is ambiguous"], [:link_auto, "Auto-detected link to unknown class or member"], [:html, "Unclosed HTML tag."], [:alt_name, "Name used as both classname and alternate classname"], [:name_missing, "Member or parameter has no name"], [:no_doc, "Public class without documentation"], [:no_doc_member, "Public member without documentation"], [:no_doc_param, "Parameter of public member without documentation"], [:dup_param, "Method has two parameters with the same name"], [:dup_member, "Class has two members with the same name"], [:req_after_opt, "Required parameter comes after optional"], [:param_count, "Less parameters documented than detected from code"], [:subproperty, "@param foo.bar where foo param doesn't exist"], [:sing_static, "Singleton class member marked as @static"], [:type_syntax, "Syntax error in {type definition}"], [:type_name, "Unknown type referenced in {type definition}"], [:enum, "Enum with invalid values or no values at all"], [:fires, "@fires references unknown event"], [:image, "{@img} referring to missing file"], [:image_unused, "An image exists in --images dir that's not used"], [:cat_old_format, "Categories file uses old deprecated format"], [:cat_no_match, "Class pattern in categories file matches nothing"], [:cat_class_missing, "Class is missing from categories file"], [:guide, "Guide is missing from --guides dir"], [:aside, "Problem with @aside tag"], [:hide, "Problem with @hide tag"], ] # Turn off all warnings by default. # This is good for testing. # When running JSDuck app, the Options class enables most warnings. @warnings = {} @warning_docs.each do |w| @warnings[w[0]] = {:enabled => false, :patterns => []} end @warnings = Warning::Registry.new @shown_warnings = {} end Loading @@ -77,31 +35,17 @@ module JsDuck # Enables or disables a particular warning # or all warnings when type == :all. # Additionally a filename pattern can be specified. def set_warning(type, enabled, pattern=nil) if type == :all # When used with a pattern, only add the pattern to the rules # where it can have an effect - otherwise we get a warning. @warnings.each_key do |key| set_warning(key, enabled, pattern) unless pattern && @warnings[key][:enabled] == enabled end elsif @warnings.has_key?(type) if pattern if @warnings[type][:enabled] == enabled warn(nil, "Warning rule '#{enabled ? '+' : '-'}#{type}:#{pattern}' has no effect") else @warnings[type][:patterns] << Regexp.new(Regexp.escape(pattern)) end else @warnings[type] = {:enabled => enabled, :patterns => []} end else warn(nil, "Warning of type '#{type}' doesn't exist") def set_warning(type, enabled, pattern=nil, params=[]) begin @warnings.set(type, enabled, pattern, params) rescue Warning::WarnException => e warn(nil, e.message) end end # get documentation for all warnings def doc_warnings @warning_docs.map {|w| " #{@warnings[w[0]][:enabled] ? '+' : '-'}#{w[0]} - #{w[1]}" } @warnings.doc end # Prints warning message. Loading @@ -125,47 +69,25 @@ module JsDuck filename = filename[:filename] end msg = paint(:yellow, "Warning: ") + format(filename, line) + " " + msg if warning_enabled?(type, filename) if !@shown_warnings[msg] $stderr.puts msg @shown_warnings[msg] = true end print_warning(msg, filename, line) end return false end # True when the warning is enabled for the given type and filename # combination. def warning_enabled?(type, filename) if type == nil true elsif !@warnings.has_key?(type) warn(nil, "Unknown warning type #{type}") false else rule = @warnings[type] if rule[:patterns].any? {|re| filename =~ re } !rule[:enabled] else rule[:enabled] end end end # Prints :nodoc warning message. # # Because the :nodoc warning needs different parameters, for now # we're using a separate method specially for these. def warn_nodoc(type, visibility, msg, file) filename = file[:filename] line = file[:linenr] # Formats filename and line number for output def format(filename=nil, line=nil) out = "" if filename out = Util::OS.windows? ? filename.gsub('/', '\\') : filename if line out += ":#{line}:" if @warnings.enabled?(:nodoc, filename, [type, visibility]) print_warning(msg, filename, line) end end paint(:magenta, out) end # Prints fatal error message with backtrace. # The error param should be $! from resque block. Loading Loading @@ -202,6 +124,37 @@ module JsDuck CLEAR = "\e[0m" def warning_enabled?(type, filename) if type == nil true elsif !@warnings.has?(type) warn(nil, "Unknown warning type #{type}") else @warnings.enabled?(type, filename) end end def print_warning(msg, filename, line) warning = paint(:yellow, "Warning: ") + format(filename, line) + " " + msg if !@shown_warnings[warning] $stderr.puts warning @shown_warnings[warning] = true end end # Formats filename and line number for output def format(filename=nil, line=nil) out = "" if filename out = Util::OS.windows? ? filename.gsub('/', '\\') : filename if line out += ":#{line}:" end end paint(:magenta, out) end # Helper for doing colored output in UNIX terminal # # Only does color output when STDERR is attached to TTY Loading lib/jsduck/options.rb +8 −8 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ require 'jsduck/util/io' require 'jsduck/util/parallel' require 'jsduck/tag_registry' require 'jsduck/js/ext_patterns' require 'jsduck/warning/parser' module JsDuck Loading Loading @@ -148,7 +149,7 @@ module JsDuck Logger.set_warning(:link_auto, false) Logger.set_warning(:param_count, false) Logger.set_warning(:fires, false) Logger.set_warning(:no_doc_param, false) Logger.set_warning(:nodoc, false) @optparser = create_option_parser end Loading Loading @@ -672,7 +673,7 @@ module JsDuck Logger.verbose = true end opts.on('--warnings=+A,-B,+C', Array, opts.on('--warnings=+A,-B,+C', "Turns warnings selectively on/off.", "", " +all - to turn on all warnings.", Loading @@ -696,13 +697,12 @@ module JsDuck "(Those with '+' in front of them default to on)", "", *Logger.doc_warnings) do |warnings| warnings.each do |op| if op =~ /^([-+]?)(\w+)(?::(.*))?$/ enable = !($1 == "-") name = $2.to_sym path = $3 Logger.set_warning(name, enable, path) begin Warning::Parser.new(warnings).parse.each do |w| Logger.set_warning(w[:type], w[:enabled], w[:path], w[:params]) end rescue Warning::WarnException => e Logger.warn(nil, e.message) end end Loading lib/jsduck/process/lint.rb +0 −28 Original line number Diff line number Diff line require 'jsduck/logger' require 'jsduck/class' module JsDuck module Process Loading @@ -14,7 +13,6 @@ module JsDuck # Runs the linter def process_all! warn_no_doc warn_unnamed warn_optional_params warn_duplicate_params Loading @@ -37,32 +35,6 @@ module JsDuck end end # print warning for each class or public member with no name def warn_no_doc @relations.each do |cls| if cls[:doc] == "" && !cls[:private] warn(:no_doc, "No documentation for #{cls[:name]}", cls) end cls.all_local_members.each do |member| if !member[:private] && !member[:hide] && !JsDuck::Class.constructor?(member) if member[:doc] == "" warn(:no_doc_member, "No documentation for #{member[:owner]}##{member[:name]}", member) end (member[:params] || []).each do |p| if p[:doc] == "" warn(:no_doc_param, "No documentation for parameter #{p[:name]} of #{member[:owner]}##{member[:name]}", member) end end end end end end # print warning for each non-optional parameter that follows an optional parameter def warn_optional_params each_member do |member| Loading lib/jsduck/process/no_doc.rb 0 → 100644 +50 −0 Original line number Diff line number Diff line require 'jsduck/logger' require 'jsduck/class' module JsDuck module Process # Reports missing documentation class NoDoc def initialize(relations) @relations = relations end # Prints warning for each class or public member with no name def process_all! @relations.each do |cls| if cls[:doc] == "" warn(:class, "No documentation for #{cls[:name]}", cls) end cls.all_local_members.each do |member| if !member[:hide] && !JsDuck::Class.constructor?(member) if member[:doc] == "" warn(:member, "No documentation for #{member[:owner]}##{member[:name]}", member) end (member[:params] || []).each do |p| if p[:doc] == "" warn(:param, "No documentation for parameter #{p[:name]} of #{member[:owner]}##{member[:name]}", member) end end end end end end private def warn(type, msg, owner) visibility = owner[:private] ? :private : (owner[:protected] ? :protected : :public) Logger.warn_nodoc(type, visibility, msg, owner[:files][0]) end end end end Loading
lib/jsduck/batch_processor.rb +2 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ require 'jsduck/process/versions' require 'jsduck/process/return_values' require 'jsduck/process/fires' require 'jsduck/process/lint' require 'jsduck/process/no_doc' require 'jsduck/process/circular_deps' module JsDuck Loading Loading @@ -71,6 +72,7 @@ module JsDuck Process::ReturnValues.new(relations).process_all! Process::Fires.new(relations).process_all! Process::Lint.new(relations).process_all! Process::NoDoc.new(relations).process_all! relations end Loading
lib/jsduck/logger.rb +51 −98 Original line number Diff line number Diff line require 'jsduck/util/singleton' require 'jsduck/util/os' require 'jsduck/warning/registry' require 'jsduck/warning/warn_exception' module JsDuck Loading @@ -18,51 +20,7 @@ module JsDuck @verbose = false @colors = nil @warning_docs = [ [:global, "Member doesn't belong to any class"], [:inheritdoc, "@inheritdoc referring to unknown class or member"], [:extend, "@extend/mixin/requires/uses referring to unknown class"], [:tag, "Use of unsupported @tag"], [:tag_repeated, "An @tag used multiple times, but only once allowed"], [:tag_syntax, "@tag syntax error"], [:link, "{@link} to unknown class or member"], [:link_ambiguous, "{@link} is ambiguous"], [:link_auto, "Auto-detected link to unknown class or member"], [:html, "Unclosed HTML tag."], [:alt_name, "Name used as both classname and alternate classname"], [:name_missing, "Member or parameter has no name"], [:no_doc, "Public class without documentation"], [:no_doc_member, "Public member without documentation"], [:no_doc_param, "Parameter of public member without documentation"], [:dup_param, "Method has two parameters with the same name"], [:dup_member, "Class has two members with the same name"], [:req_after_opt, "Required parameter comes after optional"], [:param_count, "Less parameters documented than detected from code"], [:subproperty, "@param foo.bar where foo param doesn't exist"], [:sing_static, "Singleton class member marked as @static"], [:type_syntax, "Syntax error in {type definition}"], [:type_name, "Unknown type referenced in {type definition}"], [:enum, "Enum with invalid values or no values at all"], [:fires, "@fires references unknown event"], [:image, "{@img} referring to missing file"], [:image_unused, "An image exists in --images dir that's not used"], [:cat_old_format, "Categories file uses old deprecated format"], [:cat_no_match, "Class pattern in categories file matches nothing"], [:cat_class_missing, "Class is missing from categories file"], [:guide, "Guide is missing from --guides dir"], [:aside, "Problem with @aside tag"], [:hide, "Problem with @hide tag"], ] # Turn off all warnings by default. # This is good for testing. # When running JSDuck app, the Options class enables most warnings. @warnings = {} @warning_docs.each do |w| @warnings[w[0]] = {:enabled => false, :patterns => []} end @warnings = Warning::Registry.new @shown_warnings = {} end Loading @@ -77,31 +35,17 @@ module JsDuck # Enables or disables a particular warning # or all warnings when type == :all. # Additionally a filename pattern can be specified. def set_warning(type, enabled, pattern=nil) if type == :all # When used with a pattern, only add the pattern to the rules # where it can have an effect - otherwise we get a warning. @warnings.each_key do |key| set_warning(key, enabled, pattern) unless pattern && @warnings[key][:enabled] == enabled end elsif @warnings.has_key?(type) if pattern if @warnings[type][:enabled] == enabled warn(nil, "Warning rule '#{enabled ? '+' : '-'}#{type}:#{pattern}' has no effect") else @warnings[type][:patterns] << Regexp.new(Regexp.escape(pattern)) end else @warnings[type] = {:enabled => enabled, :patterns => []} end else warn(nil, "Warning of type '#{type}' doesn't exist") def set_warning(type, enabled, pattern=nil, params=[]) begin @warnings.set(type, enabled, pattern, params) rescue Warning::WarnException => e warn(nil, e.message) end end # get documentation for all warnings def doc_warnings @warning_docs.map {|w| " #{@warnings[w[0]][:enabled] ? '+' : '-'}#{w[0]} - #{w[1]}" } @warnings.doc end # Prints warning message. Loading @@ -125,47 +69,25 @@ module JsDuck filename = filename[:filename] end msg = paint(:yellow, "Warning: ") + format(filename, line) + " " + msg if warning_enabled?(type, filename) if !@shown_warnings[msg] $stderr.puts msg @shown_warnings[msg] = true end print_warning(msg, filename, line) end return false end # True when the warning is enabled for the given type and filename # combination. def warning_enabled?(type, filename) if type == nil true elsif !@warnings.has_key?(type) warn(nil, "Unknown warning type #{type}") false else rule = @warnings[type] if rule[:patterns].any? {|re| filename =~ re } !rule[:enabled] else rule[:enabled] end end end # Prints :nodoc warning message. # # Because the :nodoc warning needs different parameters, for now # we're using a separate method specially for these. def warn_nodoc(type, visibility, msg, file) filename = file[:filename] line = file[:linenr] # Formats filename and line number for output def format(filename=nil, line=nil) out = "" if filename out = Util::OS.windows? ? filename.gsub('/', '\\') : filename if line out += ":#{line}:" if @warnings.enabled?(:nodoc, filename, [type, visibility]) print_warning(msg, filename, line) end end paint(:magenta, out) end # Prints fatal error message with backtrace. # The error param should be $! from resque block. Loading Loading @@ -202,6 +124,37 @@ module JsDuck CLEAR = "\e[0m" def warning_enabled?(type, filename) if type == nil true elsif !@warnings.has?(type) warn(nil, "Unknown warning type #{type}") else @warnings.enabled?(type, filename) end end def print_warning(msg, filename, line) warning = paint(:yellow, "Warning: ") + format(filename, line) + " " + msg if !@shown_warnings[warning] $stderr.puts warning @shown_warnings[warning] = true end end # Formats filename and line number for output def format(filename=nil, line=nil) out = "" if filename out = Util::OS.windows? ? filename.gsub('/', '\\') : filename if line out += ":#{line}:" end end paint(:magenta, out) end # Helper for doing colored output in UNIX terminal # # Only does color output when STDERR is attached to TTY Loading
lib/jsduck/options.rb +8 −8 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ require 'jsduck/util/io' require 'jsduck/util/parallel' require 'jsduck/tag_registry' require 'jsduck/js/ext_patterns' require 'jsduck/warning/parser' module JsDuck Loading Loading @@ -148,7 +149,7 @@ module JsDuck Logger.set_warning(:link_auto, false) Logger.set_warning(:param_count, false) Logger.set_warning(:fires, false) Logger.set_warning(:no_doc_param, false) Logger.set_warning(:nodoc, false) @optparser = create_option_parser end Loading Loading @@ -672,7 +673,7 @@ module JsDuck Logger.verbose = true end opts.on('--warnings=+A,-B,+C', Array, opts.on('--warnings=+A,-B,+C', "Turns warnings selectively on/off.", "", " +all - to turn on all warnings.", Loading @@ -696,13 +697,12 @@ module JsDuck "(Those with '+' in front of them default to on)", "", *Logger.doc_warnings) do |warnings| warnings.each do |op| if op =~ /^([-+]?)(\w+)(?::(.*))?$/ enable = !($1 == "-") name = $2.to_sym path = $3 Logger.set_warning(name, enable, path) begin Warning::Parser.new(warnings).parse.each do |w| Logger.set_warning(w[:type], w[:enabled], w[:path], w[:params]) end rescue Warning::WarnException => e Logger.warn(nil, e.message) end end Loading
lib/jsduck/process/lint.rb +0 −28 Original line number Diff line number Diff line require 'jsduck/logger' require 'jsduck/class' module JsDuck module Process Loading @@ -14,7 +13,6 @@ module JsDuck # Runs the linter def process_all! warn_no_doc warn_unnamed warn_optional_params warn_duplicate_params Loading @@ -37,32 +35,6 @@ module JsDuck end end # print warning for each class or public member with no name def warn_no_doc @relations.each do |cls| if cls[:doc] == "" && !cls[:private] warn(:no_doc, "No documentation for #{cls[:name]}", cls) end cls.all_local_members.each do |member| if !member[:private] && !member[:hide] && !JsDuck::Class.constructor?(member) if member[:doc] == "" warn(:no_doc_member, "No documentation for #{member[:owner]}##{member[:name]}", member) end (member[:params] || []).each do |p| if p[:doc] == "" warn(:no_doc_param, "No documentation for parameter #{p[:name]} of #{member[:owner]}##{member[:name]}", member) end end end end end end # print warning for each non-optional parameter that follows an optional parameter def warn_optional_params each_member do |member| Loading
lib/jsduck/process/no_doc.rb 0 → 100644 +50 −0 Original line number Diff line number Diff line require 'jsduck/logger' require 'jsduck/class' module JsDuck module Process # Reports missing documentation class NoDoc def initialize(relations) @relations = relations end # Prints warning for each class or public member with no name def process_all! @relations.each do |cls| if cls[:doc] == "" warn(:class, "No documentation for #{cls[:name]}", cls) end cls.all_local_members.each do |member| if !member[:hide] && !JsDuck::Class.constructor?(member) if member[:doc] == "" warn(:member, "No documentation for #{member[:owner]}##{member[:name]}", member) end (member[:params] || []).each do |p| if p[:doc] == "" warn(:param, "No documentation for parameter #{p[:name]} of #{member[:owner]}##{member[:name]}", member) end end end end end end private def warn(type, msg, owner) visibility = owner[:private] ? :private : (owner[:protected] ? :protected : :public) Logger.warn_nodoc(type, visibility, msg, owner[:files][0]) end end end end