Skip to content

Commit

Permalink
add implicit def ctor for .help()
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Nov 19, 2023
1 parent 5220685 commit a8fd096
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 101 deletions.
186 changes: 143 additions & 43 deletions src/core/chuck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9491,6 +9491,83 @@ const char * Chuck_Type::c_name()



//-----------------------------------------------------------------------------
// name: type_engine_has_implicit_def_ctor() | 1.5.1.9
// desc: determine whether type has implicit default constructor; helpful for ckdoc
//-----------------------------------------------------------------------------
t_CKBOOL type_engine_has_implicit_def_ctor( Chuck_Type * type )
{
t_CKBOOL implicitDefaultCtor = FALSE;

// no for arrays
if( isa( type, type->env()->ckt_array ) )
return FALSE;

// type pointer
Chuck_Type * t = type;
// check up the chain (don't include top-level Object in this check)
do { // at least once if type is Object itself
// check pre_ctor
if( t->has_pre_ctor )
{
implicitDefaultCtor = TRUE;
break;
}

// check
if( type->info )
{
// check for mfuns and mvars (if we get here, type->info cannot be NULL)
vector<Chuck_Func *> fs;
type->info->get_funcs( fs );
vector<Chuck_Value *> vs;
type->info->get_values( vs );

// iterate over functions
for( vector<Chuck_Func *>::iterator f = fs.begin(); f != fs.end(); f++ )
{
// the function
Chuck_Func * func = *f;
if( func == NULL ) continue;
// static or instance?
if( !func->is_static )
{
implicitDefaultCtor = TRUE;
break;
}
}
// iterate over values
for( vector<Chuck_Value *>::iterator v = vs.begin(); v != vs.end(); v++ )
{
// the function
Chuck_Value * value = *v;
if( value == NULL ) continue;
// special internal values
if( value->name.size() && value->name[0] == '@' )
continue;
// value is a function
if( isa( value->type, type->env()->ckt_function ) )
continue;

// static or instance?
if( !value->is_static )
{
implicitDefaultCtor = TRUE;
break;
}
}
}

// up to parent type
t = t->parent;
} while( t && t != t->env()->ckt_object );

return implicitDefaultCtor;
}




//-----------------------------------------------------------------------------
// name: apropos()
// desc: generate info; output to console | added 1.4.1.0 (ge)
Expand Down Expand Up @@ -9736,35 +9813,45 @@ void apropos_func( std::ostringstream & sout, Chuck_Func * theFunc,
// print line prefix, if any
sout << PREFIX;
// print static
sout << (theFunc->def()->static_decl == ae_key_static ? "static " : "");
// output return type
sout << theFunc->def()->ret_type->name();
// space
sout << " ";
sout << (theFunc->is_static ? "static " : "");
// check if need to print return type
if( !theFunc->is_ctor && !theFunc->is_dtor && theFunc->def() )
{
// print return type
sout << theFunc->def()->ret_type->name();
// space
sout << " ";
}
// output function name
sout << S_name(theFunc->def()->name);
sout << theFunc->base_name;
// open paren
sout << "(";
// extra space, if we have args
if( theFunc->def()->arg_list != NULL ) sout << " ";

// argument list
a_Arg_List args = theFunc->def()->arg_list;
while( args != NULL )
// if we have args
if( theFunc->def() && theFunc->def()->arg_list )
{
// output arg
apropos_func_arg( sout, args );
// move to next
args = args->next;
}
// extra space
sout << " ";

// extra space, if we are args
if( theFunc->def()->arg_list != NULL ) sout << " ";
// argument list
a_Arg_List args = theFunc->def()->arg_list;
while( args != NULL )
{
// output arg
apropos_func_arg( sout, args );
// move to next
args = args->next;
}
// extra space, if we are args
if( theFunc->def()->arg_list ) sout << " ";
}

// close paren
sout << ");" << endl;
// output doc
if( theFunc->doc != "" ) sout << PREFIX << " " << capitalize_and_periodize(theFunc->doc) << endl;
if( theFunc->doc != "" )
sout << PREFIX << " " << capitalize_and_periodize(theFunc->doc) << endl;
else if( !theFunc->def() || !theFunc->def()->arg_list ) // default ctor?
sout << PREFIX << " " << capitalize_and_periodize( "Default constructor for " + theFunc->base_name ) << endl;
}


Expand Down Expand Up @@ -9832,31 +9919,44 @@ void Chuck_Type::apropos_funcs( std::string & output,
}
}

// have constructors?
if( ctors.size() > 0 )
{
// type name
string theName = this->name() + " " + "constructors";
// number of '-'
t_CKUINT n = theName.length(); t_CKUINT i;
// output
for( i = 0; i < n; i++ ) { sout << "-"; }
sout << endl << theName << endl;
for( i = 0; i < n; i++ ) { sout << "-"; }
sout << endl;
}
// sort
sort( ctors.begin(), ctors.end(), ck_comp_func_args );
// output constructors | 1.5.1.9
if( ctors.size() )
// if not inherited
if( !inherited )
{
// iterate over member functions
for( vector<Chuck_Func *>::iterator f = ctors.begin(); f != ctors.end(); f++ )
// sort
sort( ctors.begin(), ctors.end(), ck_comp_func_args );
// check if potentially insert default ctor
t_CKBOOL insertDefaultCtor = type_engine_has_implicit_def_ctor( this );
// have constructors?
if( ctors.size() || insertDefaultCtor )
{
// pointer to chuck func
Chuck_Func * theFunc = *f;
// output function content
apropos_func( sout, theFunc, PREFIX );
// type name
string theName = this->name() + " " + "constructors";
// number of '-'
t_CKUINT n = theName.length(); t_CKUINT i;
// output
for( i = 0; i < n; i++ ) { sout << "-"; }
sout << endl << theName << endl;
for( i = 0; i < n; i++ ) { sout << "-"; }
sout << endl;

// add default constructor, if non-explicitly specified
if( ((ctors.size() == 0 || (ctors.size() && ctors[0]->def()->arg_list))) && insertDefaultCtor )
{
Chuck_Func ftemp;
ftemp.base_name = this->base_name;
ftemp.doc = "default constructor for " + this->base_name;
// output function content
apropos_func( sout, &ftemp, PREFIX );
}

// iterate over member functions
for( vector<Chuck_Func *>::iterator f = ctors.begin(); f != ctors.end(); f++ )
{
// pointer to chuck func
Chuck_Func * theFunc = *f;
// output function content
apropos_func( sout, theFunc, PREFIX );
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/chuck_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,8 @@ t_CKBOOL type_engine_init_op_overload( Chuck_Env * env );
t_CKBOOL type_engine_scan_func_op_overload( Chuck_Env * env, a_Func_Def func_def );
// type-check an operator overload func def | 1.5.1.5 (ge) added
t_CKBOOL type_engine_check_func_op_overload( Chuck_Env * env, a_Func_Def func_def );
// determine whether type has implicit default constructor; helpful for ckdoc | 1.5.1.9
t_CKBOOL type_engine_has_implicit_def_ctor( Chuck_Type * type );


//-----------------------------------------------------------------------------
Expand Down
63 changes: 5 additions & 58 deletions src/core/ulib_doc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1216,10 +1216,10 @@ string CKDoc::genType( Chuck_Type * type, t_CKBOOL clearOutput )
if( value->name.length() == 0 )
continue;
// special internal values
if(value->name[0] == '@')
if( value->name.size() && value->name[0] == '@' )
continue;
// value is a function
if( value->type->base_name == "[function]" )
if( isa( value->type, value->type->env()->ckt_function ) )
continue;

// static or instance?
Expand Down Expand Up @@ -1260,61 +1260,8 @@ string CKDoc::genType( Chuck_Type * type, t_CKBOOL clearOutput )
sort( mfuncs.begin(), mfuncs.end(), ck_comp_func );
sort( ctors.begin(), ctors.end(), ck_comp_func_args );

// whether to potentially insert a default constructor
t_CKBOOL insertDefaultCtor = FALSE;
// if not array, check various conditions under which to insert def ctor
if( !isa( type, type->env()->ckt_array ) )
{
// if has pre_ctor
if( type->has_pre_ctor ) insertDefaultCtor = TRUE;
// if has any mfun or mvars
else if( mfuncs.size() || mvars.size() ) insertDefaultCtor = TRUE;
// check parent pre_ctor
Chuck_Type * t = type->parent;
// check up the chain
while( t && t != t->env()->ckt_object ) // don't include Object itself in this check
{
// check pre_ctor
if( t->has_pre_ctor ) {
insertDefaultCtor = TRUE; break;
}
// check for mfuns and mvars (if we get here, type->info cannot be NULL)
vector<Chuck_Func *> fs;
type->info->get_funcs( fs );
vector<Chuck_Value *> vs;
type->info->get_values( vs );

// iterate over functions
for( vector<Chuck_Func *>::iterator f = fs.begin(); f != fs.end(); f++ )
{
// the function
Chuck_Func * func = *f;
if( func == NULL ) continue;
// static or instance?
if( !func->is_static )
{
insertDefaultCtor = TRUE;
break;
}
}
// iterate over functions
for( vector<Chuck_Value *>::iterator v = vs.begin(); v != vs.end(); v++ )
{
// the function
Chuck_Value * value = *v;
if( value == NULL ) continue;
// static or instance?
if( !value->is_static )
{
insertDefaultCtor = TRUE;
break;
}
}

// up to parent type
t = t->parent;
}
}
// whether to potentially insert a default constructor | 1.5.1.9
t_CKBOOL insertDefaultCtor = type_engine_has_implicit_def_ctor( type );

// constructors | 1.5.1.9 (ge) added
if( ctors.size() || insertDefaultCtor )
Expand Down Expand Up @@ -1357,7 +1304,7 @@ string CKDoc::genType( Chuck_Type * type, t_CKBOOL clearOutput )
output->end_member_funcs();
}

// destructor | 1.5.1.9 (ge) added
// destructor | 1.5.1.9 (ge) added but not added
// if( dtor )
// {
// // begin member functions
Expand Down

0 comments on commit a8fd096

Please sign in to comment.