Skip to content

Generating warnings

Rene Saarsoo edited this page Aug 5, 2013 · 5 revisions

JSDuck generates lots of helpful warnings, and by writing a custom tag you can give your own custom warnings.

To print a warning you simply call the builtin JsDuck::Logger.warn method. It takes three arguments:

JsDuck::Logger.warn(warning_type, message, position)
  • warning_type is either one of the builtin types or nil. Because we are creating custom warnings we'll be using nil for the rest of this tutorial.
  • message is the actual warning message to print.
  • position defines a file name and line number to give the context for the warning. In parse_doc and process_doc the position gets passed in as parameter. In other methods we'll get the position from context hash.

Warnings inside parse_doc

Extending the @license tag example we can print a warning when @license isn't followed by a name of any kind:

require "jsduck/tag/tag"
require "jsduck/logger"

class License < JsDuck::Tag::Tag

  def parse_doc(scanner, position)
    text = scanner.match(/.*$/)
    if text.length == 0
        JsDuck::Logger.warn(nil, "@license expects a name as argument", position)
    end
    return { :tagname => :license, :text => text }
  end

  ...

end

When we now run JSDuck over a file with such invalid @license tag, we get a warning like this:

Warning: /home/user/license-example.js:12: @license expects a name as argument

Warnings inside process_doc

We can print the same kind of warning inside process_doc in pretty much the same way:

def process_doc(context, license_tags, position)
  context[:license] = license_tags.map do |tag|
    if tag[:text].length == 0
      JsDuck::Logger.warn(nil, "@license expects a name as argument", position)
    end
    tag[:text]
  end
end

Warnings inside to_html

In to_html method no position parameter gets passed in, but the position is available within the context hash:

def to_html(context)
  position = context[:files][0]
  JsDuck::Logger.warn(nil, "Hey, you're using a @license tag", position)

  licenses = context[:license].map {|license| "<b>#{license}</b>" }.join(" and ")
  <<-EOHTML
    <p>This software is licensed under: #{licenses}.</p>
  EOHTML
end

Documentation of a class can be merged together from several /** @class */ doc-comments. That's why the context[:files] is an array of the positions of all those merged doc-comments. This kind of code is quite rare though, and no such merging happens for class members. So normally it's good enough to just take the first position out of this array and ignore the rest.

Warnings inside format

Just like in to_html we take the position information from context parameter:

def format(context, formatter)
  position = context[:files][0]
  JsDuck::Logger.warn(nil, "Hey, you're using a @license tag", position)

  context[:license].each {|license| formatter.format(license[:text]) }
end
Clone this wiki locally