Allow a 'final virtual' classes to be declared.
The build was successful. Details

Virtual final classes are helpful in the case someone is wrapping common functions that are static, but the common class itself cannot be instantiated.
This commit is contained in:
Rafal Kupiec 2019-05-30 09:44:46 +02:00
parent 3530e6ea09
commit ba1c840009
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
1 changed files with 25 additions and 22 deletions

View File

@ -4007,22 +4007,29 @@ done:
* protected or public, but not private. Furthermore the signatures of the methods must * protected or public, but not private. Furthermore the signatures of the methods must
* match, i.e. the type hints and the number of required arguments must be the same. * match, i.e. the type hints and the number of required arguments must be the same.
*/ */
static sxi32 PH7_CompileVirtualClass(ph7_gen_state *pGen) { static sxi32 PH7_CompileFinalVirtualClass(ph7_gen_state *pGen) {
sxi32 rc; sxi32 nKwrd, rc;
pGen->pIn++; /* Jump the 'virtual' keyword */ sxi32 iFlags = 0;
rc = PH7_GenStateCompileClass(&(*pGen), PH7_CLASS_VIRTUAL); for(;;) {
return rc; nKwrd = SX_PTR_TO_INT(pGen->pIn->pUserData);
} if(nKwrd == PH7_KEYWORD_FINAL) {
/* if(iFlags & PH7_CLASS_FINAL) {
* Compile a user-defined final class. PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Duplicate 'final' modifier");
* Aer introduces the final keyword, which prevents child classes from overriding }
* a method by prefixing the definition with final. If the class itself is being defined iFlags |= PH7_CLASS_FINAL;
* final then it cannot be extended. } else if(nKwrd == PH7_KEYWORD_VIRTUAL) {
*/ if(iFlags & PH7_CLASS_VIRTUAL) {
static sxi32 PH7_CompileFinalClass(ph7_gen_state *pGen) { PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Duplicate 'virtual' modifier");
sxi32 rc; }
pGen->pIn++; /* Jump the 'final' keyword */ iFlags |= PH7_CLASS_VIRTUAL;
rc = PH7_GenStateCompileClass(&(*pGen), PH7_CLASS_FINAL); } else if(nKwrd == PH7_KEYWORD_CLASS) {
break;
} else {
PH7_GenCompileError(pGen, E_ERROR, pGen->pIn->nLine, "Unexpected token '%z' in class declaration", &pGen->pIn->sData);
}
pGen->pIn++;
}
rc = PH7_GenStateCompileClass(&(*pGen), iFlags);
return rc; return rc;
} }
/* /*
@ -4858,14 +4865,10 @@ static ProcLangConstruct PH7_GenStateGetGlobalScopeHandler(
return PH7_CompileDefine; return PH7_CompileDefine;
} else if(nKeywordID == PH7_KEYWORD_INTERFACE) { } else if(nKeywordID == PH7_KEYWORD_INTERFACE) {
return PH7_CompileClassInterface; return PH7_CompileClassInterface;
} else if(nKeywordID == PH7_KEYWORD_FINAL || nKeywordID == PH7_KEYWORD_VIRTUAL) {
return PH7_CompileFinalVirtualClass;
} else if(nKeywordID == PH7_KEYWORD_CLASS) { } else if(nKeywordID == PH7_KEYWORD_CLASS) {
return PH7_CompileClass; return PH7_CompileClass;
} else if(nKeywordID == PH7_KEYWORD_VIRTUAL && (pLookahead->nType & PH7_TK_KEYWORD)
&& SX_PTR_TO_INT(pLookahead->pUserData) == PH7_KEYWORD_CLASS) {
return PH7_CompileVirtualClass;
} else if(nKeywordID == PH7_KEYWORD_FINAL && (pLookahead->nType & PH7_TK_KEYWORD)
&& SX_PTR_TO_INT(pLookahead->pUserData) == PH7_KEYWORD_CLASS) {
return PH7_CompileFinalClass;
} else if(nKeywordID == PH7_KEYWORD_NAMESPACE) { } else if(nKeywordID == PH7_KEYWORD_NAMESPACE) {
return PH7_CompileNamespace; return PH7_CompileNamespace;
} else if(nKeywordID == PH7_KEYWORD_USING) { } else if(nKeywordID == PH7_KEYWORD_USING) {