1 ###############################################################################
3 # Package: NaturalDocs::SymbolTable::Symbol
5 ###############################################################################
7 # A class representing a symbol or a potential symbol.
9 ###############################################################################
11 # This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
12 # Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
13 # Refer to License.txt for the complete details
18 package NaturalDocs::SymbolTable::Symbol;
21 ###############################################################################
22 # Group: Implementation
27 # The class is implemented as a blessed arrayref. The following constants are its members.
29 # DEFINITIONS - A hashref of all the files which define this symbol. The keys are the <FileNames>, and the values are
30 # <NaturalDocs::SymbolTable::SymbolDefinition> objects. If no files define this symbol, this item will
32 # GLOBAL_DEFINITION - The <FileName> which defines the global version of the symbol, which is what is used if
33 # a file references the symbol but does not have its own definition. If there are no definitions, this
35 # REFERENCES - A hashref of the references that can be interpreted as this symbol. This doesn't mean these
36 # references necessarily are. The keys are the reference strings, and the values are the scores of
37 # the interpretations. If no references can be interpreted as this symbol, this item will be undef.
39 use constant DEFINITIONS => 0;
40 use constant GLOBAL_DEFINITION => 1;
41 use constant REFERENCES => 2;
44 ###############################################################################
45 # Group: Modification Functions
50 # Creates and returns a new object.
56 # Let's make it safe, since normally you can pass values to New. Having them just be ignored would be an obscure error.
58 { die "You can't pass values to NaturalDocs::SymbolTable::Symbol->New()\n"; };
60 my $object = [ undef, undef, undef ];
61 bless $object, $package;
67 # Function: AddDefinition
69 # Adds a symbol definition. If this is the first definition for this symbol, it will become the global definition. If the definition
70 # already exists for the file, it will be ignored.
74 # file - The <FileName> that defines the symbol.
75 # type - The <TopicType> of the definition.
76 # prototype - The prototype of the definition, if applicable. Undef otherwise.
77 # summary - The summary for the definition, if applicable. Undef otherwise.
81 # Whether this provided the first definition for this symbol.
83 sub AddDefinition #(file, type, prototype, summary)
85 my ($self, $file, $type, $prototype, $summary) = @_;
89 if (!defined $self->[DEFINITIONS])
91 $self->[DEFINITIONS] = { };
92 $self->[GLOBAL_DEFINITION] = $file;
96 if (!exists $self->[DEFINITIONS]{$file})
98 $self->[DEFINITIONS]{$file} = NaturalDocs::SymbolTable::SymbolDefinition->New($type, $prototype, $summary);
106 # Function: ChangeDefinition
108 # Changes the information about an existing definition.
112 # file - The <FileName> that defines the symbol. Must exist.
113 # type - The new <TopicType> of the definition.
114 # prototype - The new prototype of the definition, if applicable. Undef otherwise.
115 # summary - The new summary of the definition, if applicable. Undef otherwise.
117 sub ChangeDefinition #(file, type, prototype, summary)
119 my ($self, $file, $type, $prototype, $summary) = @_;
121 if (defined $self->[DEFINITIONS] &&
122 exists $self->[DEFINITIONS]{$file})
124 $self->[DEFINITIONS]{$file}->SetType($type);
125 $self->[DEFINITIONS]{$file}->SetPrototype($prototype);
126 $self->[DEFINITIONS]{$file}->SetSummary($summary);
132 # Function: DeleteDefinition
134 # Removes a symbol definition. If the definition served as the global definition, a new one will be selected.
138 # file - The <FileName> which contains definition to delete.
142 # Whether that was the only definition, and the symbol is now undefined.
144 sub DeleteDefinition #(file)
146 my ($self, $file) = @_;
148 # If there are no definitions...
149 if (!defined $self->[DEFINITIONS])
152 delete $self->[DEFINITIONS]{$file};
154 # If there are no more definitions...
155 if (!scalar keys %{$self->[DEFINITIONS]})
157 $self->[DEFINITIONS] = undef;
159 # If definitions was previously defined, and now is empty, we can safely assume that the global definition was just deleted
160 # without checking it against $file.
162 $self->[GLOBAL_DEFINITION] = undef;
167 # If there are more definitions and the global one was just deleted...
168 elsif ($self->[GLOBAL_DEFINITION] eq $file)
170 # Which one becomes global is pretty much random.
171 $self->[GLOBAL_DEFINITION] = (keys %{$self->[DEFINITIONS]})[0];
178 # Function: AddReference
180 # Adds a reference that can be interpreted as this symbol. It can be, but not necessarily is.
184 # referenceString - The string of the reference.
185 # score - The score of this interpretation.
187 sub AddReference #(referenceString, score)
189 my ($self, $referenceString, $score) = @_;
191 if (!defined $self->[REFERENCES])
192 { $self->[REFERENCES] = { }; };
194 $self->[REFERENCES]{$referenceString} = $score;
199 # Function: DeleteReference
201 # Deletes a reference that can be interpreted as this symbol.
205 # referenceString - The string of the reference to delete.
207 sub DeleteReference #(referenceString)
209 my ($self, $referenceString) = @_;
211 # If there are no definitions...
212 if (!defined $self->[REFERENCES])
215 delete $self->[REFERENCES]{$referenceString};
217 # If there are no more definitions...
218 if (!scalar keys %{$self->[REFERENCES]})
220 $self->[REFERENCES] = undef;
226 # Function: DeleteAllReferences
228 # Removes all references that can be interpreted as this symbol.
230 sub DeleteAllReferences
232 $_[0]->[REFERENCES] = undef;
236 ###############################################################################
237 # Group: Information Functions
240 # Function: IsDefined
242 # Returns whether the symbol is defined anywhere or not. If it's not, that means it's just a potential interpretation of a
247 return defined $_[0]->[GLOBAL_DEFINITION];
251 # Function: IsDefinedIn
253 # Returns whether the symbol is defined in the passed <FileName>.
255 sub IsDefinedIn #(file)
257 my ($self, $file) = @_;
258 return ($self->IsDefined() && exists $self->[DEFINITIONS]{$file});
263 # Function: Definitions
265 # Returns an array of all the <FileNames> that define this symbol. If none do, will return an empty array.
271 if ($self->IsDefined())
272 { return keys %{$self->[DEFINITIONS]}; }
279 # Function: GlobalDefinition
281 # Returns the <FileName> that contains the global definition of this symbol, or undef if the symbol isn't defined.
285 return $_[0]->[GLOBAL_DEFINITION];
290 # Function: TypeDefinedIn
292 # Returns the <TopicType> of the symbol defined in the passed <FileName>, or undef if it's not defined in that file.
294 sub TypeDefinedIn #(file)
296 my ($self, $file) = @_;
298 if ($self->IsDefined())
299 { return $self->[DEFINITIONS]{$file}->Type(); }
306 # Function: GlobalType
308 # Returns the <TopicType> of the global definition, or undef if the symbol isn't defined.
314 my $globalDefinition = $self->GlobalDefinition();
316 if (!defined $globalDefinition)
319 { return $self->[DEFINITIONS]{$globalDefinition}->Type(); };
324 # Function: PrototypeDefinedIn
326 # Returns the prototype of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
328 sub PrototypeDefinedIn #(file)
330 my ($self, $file) = @_;
332 if ($self->IsDefined())
333 { return $self->[DEFINITIONS]{$file}->Prototype(); }
340 # Function: GlobalPrototype
342 # Returns the prototype of the global definition. Will be undef if it doesn't exist or the symbol isn't defined.
348 my $globalDefinition = $self->GlobalDefinition();
350 if (!defined $globalDefinition)
353 { return $self->[DEFINITIONS]{$globalDefinition}->Prototype(); };
358 # Function: SummaryDefinedIn
360 # Returns the summary of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
362 sub SummaryDefinedIn #(file)
364 my ($self, $file) = @_;
366 if ($self->IsDefined())
367 { return $self->[DEFINITIONS]{$file}->Summary(); }
374 # Function: GlobalSummary
376 # Returns the summary of the global definition. Will be undef if it doesn't exist or the symbol isn't defined.
382 my $globalDefinition = $self->GlobalDefinition();
384 if (!defined $globalDefinition)
387 { return $self->[DEFINITIONS]{$globalDefinition}->Summary(); };
392 # Function: HasReferences
394 # Returns whether the symbol can be interpreted as any references.
398 return defined $_[0]->[REFERENCES];
402 # Function: References
404 # Returns an array of all the reference strings that can be interpreted as this symbol. If none, will return an empty array.
408 if (defined $_[0]->[REFERENCES])
409 { return keys %{$_[0]->[REFERENCES]}; }
416 # Function: ReferencesAndScores
418 # Returns a hash of all the references that can be interpreted as this symbol and their scores. The keys are the reference
419 # strings, and the values are the scores. If none, will return an empty hash.
421 sub ReferencesAndScores
423 if (defined $_[0]->[REFERENCES])
424 { return %{$_[0]->[REFERENCES]}; }