Commit 16e23130 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Started out CssParser.

Implemented basic parsing of CSS variable doc-comments.
parent dcba5654
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
require 'jsduck/lexer'
require 'jsduck/doc_parser'

module JsDuck

  class CssParser
    def initialize(input)
      @lex = Lexer.new(input)
      @doc_parser = DocParser.new
      @docs = []
    end

    # Parses the whole CSS block and returns same kind of structure
    # that JavaScript parser does.
    def parse
      while !@lex.empty? do
        if look(:doc_comment)
          comment = @lex.next(true)
          @docs << {
            :comment => @doc_parser.parse(comment[:value]),
            :linenr => comment[:linenr],
            :code => {:type => :nop}
          }
        else
          @lex.next
        end
      end
      @docs
    end

    def look(*args)
      @lex.look(*args)
    end
  end

end
+14 −3
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ module JsDuck
          at_member
        elsif look(/@author\b/)
          at_author
        elsif look(/@var\b/)
          at_var
        elsif look(/@static\b/)
          boolean_at_tag(/@static/, :static)
        elsif look(/@(private|ignore|hide|protected)\b/)
@@ -179,6 +181,15 @@ module JsDuck
      skip_white
    end

    # matches @var {type} $name ...
    def at_var
      match(/@var/)
      add_tag(:var)
      maybe_type
      maybe_name(/\$[a-zA-Z0-9_-]*/)
      skip_white
    end

    # matches @type {type}  or  @type type
    #
    # The presence of @type implies that we are dealing with property.
@@ -237,10 +248,10 @@ module JsDuck
    end

    # matches identifier name if possible and sets it on @current_tag
    def maybe_name
    def maybe_name(pattern = /\w+/)
      skip_horiz_white
      if look(/\w/)
        @current_tag[:name] = ident
      if look(pattern)
        @current_tag[:name] = @input.scan(pattern)
      end
    end

+18 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ module JsDuck
        create_cfg(docs, code)
      when :property
        create_property(docs, code)
      when :var
        create_var(docs, code)
      end
    end

@@ -33,6 +35,8 @@ module JsDuck
        :method
      elsif doc_map[:property] || doc_map[:type]
        :property
      elsif doc_map[:var]
        :var
      elsif code[:type] == :ext_define
        :class
      elsif code[:type] == :assignment && class_name?(*code[:left])
@@ -67,6 +71,7 @@ module JsDuck
      end
      result[:property] = []
      result[:event] = []
      result[:var] = []
      result
    end

@@ -168,6 +173,19 @@ module JsDuck
      }
    end

    def create_var(docs, code)
      doc_map = build_doc_map(docs)
      return {
        :tagname => :var,
        :name => detect_name(:var, doc_map, code),
        :member => detect_member(doc_map),
        :type => detect_type(:var, doc_map, code),
        :doc => detect_doc(docs),
        :private => !!doc_map[:private],
        :static => !!doc_map[:static],
      }
    end

    def detect_name(tagname, doc_map, code, name_type = :last_name)
      main_tag = doc_map[tagname] ? doc_map[tagname].first : {}
      if main_tag[:name]
+41 −0
Original line number Diff line number Diff line
require "jsduck/aggregator"
require "jsduck/css_parser"

describe JsDuck::Aggregator do

  def parse(string)
    agr = JsDuck::Aggregator.new
    agr.aggregate(JsDuck::CssParser.new(string).parse)
    agr.result
  end

  it "yields no results when parsing CSS without doc-comments" do
    @docs = parse("div > p a:link {text-align: top;}")
    @docs.length.should == 0
  end

  describe "CSS with @var in doc-comment" do
    before do
      @doc = parse(<<-EOCSS)[0]
        /**
         * @var {measurement} $button-height Default height for buttons.
         */
      EOCSS
    end

    it "detects variable" do
      @doc[:tagname].should == :var
    end
    it "detects variable name" do
      @doc[:name].should == "$button-height"
    end
    it "detects variable type" do
      @doc[:type].should == "measurement"
    end
    it "detects variable description" do
      @doc[:doc].should == "Default height for buttons."
    end
  end

end