Commit 48d4847e authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Auto-detect @readonly from Object.defineProperty.

parent a6b814b4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ module JsDuck
          make(ast["key"].key_value, ast["value"])

          # Object.defineProperty(obj, "prop", {value: function() {} })
        elsif exp && (value = exp.value_of_define_property) && detect(value)
        elsif exp && (value = exp.object_descriptor("value")) && detect(value)
          name = exp["arguments"][1].to_value
          make(name, value)

+5 −3
Original line number Diff line number Diff line
@@ -120,15 +120,17 @@ module JsDuck
        end
      end

      # Returns the value field from Object.defineProperty call
      # Returns value of a given field from Object.defineProperty call
      # descriptor object.
      def value_of_define_property
      def object_descriptor(descriptor_key)
        return unless define_property?

        descriptor = child("arguments")[2]
        descriptor.each_property do |key, value, prop|
          return value if key == "value"
          return value if key == descriptor_key
        end

        return nil
      end

      # Returns line number in parsed source where the Node resides.
+5 −8
Original line number Diff line number Diff line
@@ -41,7 +41,9 @@ module JsDuck
          # Object.defineProperty(obj, "prop", {value: x})
        elsif exp && exp.define_property?
          name = exp["arguments"][1].to_value
          make(name, exp.value_of_define_property)
          writable = exp.object_descriptor("writable")
          readonly = writable ? !writable.to_value : true
          make(name, exp.object_descriptor("value"), readonly)

        else
          nil
@@ -49,12 +51,13 @@ module JsDuck
      end

      # Produces a doc-hash for a property.
      def make(name=nil, ast=nil)
      def make(name=nil, ast=nil, readonly=nil)
        return {
          :tagname => :property,
          :name => name,
          :type => ast && ast.value_type,
          :default => ast && default(ast),
          :readonly => readonly,
        }
      end

@@ -64,12 +67,6 @@ module JsDuck
        ast.to_value != nil ? ast.to_s : nil
      end

      def value_from_descriptor(descriptor)
        descriptor.each_property do |key, value, prop|
          return value if key == "value"
        end
      end

    end
  end
end
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ module JsDuck::Tag
      h = super(code)
      h[:type] = code[:type]
      h[:default] = code[:default]
      h[:readonly] = code[:readonly]
      h
    end

+47 −0
Original line number Diff line number Diff line
@@ -19,4 +19,51 @@ describe JsDuck::Aggregator do
    end
  end

  describe "Object.defineProperty with writable:true" do
    let(:doc) do
      parse_member(<<-EOS)
        /**  */
        Object.defineProperty(this, 'myCfg', {
            value: 5,
            writable: true
        });
      EOS
    end

    it "doesn't get readonly attribute" do
      doc[:readonly].should_not == true
    end
  end

  describe "Object.defineProperty with writable:false" do
    let(:doc) do
      parse_member(<<-EOS)
        /**  */
        Object.defineProperty(this, 'myCfg', {
            value: 5,
            writable: false
        });
      EOS
    end

    it "gets readonly attribute" do
      doc[:readonly].should == true
    end
  end

  describe "Object.defineProperty without writable:" do
    let(:doc) do
      parse_member(<<-EOS)
        /**  */
        Object.defineProperty(this, 'myCfg', {
            value: 5
        });
      EOS
    end

    it "gets readonly attribute" do
      doc[:readonly].should == true
    end
  end

end