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

Warn when enum contains wrong member types.

Throw away all enum members that aren't properties.

Fixes a crash when somebody attempts to add other types of members
that don't have a :type field, causing the #infer_type method to
fail.
parent 780894b6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ module JsDuck
        [:sing_static, "Singleton class member marked as @static"],
        [:type_syntax, "Syntax error in {type definition}"],
        [:type_name, "Unknown type referenced in {type definition}"],
        [:enum, "Enum defined without any values in it"],
        [:enum, "Enum with invalid values of no values at all"],

        [:image, "{@img} referring to missing file"],
        [:image_unused, "An image exists in --images dir that's not used"],
+27 −10
Original line number Diff line number Diff line
require 'jsduck/logger'

module JsDuck
  module Process

@@ -20,20 +22,11 @@ module JsDuck
      # processes single class
      def process(cls)
        expand_default(cls)
        reject_not_properties(cls)
        strip_inheritdoc(cls)
        cls[:enum][:type] = infer_type(cls) unless cls[:enum][:type]
      end

      # Given an enum class, returns the type infered from its values.
      def infer_type(cls)
        if cls[:members].length > 0
          types = cls[:members].map {|p| p[:type] }
          types.sort.uniq.join("/")
        else
          "Object"
        end
      end

      # Expands default value like widget.* into list of properties
      def expand_default(cls)
        if cls[:enum][:default] =~ /\A(.*)\.\*\z/
@@ -61,6 +54,19 @@ module JsDuck
        end
      end

      # Only allow properties as members, throw away all others.
      def reject_not_properties(cls)
        cls[:members].reject! do |m|
          if m[:tagname] == :property
            false
          else
            f = m[:files][0]
            Logger.warn(:enum, "Enums can only contain properties, #{m[:tagname]} found instead.", f[:filename], f[:linenr])
            true
          end
        end
      end

      # Remove the auto-inserted inheritdoc tag so the auto-detected enum
      # values default to being public.
      def strip_inheritdoc(cls)
@@ -68,6 +74,17 @@ module JsDuck
          p[:inheritdoc] = nil if p[:autodetected]
        end
      end

      # Given an enum class, returns the type infered from its values.
      def infer_type(cls)
        if cls[:members].length > 0
          types = cls[:members].map {|p| p[:type] }
          types.sort.uniq.join("/")
        else
          "Object"
        end
      end

    end

  end
+17 −0
Original line number Diff line number Diff line
@@ -289,4 +289,21 @@ describe JsDuck::Aggregator do
    end
  end

  describe "enum with events as members" do
    let(:doc) do
      parse(<<-EOS)["My.enum.Type"]
        /**
         * @enum My.enum.Type
         */
            /** @event foo */
            /** @event bar */
            /** @property zap */
      EOS
    end

    it "throws away all events, keeping only properties" do
      doc[:members].length.should == 1
    end
  end

end