DaoRoutine* DaoObject_GetMethod( DaoObject *self, const char *name ) { DaoValue *V; DString str = DString_WrapChars( name ); int id = DaoClass_FindConst( self->defClass, & str ); if( id < 0 ) return NULL; V = DaoClass_GetConst( self->defClass, id ); if( V == NULL || V->type != DAO_ROUTINE ) return NULL; return (DaoRoutine*) V; }
int DaoInterface_CheckBind( DList *methods, DaoType *type, DMap *binds ) { DNode *it; DaoRoutine *rout2; daoint i, n, id; if( type->tid == DAO_OBJECT || type->tid == DAO_CLASS ){ DaoClass *klass = & type->aux->xClass; for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; rout2 = klass->initRoutines; if( !(rout->attribs & DAO_ROUT_INITOR) ){ id = DaoClass_FindConst( klass, rout->routName ); if( id <0 ) return 0; rout2 = (DaoRoutine*) DaoClass_GetConst( klass, id ); if( rout2->type != DAO_ROUTINE ) return 0; } /*printf( "AAA: %s %s\n", rout->routType->name->chars,rout2->routType->name->chars);*/ if( DaoRoutine_IsCompatible( rout2, rout->routType, binds ) ==0 ) return 0; } }else if( type->tid == DAO_INTERFACE ){ DaoInterface *inter = (DaoInterface*) type->aux; for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; DString *name = rout->routName; if( rout->attribs & DAO_ROUT_INITOR ) name = inter->abtype->name; it = DMap_Find( inter->methods, name ); if( it == NULL ) return 0; if( DaoRoutine_IsCompatible( it->value.pRoutine, rout->routType, binds ) ==0 ) return 0; } }else if( type->tid == DAO_CINVALUE ){ DaoCinType *cintype = (DaoCinType*) type->aux; for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; DString *name = rout->routName; if( rout->attribs & DAO_ROUT_INITOR ) name = cintype->vatype->name; it = DMap_Find( cintype->methods, name ); if( it == NULL ) return 0; if( DaoRoutine_IsCompatible( it->value.pRoutine, rout->routType, binds ) ==0 ) return 0; } }else{ for(i=0,n=methods->size; i<n; i++){ DaoRoutine *rout = methods->items.pRoutine[i]; DString *name = rout->routName; DaoRoutine *func; if( rout->attribs & DAO_ROUT_INITOR ) name = type->name; func = DaoType_FindFunction( type, name ); if( func == NULL ) return 0; if( DaoRoutine_IsCompatible( func, rout->routType, binds ) ==0 ) return 0; } } return 1; }
static int DaoInterface_CheckMethod( DaoRoutine *routine, DaoType *type, DMap *binds ) { DaoRoutine *method = NULL; DNode *it; if( type->tid == DAO_OBJECT || type->tid == DAO_CLASS ){ DaoClass *klass = & type->aux->xClass; method = klass->initRoutines; if( !(routine->attribs & DAO_ROUT_INITOR) ){ int id = DaoClass_FindConst( klass, routine->routName ); if( id <0 ) return 0; method = (DaoRoutine*) DaoClass_GetConst( klass, id ); if( method->type != DAO_ROUTINE ) return 0; } }else if( type->tid == DAO_INTERFACE ){ DaoInterface *inter = (DaoInterface*) type->aux; DString *name = routine->routName; if( routine->attribs & DAO_ROUT_INITOR ) name = inter->abtype->name; it = DMap_Find( inter->methods, name ); if( it != NULL ) method = it->value.pRoutine; }else if( type->tid == DAO_CINVALUE ){ DaoCinType *cintype = (DaoCinType*) type->aux; DString *name = routine->routName; if( routine->attribs & DAO_ROUT_INITOR ) name = cintype->vatype->name; it = DMap_Find( cintype->methods, name ); if( it == NULL && cintype->target != NULL ){ return DaoInterface_CheckMethod( routine, cintype->target, binds ); } if( it != NULL ) method = it->value.pRoutine; }else{ DString *name = routine->routName; if( routine->attribs & DAO_ROUT_INITOR ) name = type->name; method = DaoType_FindFunction( type, name ); } if( method == NULL ) return 0; /*printf( "AAA: %s %s\n", routine->routType->name->chars,method->routType->name->chars);*/ return DaoRoutine_IsCompatible( method, routine->routType, binds ); }
/* assumed to be called before parsing class body */ int DaoClass_DeriveClassData( DaoClass *self ) { DaoType *type; DaoValue *value; DString *mbs; DNode *it, *search; DaoMethodFields *mf; daoint i, j, k, id; if( DaoCass_DeriveMixinData( self ) == 0 ) return 0; mbs = DString_New(1); mf = DaoMethodFields_New(); if( self->clsType->bases == NULL ) self->clsType->bases = DArray_New(D_VALUE); if( self->objType->bases == NULL ) self->objType->bases = DArray_New(D_VALUE); DArray_Clear( self->clsType->bases ); DArray_Clear( self->objType->bases ); self->cstParentStart = self->constants->size; self->glbParentStart = self->variables->size; DVector_PushUshort( self->offsets, self->constants->size ); DVector_PushUshort( self->offsets, self->variables->size ); if( self->parent && self->parent->type == DAO_CLASS ){ DaoClass *klass = (DaoClass*) self->parent; DArray_Append( self->clsType->bases, klass->clsType ); DArray_Append( self->objType->bases, klass->objType ); DArray_AppendArray( self->cstDataName, klass->cstDataName ); DArray_AppendArray( self->glbDataName, klass->glbDataName ); for(j=0; j<klass->constants->size; ++j){ DaoValue *cst = klass->constants->items.pConst[j]->value; DArray_Append( self->constants, klass->constants->items.pVoid[j] ); } for(j=0; j<klass->variables->size; ++j){ DArray_Append( self->variables, klass->variables->items.pVoid[j] ); } for(it=DMap_First(klass->lookupTable); it; it=DMap_Next(klass->lookupTable,it)){ daoint pm = LOOKUP_PM( it->value.pInt ); daoint st = LOOKUP_ST( it->value.pInt ); daoint up = LOOKUP_UP( it->value.pInt ); daoint id = LOOKUP_ID( it->value.pInt ); DaoValue *cst; if( st == DAO_CLASS_CONSTANT ){ id = LOOKUP_ID( it->value.pInt ); cst = klass->constants->items.pConst[id]->value; if( cst->type == DAO_ROUTINE ){ DArray_Append( mf->names, it->key.pString ); DArray_Append( mf->perms, IntToPointer( pm ) ); DArray_Append( mf->routines, cst ); } } if( st == DAO_OBJECT_VARIABLE ) continue; if( pm == DAO_DATA_PRIVATE ) continue; if( DMap_Find( self->lookupTable, it->key.pString ) ) continue; switch( st ){ case DAO_CLASS_CONSTANT : id += self->cstParentStart; break; case DAO_CLASS_VARIABLE : id += self->glbParentStart; break; case DAO_OBJECT_VARIABLE : continue; } id = LOOKUP_BIND( st, pm, up+1, id ); DMap_Insert( self->lookupTable, it->key.pString, (void*)id ); } }else if( self->parent && self->parent->type == DAO_CTYPE ){ DaoCtype *cdata = (DaoCtype*) self->parent; DaoTypeKernel *kernel = cdata->ctype->kernel; DaoTypeBase *typer = kernel->typer; DMap *methods = kernel->methods; DMap *values = kernel->values; DArray_Append( self->clsType->bases, cdata->ctype ); DArray_Append( self->objType->bases, cdata->cdtype ); DaoClass_AddConst( self, cdata->ctype->name, (DaoValue*)cdata, DAO_DATA_PUBLIC ); if( kernel->SetupValues ) kernel->SetupValues( kernel->nspace, kernel->typer ); if( kernel->SetupMethods ) kernel->SetupMethods( kernel->nspace, kernel->typer ); DaoCdataType_SpecializeMethods( cdata->ctype ); kernel = cdata->ctype->kernel; values = kernel->values; methods = kernel->methods; if( typer->numItems ){ for(j=0; typer->numItems[j].name!=NULL; j++){ DString name = DString_WrapMBS( typer->numItems[j].name ); it = DMap_Find( values, & name ); if( it == NULL ) continue; if( DMap_Find( self->lookupTable, it->key.pString ) ) continue; id = self->constants->size; id = LOOKUP_BIND( DAO_CLASS_CONSTANT, DAO_DATA_PUBLIC, 1, id ); DMap_Insert( self->lookupTable, it->key.pString, IntToPointer( id ) ); DArray_Append( self->cstDataName, it->key.pString ); DArray_Append( self->constants, DaoConstant_New( it->value.pValue ) ); } } for(it=DMap_First( methods ); it; it=DMap_Next( methods, it )){ if( DMap_Find( self->lookupTable, it->key.pString ) ) continue; id = self->constants->size; id = LOOKUP_BIND( DAO_CLASS_CONSTANT, DAO_DATA_PUBLIC, 1, id ); DMap_Insert( self->lookupTable, it->key.pString, IntToPointer( id ) ); DArray_Append( self->cstDataName, it->key.pString ); DArray_Append( self->constants, DaoConstant_New( it->value.pValue ) ); DArray_Append( mf->names, it->key.pString ); DArray_Append( mf->perms, IntToPointer( DAO_DATA_PUBLIC ) ); DArray_Append( mf->routines, it->value.pValue ); } } DaoClass_SetupMethodFields( self, mf ); DaoMethodFields_Delete( mf ); self->cstParentEnd = self->constants->size; self->glbParentEnd = self->variables->size; #if 0 for(j=0; j<self->constants->size; ++j){ DaoValue *value = self->constants->items.pConst[j]->value; DaoRoutine *routine = (DaoRoutine*) value; printf( "%3i: %3i %s\n", j, value->type, self->cstDataName->items.pString[j]->mbs ); if( value->type != DAO_ROUTINE ) continue; printf( "%3i: %3i %s\n", j, value->type, routine->routName->mbs ); if( routine->overloads ){ DArray *routs = routine->overloads->routines; for(k=0; k<routs->size; ++k){ DaoRoutine *rout = routs->items.pRoutine[k]; } }else{ if( routine->attribs & DAO_ROUT_PRIVATE ) continue; } } for(it=DMap_First(self->lookupTable); it; it=DMap_Next(self->lookupTable,it)){ printf( "%s %i\n", it->key.pString->mbs, it->value.pInt ); if( LOOKUP_ST( it->value.pInt ) != DAO_CLASS_CONSTANT ) continue; DaoValue *value = DaoClass_GetConst( self, it->value.pInt ); printf( "%i\n", value->type ); } #endif DString_Delete( mbs ); return 1; }