mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 04:28:20 +00:00
GH-427: improve default ID values shown by Zeekygen
The default value of an ID is now truly the one used to initialize it, unaltered by any subsequent redefs. Redefs are now shown separately, along with the expression that modifies the ID's value.
This commit is contained in:
parent
c139ad07f4
commit
9e9440e88d
7 changed files with 153 additions and 43 deletions
51
src/ID.cc
51
src/ID.cc
|
@ -471,12 +471,18 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
|
||||||
ModuleName() != "Version" )
|
ModuleName() != "Version" )
|
||||||
{
|
{
|
||||||
d->Add(":Default:");
|
d->Add(":Default:");
|
||||||
|
auto ii = zeekygen_mgr->GetIdentifierInfo(Name());
|
||||||
|
auto redefs = ii->GetRedefs();
|
||||||
|
auto iv = val;
|
||||||
|
|
||||||
|
if ( ! redefs.empty() && ii->InitialVal() )
|
||||||
|
iv = ii->InitialVal();
|
||||||
|
|
||||||
if ( type->InternalType() == TYPE_INTERNAL_OTHER )
|
if ( type->InternalType() == TYPE_INTERNAL_OTHER )
|
||||||
{
|
{
|
||||||
switch ( type->Tag() ) {
|
switch ( type->Tag() ) {
|
||||||
case TYPE_TABLE:
|
case TYPE_TABLE:
|
||||||
if ( val->AsTable()->Length() == 0 )
|
if ( iv->AsTable()->Length() == 0 )
|
||||||
{
|
{
|
||||||
d->Add(" ``{}``");
|
d->Add(" ``{}``");
|
||||||
d->NL();
|
d->NL();
|
||||||
|
@ -486,11 +492,12 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
|
||||||
|
|
||||||
default:
|
default:
|
||||||
d->NL();
|
d->NL();
|
||||||
d->NL();
|
d->PushIndent();
|
||||||
d->Add("::");
|
d->Add("::");
|
||||||
d->NL();
|
d->NL();
|
||||||
d->PushIndent();
|
d->PushIndent();
|
||||||
val->DescribeReST(d);
|
iv->DescribeReST(d);
|
||||||
|
d->PopIndent();
|
||||||
d->PopIndent();
|
d->PopIndent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -498,9 +505,45 @@ void ID::DescribeReST(ODesc* d, bool roles_only) const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d->SP();
|
d->SP();
|
||||||
val->DescribeReST(d);
|
iv->DescribeReST(d);
|
||||||
d->NL();
|
d->NL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( auto& ir : redefs )
|
||||||
|
{
|
||||||
|
if ( ! ir->init_expr )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( ir->ic == INIT_NONE )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string redef_str;
|
||||||
|
ODesc expr_desc;
|
||||||
|
ir->init_expr->Describe(&expr_desc);
|
||||||
|
redef_str = expr_desc.Description();
|
||||||
|
redef_str = strreplace(redef_str, "\n", " ");
|
||||||
|
|
||||||
|
d->Add(":Redefinition: ");
|
||||||
|
d->Add(fmt("from :doc:`/scripts/%s`", ir->from_script.data()));
|
||||||
|
d->NL();
|
||||||
|
d->PushIndent();
|
||||||
|
|
||||||
|
if ( ir->ic == INIT_FULL )
|
||||||
|
d->Add("``=``");
|
||||||
|
else if ( ir->ic == INIT_EXTRA )
|
||||||
|
d->Add("``+=``");
|
||||||
|
else if ( ir->ic == INIT_REMOVE )
|
||||||
|
d->Add("``-=``");
|
||||||
|
else
|
||||||
|
assert(false);
|
||||||
|
|
||||||
|
d->Add("::");
|
||||||
|
d->NL();
|
||||||
|
d->PushIndent();
|
||||||
|
d->Add(redef_str.data());
|
||||||
|
d->PopIndent();
|
||||||
|
d->PopIndent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1096,7 +1096,7 @@ decl:
|
||||||
| TOK_REDEF global_id opt_type init_class opt_init opt_attr ';'
|
| TOK_REDEF global_id opt_type init_class opt_init opt_attr ';'
|
||||||
{
|
{
|
||||||
add_global($2, $3, $4, $5, $6, VAR_REDEF);
|
add_global($2, $3, $4, $5, $6, VAR_REDEF);
|
||||||
zeekygen_mgr->Redef($2, ::filename);
|
zeekygen_mgr->Redef($2, ::filename, $4, $5);
|
||||||
}
|
}
|
||||||
|
|
||||||
| TOK_REDEF TOK_ENUM global_id TOK_ADD_TO '{'
|
| TOK_REDEF TOK_ENUM global_id TOK_ADD_TO '{'
|
||||||
|
|
|
@ -5,28 +5,26 @@
|
||||||
|
|
||||||
#include "Desc.h"
|
#include "Desc.h"
|
||||||
#include "Val.h"
|
#include "Val.h"
|
||||||
|
#include "Expr.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace zeekygen;
|
using namespace zeekygen;
|
||||||
|
|
||||||
IdentifierInfo::IdentifierInfo(ID* arg_id, ScriptInfo* script)
|
IdentifierInfo::IdentifierInfo(ID* arg_id, ScriptInfo* script)
|
||||||
: Info(),
|
: Info(),
|
||||||
comments(), id(arg_id), initial_val_desc(), redefs(), fields(),
|
comments(), id(arg_id), initial_val(), redefs(), fields(),
|
||||||
last_field_seen(), declaring_script(script)
|
last_field_seen(), declaring_script(script)
|
||||||
{
|
{
|
||||||
Ref(id);
|
Ref(id);
|
||||||
|
|
||||||
if ( id->ID_Val() )
|
if ( id->ID_Val() && (id->IsOption() || id->IsRedefinable()) )
|
||||||
{
|
initial_val = id->ID_Val()->Clone();
|
||||||
ODesc d;
|
|
||||||
id->ID_Val()->Describe(&d);
|
|
||||||
initial_val_desc = d.Description();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentifierInfo::~IdentifierInfo()
|
IdentifierInfo::~IdentifierInfo()
|
||||||
{
|
{
|
||||||
Unref(id);
|
Unref(id);
|
||||||
|
Unref(initial_val);
|
||||||
|
|
||||||
for ( redef_list::const_iterator it = redefs.begin(); it != redefs.end();
|
for ( redef_list::const_iterator it = redefs.begin(); it != redefs.end();
|
||||||
++it )
|
++it )
|
||||||
|
@ -37,20 +35,10 @@ IdentifierInfo::~IdentifierInfo()
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdentifierInfo::AddRedef(const string& script,
|
void IdentifierInfo::AddRedef(const string& script, init_class ic,
|
||||||
const vector<string>& comments)
|
Expr* init_expr, const vector<string>& comments)
|
||||||
{
|
{
|
||||||
Redefinition* redef = new Redefinition();
|
Redefinition* redef = new Redefinition(script, ic, init_expr, comments);
|
||||||
redef->from_script = script;
|
|
||||||
|
|
||||||
if ( id->ID_Val() )
|
|
||||||
{
|
|
||||||
ODesc d;
|
|
||||||
id->ID_Val()->Describe(&d);
|
|
||||||
redef->new_val_desc = d.Description();
|
|
||||||
}
|
|
||||||
|
|
||||||
redef->comments = comments;
|
|
||||||
redefs.push_back(redef);
|
redefs.push_back(redef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,3 +134,48 @@ time_t IdentifierInfo::DoGetModificationTime() const
|
||||||
// contributed to the ID declaration/redefinitions, but this is easier...
|
// contributed to the ID declaration/redefinitions, but this is easier...
|
||||||
return declaring_script->GetModificationTime();
|
return declaring_script->GetModificationTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdentifierInfo::Redefinition::Redefinition(
|
||||||
|
std::string arg_script,
|
||||||
|
init_class arg_ic,
|
||||||
|
Expr* arg_expr,
|
||||||
|
std::vector<std::string> arg_comments)
|
||||||
|
: from_script(std::move(arg_script)),
|
||||||
|
ic(arg_ic),
|
||||||
|
init_expr(arg_expr ? arg_expr->Ref() : nullptr),
|
||||||
|
comments(std::move(arg_comments))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentifierInfo::Redefinition::Redefinition(const IdentifierInfo::Redefinition& other)
|
||||||
|
{
|
||||||
|
from_script = other.from_script;
|
||||||
|
ic = other.ic;
|
||||||
|
init_expr = other.init_expr;
|
||||||
|
comments = other.comments;
|
||||||
|
|
||||||
|
if ( init_expr )
|
||||||
|
init_expr->Ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentifierInfo::Redefinition&
|
||||||
|
IdentifierInfo::Redefinition::operator=(const IdentifierInfo::Redefinition& other)
|
||||||
|
{
|
||||||
|
if ( &other == this )
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
from_script = other.from_script;
|
||||||
|
ic = other.ic;
|
||||||
|
init_expr = other.init_expr;
|
||||||
|
comments = other.comments;
|
||||||
|
|
||||||
|
if ( init_expr )
|
||||||
|
init_expr->Ref();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentifierInfo::Redefinition::~Redefinition()
|
||||||
|
{
|
||||||
|
Unref(init_expr);
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,12 @@ public:
|
||||||
*/
|
*/
|
||||||
~IdentifierInfo() override;
|
~IdentifierInfo() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the initial value of the identifier.
|
||||||
|
*/
|
||||||
|
Val* InitialVal() const
|
||||||
|
{ return initial_val; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a comment associated with the identifier. If the identifier is a
|
* Add a comment associated with the identifier. If the identifier is a
|
||||||
* record type and it's in the middle of parsing fields, the comment is
|
* record type and it's in the middle of parsing fields, the comment is
|
||||||
|
@ -59,9 +65,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* Register a redefinition of the identifier.
|
* Register a redefinition of the identifier.
|
||||||
* @param from_script The script in which the redef occurred.
|
* @param from_script The script in which the redef occurred.
|
||||||
|
* @param ic The initialization class used (e.g. =, +=, -=)
|
||||||
|
* @param init_expr The initialzation expression used.
|
||||||
* @param comments Comments associated with the redef statement.
|
* @param comments Comments associated with the redef statement.
|
||||||
*/
|
*/
|
||||||
void AddRedef(const std::string& from_script,
|
void AddRedef(const std::string& from_script, init_class ic,
|
||||||
|
Expr* init_expr,
|
||||||
const std::vector<std::string>& comments);
|
const std::vector<std::string>& comments);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,8 +126,19 @@ public:
|
||||||
*/
|
*/
|
||||||
struct Redefinition {
|
struct Redefinition {
|
||||||
std::string from_script; /**< Name of script doing the redef. */
|
std::string from_script; /**< Name of script doing the redef. */
|
||||||
std::string new_val_desc; /**< Description of new value bound to ID. */
|
init_class ic;
|
||||||
|
Expr* init_expr;
|
||||||
std::vector<std::string> comments; /**< Zeekygen comments on redef. */
|
std::vector<std::string> comments; /**< Zeekygen comments on redef. */
|
||||||
|
|
||||||
|
Redefinition(std::string arg_script, init_class arg_ic,
|
||||||
|
Expr* arg_expr,
|
||||||
|
std::vector<std::string> arg_comments);
|
||||||
|
|
||||||
|
Redefinition(const Redefinition& other);
|
||||||
|
|
||||||
|
Redefinition& operator=(const Redefinition& other);
|
||||||
|
|
||||||
|
~Redefinition();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,6 +149,13 @@ public:
|
||||||
*/
|
*/
|
||||||
std::list<Redefinition> GetRedefs(const std::string& from_script) const;
|
std::list<Redefinition> GetRedefs(const std::string& from_script) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of information about redefinitions of the identifier.
|
||||||
|
* @return A list of redefs that occurred for the identifier.
|
||||||
|
*/
|
||||||
|
const std::list<Redefinition*>& GetRedefs() const
|
||||||
|
{ return redefs; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
time_t DoGetModificationTime() const override;
|
time_t DoGetModificationTime() const override;
|
||||||
|
@ -152,7 +179,7 @@ private:
|
||||||
|
|
||||||
std::vector<std::string> comments;
|
std::vector<std::string> comments;
|
||||||
ID* id;
|
ID* id;
|
||||||
std::string initial_val_desc;
|
Val* initial_val;
|
||||||
redef_list redefs;
|
redef_list redefs;
|
||||||
record_field_map fields;
|
record_field_map fields;
|
||||||
RecordField* last_field_seen;
|
RecordField* last_field_seen;
|
||||||
|
|
|
@ -352,7 +352,8 @@ void Manager::RecordField(const ID* id, const TypeDecl* field,
|
||||||
field->id, id->Name(), script.c_str());
|
field->id, id->Name(), script.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::Redef(const ID* id, const string& path)
|
void Manager::Redef(const ID* id, const string& path,
|
||||||
|
init_class ic, Expr* init_expr)
|
||||||
{
|
{
|
||||||
if ( disabled )
|
if ( disabled )
|
||||||
return;
|
return;
|
||||||
|
@ -380,7 +381,7 @@ void Manager::Redef(const ID* id, const string& path)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
id_info->AddRedef(from_script, comment_buffer);
|
id_info->AddRedef(from_script, ic, init_expr, comment_buffer);
|
||||||
script_info->AddRedef(id_info);
|
script_info->AddRedef(id_info);
|
||||||
comment_buffer.clear();
|
comment_buffer.clear();
|
||||||
last_identifier_seen = id_info;
|
last_identifier_seen = id_info;
|
||||||
|
|
|
@ -136,8 +136,11 @@ public:
|
||||||
* Register a redefinition of a particular identifier.
|
* Register a redefinition of a particular identifier.
|
||||||
* @param id The identifier being redef'd.
|
* @param id The identifier being redef'd.
|
||||||
* @param path Absolute path to a Bro script doing the redef.
|
* @param path Absolute path to a Bro script doing the redef.
|
||||||
|
* @param ic The initialization class that was used (e.g. =, +=, -=).
|
||||||
|
* @param init_expr The intiialization expression that was used.
|
||||||
*/
|
*/
|
||||||
void Redef(const ID* id, const std::string& path);
|
void Redef(const ID* id, const std::string& path,
|
||||||
|
init_class ic = INIT_NONE, Expr* init_expr = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register Zeekygen script summary content.
|
* Register Zeekygen script summary content.
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
|
||||||
Yield type is documented/cross-referenced for primitize types.
|
Yield type is documented/cross-referenced for primitize types.
|
||||||
|
|
||||||
.. zeek:id:: test_vector1
|
.. zeek:id:: test_vector1
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
|
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
|
||||||
Yield type is documented/cross-referenced for composite types.
|
Yield type is documented/cross-referenced for composite types.
|
||||||
|
|
||||||
.. zeek:id:: test_vector2
|
.. zeek:id:: test_vector2
|
||||||
|
@ -29,5 +31,6 @@
|
||||||
|
|
||||||
[]
|
[]
|
||||||
|
|
||||||
|
|
||||||
Just showing an even fancier yield type.
|
Just showing an even fancier yield type.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue