Loading lib/jsduck/lint.rb +18 −4 Original line number Diff line number Diff line Loading @@ -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 Loading lib/jsduck/type_parser.rb +36 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading spec/type_parser_spec.rb +9 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading
lib/jsduck/lint.rb +18 −4 Original line number Diff line number Diff line Loading @@ -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 Loading
lib/jsduck/type_parser.rb +36 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading
spec/type_parser_spec.rb +9 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading