From 7b1ed59f41a47ae9d6151564e36a353cd4edbe29 Mon Sep 17 00:00:00 2001 From: belliash Date: Wed, 20 Mar 2019 09:24:30 +0100 Subject: [PATCH] Basic check if all methods declared in interface are also defined in class. --- engine/oop.c | 17 ++++++++++++++++- engine/vm.c | 2 +- include/ph7int.h | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/engine/oop.c b/engine/oop.c index 863be1b..d74a270 100644 --- a/engine/oop.c +++ b/engine/oop.c @@ -383,7 +383,8 @@ PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub, ph7_class *pBase) { * Any other return value indicates failure and the upper layer must generate an appropriate * error message. */ -PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface) { +PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_vm *pVm, ph7_class *pMain, ph7_class *pInterface) { + ph7_class_method *pMeth; ph7_class_attr *pAttr; SyHashEntry *pEntry; SyString *pName; @@ -403,6 +404,20 @@ PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface) { } } } + SyHashResetLoopCursor(&pInterface->hMethod); + while((pEntry = SyHashGetNextEntry(&pInterface->hMethod)) != 0) { + pMeth = (ph7_class_method *)pEntry->pUserData; + pName = &pMeth->sFunc.sName; + if((pEntry = SyHashGet(&pMain->hMethod, (const void *)pName->zString, pName->nByte)) != 0) { + continue; + } else { + rc = PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Method '%z:%z()' must be defined inside class '%z'", &pInterface->sName, pName, &pMain->sName); + if(rc == SXERR_ABORT) { + return SXERR_ABORT; + } + continue; + } + } /* Install in the interface container */ SySetPut(&pMain->aInterface, (const void *)&pInterface); /* TICKET 1433-49/1: Symisc eXtension diff --git a/engine/vm.c b/engine/vm.c index 63228e6..15244a6 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -4220,7 +4220,7 @@ static sxi32 VmByteCodeExec( /* Trying to implement a class */ PH7_VmThrowError(&(*pVm), PH7_CTX_ERR, "Class '%z' cannot implement a class '%z'", &pClass->sName.zString, &apImplements->zString); } - rc = PH7_ClassImplement(pClass, pBase); + rc = PH7_ClassImplement(pVm, pClass, pBase); if(rc != SXRET_OK) { break; } diff --git a/include/ph7int.h b/include/ph7int.h index fae3501..c7afaa6 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -1784,7 +1784,7 @@ PH7_PRIVATE sxi32 PH7_ClassInstallAttr(ph7_class *pClass, ph7_class_attr *pAttr) PH7_PRIVATE sxi32 PH7_ClassInstallMethod(ph7_class *pClass, ph7_class_method *pMeth); PH7_PRIVATE sxi32 PH7_ClassInherit(ph7_vm *pVm, ph7_class *pSub, ph7_class *pBase); PH7_PRIVATE sxi32 PH7_ClassInterfaceInherit(ph7_class *pSub, ph7_class *pBase); -PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_class *pMain, ph7_class *pInterface); +PH7_PRIVATE sxi32 PH7_ClassImplement(ph7_vm *pVm, ph7_class *pMain, ph7_class *pInterface); PH7_PRIVATE ph7_class_instance *PH7_NewClassInstance(ph7_vm *pVm, ph7_class *pClass); PH7_PRIVATE ph7_class_instance *PH7_CloneClassInstance(ph7_class_instance *pSrc); PH7_PRIVATE sxi32 PH7_ClassInstanceCmp(ph7_class_instance *pLeft, ph7_class_instance *pRight, int bStrict, int iNest);