parent
4a62e9ed76
commit
a5909ac4de
|
@ -76,6 +76,18 @@ bool CBotFunction::IsPublic()
|
||||||
return m_bPublic;
|
return m_bPublic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CBotFunction::IsProtected()
|
||||||
|
{
|
||||||
|
return m_bProtect;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool CBotFunction::IsPrivate()
|
||||||
|
{
|
||||||
|
return m_bPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool CBotFunction::IsExtern()
|
bool CBotFunction::IsExtern()
|
||||||
{
|
{
|
||||||
|
@ -135,11 +147,9 @@ CBotFunction* CBotFunction::Compile(CBotToken* &p, CBotCStack* pStack, CBotFunct
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if ( IsOfType(p, ID_PUBLIC) )
|
if (IsOfType(p, ID_PRIVATE)) break;
|
||||||
{
|
if (IsOfType(p, ID_PROTECTED)) break;
|
||||||
func->m_bPublic = true;
|
if (IsOfType(p, ID_PUBLIC)) continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pp = p;
|
pp = p;
|
||||||
if (IsOfType(p, ID_EXTERN))
|
if (IsOfType(p, ID_EXTERN))
|
||||||
{
|
{
|
||||||
|
@ -249,14 +259,30 @@ CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClas
|
||||||
|
|
||||||
CBotCStack* pStk = pStack->TokenStack(p, true);
|
CBotCStack* pStk = pStack->TokenStack(p, true);
|
||||||
|
|
||||||
|
CBotToken* pPriv = p;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
if (!func->m_bPublic) // don't repeat 'public'
|
||||||
|
{
|
||||||
|
pPriv = p;
|
||||||
|
if (IsOfType(p, ID_PRIVATE))
|
||||||
|
{
|
||||||
|
func->m_bPrivate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IsOfType(p, ID_PROTECTED))
|
||||||
|
{
|
||||||
|
func->m_bProtect = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (IsOfType(p, ID_PUBLIC))
|
if (IsOfType(p, ID_PUBLIC))
|
||||||
{
|
{
|
||||||
// func->m_bPublic = true; // will be done in two passes
|
func->m_bPublic = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( IsOfType(p, ID_EXTERN) )
|
}
|
||||||
|
if (!func->m_bExtern && IsOfType(p, ID_EXTERN))
|
||||||
{
|
{
|
||||||
func->m_bExtern = true;
|
func->m_bExtern = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -292,6 +318,14 @@ CBotFunction* CBotFunction::Compile1(CBotToken* &p, CBotCStack* pStack, CBotClas
|
||||||
if (!IsOfType(p, TokenTypVar)) goto bad;
|
if (!IsOfType(p, TokenTypVar)) goto bad;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (pClass == nullptr) // not method in a class ?
|
||||||
|
{
|
||||||
|
if (func->m_bPrivate || func->m_bProtect) // not allowed for regular functions
|
||||||
|
{
|
||||||
|
pStk->SetError(CBotErrNoType, pPriv);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CBotToken* openPar = p;
|
CBotToken* openPar = p;
|
||||||
func->m_param = CBotDefParam::Compile(p, pStk); // compile parameters
|
func->m_param = CBotDefParam::Compile(p, pStk); // compile parameters
|
||||||
|
@ -877,6 +911,25 @@ CBotTypResult CBotFunction::CompileMethodCall(const std::string& name, CBotVar**
|
||||||
|
|
||||||
if (pt != nullptr)
|
if (pt != nullptr)
|
||||||
{
|
{
|
||||||
|
CBotToken token("this");
|
||||||
|
CBotVar* pThis = pStack->FindVar(token); // for 'this' context
|
||||||
|
|
||||||
|
if (pThis == nullptr || pThis->GetType() != CBotTypPointer) // called from inside a function
|
||||||
|
{
|
||||||
|
if (pt->IsPrivate() || pt->IsProtected())
|
||||||
|
type.SetType(CBotErrPrivate);
|
||||||
|
}
|
||||||
|
else // called from inside a method
|
||||||
|
{
|
||||||
|
CBotClass* thisClass = pThis->GetClass(); // current class
|
||||||
|
CBotClass* funcClass = CBotClass::Find(pt->m_MasterClass); // class of the method
|
||||||
|
|
||||||
|
if (pt->IsPrivate() && thisClass != funcClass)
|
||||||
|
type.SetType(CBotErrPrivate);
|
||||||
|
|
||||||
|
if (pt->IsProtected() && !thisClass->IsChildOf(funcClass))
|
||||||
|
type.SetType(CBotErrPrivate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
|
|
@ -283,6 +283,18 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsPublic();
|
bool IsPublic();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Check if a method is protected.
|
||||||
|
* \return true if a method was compiled with "protected" keyword.
|
||||||
|
*/
|
||||||
|
bool IsProtected();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Check if a method is private.
|
||||||
|
* \return true if a method was compiled with "private" keyword.
|
||||||
|
*/
|
||||||
|
bool IsPrivate();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief IsExtern
|
* \brief IsExtern
|
||||||
* \return
|
* \return
|
||||||
|
@ -328,6 +340,10 @@ private:
|
||||||
CBotTypResult m_retTyp;
|
CBotTypResult m_retTyp;
|
||||||
//! Public function.
|
//! Public function.
|
||||||
bool m_bPublic;
|
bool m_bPublic;
|
||||||
|
//! Protected method.
|
||||||
|
bool m_bProtect = false;
|
||||||
|
//! Private method.
|
||||||
|
bool m_bPrivate = false;
|
||||||
//! Extern function.
|
//! Extern function.
|
||||||
bool m_bExtern;
|
bool m_bExtern;
|
||||||
//! Name of the class we are part of
|
//! Name of the class we are part of
|
||||||
|
|
|
@ -3068,3 +3068,132 @@ TEST_F(CBotUT, ClassInheritanceTestThisOutOfClass)
|
||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CBotUT, ClassTestProtectedMethod)
|
||||||
|
{
|
||||||
|
auto publicProgram = ExecuteTest(
|
||||||
|
"public class BaseClass {\n"
|
||||||
|
" protected bool BaseClassProtected() {\n"
|
||||||
|
" return true;\n"
|
||||||
|
" }\n"
|
||||||
|
" bool NoErrorProtectedSameClass() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" ASSERT(true == b.BaseClassProtected());\n"
|
||||||
|
" return BaseClassProtected();\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"extern void Test() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" ASSERT(true == b.NoErrorProtectedSameClass());\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"public class SubClass extends BaseClass {\n"
|
||||||
|
" bool NoErrorProtectedSubClass() {\n"
|
||||||
|
" ASSERT(true == BaseClassProtected());\n"
|
||||||
|
" ASSERT(true == this.BaseClassProtected());\n"
|
||||||
|
" ASSERT(true == super.BaseClassProtected());\n"
|
||||||
|
" return true;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"extern void TestNoErrorProtected() {\n"
|
||||||
|
" SubClass s();\n"
|
||||||
|
" ASSERT(true == s.NoErrorProtectedSubClass());\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void TestErrorProtected_1() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" b.BaseClassProtected();\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"public class SubClass extends BaseClass {}\n"
|
||||||
|
"\n"
|
||||||
|
"extern void TestErrorProtected_2() {\n"
|
||||||
|
" SubClass s();\n"
|
||||||
|
" s.BaseClassProtected();\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"public class SomeOtherClass {\n"
|
||||||
|
" void testErrorProtected() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" b.BaseClassProtected();\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CBotUT, ClassTestPrivateMethod)
|
||||||
|
{
|
||||||
|
auto publicProgram = ExecuteTest(
|
||||||
|
"public class BaseClass {\n"
|
||||||
|
" private bool BaseClassPrivate() {\n"
|
||||||
|
" return true;\n"
|
||||||
|
" }\n"
|
||||||
|
" bool NoErrorPrivateSameClass() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" ASSERT(true == b.BaseClassPrivate());\n"
|
||||||
|
" return BaseClassPrivate();\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n"
|
||||||
|
"extern void Test() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" ASSERT(true == b.NoErrorPrivateSameClass());\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"public class SubClass extends BaseClass {\n"
|
||||||
|
" void ErrorPrivateThis() {\n"
|
||||||
|
" this.BaseClassPrivate();\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"public class SubClass extends BaseClass {\n"
|
||||||
|
" void ErrorPrivateSuper() {\n"
|
||||||
|
" super.BaseClassPrivate();\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"extern void TestErrorPrivate_1() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" b.BaseClassPrivate();\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"public class SubClass extends BaseClass {}\n"
|
||||||
|
"\n"
|
||||||
|
"extern void TestErrorPrivate_2() {\n"
|
||||||
|
" SubClass s();\n"
|
||||||
|
" s.BaseClassPrivate();\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
|
||||||
|
ExecuteTest(
|
||||||
|
"public class SomeOtherClass {\n"
|
||||||
|
" void ErrorPrivate() {\n"
|
||||||
|
" BaseClass b();\n"
|
||||||
|
" b.BaseClassPrivate();\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n",
|
||||||
|
CBotErrPrivate
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue