1 # frozen_string_literal: true
3 # A TopLevel context is a representation of the contents of a single file
5 class RDoc::TopLevel < RDoc::Context
7 MARSHAL_VERSION = 0 # :nodoc:
10 # This TopLevel's File::Stat struct
12 attr_accessor :file_stat
15 # Relative name of this file
17 attr_accessor :relative_name
20 # Absolute name of this file
22 attr_accessor :absolute_name
25 # All the classes or modules that were declared in
26 # this file. These are assigned to either +#classes_hash+
27 # or +#modules_hash+ once we know what they really are.
29 attr_reader :classes_or_modules
31 attr_accessor :diagram # :nodoc:
34 # The parser class that processed this file
39 # Creates a new TopLevel for the file at +absolute_name+. If documentation
40 # is being generated outside the source dir +relative_name+ is relative to
41 # the source directory.
43 def initialize absolute_name, relative_name = absolute_name
46 @absolute_name = absolute_name
47 @relative_name = relative_name
48 @file_stat = File.stat(absolute_name) rescue nil # HACK for testing
52 @classes_or_modules = []
56 # Sets the parser for this toplevel context, also the store.
60 @store.update_parser_of_file(absolute_name, val) if @store
65 # An RDoc::TopLevel is equal to another with the same relative_name
68 self.class === other and @relative_name == other.relative_name
74 # Adds +an_alias+ to +Object+ instead of +self+.
76 def add_alias(an_alias)
77 object_class.record_location self
78 return an_alias unless @document_self
79 object_class.add_alias an_alias
83 # Adds +constant+ to +Object+ instead of +self+.
85 def add_constant constant
86 object_class.record_location self
87 return constant unless @document_self
88 object_class.add_constant constant
92 # Adds +include+ to +Object+ instead of +self+.
94 def add_include(include)
95 object_class.record_location self
96 return include unless @document_self
97 object_class.add_include include
101 # Adds +method+ to +Object+ instead of +self+.
103 def add_method(method)
104 object_class.record_location self
105 return method unless @document_self
106 object_class.add_method method
110 # Adds class or module +mod+. Used in the building phase
111 # by the Ruby parser.
113 def add_to_classes_or_modules mod
114 @classes_or_modules << mod
118 # Base name of this file
121 File.basename @relative_name
127 # Only a TopLevel that contains text file) will be displayed. See also
128 # RDoc::CodeObject#display?
135 # See RDoc::TopLevel::find_class_or_module
137 # TODO Why do we search through all classes/modules found, not just the
138 # ones of this instance?
140 def find_class_or_module name
141 @store.find_class_or_module name
145 # Finds a class or module named +symbol+
147 def find_local_symbol(symbol)
148 find_class_or_module(symbol) || super
152 # Finds a module or class with +name+
154 def find_module_named(name)
155 find_class_or_module(name)
159 # Returns the relative name of this file
166 # An RDoc::TopLevel has the same hash as another with the same
174 # URL for this with a +prefix+
177 path = [prefix, @relative_name.tr('.', '_')]
179 File.join(*path.compact) + '.html'
182 def inspect # :nodoc:
183 "#<%s:0x%x %p modules: %p classes: %p>" % [
184 self.class, object_id,
186 @modules.map { |n,m| m },
187 @classes.map { |n,c| c }
192 # Time this file was last modified, if known
195 @file_stat ? file_stat.mtime : nil
199 # Dumps this TopLevel for use by ri. See also #marshal_load
211 # Loads this TopLevel from +array+.
213 def marshal_load array # :nodoc:
223 # Returns the NormalClass "Object", creating it if not found.
225 # Records +self+ as a location in "Object".
228 @object_class ||= begin
229 oc = @store.find_class_named('Object') || add_class(RDoc::NormalClass, 'Object')
230 oc.record_location self
236 # Base name of this file without the extension
239 basename = File.basename @relative_name
240 basename =~ /\.(rb|rdoc|txt|md)$/i
246 # Path to this file for use with HTML generator output.
249 http_url @store.rdoc.generator.file_dir
252 def pretty_print q # :nodoc:
253 q.group 2, "[#{self.class}: ", "]" do
254 q.text "base name: #{base_name.inspect}"
257 items = @modules.map { |n,m| m }
258 items.concat @modules.map { |n,c| c }
259 q.seplist items do |mod| q.pp mod end
264 # Search record used by RDoc::Generator::JsonIndex
267 return unless @parser < RDoc::Parser::Text
281 # Is this TopLevel from a text file instead of a source code file?
284 @parser and @parser.include? RDoc::Parser::Text