Commit 82190145 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Display warnings for unknown types.

parent 44e480f2
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -73,18 +73,32 @@ module JsDuck

    # Check parameter types
    def warn_types
      parser = TypeParser.new
      parser = TypeParser.new(@relations)
      each_member do |member|
        (member[:params] || []).each do |p|
          if !parser.parse(p[:type])
            if parser.error == :syntax
              warn("Incorrect parameter type syntax #{p[:type]}", member)
            else
              warn("Unknown parameter type #{p[:type]}", member)
            end
          end
        end

        if member[:return] && !parser.parse(member[:return][:type])
          if parser.error == :syntax
            warn("Incorrect return type syntax #{member[:return][:type]}", member)
          else
            warn("Unknown return type #{member[:return][:type]}", member)
          end
        end

        if member[:type] && !parser.parse(member[:type])
          if parser.error == :syntax
            warn("Incorrect type syntax #{member[:type]}", member)
          else
            warn("Unkown type #{member[:type]}", member)
          end
        end
      end
    end
+36 −1
Original line number Diff line number Diff line
@@ -15,8 +15,32 @@ module JsDuck
  # Details are covered in spec.
  #
  class TypeParser
    # Allows to check the type of error that was encountered.
    # It will be either of the two:
    # - :syntax - type definition syntax is incorrect
    # - :name - one of the names of the types is unknown
    attr_reader :error

    # Initializes the parser with hash of valid type names
    def initialize(relations={})
      @relations = relations
      @builtins = {
        "Object" => true,
        "String" => true,
        "Number" => true,
        "Boolean" => true,
        "RegExp" => true,
        "Function" => true,
        "Array" => true,
        "Date" => true,
        "undefined" => true,
        "Mixed" => true,
      }
    end

    def parse(str)
      @input = StringScanner.new(str)
      @error = :syntax

      # Return immediately if base type doesn't match
      return false unless base_type
@@ -41,7 +65,18 @@ module JsDuck
    #
    # dot-separated identifiers followed by optional "[]"
    def base_type
      @input.scan(/[a-zA-Z_]+(\.[a-zA-Z_]+)*(\[\])?/)
      type = @input.scan(/[a-zA-Z_]+(\.[a-zA-Z_]+)*(\[\])?/)
      return type && exists?(type)
    end

    def exists?(type)
      stype = type.sub(/\[\]$/, "")
      if @builtins[stype] || @relations[stype]
        true
      else
        @error = :name
        false
      end
    end

  end
+9 −1
Original line number Diff line number Diff line
@@ -3,7 +3,11 @@ require "jsduck/type_parser"
describe JsDuck::TypeParser do

  def parse(str)
    JsDuck::TypeParser.new.parse(str)
    types = {
      "Ext.form.Panel" => true,
      "Ext.Element" => true,
    }
    JsDuck::TypeParser.new(types).parse(str)
  end

  it "matches simple type" do
@@ -59,6 +63,10 @@ describe JsDuck::TypeParser do
      parse("").should == false
    end

    it "unknown type name" do
      parse("Blah").should == false
    end

    it "type ending with dot" do
      parse("Ext.").should == false
    end