1##
2# A constant
3
4class RDoc::Constant < RDoc::CodeObject
5
6  MARSHAL_VERSION = 0 # :nodoc:
7
8  ##
9  # Sets the module or class this is constant is an alias for.
10
11  attr_writer :is_alias_for
12
13  ##
14  # The constant's name
15
16  attr_accessor :name
17
18  ##
19  # The constant's value
20
21  attr_accessor :value
22
23  ##
24  # The constant's visibility
25
26  attr_accessor :visibility
27
28  ##
29  # Creates a new constant with +name+, +value+ and +comment+
30
31  def initialize(name, value, comment)
32    super()
33
34    @name  = name
35    @value = value
36
37    @is_alias_for = nil
38    @visibility   = nil
39
40    self.comment = comment
41  end
42
43  ##
44  # Constants are ordered by name
45
46  def <=> other
47    return unless self.class === other
48
49    [parent_name, name] <=> [other.parent_name, other.name]
50  end
51
52  ##
53  # Constants are equal when their #parent and #name is the same
54
55  def == other
56    self.class == other.class and
57      @parent == other.parent and
58      @name == other.name
59  end
60
61  ##
62  # A constant is documented if it has a comment, or is an alias
63  # for a documented class or module.
64
65  def documented?
66    super or is_alias_for && is_alias_for.documented?
67  end
68
69  ##
70  # Full constant name including namespace
71
72  def full_name
73    @full_name ||= "#{parent_name}::#{@name}"
74  end
75
76  ##
77  # The module or class this constant is an alias for
78
79  def is_alias_for
80    case @is_alias_for
81    when String then
82      found = @store.find_class_or_module @is_alias_for
83      @is_alias_for = found if found
84      @is_alias_for
85    else
86      @is_alias_for
87    end
88  end
89
90  def inspect # :nodoc:
91    "#<%s:0x%x %s::%s>" % [
92      self.class, object_id,
93      parent_name, @name,
94    ]
95  end
96
97  ##
98  # Dumps this Constant for use by ri.  See also #marshal_load
99
100  def marshal_dump
101    alias_name = case found = is_alias_for
102                 when RDoc::CodeObject then found.full_name
103                 else                       found
104                 end
105
106    [ MARSHAL_VERSION,
107      @name,
108      full_name,
109      @visibility,
110      alias_name,
111      parse(@comment),
112      @file.relative_name,
113      parent.name,
114      parent.class,
115      section.title,
116    ]
117  end
118
119  ##
120  # Loads this Constant from +array+.  For a loaded Constant the following
121  # methods will return cached values:
122  #
123  # * #full_name
124  # * #parent_name
125
126  def marshal_load array
127    initialize array[1], nil, array[5]
128
129    @full_name     = array[2]
130    @visibility    = array[3]
131    @is_alias_for  = array[4]
132    #                      5 handled above
133    #                      6 handled below
134    @parent_name   = array[7]
135    @parent_class  = array[8]
136    @section_title = array[9]
137
138    @file = RDoc::TopLevel.new array[6]
139  end
140
141  ##
142  # Path to this constant for use with HTML generator output.
143
144  def path
145    "#{@parent.path}##{@name}"
146  end
147
148  def pretty_print q # :nodoc:
149    q.group 2, "[#{self.class.name} #{full_name}", "]" do
150      unless comment.empty? then
151        q.breakable
152        q.text "comment:"
153        q.breakable
154        q.pp @comment
155      end
156    end
157  end
158
159  ##
160  # Sets the store for this class or module and its contained code objects.
161
162  def store= store
163    super
164
165    @file = @store.add_file @file.full_name if @file
166  end
167
168  def to_s # :nodoc:
169    parent_name = parent ? parent.full_name : '(unknown)'
170    if is_alias_for
171      "constant #{parent_name}::#@name -> #{is_alias_for}"
172    else
173      "constant #{parent_name}::#@name"
174    end
175  end
176
177end
178
179