Class: JsDuck::Logger

Inherits:
Object
  • Object
show all
Includes:
Util::Singleton
Defined in:
lib/jsduck/logger.rb

Overview

Central logging of JsDuck

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util::Singleton

included

Constructor Details

#initializeLogger



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/jsduck/logger.rb', line 17

def initialize
  @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

  @shown_warnings = {}
end

Instance Attribute Details

#colorsObject

Set true to force colored output. Set false to force no colors.



15
16
17
# File 'lib/jsduck/logger.rb', line 15

def colors
  @colors
end

#verboseObject

Set to true to enable verbose logging



11
12
13
# File 'lib/jsduck/logger.rb', line 11

def verbose
  @verbose
end

Instance Method Details

#doc_warningsObject

get documentation for all warnings



103
104
105
# File 'lib/jsduck/logger.rb', line 103

def doc_warnings
  @warning_docs.map {|w| " #{@warnings[w[0]][:enabled] ? '+' : '-'}#{w[0]} - #{w[1]}" }
end

#fatal(msg) ⇒ Object

Prints fatal error message with backtrace. The error param should be $! from resque block.



172
173
174
# File 'lib/jsduck/logger.rb', line 172

def fatal(msg)
  $stderr.puts paint(:red, "Error: ") + msg
end

#fatal_backtrace(msg, error) ⇒ Object

Prints fatal error message with backtrace. The error param should be $! from resque block.



178
179
180
181
182
183
# File 'lib/jsduck/logger.rb', line 178

def fatal_backtrace(msg, error)
  $stderr.puts paint(:red, "Error: ") + "#{msg}: #{error}"
  $stderr.puts
  $stderr.puts "Here's a full backtrace:"
  $stderr.puts error.backtrace
end

#format(filename = nil, line = nil) ⇒ Object

Formats filename and line number for output



159
160
161
162
163
164
165
166
167
168
# File 'lib/jsduck/logger.rb', line 159

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

#log(msg, filename = nil) ⇒ Object

Prints log message with optional filename appended



71
72
73
74
75
# File 'lib/jsduck/logger.rb', line 71

def log(msg, filename=nil)
  if @verbose
    $stderr.puts paint(:green, msg) + " " + format(filename) + " ..."
  end
end

#set_warning(type, enabled, pattern = nil) ⇒ Object

Enables or disables a particular warning or all warnings when type == :all. Additionally a filename pattern can be specified.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/jsduck/logger.rb', line 80

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")
  end
end

#warn(type, msg, filename = nil, line = nil) ⇒ Object

Prints warning message.

The type must be one of predefined warning types which can be toggled on/off with command-line options, or it can be nil, in which case the warning is always shown.

Ignores duplicate warnings - only prints the first one. Works best when –processes=0, but it reduces the amount of warnings greatly also when run multiple processes.

Optionally filename and line number will be inserted to message. These two last arguments can also be supplied as one hash of:

{:filename => "foo.js", :linenr => 17}


122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/jsduck/logger.rb', line 122

def warn(type, msg, filename=nil, line=nil)
  if filename.is_a?(Hash)
    line = filename[:linenr]
    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
  end

  return false
end

#warning_enabled?(type, filename) ⇒ Boolean

True when the warning is enabled for the given type and filename combination.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/jsduck/logger.rb', line 142

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

#warnings_logged?Boolean

True when at least one warning was logged.



186
187
188
# File 'lib/jsduck/logger.rb', line 186

def warnings_logged?
  @shown_warnings.length > 0
end