From 0c4fe37f355e337a7cd0ec9981ea7f741b1e8842 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 13 Mar 2012 17:46:23 +0200 Subject: [PATCH] Support record type in TypeParser. In supporting Google Closure Compiler syntax. For the record types to even reach type parser the DocParser needed to be modified to parse the {...} type blocks by taking account the need to balance the braces. --- lib/jsduck/doc_parser.rb | 12 +++++++++- lib/jsduck/type_parser.rb | 50 +++++++++++++++++++++++++++++++++++---- spec/doc_parser_spec.rb | 13 ++++++++++ spec/type_parser_spec.rb | 18 ++++++++++++++ 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/lib/jsduck/doc_parser.rb b/lib/jsduck/doc_parser.rb index 31001446..9dab1605 100644 --- a/lib/jsduck/doc_parser.rb +++ b/lib/jsduck/doc_parser.rb @@ -439,14 +439,24 @@ module JsDuck # matches {...=} and returns text inside brackets def typedef match(/\{/) - name = @input.scan(/[^}]+/) + name = @input.scan(/[^{}]*/) + + # Type definition can contain nested braces: {{foo:Number}} + # In such case we parse the definition so that the braces are balanced. + while @input.check(/[{]/) + name += "{" + typedef[:type] +"}" + name += @input.scan(/[^{}]*/) + end + if name =~ /=$/ name = name.chop optional = true else optional = false end + match(/\}/) + return {:type => name, :optional => optional} end diff --git a/lib/jsduck/type_parser.rb b/lib/jsduck/type_parser.rb index 87348227..7e00185f 100644 --- a/lib/jsduck/type_parser.rb +++ b/lib/jsduck/type_parser.rb @@ -23,6 +23,8 @@ module JsDuck # Array. # Object. # + # {myNum: number, myObject} + # # (number|boolean) # ?number # !Object @@ -35,10 +37,6 @@ module JsDuck # function(?string=, number=) # function(string, ...[number]) # - # Currently not supported: - # - # {myNum: number, myObject} - # class TypeParser # Allows to check the type of error that was encountered. # It will be either of the two: @@ -143,7 +141,7 @@ module JsDuck # # ::= [ "[]" ]* # - # ::= | | + # ::= | | | # def null_type if nullability = @input.scan(/[?!]/) @@ -152,6 +150,8 @@ module JsDuck if @input.check(/\(/) return false unless union_type + elsif @input.check(/\{/) + return false unless record_type elsif @input.check(/function\(/) return false unless function_type else @@ -179,6 +179,46 @@ module JsDuck true end + # + # ::= "{" [ "," ]* "}" + # + def record_type + @out << @input.scan(/\{/) + + return false unless rtype_item + + while @input.scan(/,/) + @out << "," + return false unless rtype_item + end + + return false unless @input.scan(/\}/) + @out << "}" + + true + end + + # + # ::= ":" + # | + # + def rtype_item + skip_whitespace + + key = @input.scan(/[a-zA-Z0-9_]+/) + return false unless key + + skip_whitespace + if @input.scan(/:/) + @out << ":" + skip_whitespace + return false unless null_type + skip_whitespace + end + + true + end + # # ::= "function(" ")" [ ":" ] # diff --git a/spec/doc_parser_spec.rb b/spec/doc_parser_spec.rb index 12af220a..9cb76b04 100644 --- a/spec/doc_parser_spec.rb +++ b/spec/doc_parser_spec.rb @@ -117,5 +117,18 @@ describe JsDuck::DocParser do end end + describe "type definition with nested {braces}" do + before do + @tag = parse_single(<<-EOS.strip)[0] + /** + * @param {{foo:{bar:Number}}} x + */ + EOS + end + it "is parsed ensuring balanced braces" do + @tag[:type].should == "{foo:{bar:Number}}" + end + end + end diff --git a/spec/type_parser_spec.rb b/spec/type_parser_spec.rb index 0aa6e9e0..c0503960 100644 --- a/spec/type_parser_spec.rb +++ b/spec/type_parser_spec.rb @@ -268,6 +268,24 @@ describe JsDuck::TypeParser do end end + describe "record type" do + it "matches list of properties" do + parse("{foo, bar, baz}").should == true + end + + it "matches properties with types" do + parse("{foo: String, bar: Number}").should == true + end + + it "matches property with complex type" do + parse("{foo: (String|Array.)}").should == true + end + + it "matches nested record type" do + parse("{foo: {bar}}").should == true + end + end + it "always matches primitive types" do parse("boolean").should == true parse("number").should == true -- GitLab