mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 18:18:18 +00:00
429 lines
11 KiB
Perl
429 lines
11 KiB
Perl
|
###############################################################################
|
||
|
#
|
||
|
# Package: NaturalDocs::SymbolTable::Symbol
|
||
|
#
|
||
|
###############################################################################
|
||
|
#
|
||
|
# A class representing a symbol or a potential symbol.
|
||
|
#
|
||
|
###############################################################################
|
||
|
|
||
|
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
||
|
# Natural Docs is licensed under the GPL
|
||
|
|
||
|
use strict;
|
||
|
use integer;
|
||
|
|
||
|
package NaturalDocs::SymbolTable::Symbol;
|
||
|
|
||
|
|
||
|
###############################################################################
|
||
|
# Group: Implementation
|
||
|
|
||
|
#
|
||
|
# Constants: Members
|
||
|
#
|
||
|
# The class is implemented as a blessed arrayref. The following constants are its members.
|
||
|
#
|
||
|
# DEFINITIONS - A hashref of all the files which define this symbol. The keys are the <FileNames>, and the values are
|
||
|
# <NaturalDocs::SymbolTable::SymbolDefinition> objects. If no files define this symbol, this item will
|
||
|
# be undef.
|
||
|
# GLOBAL_DEFINITION - The <FileName> which defines the global version of the symbol, which is what is used if
|
||
|
# a file references the symbol but does not have its own definition. If there are no definitions, this
|
||
|
# item will be undef.
|
||
|
# REFERENCES - A hashref of the references that can be interpreted as this symbol. This doesn't mean these
|
||
|
# references necessarily are. The keys are the reference strings, and the values are the scores of
|
||
|
# the interpretations. If no references can be interpreted as this symbol, this item will be undef.
|
||
|
#
|
||
|
use constant DEFINITIONS => 0;
|
||
|
use constant GLOBAL_DEFINITION => 1;
|
||
|
use constant REFERENCES => 2;
|
||
|
|
||
|
|
||
|
###############################################################################
|
||
|
# Group: Modification Functions
|
||
|
|
||
|
#
|
||
|
# Function: New
|
||
|
#
|
||
|
# Creates and returns a new object.
|
||
|
#
|
||
|
sub New
|
||
|
{
|
||
|
my $package = shift;
|
||
|
|
||
|
# Let's make it safe, since normally you can pass values to New. Having them just be ignored would be an obscure error.
|
||
|
if (scalar @_)
|
||
|
{ die "You can't pass values to NaturalDocs::SymbolTable::Symbol->New()\n"; };
|
||
|
|
||
|
my $object = [ undef, undef, undef ];
|
||
|
bless $object, $package;
|
||
|
|
||
|
return $object;
|
||
|
};
|
||
|
|
||
|
#
|
||
|
# Function: AddDefinition
|
||
|
#
|
||
|
# Adds a symbol definition. If this is the first definition for this symbol, it will become the global definition. If the definition
|
||
|
# already exists for the file, it will be ignored.
|
||
|
#
|
||
|
# Parameters:
|
||
|
#
|
||
|
# file - The <FileName> that defines the symbol.
|
||
|
# type - The <TopicType> of the definition.
|
||
|
# prototype - The prototype of the definition, if applicable. Undef otherwise.
|
||
|
# summary - The summary for the definition, if applicable. Undef otherwise.
|
||
|
#
|
||
|
# Returns:
|
||
|
#
|
||
|
# Whether this provided the first definition for this symbol.
|
||
|
#
|
||
|
sub AddDefinition #(file, type, prototype, summary)
|
||
|
{
|
||
|
my ($self, $file, $type, $prototype, $summary) = @_;
|
||
|
|
||
|
my $isFirst;
|
||
|
|
||
|
if (!defined $self->[DEFINITIONS])
|
||
|
{
|
||
|
$self->[DEFINITIONS] = { };
|
||
|
$self->[GLOBAL_DEFINITION] = $file;
|
||
|
$isFirst = 1;
|
||
|
};
|
||
|
|
||
|
if (!exists $self->[DEFINITIONS]{$file})
|
||
|
{
|
||
|
$self->[DEFINITIONS]{$file} = NaturalDocs::SymbolTable::SymbolDefinition->New($type, $prototype, $summary);
|
||
|
};
|
||
|
|
||
|
return $isFirst;
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: ChangeDefinition
|
||
|
#
|
||
|
# Changes the information about an existing definition.
|
||
|
#
|
||
|
# Parameters:
|
||
|
#
|
||
|
# file - The <FileName> that defines the symbol. Must exist.
|
||
|
# type - The new <TopicType> of the definition.
|
||
|
# prototype - The new prototype of the definition, if applicable. Undef otherwise.
|
||
|
# summary - The new summary of the definition, if applicable. Undef otherwise.
|
||
|
#
|
||
|
sub ChangeDefinition #(file, type, prototype, summary)
|
||
|
{
|
||
|
my ($self, $file, $type, $prototype, $summary) = @_;
|
||
|
|
||
|
if (defined $self->[DEFINITIONS] &&
|
||
|
exists $self->[DEFINITIONS]{$file})
|
||
|
{
|
||
|
$self->[DEFINITIONS]{$file}->SetType($type);
|
||
|
$self->[DEFINITIONS]{$file}->SetPrototype($prototype);
|
||
|
$self->[DEFINITIONS]{$file}->SetSummary($summary);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: DeleteDefinition
|
||
|
#
|
||
|
# Removes a symbol definition. If the definition served as the global definition, a new one will be selected.
|
||
|
#
|
||
|
# Parameters:
|
||
|
#
|
||
|
# file - The <FileName> which contains definition to delete.
|
||
|
#
|
||
|
# Returns:
|
||
|
#
|
||
|
# Whether that was the only definition, and the symbol is now undefined.
|
||
|
#
|
||
|
sub DeleteDefinition #(file)
|
||
|
{
|
||
|
my ($self, $file) = @_;
|
||
|
|
||
|
# If there are no definitions...
|
||
|
if (!defined $self->[DEFINITIONS])
|
||
|
{ return undef; };
|
||
|
|
||
|
delete $self->[DEFINITIONS]{$file};
|
||
|
|
||
|
# If there are no more definitions...
|
||
|
if (!scalar keys %{$self->[DEFINITIONS]})
|
||
|
{
|
||
|
$self->[DEFINITIONS] = undef;
|
||
|
|
||
|
# If definitions was previously defined, and now is empty, we can safely assume that the global definition was just deleted
|
||
|
# without checking it against $file.
|
||
|
|
||
|
$self->[GLOBAL_DEFINITION] = undef;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
# If there are more definitions and the global one was just deleted...
|
||
|
elsif ($self->[GLOBAL_DEFINITION] eq $file)
|
||
|
{
|
||
|
# Which one becomes global is pretty much random.
|
||
|
$self->[GLOBAL_DEFINITION] = (keys %{$self->[DEFINITIONS]})[0];
|
||
|
return undef;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: AddReference
|
||
|
#
|
||
|
# Adds a reference that can be interpreted as this symbol. It can be, but not necessarily is.
|
||
|
#
|
||
|
# Parameters:
|
||
|
#
|
||
|
# referenceString - The string of the reference.
|
||
|
# score - The score of this interpretation.
|
||
|
#
|
||
|
sub AddReference #(referenceString, score)
|
||
|
{
|
||
|
my ($self, $referenceString, $score) = @_;
|
||
|
|
||
|
if (!defined $self->[REFERENCES])
|
||
|
{ $self->[REFERENCES] = { }; };
|
||
|
|
||
|
$self->[REFERENCES]{$referenceString} = $score;
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: DeleteReference
|
||
|
#
|
||
|
# Deletes a reference that can be interpreted as this symbol.
|
||
|
#
|
||
|
# Parameters:
|
||
|
#
|
||
|
# referenceString - The string of the reference to delete.
|
||
|
#
|
||
|
sub DeleteReference #(referenceString)
|
||
|
{
|
||
|
my ($self, $referenceString) = @_;
|
||
|
|
||
|
# If there are no definitions...
|
||
|
if (!defined $self->[REFERENCES])
|
||
|
{ return; };
|
||
|
|
||
|
delete $self->[REFERENCES]{$referenceString};
|
||
|
|
||
|
# If there are no more definitions...
|
||
|
if (!scalar keys %{$self->[REFERENCES]})
|
||
|
{
|
||
|
$self->[REFERENCES] = undef;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: DeleteAllReferences
|
||
|
#
|
||
|
# Removes all references that can be interpreted as this symbol.
|
||
|
#
|
||
|
sub DeleteAllReferences
|
||
|
{
|
||
|
$_[0]->[REFERENCES] = undef;
|
||
|
};
|
||
|
|
||
|
|
||
|
###############################################################################
|
||
|
# Group: Information Functions
|
||
|
|
||
|
#
|
||
|
# Function: IsDefined
|
||
|
#
|
||
|
# Returns whether the symbol is defined anywhere or not. If it's not, that means it's just a potential interpretation of a
|
||
|
# reference.
|
||
|
#
|
||
|
sub IsDefined
|
||
|
{
|
||
|
return defined $_[0]->[GLOBAL_DEFINITION];
|
||
|
};
|
||
|
|
||
|
#
|
||
|
# Function: IsDefinedIn
|
||
|
#
|
||
|
# Returns whether the symbol is defined in the passed <FileName>.
|
||
|
#
|
||
|
sub IsDefinedIn #(file)
|
||
|
{
|
||
|
my ($self, $file) = @_;
|
||
|
return ($self->IsDefined() && exists $self->[DEFINITIONS]{$file});
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: Definitions
|
||
|
#
|
||
|
# Returns an array of all the <FileNames> that define this symbol. If none do, will return an empty array.
|
||
|
#
|
||
|
sub Definitions
|
||
|
{
|
||
|
my $self = shift;
|
||
|
|
||
|
if ($self->IsDefined())
|
||
|
{ return keys %{$self->[DEFINITIONS]}; }
|
||
|
else
|
||
|
{ return ( ); };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: GlobalDefinition
|
||
|
#
|
||
|
# Returns the <FileName> that contains the global definition of this symbol, or undef if the symbol isn't defined.
|
||
|
#
|
||
|
sub GlobalDefinition
|
||
|
{
|
||
|
return $_[0]->[GLOBAL_DEFINITION];
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: TypeDefinedIn
|
||
|
#
|
||
|
# Returns the <TopicType> of the symbol defined in the passed <FileName>, or undef if it's not defined in that file.
|
||
|
#
|
||
|
sub TypeDefinedIn #(file)
|
||
|
{
|
||
|
my ($self, $file) = @_;
|
||
|
|
||
|
if ($self->IsDefined())
|
||
|
{ return $self->[DEFINITIONS]{$file}->Type(); }
|
||
|
else
|
||
|
{ return undef; };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: GlobalType
|
||
|
#
|
||
|
# Returns the <TopicType> of the global definition, or undef if the symbol isn't defined.
|
||
|
#
|
||
|
sub GlobalType
|
||
|
{
|
||
|
my $self = shift;
|
||
|
|
||
|
my $globalDefinition = $self->GlobalDefinition();
|
||
|
|
||
|
if (!defined $globalDefinition)
|
||
|
{ return undef; }
|
||
|
else
|
||
|
{ return $self->[DEFINITIONS]{$globalDefinition}->Type(); };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: PrototypeDefinedIn
|
||
|
#
|
||
|
# Returns the prototype of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
|
||
|
#
|
||
|
sub PrototypeDefinedIn #(file)
|
||
|
{
|
||
|
my ($self, $file) = @_;
|
||
|
|
||
|
if ($self->IsDefined())
|
||
|
{ return $self->[DEFINITIONS]{$file}->Prototype(); }
|
||
|
else
|
||
|
{ return undef; };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: GlobalPrototype
|
||
|
#
|
||
|
# Returns the prototype of the global definition. Will be undef if it doesn't exist or the symbol isn't defined.
|
||
|
#
|
||
|
sub GlobalPrototype
|
||
|
{
|
||
|
my $self = shift;
|
||
|
|
||
|
my $globalDefinition = $self->GlobalDefinition();
|
||
|
|
||
|
if (!defined $globalDefinition)
|
||
|
{ return undef; }
|
||
|
else
|
||
|
{ return $self->[DEFINITIONS]{$globalDefinition}->Prototype(); };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: SummaryDefinedIn
|
||
|
#
|
||
|
# Returns the summary of symbol defined in the passed <FileName>, or undef if it doesn't exist or is not defined in that file.
|
||
|
#
|
||
|
sub SummaryDefinedIn #(file)
|
||
|
{
|
||
|
my ($self, $file) = @_;
|
||
|
|
||
|
if ($self->IsDefined())
|
||
|
{ return $self->[DEFINITIONS]{$file}->Summary(); }
|
||
|
else
|
||
|
{ return undef; };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: GlobalSummary
|
||
|
#
|
||
|
# Returns the summary of the global definition. Will be undef if it doesn't exist or the symbol isn't defined.
|
||
|
#
|
||
|
sub GlobalSummary
|
||
|
{
|
||
|
my $self = shift;
|
||
|
|
||
|
my $globalDefinition = $self->GlobalDefinition();
|
||
|
|
||
|
if (!defined $globalDefinition)
|
||
|
{ return undef; }
|
||
|
else
|
||
|
{ return $self->[DEFINITIONS]{$globalDefinition}->Summary(); };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: HasReferences
|
||
|
#
|
||
|
# Returns whether the symbol can be interpreted as any references.
|
||
|
#
|
||
|
sub HasReferences
|
||
|
{
|
||
|
return defined $_[0]->[REFERENCES];
|
||
|
};
|
||
|
|
||
|
#
|
||
|
# Function: References
|
||
|
#
|
||
|
# Returns an array of all the reference strings that can be interpreted as this symbol. If none, will return an empty array.
|
||
|
#
|
||
|
sub References
|
||
|
{
|
||
|
if (defined $_[0]->[REFERENCES])
|
||
|
{ return keys %{$_[0]->[REFERENCES]}; }
|
||
|
else
|
||
|
{ return ( ); };
|
||
|
};
|
||
|
|
||
|
|
||
|
#
|
||
|
# Function: ReferencesAndScores
|
||
|
#
|
||
|
# Returns a hash of all the references that can be interpreted as this symbol and their scores. The keys are the reference
|
||
|
# strings, and the values are the scores. If none, will return an empty hash.
|
||
|
#
|
||
|
sub ReferencesAndScores
|
||
|
{
|
||
|
if (defined $_[0]->[REFERENCES])
|
||
|
{ return %{$_[0]->[REFERENCES]}; }
|
||
|
else
|
||
|
{ return ( ); };
|
||
|
};
|
||
|
|
||
|
1;
|