GME
13
|
00001 //############################################################################################################################################### 00002 // 00003 // Object Constraint Language Generic Manager 00004 // OCLTree.cpp 00005 // 00006 //############################################################################################################################################### 00007 #include "Solve4786.h" 00008 #include "OCLTree.h" 00009 00010 #include "OCLObjectExBasic.h" 00011 #include "OCLSignature.h" 00012 #include "OCLFeature.h" 00013 #include "OCLFeatureImplementation.h" 00014 #include "OCLParserStatic.h" 00015 #include "OCLException.h" 00016 00017 #define NILNAMESPACE "" 00018 namespace OclTree 00019 { 00020 #define EXCEPTION0( iCode, pos ) \ 00021 OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, iCode, pos.iLine, pos.iColumn ) 00022 00023 #define EXCEPTION1( iCode, param1, pos ) \ 00024 OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, iCode, param1, pos.iLine, pos.iColumn ) 00025 00026 #define EXCEPTION2( iCode, param1, param2, pos ) \ 00027 OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, iCode, param1, param2, pos.iLine, pos.iColumn ) 00028 00029 #define ADDEX( ex ) \ 00030 { \ 00031 OclCommon::Exception exp( ex ); \ 00032 context.m_poolExceptions.Add( exp ); \ 00033 } 00034 00035 #define ADDEXP( ex ) \ 00036 context.m_poolExceptions.Add( ex ) 00037 00038 #define POOLADDEX( ex_pool, ex ) \ 00039 { \ 00040 OclCommon::Exception exp( ex ); \ 00041 ex_pool.Add( exp ); \ 00042 } 00043 00044 #define SETEXPOS( ex, pos ) \ 00045 ex.SetLine( pos.iLine ); ex.SetColumn( pos.iColumn ); 00046 00047 #define EVALTRY \ 00048 try 00049 00050 #define EVALCATCH( iLinee, strSigg ) \ 00051 catch ( OclCommon::Exception ex ) { \ 00052 AddViolation( context, iLinee, strSigg, ex.GGetMessage() ); \ 00053 } \ 00054 catch ( char* ex ) { \ 00055 AddViolation( context, iLinee, strSigg, std::string( ex ) + " " ); \ 00056 } \ 00057 catch ( ... ) { \ 00058 AddViolation( context, iLinee, strSigg, "UNEX" ); \ 00059 } 00060 00061 //############################################################################################################################################## 00062 // 00063 // A B S T R A C T C L A S S : OclTree::TreeNode 00064 // 00065 //============================================================================================================================================== 00066 // 00067 // D E S C R I P T I O N : 00068 // 00069 //############################################################################################################################################## 00070 00071 TreeNode::TreeNode( TreeManager* pManager, NodeKind eKind ) 00072 : m_pManager( pManager ), m_eKind( eKind ), m_bTester( false ), m_bSelfTester( false ) 00073 { 00074 } 00075 00076 TreeNode::~TreeNode() 00077 { 00078 } 00079 00080 TreeManager* TreeNode::GetTreeManager() const 00081 { 00082 return m_pManager; 00083 } 00084 00085 TreeNode::NodeKind TreeNode::GetKind() const 00086 { 00087 return m_eKind; 00088 } 00089 00090 bool TreeNode::ParseTypeSeq( TypeContext& context, const Position& position, std::string& strType, TypeSeq& vecType ) const 00091 { 00092 TypeSeq vecSavedType = vecType; 00093 int iRes = OclCommon::Convert( strType, vecType ); 00094 if ( iRes > 0 ) { 00095 ADDEX( EXCEPTION1( EX_INVALID_TYPE, strType, position ) ); 00096 return false; 00097 } 00098 bool bValid = true; 00099 for ( unsigned int i = 0 ; i < vecType.size() ; i++ ) { 00100 try { 00101 std::shared_ptr<OclMeta::Type> pType = m_pManager->GetTypeManager()->GetType( vecType[ i ], context.m_namespace); 00102 if ( i != vecType.size() - 1 ) { 00103 if ( ! pType->IsCompound() ) { 00104 ADDEX( EXCEPTION1( EX_TYPE_ISNT_COMPOUND, vecType[ i ], position ) ); 00105 bValid = false; 00106 } 00107 } 00108 else { 00109 if ( pType->IsCompound() ) 00110 vecType.push_back( "ocl::Any" ); 00111 } 00112 if ( bValid ) 00113 vecType[ i ] = pType->GetName(); 00114 } catch ( OclCommon::Exception ex ) { 00115 SETEXPOS( ex, position ); 00116 ADDEX( ex ); 00117 bValid = false; 00118 } 00119 } 00120 if ( ! bValid ) 00121 vecType = vecSavedType; 00122 else 00123 OclCommon::Convert( vecType, strType ); 00124 return bValid; 00125 } 00126 00127 bool TreeNode::CastType( TypeContext& context, const Position& position, const TypeSeq& vecTypeFrom, const TypeSeq& vecTypeTo ) const 00128 { 00129 OclMeta::TypeManager* pManager = m_pManager->GetTypeManager(); 00130 if ( ! pManager->IsTypeA( vecTypeFrom, vecTypeTo ) && ! pManager ->IsTypeA( vecTypeTo, vecTypeFrom ) ) { 00131 std::string strCType, strSType; 00132 OclCommon::Convert( vecTypeFrom, strSType ); 00133 OclCommon::Convert( vecTypeTo, strCType ); 00134 ADDEX( EXCEPTION2( EX_CAST_TYPE_MISMATCH, strSType, strCType, position ) ); 00135 return false; 00136 } 00137 return true; 00138 } 00139 00140 TypeSeq TreeNode::GetParametralTypeSeq( const TypeSeq& vecType1, const TypeSeq& vecType2, const TypeSeq& vecTypeReturn ) 00141 { 00142 m_vecType.clear(); 00143 int i; 00144 00145 for ( i = 0 ; i < (int) vecTypeReturn.size() - 1 ; i++ ) 00146 m_vecType.push_back( vecTypeReturn[ i ] ); 00147 00148 std::string strLastType = vecTypeReturn[ vecTypeReturn.size() - 1 ]; 00149 00150 if ( strLastType == TYPE_AGGREGATED_OBJECT ) { 00151 for ( i = 1 ; i < (int) vecType1.size() ; i++ ) 00152 m_vecType.push_back( vecType1[ i ] ); 00153 return m_vecType; 00154 } 00155 00156 if ( ! vecType2.empty() ) { 00157 00158 if ( strLastType == TYPE_EXPRESSION_RETURN ) { 00159 for ( i = 0 ; i < (int) vecType2.size() ; i++ ) 00160 m_vecType.push_back( vecType2[ i ] ); 00161 return m_vecType; 00162 } 00163 00164 if ( GetTreeManager()->GetTypeManager()->GetType( vecType1[ 0 ], NILNAMESPACE )->IsCompound() ) { 00165 00166 if ( strLastType == TYPE_ARGUMENT_SELF_BASE || strLastType == TYPE_COMPOUNDARGUMENT_SELF_BASE ) { 00167 00168 TypeSeq vecTypeS = vecType1; 00169 vecTypeS.erase( vecTypeS.begin() ); 00170 TypeSeq vecTypeA = vecType2; 00171 00172 if ( strLastType == TYPE_COMPOUNDARGUMENT_SELF_BASE && GetTreeManager()->GetTypeManager()->GetType( vecType2[ 0 ], NILNAMESPACE )->IsCompound() ) 00173 vecTypeA.erase( vecTypeA.begin() ); 00174 00175 vecTypeS = GetTreeManager()->GetTypeManager()->GetTypeBase( vecTypeS, vecTypeA ); 00176 for ( i = 0 ; i < (int) vecTypeS.size() ; i++ ) 00177 m_vecType.push_back( vecTypeS[ i ] ); 00178 00179 return m_vecType; 00180 } 00181 } 00182 } 00183 00184 m_vecType.push_back( strLastType ); 00185 return m_vecType; 00186 } 00187 00188 VariableNode* TreeNode::CreateThis( TypeContext& context, int iImplicitPos ) const 00189 { 00190 if ( iImplicitPos == -1 ) 00191 iImplicitPos = context.m_vecImplicits.size() - 1; 00192 00193 VariableNode* pVariableNode = GetTreeManager()->CreateVariable(); 00194 pVariableNode->m_strName = context.m_vecImplicits[ iImplicitPos ]; 00195 context.m_ctxTypes.GetVariable( context.m_vecImplicits[ iImplicitPos ], pVariableNode->m_vecType ); 00196 return pVariableNode; 00197 } 00198 00199 int TreeNode::GetLastExceptionCode( TypeContext& context ) const 00200 { 00201 int iLastCode = context.m_poolExceptions.Size(); 00202 return ( iLastCode == 0 ) ? -1 : context.m_poolExceptions.GetAt( context.m_poolExceptions.Size() - 1 ).GetCode(); 00203 } 00204 00205 OclMeta::Feature* TreeNode::CheckAmbiguity( const std::vector<OclMeta::Type*>& vecTypes, const std::vector<OclSignature::Feature*>& vecSignatures, std::vector<int>& vecAmbiguities, int& iPrecedence, OclCommon::ExceptionPool& exAmbiguity ) 00206 { 00207 OclCommon::Exception exception; 00208 OclCommon::Exception exception2; 00209 OclMeta::Feature* feature1 = NULL; 00210 OclMeta::Feature* feature2 = NULL; 00211 try { 00212 switch ( vecSignatures[ 0 ]->GetKind() ) { 00213 case OclSignature::Feature::FK_OPERATOR : feature1 = m_pManager->GetTypeManager()->GetOperator( *( (OclSignature::Operator*)vecSignatures[ 0 ] ) ); break; 00214 case OclSignature::Feature::FK_FUNCTION : feature1 = m_pManager->GetTypeManager()->GetFunction( *( (OclSignature::Function*)vecSignatures[ 0 ] ) ); break; 00215 case OclSignature::Feature::FK_METHOD : feature1 = vecTypes[ 0 ]->GetMethod( *( (OclSignature::Method*)vecSignatures[ 0 ] ) ); break; 00216 case OclSignature::Feature::FK_ITERATOR : feature1 = ( ( OclMeta::CompoundType*) vecTypes[ 0 ] )->GetIterator(0, *( (OclSignature::Iterator*)vecSignatures[ 0 ] ) ); break; 00217 case OclSignature::Feature::FK_ATTRIBUTE : feature1 = vecTypes[ 0 ]->GetAttribute( *( (OclSignature::Attribute*)vecSignatures[ 0 ] ) ); break; 00218 case OclSignature::Feature::FK_ASSOCIATION : feature1 = vecTypes[ 0 ]->GetAssociation( *( (OclSignature::Association*)vecSignatures[ 0 ] ) ); break; 00219 } 00220 if ( iPrecedence == -1 ) 00221 return feature1; 00222 } 00223 catch ( OclCommon::Exception ex ) { 00224 if ( iPrecedence == -1 ) { 00225 exAmbiguity.Add( ex ); 00226 return NULL; 00227 } 00228 exception = ex; 00229 } 00230 try { 00231 switch ( vecSignatures[ 1 ]->GetKind() ) { 00232 case OclSignature::Feature::FK_OPERATOR : feature2 = m_pManager->GetTypeManager()->GetOperator( *( (OclSignature::Operator*)vecSignatures[ 1 ] ) ); break; 00233 case OclSignature::Feature::FK_FUNCTION : feature2 = m_pManager->GetTypeManager()->GetFunction( *( (OclSignature::Function*)vecSignatures[ 1 ] ) ); break; 00234 case OclSignature::Feature::FK_METHOD : feature2 = vecTypes[ 1 ]->GetMethod( *( (OclSignature::Method*)vecSignatures[ 1 ] ) ); break; 00235 case OclSignature::Feature::FK_ITERATOR : feature2 = ( ( OclMeta::CompoundType*) vecTypes[ 1 ] )->GetIterator(0, *( (OclSignature::Iterator*)vecSignatures[ 1 ] ) ); break; 00236 case OclSignature::Feature::FK_ATTRIBUTE : feature2 = vecTypes[ 1 ]->GetAttribute( *( (OclSignature::Attribute*)vecSignatures[ 1 ] ) ); break; 00237 case OclSignature::Feature::FK_ASSOCIATION : feature2 = vecTypes[ 1 ]->GetAssociation( *( (OclSignature::Association*)vecSignatures[ 1 ] ) ); break; 00238 } 00239 if ( iPrecedence == 1 ) 00240 return feature2; 00241 00242 vecAmbiguities[ 1 ] = 0; 00243 if ( feature1 || ! feature1 && exception.GetCode() == vecAmbiguities[ 0 ] ) { 00244 if ( feature1 ) 00245 vecAmbiguities[ 0 ] = 0; 00246 POOLADDEX(exAmbiguity, OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, vecAmbiguities[ 2 ], vecSignatures[ 0 ]->Print(), vecSignatures[ 1 ]->Print() ) ); 00247 return NULL; 00248 } 00249 iPrecedence = 1; 00250 return feature2; 00251 } 00252 catch ( OclCommon::Exception ex ) { 00253 if ( iPrecedence == 1 ) { 00254 exAmbiguity.Add( ex ); 00255 return NULL; 00256 } 00257 00258 if ( ex.GetCode() == vecAmbiguities[ 1 ] ) { 00259 if ( feature1 || ! feature1 && exception.GetCode() == vecAmbiguities[ 0 ] ) { 00260 if ( feature1 ) 00261 vecAmbiguities[ 0 ] = 0; 00262 POOLADDEX(exAmbiguity, OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, vecAmbiguities[ 2 ], vecSignatures[ 0 ]->Print(), vecSignatures[ 1 ]->Print() ) ); 00263 return NULL; 00264 } 00265 else { 00266 vecAmbiguities[ 0 ] = exception.GetCode(); 00267 exAmbiguity.Add( ex ); 00268 return NULL; 00269 } 00270 } 00271 else { 00272 vecAmbiguities[ 1 ] = ex.GetCode(); 00273 if ( feature1 ) { 00274 vecAmbiguities[ 0 ] = 0; 00275 iPrecedence = -1; 00276 return feature1; 00277 } 00278 else { 00279 exAmbiguity.Add( exception ); 00280 if ( exception.GetCode() != vecAmbiguities[ 0 ] ) 00281 exAmbiguity.Add( ex ); 00282 vecAmbiguities[ 0 ] = exception.GetCode(); 00283 return NULL; 00284 } 00285 } 00286 } 00287 } 00288 00289 void TreeNode::AddViolation( ObjectContext& context, int iLine, const std::string& strSignature, const std::string& strMessage ) 00290 { 00291 if ( ! context.m_bEnableTracking ) 00292 return; 00293 00294 Violation violation; 00295 00296 violation.bIsException = ! strMessage.empty(); 00297 violation.position.iLine = iLine; 00298 if ( strMessage.empty() ) 00299 violation.strMessage = "Expression evaluated to false."; 00300 else 00301 if ( strMessage == "UNEX" ) 00302 violation.strMessage = "Unexpected exception occurred."; 00303 else 00304 violation.strMessage = strMessage; 00305 violation.strSignature = strSignature; 00306 00307 ObjectContextStack::StateItemVector vecItems = context.oCtx.GetState(); 00308 for ( unsigned int i = 0 ; i < vecItems.size() ; i++ ) { 00309 // ObjectContextStack::StateItem itemx = vecItems[i]; 00310 string nam = vecItems[ i ].name; 00311 violation.vecVariables.push_back( nam ); 00312 string str = vecItems[ i ].item.Print(); 00313 violation.vecObjects.push_back( str ); 00314 IUnknown* iu; 00315 iu = vecItems[ i ].item.GetObject(); 00316 violation.vecObjectsPtr.push_back(iu); 00317 } 00318 context.vecViolations.push_back( violation ); 00319 context.iViolationCount++; 00320 00321 if ( violation.bIsException ) 00322 context.m_bHasException; 00323 } 00324 00325 // terge 00326 void TreeNode::AddViolation(ObjectContext& context, Violation &violation) 00327 { 00328 context.vecViolations.push_back( violation ); 00329 context.iViolationCount++; 00330 00331 if ( violation.bIsException ) 00332 context.m_bHasException; 00333 } 00334 00335 bool TreeNode::IsBooleanReturned() 00336 { 00337 return GetTreeManager()->GetTypeManager()->IsTypeA( m_vecType[ 0 ], "ocl::Boolean" ) >= 0; 00338 } 00339 00340 OclMeta::Object TreeNode::CheckFalseResult( ObjectContext& context, OclMeta::Object spObject, int iLine, const std::string& strSignature ) 00341 { 00342 if ( spObject.IsUndefined() ) 00343 return spObject; 00344 if ( IsBooleanReturned() && context.bDoSnapshot ) { 00345 DECL_BOOLEAN( bResult, spObject ); 00346 if ( ! bResult ) 00347 AddViolation( context, iLine, strSignature ); 00348 } 00349 return spObject; 00350 } 00351 00352 OclMeta::Object TreeNode::EvaluateCast( ObjectContext& context, OclMeta::Object spObject, int iLine, const std::string& strSignature, const std::string& strTypeName, bool bOnlyTest ) 00353 { 00354 std::string strTypeName2 = ( strTypeName.empty() ) ? m_vecType[ 0 ] : strTypeName; 00355 if ( spObject.IsUndefined() ) 00356 return spObject; 00357 EVALTRY { 00358 if ( GetTreeManager()->GetTypeManager()->IsTypeA( spObject.GetTypeName(), strTypeName2 ) >= 0 ) { 00359 if ( ! bOnlyTest ) { 00360 OclMeta::Object spNewObject( spObject ); 00361 spNewObject.SetStaticTypeName( strTypeName2 ); 00362 return spNewObject; 00363 } 00364 return spObject; 00365 } 00366 AddViolation( context, iLine, strSignature, "Object is not instance of type [ " + strTypeName2 + " ]." ); 00367 return OclMeta::Object::UNDEFINED; 00368 } EVALCATCH( iLine, "At casting object: " + strSignature ); 00369 return OclMeta::Object::UNDEFINED; 00370 } 00371 00372 void TreeNode::CheckInitialize() 00373 { 00374 m_vecType.clear(); 00375 m_bSelfTester = false; 00376 } 00377 00378 bool TreeNode::Check( TypeContext& context ) 00379 { 00380 CheckInitialize(); 00381 return CheckImplementation( context ); 00382 } 00383 00384 //############################################################################################################################################## 00385 // 00386 // C L A S S : OclNodes::ObjectNode <<< + OclTree::TreeNode 00387 // 00388 //############################################################################################################################################## 00389 00390 ObjectNode::ObjectNode( TreeManager* pManager ) 00391 : TreeNode( pManager, TreeNode::NK_OBJECT ), m_strType( "" ), m_strValue( "" ) 00392 { 00393 } 00394 00395 std::string ObjectNode::Print( const std::string& strTabs ) const 00396 { 00397 return GetTreeManager()->m_pOAdaptor->Print( strTabs, (ObjectNode*)this ); 00398 } 00399 00400 bool ObjectNode::CheckImplementation( TypeContext& context ) 00401 { 00402 return GetTreeManager()->m_pOAdaptor->Check( context, (ObjectNode*)this ); 00403 } 00404 00405 OclMeta::Object ObjectNode::Evaluate( ObjectContext& context ) 00406 { 00407 OclMeta::Object spResult = GetTreeManager()->m_pOAdaptor->Evaluate( context, (ObjectNode*)this ); 00408 spResult = EvaluateCast( context, spResult, m_mapPositions[ LID_NODE_START ].iLine, "At creating object: " + m_vecType[ 0 ] ); 00409 return CheckFalseResult( context, spResult, m_mapPositions[ LID_NODE_START ].iLine, "At creating object: " + m_vecType[ 0 ] ); 00410 } 00411 00412 //############################################################################################################################################## 00413 // 00414 // C L A S S : OclTree::CollectionNode <<< + OclTree::TreeNode 00415 // 00416 //============================================================================================================================================== 00417 // 00418 // D E S C R I P T I O N : 00419 // 00420 //############################################################################################################################################## 00421 00422 CollectionNode::CollectionNode( TreeManager* pManager ) 00423 : TreeNode( pManager, TreeNode::NK_COLLECTION ), m_strType( "" ) 00424 { 00425 } 00426 00427 CollectionNode::~CollectionNode() 00428 { 00429 if ( ! m_bTester && ! m_bSelfTester ) 00430 for ( unsigned int i = 0; i < m_vecNodes.size() ; i++ ) 00431 delete m_vecNodes[ i ]; 00432 } 00433 00434 std::string CollectionNode::Print( const std::string& strTabs ) const 00435 { 00436 return GetTreeManager()->m_pCAdaptor->Print( strTabs, (CollectionNode*)this ); 00437 } 00438 00439 bool CollectionNode::CheckImplementation( TypeContext& context ) 00440 { 00441 return GetTreeManager()->m_pCAdaptor->Check( context, (CollectionNode*)this ); 00442 } 00443 00444 OclMeta::Object CollectionNode::Evaluate( ObjectContext& context ) 00445 { 00446 OclMeta::Object spResult = GetTreeManager()->m_pCAdaptor->Evaluate( context, (CollectionNode*)this ); 00447 spResult = EvaluateCast( context, spResult, m_mapPositions[ LID_NODE_START ].iLine, "At creating collection: " + m_vecType[ 0 ] ); 00448 return CheckFalseResult( context, spResult, m_mapPositions[ LID_NODE_START ].iLine, "At creating collection: " + m_vecType[ 0 ] ); 00449 } 00450 00451 //############################################################################################################################################## 00452 // 00453 // C L A S S : OclNodes::DeclarationNode <<< + OclNodes::SyntaxTreeNode 00454 // 00455 //############################################################################################################################################## 00456 00457 DeclarationNode::DeclarationNode( TreeManager* pManager ) 00458 : TreeNode( pManager, TreeNode::NK_DECLARATION ), m_strName( "" ), m_strType( "" ), m_pValueNode( NULL ), m_pInnerNode( NULL ) 00459 { 00460 } 00461 00462 DeclarationNode::~DeclarationNode() 00463 { 00464 if ( ! m_bTester && ! m_bSelfTester ) { 00465 if ( m_pInnerNode ) 00466 delete m_pInnerNode; 00467 if ( m_pValueNode ) 00468 delete m_pValueNode; 00469 } 00470 } 00471 00472 std::string DeclarationNode::Print( const std::string& strTabs ) const 00473 { 00474 std::string strOut = strTabs + "<Declaration name=\"" + m_strName + "\" type=\"" + m_strType + "\">\r\n"; 00475 00476 strOut += strTabs + TABSTR + "<Variable>\r\n"; 00477 strOut += m_pValueNode->Print( strTabs + TABSTR + TABSTR ); 00478 strOut += strTabs + TABSTR + "</Variable>\r\n"; 00479 00480 strOut += strTabs + TABSTR + "<Expression>\r\n"; 00481 strOut += m_pInnerNode->Print( strTabs + TABSTR + TABSTR ); 00482 strOut += strTabs + TABSTR + "</Expression>\r\n"; 00483 00484 strOut += strTabs + "</Declaration>\r\n"; 00485 return strOut; 00486 } 00487 00488 void DeclarationNode::CheckInitialize() 00489 { 00490 TreeNode::CheckInitialize(); 00491 m_vecTypeDecl.clear(); 00492 } 00493 00494 bool DeclarationNode::CheckImplementation( TypeContext& context ) 00495 { 00496 // Check Expression of Declaration 00497 00498 if ( m_pValueNode->Check( context ) ) 00499 m_vecTypeDecl = m_pValueNode->m_vecType; 00500 00501 // Check explicit type of variable if it exists 00502 00503 if ( ! m_strType.empty() ) 00504 if ( ParseTypeSeq( context, m_mapPositions[ LID_VARIABLE_TYPE ], m_strType, m_vecTypeDecl ) ) 00505 if ( ! m_pValueNode->m_vecType.empty() ) 00506 if ( ! CastType( context, m_mapPositions[ LID_VARIABLE_TYPE ], m_pValueNode->m_vecType, m_vecTypeDecl ) ) 00507 m_vecTypeDecl.clear(); 00508 00509 00510 // Check if variable already exists , Add variable 00511 00512 if ( context.m_ctxTypes.ExistsVariable( m_strName ) ) 00513 ADDEX( EXCEPTION1( EX_VARIABLE_ALREADY_EXISTS, m_strName, m_mapPositions[ LID_VARIABLE_NAME ] ) ) 00514 else 00515 if ( ! m_vecTypeDecl.empty() ) 00516 context.m_ctxTypes.AddVariable( m_strName, m_vecTypeDecl, true ); 00517 00518 // Check Expression 00519 00520 if ( m_pInnerNode->Check( context ) ) 00521 m_vecType = m_pInnerNode->m_vecType; 00522 00523 // Remove Variable 00524 00525 if ( ! m_vecTypeDecl.empty() ) 00526 context.m_ctxTypes.RemoveVariable( m_strName ); 00527 00528 return ! m_vecType.empty() && ! m_pValueNode->m_vecType.empty(); 00529 } 00530 00531 OclMeta::Object DeclarationNode::Evaluate( ObjectContext& context ) 00532 { 00533 OclMeta::Object spObject = EvaluateCast( context, m_pValueNode->Evaluate( context ), m_mapPositions[ LID_NODE_START ].iLine, "let " + m_strName + " : " + m_vecTypeDecl[ 0 ] + " = ...", m_vecTypeDecl[ 0 ], m_strType.empty() ); 00534 00535 context.oCtx.AddVariable( m_strName, spObject, true ); 00536 OclMeta::Object spResult = m_pInnerNode->Evaluate( context ); 00537 context.oCtx.RemoveVariable( m_strName ); 00538 00539 return spResult; 00540 } 00541 00542 //############################################################################################################################################## 00543 // 00544 // C L A S S : OclTree::TypeCastNode <<< + OclTree::TreeNode 00545 // 00546 //============================================================================================================================================== 00547 // 00548 // D E S C R I P T I O N : 00549 // 00550 //############################################################################################################################################## 00551 00552 TypeCastNode::TypeCastNode( TreeManager* pManager ) 00553 : TreeNode( pManager, TreeNode::NK_TYPECAST ), m_pThisNode( NULL ), m_strType( "" ), m_bIsDynamic( false ) 00554 { 00555 } 00556 00557 TypeCastNode::~TypeCastNode() 00558 { 00559 if ( ! m_bTester ) 00560 if ( m_pThisNode ) 00561 delete m_pThisNode; 00562 } 00563 00564 std::string TypeCastNode::Print( const std::string& strTabs ) const 00565 { 00566 std::string strOut = strTabs + "<TypeCast type=\"" + m_strType + "\" dynamic=\"" + ( ( m_bIsDynamic ) ? "true" : "false" ) + "\">\r\n"; 00567 00568 strOut += strTabs + TABSTR + "<This>\r\n"; 00569 if ( m_pThisNode ) 00570 strOut += m_pThisNode->Print( strTabs + TABSTR + TABSTR ); 00571 strOut += strTabs + TABSTR + "</This>\r\n"; 00572 00573 strOut += strTabs + "</TypeCast>\r\n"; 00574 return strOut; 00575 } 00576 00577 void TypeCastNode::CheckInitialize() 00578 { 00579 if ( m_bSelfTester && m_pThisNode ) { 00580 delete m_pThisNode; 00581 m_pThisNode = NULL; 00582 } 00583 TreeNode::CheckInitialize(); 00584 } 00585 00586 bool TypeCastNode::CheckImplementation( TypeContext& context ) 00587 { 00588 bool bThisValid = true; 00589 if ( ! m_pThisNode ) { 00590 if ( context.m_vecImplicits.empty() ) 00591 return false; 00592 m_bSelfTester = true; 00593 m_pThisNode = CreateThis( context, -1 ); 00594 } 00595 else 00596 bThisValid = m_pThisNode->Check( context ); 00597 00598 if ( bThisValid ) { 00599 00600 // Check if Object Node is callable 00601 00602 if ( m_pThisNode->GetKind() == TreeNode::NK_OBJECT ) { 00603 ObjectNode* pONode = (ObjectNode*) m_pThisNode; 00604 if ( ! pONode->m_bCallable ) 00605 ADDEX( EXCEPTION1( EX_OBJECT_CALL_PROHIBITED, m_pThisNode->m_vecType[ 0 ], m_mapPositions[ LID_CALL_OPERATOR ] ) ); 00606 } 00607 00608 if ( ParseTypeSeq( context, m_mapPositions[ LID_FEATURE_NAME ], m_strType, m_vecType ) ) { 00609 if ( ! CastType( context, m_mapPositions[ LID_FEATURE_NAME ], m_pThisNode->m_vecType, m_vecType ) ) { 00610 m_vecType.clear(); 00611 return false; 00612 } 00613 return true; 00614 } 00615 } 00616 return false; 00617 } 00618 00619 OclMeta::Object TypeCastNode::Evaluate( ObjectContext& context ) 00620 { 00621 return EvaluateCast( context, m_pThisNode->Evaluate( context ), m_mapPositions[ LID_FEATURE_NAME ].iLine, "ocl::Any::oclAsType( ocl::Type )" , m_vecType[ 0 ], false ); 00622 } 00623 00624 //############################################################################################################################################## 00625 // 00626 // C L A S S : OclTree::IfThenElseNode <<< + OclTree::TreeNode 00627 // 00628 //############################################################################################################################################## 00629 00630 IfThenElseNode::IfThenElseNode( TreeManager* pManager ) 00631 : TreeNode( pManager, TreeNode::NK_IFTHENELSE ), m_pIfNode( NULL ), m_pThenNode( NULL ), m_pElseNode( NULL ) 00632 { 00633 } 00634 00635 IfThenElseNode::~IfThenElseNode() 00636 { 00637 if ( ! m_bTester && ! m_bSelfTester ) { 00638 if ( m_pIfNode ) 00639 delete m_pIfNode; 00640 if ( m_pThenNode ) 00641 delete m_pThenNode; 00642 if ( m_pElseNode ) 00643 delete m_pElseNode; 00644 } 00645 } 00646 00647 std::string IfThenElseNode::Print( const std::string& strTabs ) const 00648 { 00649 std::string strOut = strTabs + "<IfThenElse>\r\n"; 00650 00651 strOut += strTabs + TABSTR + "<IfExpression>\r\n"; 00652 strOut += m_pIfNode->Print( strTabs + TABSTR + TABSTR ); 00653 strOut += strTabs + TABSTR + "</IfExpression>\r\n"; 00654 00655 strOut += strTabs + TABSTR + "<ThenExpression>\r\n"; 00656 strOut += m_pThenNode->Print( strTabs + TABSTR + TABSTR ); 00657 strOut += strTabs + TABSTR + "</ThenExpression>\r\n"; 00658 00659 strOut += strTabs + TABSTR + "<ElseExpression>\r\n"; 00660 strOut += m_pElseNode->Print( strTabs + TABSTR + TABSTR ); 00661 strOut += strTabs + TABSTR + "</ElseExpression>\r\n"; 00662 00663 strOut += strTabs + "</IfThenElse>\r\n"; 00664 return strOut; 00665 } 00666 00667 bool IfThenElseNode::CheckImplementation( TypeContext& context ) 00668 { 00669 // Check if IF Expression returns kind of ocl::Boolean 00670 00671 bool bIfValid = m_pIfNode->Check( context ); 00672 if ( bIfValid ) { 00673 TypeSeq vecTypeB( 1, "ocl::Boolean" ); 00674 bIfValid = GetTreeManager()->GetTypeManager()->IsTypeA( m_pIfNode->m_vecType, vecTypeB ); 00675 if ( ! bIfValid ) 00676 ADDEX( EXCEPTION0( EX_BOOLEAN_REQUIRED, m_pIfNode->m_mapPositions[ LID_NODE_START ] ) ); 00677 } 00678 00679 // Check THEN and ELSE Expressions 00680 00681 bool bThenElseValid = m_pThenNode->Check( context ); 00682 bThenElseValid = m_pElseNode->Check( context ) && bThenElseValid; 00683 00684 // Check whether these Expression returns the same type 00685 00686 if ( bThenElseValid ) { 00687 if ( ! ( m_pThenNode->m_vecType[ 0 ] == m_pElseNode->m_vecType[ 0 ] ) ) { 00688 std::string strType1, strType2; 00689 OclCommon::Convert( m_pThenNode->m_vecType, strType1 ); 00690 OclCommon::Convert( m_pElseNode->m_vecType, strType2 ); 00691 ADDEX( EXCEPTION2( EX_IF_TYPE_MISMATCH, strType1, strType2, m_mapPositions[ LID_NODE_START ] ) ); 00692 return false; 00693 } 00694 if ( bIfValid ) { 00695 m_vecType = GetTreeManager()->GetTypeManager()->GetTypeBase( m_pThenNode->m_vecType, m_pElseNode->m_vecType ); 00696 return true; 00697 } 00698 } 00699 return false; 00700 } 00701 00702 OclMeta::Object IfThenElseNode::Evaluate( ObjectContext& context ) 00703 { 00704 OclMeta::Object spCondition = m_pIfNode->Evaluate( context ); 00705 if ( spCondition.IsUndefined() ) 00706 return spCondition; 00707 00708 DECL_BOOLEAN( bCondition, spCondition ); 00709 if ( bCondition ) 00710 return m_pThenNode->Evaluate( context ); 00711 else 00712 return m_pElseNode->Evaluate( context ); 00713 } 00714 00715 //############################################################################################################################################## 00716 // 00717 // C L A S S : OclTree::OperatorNode <<< + OclTree::TreeNode 00718 // 00719 //############################################################################################################################################## 00720 00721 OperatorNode::OperatorNode( TreeManager* pManager ) 00722 : TreeNode( pManager, TreeNode::NK_OPERATOR ), m_pOperandNode1( NULL ), m_pOperandNode2( NULL ), m_strName( "" ) 00723 { 00724 } 00725 00726 OperatorNode::~OperatorNode() 00727 { 00728 if ( ! m_bTester && ! m_bSelfTester ) { 00729 if ( m_pOperandNode1 ) 00730 delete m_pOperandNode1; 00731 if ( m_pOperandNode2 ) 00732 delete m_pOperandNode2; 00733 } 00734 } 00735 00736 std::string OperatorNode::Print( const std::string& strTabs ) const 00737 { 00738 std::string strOut = strTabs + "<Operator name=\"" + m_strName + "\">\r\n"; 00739 00740 strOut += strTabs + TABSTR + "<Operand1>\r\n"; 00741 strOut += m_pOperandNode1->Print( strTabs + TABSTR + TABSTR ); 00742 strOut += strTabs + TABSTR + "</Operand1>\r\n"; 00743 00744 if ( m_pOperandNode2 ) { 00745 strOut += strTabs + TABSTR + "<Operand2>\r\n"; 00746 strOut += m_pOperandNode2->Print( strTabs + TABSTR + TABSTR ); 00747 strOut += strTabs + TABSTR + "</Operand2>\r\n"; 00748 } 00749 00750 strOut += strTabs + "</Operator>\r\n"; 00751 return strOut; 00752 } 00753 00754 void OperatorNode::CheckInitialize() 00755 { 00756 TreeNode::CheckInitialize(); 00757 m_strAssignVarName = ""; 00758 } 00759 00760 bool OperatorNode::CheckImplementation( TypeContext& context ) 00761 { 00762 bool bIsValid = m_pOperandNode1->Check( context ); 00763 if ( m_pOperandNode2 ) 00764 bIsValid = m_pOperandNode2->Check( context ) && bIsValid; 00765 00766 if ( bIsValid ) { 00767 00768 /* 00769 This Feature is commented for the time being 00770 00771 // Assignment operator check 00772 00773 if ( m_strName == "=" && m_pOperandNode2 && m_pOperandNode1->GetKind() == TreeNode::NK_VARIABLE ) { 00774 VariableNode* pVariable = ( VariableNode* ) m_pOperandNode1; 00775 bool bAssignable = false; 00776 context.m_ctxTypes.IsAssignable( pVariable->m_strName, bAssignable ); 00777 if ( bAssignable ) { 00778 m_strAssignVarName = pVariable->m_strName; 00779 if ( ! GetTreeManager()->GetTypeManager()->IsTypeA( m_pOperandNode2->m_vecType, m_pOperandNode1->m_vecType ) ) { 00780 std::string strVarType, strValType; 00781 OclCommon::Convert( m_pOperandNode1->m_vecType , strVarType ); 00782 OclCommon::Convert( m_pOperandNode2->m_vecType , strValType ); 00783 ADDEX( EXCEPTION2( EX_ASSIGNMENT_TYPE_MISMATCH, strVarType, strValType, GetPos( LID_NODE_START ) ) ); 00784 return false; 00785 } 00786 m_vecType = m_pOperandNode1->m_vecType; 00787 return true; 00788 } 00789 } 00790 */ 00791 00792 // Any other operator check 00793 00794 OclMeta::Operator* pOperator = NULL; 00795 if ( ! m_pOperandNode2 ) { 00796 try { 00797 pOperator = GetTreeManager()->GetTypeManager()->GetOperator( OclSignature::Operator( m_strName, m_pOperandNode1->m_vecType[ 0 ] ) ); 00798 GetParametralTypeSeq( m_pOperandNode1->m_vecType, TypeSeq(), pOperator->GetReturnTypeSeq() ); 00799 return true; 00800 } 00801 catch ( OclCommon::Exception ex ) { 00802 SETEXPOS( ex, m_mapPositions[ LID_FEATURE_NAME ] ); 00803 ADDEX( ex ); 00804 return false; 00805 } 00806 } 00807 try { 00808 pOperator = GetTreeManager()->GetTypeManager()->GetOperator( OclSignature::Operator( m_strName, m_pOperandNode1->m_vecType[ 0 ], m_pOperandNode2->m_vecType[ 0 ] ) ); 00809 GetParametralTypeSeq( m_pOperandNode1->m_vecType, m_pOperandNode1->m_vecType, pOperator->GetReturnTypeSeq() ); 00810 return true; 00811 } 00812 catch ( OclCommon::Exception ex ) { 00813 SETEXPOS( ex, m_mapPositions[ LID_FEATURE_NAME ] ); 00814 ADDEX( ex ); 00815 return false; 00816 } 00817 } 00818 return false; 00819 } 00820 00821 OclMeta::Object OperatorNode::Evaluate( ObjectContext& context ) 00822 { 00823 OclSignature::Operator signature = ( ! m_pOperandNode2 ) ? OclSignature::Operator( m_strName, m_pOperandNode1->m_vecType[ 0 ] ) : OclSignature::Operator( m_strName, m_pOperandNode1->m_vecType[ 0 ], m_pOperandNode2->m_vecType[ 0 ] ); 00824 int iLineFeatureName = m_mapPositions[ LID_FEATURE_NAME ].iLine; 00825 00826 // Evaluation of Logical Operators 00827 00828 /* if ( m_pOperandNode1->IsBooleanReturned() && m_pOperandNode2 && m_pOperandNode2->IsBooleanReturned() && m_vecType[ 0 ] == "ocl::Boolean" ) { 00829 00830 if ( m_strName == "and" || m_strName == "&&" ) { 00831 OclMeta::Object spOperand1 = m_pOperandNode1->Evaluate( context ); 00832 if ( spOperand1.IsUndefined() ) { 00833 if ( m_strName == "and" || ! context.m_bShortCircuitLogical ) 00834 m_pOperandNode2->Evaluate( context ); 00835 return spOperand1; 00836 } 00837 DECL_BOOLEAN( bOperand1, spOperand1 ); 00838 if ( ! bOperand1 ) { 00839 if ( m_strName == "and" || ! context.m_bShortCircuitLogical ) { 00840 OclMeta::Object spOperand2 = m_pOperandNode2->Evaluate( context ); 00841 if ( spOperand2.IsUndefined() ) 00842 return spOperand2; 00843 } 00844 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 00845 } 00846 OclMeta::Object spOperand2 = m_pOperandNode2->Evaluate( context ); 00847 if ( spOperand2.IsUndefined() ) 00848 return spOperand2; 00849 DECL_BOOLEAN( bOperand2, spOperand2 ); 00850 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), bOperand2 ), iLineFeatureName, signature.Print() ); 00851 }*/ 00852 00853 // undef and/&& false = false and/&& undef = false 00854 // undef and/&& anything = undef 00855 if ( m_pOperandNode1->IsBooleanReturned() && m_pOperandNode2 && m_pOperandNode2->IsBooleanReturned() && m_vecType[ 0 ] == "ocl::Boolean" ) { 00856 00857 if ( m_strName == "and" || m_strName == "&&" ) { 00858 OclMeta::Object spOperand1 = m_pOperandNode1->Evaluate( context ); 00859 if ( ! spOperand1.IsUndefined() ) { 00860 DECL_BOOLEAN( bOperand1, spOperand1 ); 00861 if ( ! bOperand1 ) { 00862 if ( m_strName == "&&" || context.m_bShortCircuitLogical ) 00863 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 00864 } 00865 } 00866 OclMeta::Object spOperand2 = m_pOperandNode2->Evaluate( context ); 00867 if ( ! spOperand1.IsUndefined() && ! spOperand2.IsUndefined()) { 00868 DECL_BOOLEAN( bOperand1, spOperand1 ); 00869 DECL_BOOLEAN( bOperand2, spOperand2 ); 00870 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), bOperand1 && bOperand2 ), iLineFeatureName, signature.Print() ); 00871 } 00872 // cannot create UNDEFINED result 00873 else if (spOperand1.IsUndefined() && spOperand2.IsUndefined()) { 00874 return spOperand1; 00875 } 00876 else if (spOperand1.IsUndefined()) { 00877 DECL_BOOLEAN( bOperand2, spOperand2 ); 00878 if (bOperand2) 00879 return spOperand1; 00880 else 00881 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 00882 } 00883 else if (spOperand2.IsUndefined()) { 00884 DECL_BOOLEAN( bOperand1, spOperand1 ); 00885 if (bOperand1) 00886 return spOperand2; 00887 else 00888 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 00889 } 00890 } 00891 00892 00893 /* if ( m_strName == "or" || m_strName == "||" ) { 00894 OclMeta::Object spOperand1 = m_pOperandNode1->Evaluate( context ); 00895 if ( ! spOperand1.IsUndefined() ) { 00896 DECL_BOOLEAN( bOperand1, spOperand1 ); 00897 if ( bOperand1 ) { 00898 if ( m_strName == "or" || ! context.m_bShortCircuitLogical ) 00899 m_pOperandNode2->Evaluate( context ); 00900 return CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ); 00901 } 00902 } 00903 OclMeta::Object spOperand2 = m_pOperandNode2->Evaluate( context ); 00904 if ( spOperand2.IsUndefined() ) { 00905 if ( spOperand1.IsUndefined() ) 00906 return spOperand1; 00907 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 00908 } 00909 DECL_BOOLEAN( bOperand2, spOperand2 ); 00910 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), bOperand2 ), iLineFeatureName, signature.Print() ); 00911 }*/ 00912 00913 // true OR/|| UNDEF = UNDEF OR/|| true = true 00914 // UNDEF OR/|| anything = UNDEF 00915 if ( m_strName == "or" || m_strName == "||" ) { 00916 OclMeta::Object spOperand1 = m_pOperandNode1->Evaluate( context ); 00917 if ( ! spOperand1.IsUndefined() ) { 00918 DECL_BOOLEAN( bOperand1, spOperand1 ); 00919 if ( bOperand1 ) { 00920 if ( m_strName == "||" || context.m_bShortCircuitLogical ) 00921 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ), iLineFeatureName, signature.Print() ); 00922 } 00923 } 00924 OclMeta::Object spOperand2 = m_pOperandNode2->Evaluate( context ); 00925 if ( ! spOperand1.IsUndefined() && ! spOperand2.IsUndefined()) { 00926 DECL_BOOLEAN( bOperand1, spOperand1 ); 00927 DECL_BOOLEAN( bOperand2, spOperand2 ); 00928 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), bOperand1 || bOperand2 ), iLineFeatureName, signature.Print() ); 00929 } 00930 else if (spOperand1.IsUndefined() && spOperand2.IsUndefined() ) 00931 return spOperand1; 00932 else if (spOperand1.IsUndefined()) { 00933 DECL_BOOLEAN( bOperand2, spOperand2 ); 00934 if (!bOperand2) 00935 return spOperand1; 00936 else 00937 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ), iLineFeatureName, signature.Print() ); 00938 } 00939 else if (spOperand2.IsUndefined()) { 00940 DECL_BOOLEAN( bOperand1, spOperand1 ); 00941 if (!bOperand1) 00942 return spOperand2; 00943 else 00944 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ), iLineFeatureName, signature.Print() ); 00945 } 00946 } 00947 00948 00949 00950 /* if ( m_strName == "implies" || m_strName == "=>" ) { 00951 OclMeta::Object spOperand1 = m_pOperandNode1->Evaluate( context ); 00952 if ( spOperand1.IsUndefined() ) 00953 return spOperand1; 00954 DECL_BOOLEAN( bOperand1, spOperand1 ); 00955 if ( ! bOperand1 ) { 00956 if ( m_strName == "implies" || ! context.m_bShortCircuitLogical ) 00957 m_pOperandNode2->Evaluate( context ); 00958 return CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ); 00959 } 00960 OclMeta::Object spOperand2 = m_pOperandNode2->Evaluate( context ); 00961 if ( spOperand2.IsUndefined() ) 00962 return spOperand2; 00963 DECL_BOOLEAN( bOperand2, spOperand2 ); 00964 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), bOperand2 ), iLineFeatureName, signature.Print() ); 00965 } 00966 }*/ 00967 00968 // FALSE =>/implies anything - true 00969 // anything =>/implies TRUE - true 00970 if ( m_strName == "implies" || m_strName == "=>" ) { 00971 OclMeta::Object spOperand1 = m_pOperandNode1->Evaluate( context ); 00972 if ( !spOperand1.IsUndefined() ) { 00973 DECL_BOOLEAN( bOperand1, spOperand1 ); 00974 if (! bOperand1) { 00975 if ( m_strName == "=>" || context.m_bShortCircuitLogical ) 00976 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ), iLineFeatureName, signature.Print() ); 00977 } 00978 } 00979 OclMeta::Object spOperand2 = m_pOperandNode2->Evaluate( context ); 00980 if ( ! spOperand1.IsUndefined() && ! spOperand2.IsUndefined()) { 00981 DECL_BOOLEAN( bOperand1, spOperand1 ); 00982 DECL_BOOLEAN( bOperand2, spOperand2 ); 00983 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), !bOperand1 || bOperand2), iLineFeatureName, signature.Print() ); 00984 } 00985 else if (spOperand1.IsUndefined() && spOperand2.IsUndefined() ) 00986 return spOperand1; 00987 else if (spOperand1.IsUndefined()) { 00988 DECL_BOOLEAN( bOperand2, spOperand2 ); 00989 if (!bOperand2) 00990 return spOperand1; 00991 else 00992 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true), iLineFeatureName, signature.Print() ); 00993 } 00994 else if (spOperand2.IsUndefined()) { 00995 DECL_BOOLEAN( bOperand1, spOperand1 ); 00996 if (bOperand1) 00997 return spOperand2; 00998 else 00999 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ), iLineFeatureName, signature.Print() ); 01000 } 01001 } 01002 } 01003 01004 OclMeta::Object spOperand1 = m_pOperandNode1->Evaluate( context ); 01005 OclMeta::Object spOperand2; 01006 01007 /* 01008 // Evaluation of Assignment 01009 01010 if ( ! m_strAssignVarName.empty() ) { 01011 operand2 = EvaluateAndCast( context, m_pOperandNode2, LID_NODE_START, signature.Print(), m_pOperandNode1->m_vecType[ 0 ] ); 01012 context.oCtx.SetVariable( m_strAssignVarName, operand2 ); 01013 if ( bIsBoolean && ! operand2.IsUndefined() && context.bDoSnapshot ) { 01014 DECL_BOOLEAN( bResult, operand2 ); 01015 if ( ! bResult ) 01016 AddViolation( context, false, LID_FEATURE_NAME, signature.Print() ); 01017 } 01018 return operand2; 01019 } 01020 */ 01021 01022 // Evaluation of Equality and non equality 01023 01024 if ( m_pOperandNode2 ) 01025 spOperand2 = m_pOperandNode2->Evaluate( context ); 01026 01027 if ( ( m_strName == "==" || m_strName == "=" ) && m_pOperandNode2 && m_vecType[ 0 ] == "ocl::Boolean" ) { 01028 if ( spOperand1.IsUndefined() ) 01029 if ( spOperand2.IsUndefined() ) 01030 return CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ); 01031 else 01032 CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 01033 else 01034 if ( spOperand2.IsUndefined() ) 01035 CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 01036 } 01037 01038 if ( ( m_strName == "!=" || m_strName == "<>" ) && m_pOperandNode2 && m_vecType[ 0 ] == "ocl::Boolean" ) { 01039 if ( spOperand1.IsUndefined() ) 01040 if ( spOperand2.IsUndefined() ) 01041 CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), false ), iLineFeatureName, signature.Print() ); 01042 else 01043 return CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ); 01044 else 01045 if ( spOperand2.IsUndefined() ) 01046 return CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), true ); 01047 } 01048 01049 // Evaluation of any kind of operators 01050 01051 if ( spOperand1.IsUndefined() || m_pOperandNode2 && spOperand2.IsUndefined() ) 01052 return OclMeta::Object::UNDEFINED; 01053 01054 EVALTRY { 01055 OclMeta::Operator* pOperator = GetTreeManager()->GetTypeManager()->GetOperator( signature ); 01056 OclImplementation::Operator* pIOperator = pOperator->GetImplementation(); 01057 if ( ! pIOperator ) 01058 THROWOCL0( ET_RUNTIME, EX_OPERATOR_NOT_IMPLEMENTED ); 01059 01060 OclMeta::ObjectVector vecOperands( 1, spOperand1 ); 01061 if ( m_pOperandNode2 ) 01062 vecOperands.push_back( spOperand2 ); 01063 pIOperator->SetArguments( vecOperands ); 01064 pIOperator->Initialize(); 01065 01066 (*pIOperator)(); 01067 01068 OclMeta::Object spResult = EvaluateCast( context, pIOperator->GetResult(), iLineFeatureName, signature.Print() ); 01069 pIOperator->Finalize(); 01070 01071 return CheckFalseResult( context, spResult, iLineFeatureName, signature.Print() ); 01072 } EVALCATCH( iLineFeatureName, signature.Print() ); 01073 return OclMeta::Object::UNDEFINED; 01074 } 01075 01076 //############################################################################################################################################## 01077 // 01078 // C L A S S : OclTree::IteratorNode <<< + OclTree::TreeNode 01079 // 01080 //############################################################################################################################################## 01081 int IteratorNode::m_iteratorLevel = 0; 01082 01083 IteratorNode::IteratorNode( TreeManager* pManager ) 01084 : TreeNode( pManager, TreeNode::NK_ITERATOR ), m_strName( "" ), m_pThisNode( NULL ), m_pArgumentNode( NULL ), m_strDeclType( "" ), m_strCallOperator( "" ), m_strAccuName( "" ), m_strAccuType( "" ), m_pAccuNode( NULL ) 01085 { 01086 } 01087 01088 IteratorNode::~IteratorNode() 01089 { 01090 if ( ! m_bTester ) { 01091 if ( m_pThisNode ) 01092 delete m_pThisNode; 01093 if ( m_pArgumentNode ) 01094 delete m_pArgumentNode; 01095 if ( m_pAccuNode ) 01096 delete m_pAccuNode; 01097 } 01098 } 01099 01100 std::string IteratorNode::Print( const std::string& strTabs ) const 01101 { 01102 std::string strOut = strTabs + "<Iterator name=\"" + m_strName + "\">\r\n"; 01103 01104 if ( m_vecDeclarators.size() > 0 ) { 01105 strOut += strTabs + TABSTR + "<Declarators type=\"" + m_strDeclType + "\">\r\n" + strTabs + TABSTR + TABSTR; 01106 for ( unsigned int i = 0 ; i < m_vecDeclarators.size() ; i++ ) 01107 strOut += m_vecDeclarators[ i ] + " "; 01108 strOut += "\r\n" + strTabs + TABSTR + "</Declarators>\r\n"; 01109 } 01110 01111 if ( m_pAccuNode ) { 01112 strOut += strTabs + TABSTR + "<Accumulator type=\"" + m_strAccuType + "\">\r\n"; 01113 strOut += m_pAccuNode->Print( strTabs + TABSTR + TABSTR ); 01114 strOut += strTabs + TABSTR + "</Accumulator>\r\n"; 01115 } 01116 01117 strOut += strTabs + TABSTR + "<This>\r\n"; 01118 if ( m_pThisNode ) 01119 strOut += m_pThisNode->Print( strTabs + TABSTR + TABSTR ); 01120 strOut += strTabs + TABSTR + "</This>\r\n"; 01121 01122 strOut += strTabs + TABSTR + "<Argument>\r\n"; 01123 strOut += m_pArgumentNode->Print( strTabs + TABSTR + TABSTR ); 01124 strOut += strTabs + TABSTR + "</Argument>\r\n"; 01125 01126 strOut += strTabs + "</Method>\r\n"; 01127 01128 return strOut; 01129 } 01130 01131 void IteratorNode::CheckInitialize() 01132 { 01133 if ( m_bSelfTester && ! m_bTester && m_pThisNode ) { 01134 delete m_pThisNode; 01135 m_pThisNode = NULL; 01136 } 01137 TreeNode::CheckInitialize(); 01138 if ( ! m_vecDeclarators.empty() && m_vecDeclarators[ 0 ].substr( 0, 1 ) == "!" ) 01139 m_vecDeclarators.clear(); 01140 } 01141 01142 bool IteratorNode::CheckImplementation( TypeContext& context ) 01143 { 01144 // Iterator cannot be called by . 01145 01146 if ( m_strCallOperator == "." ) 01147 ADDEX( EXCEPTION1( EX_INVALID_CALL, m_strCallOperator, m_mapPositions[ LID_CALL_OPERATOR ] ) ); 01148 01149 // Check This if exists 01150 01151 if ( m_pThisNode ) { 01152 bool bThisValid = m_bTester || m_pThisNode->Check( context ); 01153 if ( bThisValid ) 01154 return CheckIterator( context ); 01155 return false; 01156 } 01157 01158 m_bSelfTester = true; 01159 01160 // Check Implicits variables 01161 01162 for ( int i = context.m_vecImplicits.size() - 1 ; i >= 0 ; i-- ) { 01163 01164 TypeContext contextIterator( context.m_namespace); 01165 CheckInitialize(); 01166 m_pThisNode = CreateThis( context, i ); 01167 if ( CheckIterator( contextIterator ) ) 01168 return true; 01169 else { 01170 delete m_pThisNode; 01171 m_pThisNode = NULL; 01172 int iLastCode = GetLastExceptionCode( contextIterator ); 01173 if ( iLastCode != EX_ITERATOR_DOESNT_EXIST && iLastCode != EX_TYPE_NOT_COMPOUND_ITERATOR && iLastCode != -1 ) { 01174 ADDEXP( contextIterator.m_poolExceptions ); 01175 return false; 01176 } 01177 } 01178 } 01179 ADDEX( EXCEPTION1( EX_IMPL_ITER_DOESNT_EXIST, m_strName + "( ... | ... )", m_mapPositions[ LID_FEATURE_NAME ] ) ); 01180 return false; 01181 } 01182 01183 bool IteratorNode::CheckIterator( TypeContext& context ) 01184 { 01185 01186 std::shared_ptr<OclMeta::Type> pType = GetTreeManager()->GetTypeManager()->GetType( m_pThisNode->m_vecType[ 0 ], context.m_namespace ); 01187 01188 // Not compound Type cannot have iterators 01189 01190 if ( ! pType->IsCompound() ) { 01191 ADDEX( EXCEPTION1( EX_TYPE_NOT_COMPOUND_ITERATOR, pType->GetName(), m_mapPositions[ LID_NODE_START ] ) ); 01192 return false; 01193 } 01194 m_vecTypeDecl = m_pThisNode->m_vecType; 01195 m_vecTypeDecl.erase( m_vecTypeDecl.begin() ); 01196 01197 // Check Type of Declaration if it exists 01198 01199 if ( ! m_strDeclType.empty() ) { 01200 TypeSeq vecType; 01201 if ( ParseTypeSeq( context, m_mapPositions[ LID_DECLARATOR_TYPE ], m_strDeclType, vecType ) ) 01202 if ( CastType( context, m_mapPositions[ LID_DECLARATOR_TYPE ], m_vecTypeDecl, vecType ) ) 01203 m_vecTypeDecl = vecType; 01204 } 01205 01206 // Check Accu expression and set accumulator type 01207 01208 if ( m_pAccuNode && m_pAccuNode->Check( context ) ) { 01209 m_vecTypeAccu = m_pAccuNode->m_vecType; 01210 01211 if ( ! m_strAccuType.empty() ) { 01212 TypeSeq vecType; 01213 if ( ParseTypeSeq( context, m_mapPositions[ LID_ACCUMULATOR_TYPE ], m_strAccuType, vecType ) ) 01214 if ( CastType( context, m_mapPositions[ LID_ACCUMULATOR_TYPE ], m_vecTypeAccu, vecType ) ) 01215 m_vecTypeAccu = vecType; 01216 } 01217 } 01218 01219 // Create implicit iterator variable if it is necessary 01220 01221 if ( m_vecDeclarators.empty() ) { 01222 char chBuffer[ 20 ]; 01223 sprintf_s( chBuffer, sizeof(chBuffer), "!iter%ld", context.m_vecImplicits.size() ); 01224 m_vecDeclarators.push_back( std::string( chBuffer ) ); 01225 context.m_vecImplicits.push_back( std::string( chBuffer ) ); 01226 } 01227 01228 // Check and Add Declarators 01229 01230 std::vector< bool > vecDeclDone( m_vecDeclarators.size(), true ); 01231 01232 if ( ! m_vecTypeDecl.empty() ) { 01233 for ( unsigned int i = 0 ; i < m_vecDeclarators.size() ; i++ ) { 01234 vecDeclDone[ i ] = context.m_ctxTypes.AddVariable( m_vecDeclarators[ i ], m_vecTypeDecl, true ); 01235 if ( ! vecDeclDone[ i ] ) 01236 ADDEX( EXCEPTION1( EX_VARIABLE_ALREADY_EXISTS, m_vecDeclarators[ i ], m_mapPositions[ LID_DECLARATOR_NAME + i ] ) ); 01237 } 01238 } 01239 01240 // Check and Add Accumulator 01241 01242 bool bAccuAdded = false; 01243 if ( ! m_vecTypeAccu.empty() ) { 01244 if ( context.m_ctxTypes.AddVariable( m_strAccuName, m_vecTypeAccu, true ) ) 01245 bAccuAdded = true; 01246 else 01247 ADDEX( EXCEPTION1( EX_VARIABLE_ALREADY_EXISTS, m_strAccuName, m_mapPositions[ LID_ACCUMULATOR_NAME ] ) ); 01248 } 01249 01250 // Check Argument 01251 01252 bool bArgumentValid = m_bTester && ! m_pArgumentNode->m_vecType.empty() || ! m_vecTypeDecl.empty() && m_pArgumentNode->Check( context ); 01253 01254 // Check if Iterator exists 01255 01256 if ( bArgumentValid ) { 01257 01258 if ( ! m_pAccuNode ) { 01259 01260 // It is predefined iterator 01261 01262 try { 01263 OclMeta::CompoundType* pCType = (OclMeta::CompoundType*) pType.get(); 01264 OclMeta::Iterator* pIterator = pCType->GetIterator(0, OclSignature::Iterator( m_strName, m_pThisNode->m_vecType[ 0 ], m_pArgumentNode->m_vecType[ 0 ] ) ); 01265 GetParametralTypeSeq( m_pThisNode->m_vecType, m_pArgumentNode->m_vecType, pIterator->GetReturnTypeSeq() ); 01266 } 01267 catch ( OclCommon::Exception ex ) { 01268 SETEXPOS( ex, m_mapPositions[ LID_FEATURE_NAME ] ); 01269 ADDEX( ex ); 01270 } 01271 } 01272 else { 01273 01274 // It is generic iterator 01275 01276 CastType( context, m_mapPositions[ LID_ACCUMULATOR_TYPE ], m_vecTypeAccu, m_pArgumentNode->m_vecType ); 01277 m_vecType = m_vecTypeAccu; 01278 } 01279 } 01280 01281 // Remove Declarators 01282 01283 if ( ! m_vecTypeDecl.empty() ) { 01284 for ( unsigned int i = 0 ; i < m_vecDeclarators.size() ; i++ ) 01285 if ( vecDeclDone[ i ] ) 01286 context.m_ctxTypes.RemoveVariable( m_vecDeclarators[ i ] ); 01287 } 01288 01289 // Remove Accumulator 01290 01291 if ( bAccuAdded ) 01292 context.m_ctxTypes.RemoveVariable( m_strAccuName ); 01293 01294 // Remove Implicit variable if it was 01295 01296 if ( m_vecDeclarators[ 0 ].substr( 0, 1 ) == "!" ) { 01297 context.m_vecImplicits.pop_back(); 01298 } 01299 01300 return ! m_vecType.empty(); 01301 } 01302 01303 OclMeta::Object IteratorNode::Evaluate( ObjectContext& context ) 01304 { 01305 // recursion corrected: terge 01306 LevelCounter level(&m_iteratorLevel); 01307 01308 int iLineFeatureName = m_mapPositions[ LID_FEATURE_NAME ].iLine; 01309 OclSignature::Iterator signature( m_strName, m_pThisNode->m_vecType[ 0 ], m_pArgumentNode->m_vecType[ 0 ] ); 01310 01311 OclMeta::Object objectThis = m_pThisNode->Evaluate( context ); 01312 01313 if ( objectThis.IsUndefined() ) 01314 return OclMeta::Object::UNDEFINED; 01315 01316 EVALTRY { 01317 OclImplementation::Iterator* pIIterator = NULL; 01318 if ( ! m_pAccuNode ) { 01319 OclMeta::CompoundType* pCType = (OclMeta::CompoundType*) GetTreeManager()->GetTypeManager()->GetType( objectThis.GetStaticTypeName(), NILNAMESPACE ).get(); 01320 OclMeta::Iterator* pIterator = pCType->GetIterator(m_iteratorLevel, signature ); 01321 pIIterator = pIterator->GetImplementation(); 01322 if ( ! pIIterator ) 01323 THROWOCL0( ET_RUNTIME, EX_ITERATOR_NOT_IMPLEMENTED ); 01324 01325 pIIterator->Initialize(); 01326 pIIterator->SetThis( objectThis ); 01327 } 01328 else { 01329 OclMeta::Object accumulator = EvaluateCast( context, m_pAccuNode->Evaluate( context ), m_mapPositions[ LID_ACCUMULATOR_TYPE ].iLine, m_strAccuName + " = ...", m_vecType[ 0 ], m_strAccuType.empty() ); 01330 context.oCtx.AddVariable( m_strAccuName, accumulator, true ); 01331 } 01332 01333 OclMeta::ObjectVector vecArguments( m_vecDeclarators.size(), OclMeta::Object::UNDEFINED ); 01334 01335 Iterate( context, pIIterator, objectThis, vecArguments, 0 ); 01336 01337 OclMeta::Object spResult; 01338 if ( ! m_pAccuNode ) { 01339 spResult = pIIterator->GetResult(); 01340 pIIterator->Finalize(); 01341 } 01342 else { 01343 context.oCtx.GetVariable( m_strAccuName, spResult ); 01344 context.oCtx.RemoveVariable( m_strAccuName ); 01345 } 01346 spResult = EvaluateCast( context, spResult, iLineFeatureName, signature.Print() ); 01347 return CheckFalseResult( context, spResult, iLineFeatureName, signature.Print() ); 01348 } EVALCATCH( iLineFeatureName, signature.Print() ); 01349 return OclMeta::Object::UNDEFINED; 01350 } 01351 01352 bool IteratorNode::Iterate( ObjectContext& context, OclImplementation::Iterator* pIIterator, OclMeta::Object& objectThis, OclMeta::ObjectVector& vecArguments, int iDeclNum ) 01353 { 01354 int iLineFeatureName = m_mapPositions[ LID_FEATURE_NAME ].iLine; 01355 OclSignature::Iterator signature( m_strName, m_pThisNode->m_vecType[ 0 ], m_pArgumentNode->m_vecType[ 0 ] ); 01356 01357 std::string strDecl = m_vecDeclarators[ iDeclNum ]; 01358 context.oCtx.AddVariable( strDecl, OclMeta::Object::UNDEFINED, true ); 01359 01360 DECL_ITERATOR( iterator, objectThis ); 01361 OclMeta::Object objectIter; 01362 01363 bool bDoStop = false; 01364 01365 while ( iterator->HasNext() && ( ! bDoStop || ! context.m_bShortCircuitIterator ) ) { 01366 01367 objectIter = iterator->GetNext(); 01368 if ( ! m_strDeclType.empty() ) 01369 objectIter = EvaluateCast( context, objectIter, m_mapPositions[ LID_DECLARATOR_TYPE ].iLine, signature.Print(), m_vecTypeDecl[ 0 ], false ); 01370 context.oCtx.SetVariable( strDecl, objectIter ); 01371 vecArguments[ iDeclNum ] = objectIter; 01372 01373 if ( iDeclNum == (int)m_vecDeclarators.size() - 1 ) { 01374 EVALTRY { 01375 OclMeta::Object spAccu = m_pArgumentNode->Evaluate( context ); // evaluate the argument 01376 if ( ! m_pAccuNode ) { 01377 pIIterator->SetArguments( vecArguments ); 01378 pIIterator->SetSubResult( spAccu ); 01379 pIIterator->SetSubOriResult( objectIter ); 01380 (*pIIterator)(); 01381 if ( pIIterator->DoStop() ) 01382 bDoStop = true; 01383 } 01384 else 01385 context.oCtx.SetVariable( m_strAccuName, spAccu ); 01386 } EVALCATCH( iLineFeatureName, signature.Print() ); 01387 } 01388 else 01389 bDoStop = Iterate( context, pIIterator, objectThis, vecArguments, iDeclNum + 1 ); 01390 } 01391 context.oCtx.RemoveVariable( strDecl ); 01392 return bDoStop; 01393 } 01394 01395 //############################################################################################################################################## 01396 // 01397 // C L A S S : OclTree::MethodNode <<< + OclTree::TreeNode 01398 // 01399 //############################################################################################################################################## 01400 int MethodNode::m_stackLevel = 0; 01401 01402 MethodNode::MethodNode( TreeManager* pManager ) 01403 : TreeNode( pManager, TreeNode::NK_METHOD ), m_strName( "" ), m_pThisNode( NULL ), m_strCallOperator( "" ), m_pIterator( NULL ) 01404 { 01405 } 01406 01407 MethodNode::~MethodNode() 01408 { 01409 if ( ! m_bTester && ! m_bSelfTester ) { 01410 delete m_pThisNode; 01411 for ( unsigned int i = 0 ; i < m_vecArguments.size() ; i++ ) 01412 delete m_vecArguments[ i ]; 01413 } 01414 if ( m_pIterator ) { 01415 delete m_pIterator; 01416 m_pIterator = NULL; 01417 } 01418 } 01419 01420 std::string MethodNode::Print( const std::string& strTabs ) const 01421 { 01422 if ( m_pIterator ) 01423 return m_pIterator->Print( strTabs ); 01424 01425 std::string strOut = strTabs + "<Method name=\"" + m_strName + "\">\r\n"; 01426 01427 strOut += strTabs + TABSTR + "<This>\r\n"; 01428 strOut += m_pThisNode->Print( strTabs + TABSTR + TABSTR ); 01429 strOut += strTabs + TABSTR + "</This>\r\n"; 01430 01431 if ( ! m_vecArguments.empty() ) { 01432 for ( unsigned int i = 0 ; i < m_vecArguments.size() ; i++ ) { 01433 char chNum[ 100 ]; 01434 sprintf_s( chNum, sizeof(chNum), "%lu", i ); 01435 strOut += strTabs + TABSTR + "<Argument_" + std::string( chNum ) + ">\r\n"; 01436 strOut += m_vecArguments[ i ]->Print( strTabs + TABSTR + TABSTR ); 01437 strOut += strTabs + TABSTR + "</Argument_" + std::string( chNum ) + ">\r\n"; 01438 } 01439 } 01440 01441 strOut += strTabs + "</Method>\r\n"; 01442 return strOut; 01443 } 01444 01445 void MethodNode::CheckInitialize() 01446 { 01447 TreeNode::CheckInitialize(); 01448 if ( m_pIterator ) { 01449 m_pIterator->m_bTester = true; 01450 delete m_pIterator; 01451 m_pIterator = NULL; 01452 } 01453 } 01454 01455 bool MethodNode::CheckImplementation( TypeContext& context ) 01456 { 01457 // Check Self 01458 01459 bool bThisValid = m_bTester || m_pThisNode->Check( context ); 01460 01461 // Check whether it is IsUndefined method 01462 01463 if ( m_strName == "isUndefined" && m_vecArguments.empty() ) { 01464 m_vecType = TypeSeq( 1, "ocl::Boolean" ); 01465 return true; 01466 } 01467 01468 if ( bThisValid ) { 01469 01470 OclMeta::Type* pType = GetTreeManager()->GetTypeManager()->GetType( m_pThisNode->m_vecType[ 0 ], context.m_namespace ).get(); 01471 01472 // Check if Object Node is callable 01473 01474 if ( m_pThisNode->GetKind() == TreeNode::NK_OBJECT ) { 01475 ObjectNode* pONode = (ObjectNode*) m_pThisNode; 01476 if ( ! pONode->m_bCallable ) 01477 ADDEX( EXCEPTION1( EX_OBJECT_CALL_PROHIBITED, m_pThisNode->m_vecType[ 0 ], m_mapPositions[ LID_CALL_OPERATOR ] ) ); 01478 } 01479 01480 // Check member selection operator 01481 01482 if ( m_strCallOperator == "->" && ! pType->IsCompound() ) 01483 ADDEX( EXCEPTION1( EX_TYPE_NOT_COMPOUND_ITERATOR, pType->GetName(), m_mapPositions[ LID_CALL_OPERATOR ] ) ); 01484 01485 // Check method exists 01486 01487 if ( ! pType->IsCompound() || m_vecArguments.size() != 1 ) { 01488 01489 bool bArgumentsValid = true; 01490 unsigned int i; 01491 for ( i = 0 ; i < m_vecArguments.size() ; i++ ) 01492 bArgumentsValid = m_vecArguments[ i ]->Check( context ) && bArgumentsValid; 01493 01494 if ( bArgumentsValid ) { 01495 StringVector vecTypes; 01496 for ( i = 0 ; i < m_vecArguments.size() ; i++ ) 01497 vecTypes.push_back( m_vecArguments[ i ]->m_vecType[ 0 ] ); 01498 OclSignature::Method sigMethod( m_strName, pType->GetName(), vecTypes ); 01499 01500 try { 01501 OclMeta::Method* pMethod = pType->GetMethod( sigMethod ); 01502 GetParametralTypeSeq( m_pThisNode->m_vecType, ( m_vecArguments.empty() ) ? TypeSeq() : m_vecArguments[ 0 ]->m_vecType, pMethod->GetReturnTypeSeq() ); 01503 if ( pMethod->IsDependence() ) 01504 context.m_setDependencies.insert( OclMeta::Dependency( sigMethod.Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 01505 return true; 01506 } 01507 catch ( OclCommon::Exception ex ) { 01508 SETEXPOS( ex, m_mapPositions[ LID_FEATURE_NAME ] ); 01509 ADDEX( ex ); 01510 return false; 01511 } 01512 } 01513 return false; 01514 01515 } 01516 01517 // Try argument as method argument 01518 01519 TypeContext contextMethod = context; 01520 contextMethod.m_poolExceptions.Clear(); 01521 bool bMethodValid = m_vecArguments[ 0 ]->Check( contextMethod ); 01522 TypeSeq vecTypeMethod = m_vecArguments[ 0 ]->m_vecType; 01523 01524 // Try argument as iterator body expression 01525 01526 TypeContext contextIterator = context; 01527 contextIterator.m_poolExceptions.Clear(); 01528 01529 // Add new implicit iterator variable 01530 01531 TypeSeq vecType = m_pThisNode->m_vecType; 01532 vecType.erase( vecType.begin() ); 01533 char chBuffer[ 20 ]; 01534 sprintf_s( chBuffer, sizeof(chBuffer), "!iter%lu", contextIterator.m_vecImplicits.size() ); 01535 contextIterator.m_ctxTypes.AddVariable( std::string( chBuffer ), vecType, true ); 01536 contextIterator.m_vecImplicits.push_back( std::string( chBuffer ) ); 01537 01538 // Check the iterator 01539 01540 bool bIteratorValid = m_vecArguments[ 0 ]->Check( contextIterator ); 01541 01542 // Remove the newly created implicit iterator 01543 01544 contextIterator.m_ctxTypes.RemoveVariable( std::string( chBuffer ) ); 01545 contextIterator.m_vecImplicits.pop_back(); 01546 01547 TypeSeq vecTypeIterator = m_vecArguments[ 0 ]->m_vecType; 01548 01549 if ( bMethodValid ) { 01550 std::vector<OclMeta::Type*> vecTypes( 2, pType ); 01551 01552 OclSignature::Method sigMethod( m_strName, pType->GetName(), StringVector( 1, vecTypeMethod[ 0 ] ) ); 01553 OclSignature::Iterator sigIterator( m_strName, pType->GetName(), vecTypeMethod[ 0 ] ); 01554 std::vector<OclSignature::Feature*> vecSignatures( 2, &sigMethod ); vecSignatures[ 1 ] = &sigIterator; 01555 01556 std::vector<int> vecCodes( 3, EX_METHOD_AMBIGUOUS ); vecCodes[ 1 ] = EX_ITERATOR_AMBIGUOUS; vecCodes[ 2 ] = EX_METHOD_ITERATOR_AMBIGUOUS; 01557 01558 OclCommon::ExceptionPool poolResult; 01559 01560 int iPrecedence = ( m_strCallOperator.empty() ) ? 0 : ( m_strCallOperator == "." ) ? -1 : 1; 01561 01562 OclMeta::Feature* pFeature = CheckAmbiguity( vecTypes, vecSignatures, vecCodes, iPrecedence, poolResult ); 01563 if ( ! pFeature ) { 01564 ADDEXP( poolResult ); 01565 return false; 01566 } 01567 else { 01568 if ( iPrecedence == -1 ) { 01569 ADDEXP( contextMethod.m_poolExceptions ); 01570 TypeContext contextTemp = context; 01571 m_vecArguments[ 0 ]->Check( contextTemp ); 01572 GetParametralTypeSeq( m_pThisNode->m_vecType, vecTypeMethod, pFeature->GetReturnTypeSeq() ); 01573 if ( pFeature->IsDependence() ) 01574 context.m_setDependencies.insert( OclMeta::Dependency( sigMethod.Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 01575 return true; 01576 } 01577 else { 01578 ADDEXP( contextIterator.m_poolExceptions ); 01579 if ( ! bIteratorValid ) 01580 return false; 01581 if ( vecTypeMethod != vecTypeIterator ) 01582 return false; 01583 m_pIterator= GetTreeManager()->CreateIterator(); 01584 m_pIterator->m_bTester = true; 01585 m_pIterator->m_pThisNode = m_pThisNode; 01586 m_pIterator->m_strCallOperator = "->"; 01587 m_pIterator->m_strName = m_strName; 01588 m_pIterator->m_vecDeclarators; 01589 m_pIterator->m_mapPositions = m_mapPositions; 01590 m_pIterator->m_pArgumentNode = m_vecArguments[ 0 ]; 01591 01592 m_pIterator->Check( context ); 01593 m_pIterator->m_bTester = false; 01594 m_bSelfTester = true; 01595 m_vecType = m_pIterator->m_vecType; 01596 return true; 01597 } 01598 } 01599 } 01600 if ( bIteratorValid ) { 01601 std::vector<OclMeta::Type*> vecTypes( 2, pType ); 01602 01603 OclSignature::Iterator sigIterator( m_strName, pType->GetName(), vecTypeIterator[ 0 ] ); 01604 OclSignature::Method sigMethod( m_strName, pType->GetName(), StringVector( 1, vecTypeIterator[ 0 ] ) ); 01605 std::vector<OclSignature::Feature*> vecSignatures( 2, &sigIterator ); vecSignatures[ 1 ] = &sigMethod; 01606 01607 std::vector<int> vecCodes( 3, EX_ITERATOR_AMBIGUOUS ); vecCodes[ 1 ] = EX_METHOD_AMBIGUOUS; vecCodes[ 2 ] = EX_METHOD_ITERATOR_AMBIGUOUS; 01608 01609 OclCommon::ExceptionPool poolResult; 01610 01611 int iPrecedence = 0; 01612 01613 OclMeta::Feature* pFeature = CheckAmbiguity( vecTypes, vecSignatures, vecCodes, iPrecedence, poolResult ); 01614 if ( ! pFeature ) { 01615 ADDEXP( poolResult ); 01616 return false; 01617 } 01618 else { 01619 if ( iPrecedence == 1 ) { 01620 ADDEXP( contextMethod.m_poolExceptions ); 01621 if ( pFeature->IsDependence() ) 01622 context.m_setDependencies.insert( OclMeta::Dependency( sigMethod.Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 01623 return true; 01624 } 01625 else { 01626 ADDEXP( contextIterator.m_poolExceptions ); 01627 m_pIterator= GetTreeManager()->CreateIterator(); 01628 m_pIterator->m_bTester = true; 01629 m_pIterator->m_pThisNode = m_pThisNode; 01630 m_pIterator->m_strCallOperator = "->"; 01631 m_pIterator->m_strName = m_strName; 01632 m_pIterator->m_vecDeclarators; 01633 m_pIterator->m_mapPositions = m_mapPositions; 01634 m_pIterator->m_pArgumentNode = m_vecArguments[ 0 ]; 01635 01636 m_pIterator->Check( context ); 01637 m_pIterator->m_bTester = false; 01638 m_bSelfTester = true; 01639 m_vecType = m_pIterator->m_vecType; 01640 return true; 01641 } 01642 } 01643 } 01644 if ( m_strCallOperator == "->" ) 01645 ADDEXP( contextIterator.m_poolExceptions ); 01646 else 01647 ADDEXP( contextMethod.m_poolExceptions ); 01648 return false; 01649 } 01650 return false; 01651 } 01652 01653 #define MAX_CONSTR_FUNC_LEVEL 100 // max level of constraint function encapsulation 01654 01655 OclMeta::Object MethodNode::Evaluate( ObjectContext& context ) 01656 { 01657 LevelCounter level(&m_stackLevel); 01658 std::string lastFuncName = ""; 01659 static std::string currFuncName = ""; 01660 std::string *szivas = &currFuncName; 01661 01662 if (m_stackLevel <= 1) 01663 currFuncName = ""; 01664 01665 if ( m_pIterator ) 01666 return m_pIterator->Evaluate( context ); 01667 01668 int iLineFeatureName = m_mapPositions[ LID_FEATURE_NAME ].iLine; 01669 01670 StringVector vecTypes; 01671 unsigned int i; 01672 for ( i = 0 ; i < m_vecArguments.size() ; i++ ) 01673 vecTypes.push_back( m_vecArguments[ i ]->m_vecType[ 0 ] ); 01674 OclSignature::Method signature( m_strName, m_pThisNode->m_vecType[ 0 ], vecTypes ); 01675 01676 if (m_stackLevel >= MAX_CONSTR_FUNC_LEVEL) 01677 { 01678 std::string message = "possibly infinite loop broken"; 01679 AddViolation(context, iLineFeatureName, signature.Print(), message); 01680 return OclMeta::Object::UNDEFINED; 01681 } 01682 01683 OclMeta::Object objectThis = m_pThisNode->Evaluate( context ); 01684 OclMeta::ObjectVector vecArguments; 01685 for ( i = 0 ; i < m_vecArguments.size() ; i++ ) 01686 vecArguments.push_back( m_vecArguments[ i ]->Evaluate( context ) ); 01687 01688 if ( m_strName == "isUndefined" && m_vecArguments.empty() && m_vecType[ 0 ] == "ocl::Boolean" ) 01689 return CheckFalseResult( context, CREATE_BOOLEAN( GetTreeManager()->GetTypeManager(), objectThis.IsUndefined() ), iLineFeatureName, signature.Print() ); 01690 01691 if ( objectThis.IsUndefined() ) 01692 return OclMeta::Object::UNDEFINED; 01693 for ( i = 0 ; i < vecArguments.size() ; i++ ) 01694 if ( vecArguments[ i ].IsUndefined() ) 01695 return OclMeta::Object::UNDEFINED; 01696 01697 EVALTRY { 01698 OclMeta::Type* pType = GetTreeManager()->GetTypeManager()->GetType( objectThis.GetStaticTypeName(), NILNAMESPACE ).get(); 01699 OclMeta::Method* pMethod = pType->GetMethod( signature ); 01700 OclImplementation::Method* pIMethod = pMethod->GetImplementation(); 01701 if ( ! pIMethod ) 01702 THROWOCL0( ET_RUNTIME, EX_METHOD_NOT_IMPLEMENTED ); 01703 01704 if (((OclMeta::Feature*)pMethod)->IsDynamic()) // userdef method 01705 { 01706 lastFuncName = currFuncName; 01707 currFuncName = m_strName; // GetFullName(); 01708 } 01709 01710 pIMethod->Initialize(); 01711 pIMethod->SetThis( objectThis ); 01712 pIMethod->SetArguments( vecArguments ); 01713 01714 (*pIMethod)(); 01715 01716 OclMeta::Object spResult = EvaluateCast( context, pIMethod->GetResult(), iLineFeatureName, signature.Print() ); 01717 01718 pIMethod->Finalize(); 01719 01720 // all of the violations collected in pIMethod (((OclGmeCM::ConstraintMethod*)pIMethod)->m_spFunction) 01721 // will lose, one violation will be added to context depending on spResult 01722 // ?? !! terge 01723 OclTree::ViolationVector vec = pIMethod->GetViolations(); 01724 pIMethod->ClearViolations(); 01725 int num = vec.size(); 01726 for (int kk=0; kk<num; kk++) 01727 { 01728 if (vec[kk].methodName.empty()) 01729 vec[kk].methodName = currFuncName; 01730 AddViolation(context, vec[kk]); 01731 } 01732 if (!lastFuncName.empty()) 01733 currFuncName = lastFuncName; 01734 01735 return CheckFalseResult( context, spResult, iLineFeatureName, signature.Print() ); 01736 } EVALCATCH( iLineFeatureName, signature.Print() ); 01737 return OclMeta::Object::UNDEFINED; 01738 } 01739 01740 //############################################################################################################################################## 01741 // 01742 // C L A S S : OclTree::FunctionNode <<< + OclTree::TreeNode 01743 // 01744 //############################################################################################################################################## 01745 01746 FunctionNode::FunctionNode( TreeManager* pManager ) 01747 : TreeNode( pManager, TreeNode::NK_FUNCTION ), m_strName( "" ), m_pMethod( NULL ) 01748 { 01749 } 01750 01751 FunctionNode::~FunctionNode() 01752 { 01753 if ( ! m_bTester && ! m_bSelfTester ) { 01754 for ( unsigned int i = 0 ; i < m_vecArguments.size() ; i++ ) 01755 delete m_vecArguments[ i ]; 01756 } 01757 CheckInitialize(); 01758 } 01759 01760 std::string FunctionNode::Print( const std::string& strTabs ) const 01761 { 01762 if ( m_pMethod ) 01763 return m_pMethod->Print( strTabs ); 01764 01765 std::string strOut = strTabs + "<Function name=\"" + m_strName + "\">\r\n"; 01766 01767 if ( ! m_vecArguments.empty() ) { 01768 for ( unsigned int i = 0 ; i < m_vecArguments.size() ; i++ ) { 01769 char chNum[ 100 ]; 01770 sprintf_s( chNum, sizeof(chNum), "%lu", i ); 01771 strOut += strTabs + TABSTR + "<Argument_" + std::string( chNum ) + ">\r\n"; 01772 strOut += m_vecArguments[ i ]->Print( strTabs + TABSTR + TABSTR ); 01773 strOut += strTabs + TABSTR + "</Argument_" + std::string( chNum ) + ">\r\n"; 01774 } 01775 } 01776 01777 strOut += strTabs + "</Function>\r\n"; 01778 return strOut; 01779 } 01780 01781 void FunctionNode::CheckInitialize() 01782 { 01783 TreeNode::CheckInitialize(); 01784 if ( m_pMethod ) { 01785 m_pMethod->CheckInitialize(); 01786 m_pMethod->m_bTester = true; 01787 delete m_pMethod->m_pThisNode; 01788 m_pMethod->m_pThisNode = NULL; 01789 delete m_pMethod; 01790 m_pMethod = NULL; 01791 } 01792 } 01793 01794 bool FunctionNode::CheckImplementation( TypeContext& context ) 01795 { 01796 TypeContext contextFunction = context; 01797 contextFunction.m_poolExceptions.Clear(); 01798 01799 bool bArgumentsValid = true; 01800 int i; 01801 for ( i = 0 ; i < (int) m_vecArguments.size() ; i++ ) 01802 bArgumentsValid = m_vecArguments[ i ]->Check( contextFunction ) && bArgumentsValid; 01803 01804 OclCommon::Exception exFunction; 01805 01806 if ( bArgumentsValid ) { 01807 StringVector vecTypes; 01808 for ( i = 0 ; i < (int) m_vecArguments.size() ; i++ ) 01809 vecTypes.push_back( m_vecArguments[ i ]->m_vecType[ 0 ] ); 01810 OclSignature::Function sigFunction( m_strName, vecTypes ); 01811 01812 try { 01813 OclMeta::Function* pFunction = GetTreeManager()->GetTypeManager()->GetFunction( sigFunction ); 01814 ADDEXP( contextFunction.m_poolExceptions ); 01815 GetParametralTypeSeq( TypeSeq(), ( m_vecArguments.empty() ) ? TypeSeq() : m_vecArguments[ 0 ]->m_vecType, pFunction->GetReturnTypeSeq() ); 01816 if ( pFunction->IsDependence() ) 01817 context.m_setDependencies.insert( OclMeta::Dependency( sigFunction.Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 01818 return true; 01819 } 01820 catch ( OclCommon::Exception ex ) { 01821 SETEXPOS( ex, m_mapPositions[ LID_FEATURE_NAME ] ); 01822 if ( ex.GetCode() != EX_FUNCTION_DOESNT_EXIST ) { 01823 ADDEXP( contextFunction.m_poolExceptions ); 01824 ADDEX( ex ); 01825 return false; 01826 } 01827 exFunction = ex; 01828 } 01829 } 01830 01831 // Check implicit variables 01832 01833 OclCommon::ExceptionPool poolExceptions; 01834 for ( i = context.m_vecImplicits.size() - 1 ; i >= 0 ; i-- ) { 01835 01836 TypeContext contextMethod = context; 01837 contextMethod.m_poolExceptions.Clear(); 01838 01839 m_pMethod = GetTreeManager()->CreateMethod(); 01840 m_pMethod->m_bTester = true; 01841 m_pMethod->m_pThisNode = CreateThis( context, i ); 01842 m_pMethod->m_strCallOperator = ""; 01843 m_pMethod->m_strName = m_strName; 01844 m_pMethod->m_mapPositions = m_mapPositions; 01845 m_pMethod->m_vecArguments = m_vecArguments; 01846 01847 if ( m_pMethod->Check( contextMethod ) ) { 01848 ADDEXP( contextMethod.m_poolExceptions ); 01849 m_pMethod->m_bTester = false; 01850 m_bSelfTester = true; 01851 m_vecType = m_pMethod->m_vecType; 01852 return true; 01853 } 01854 else { 01855 delete m_pMethod->m_pThisNode; 01856 m_pMethod->m_pThisNode = NULL; 01857 delete m_pMethod; 01858 m_pMethod = NULL; 01859 int iLastCode = GetLastExceptionCode( contextMethod); 01860 if ( iLastCode != EX_METHOD_DOESNT_EXIST && iLastCode != EX_ITERATOR_DOESNT_EXIST && iLastCode != EX_TYPE_NOT_COMPOUND_ITERATOR && iLastCode != -1 ) { 01861 ADDEXP( contextMethod.m_poolExceptions ); 01862 return false; 01863 } 01864 } 01865 } 01866 ADDEX( EXCEPTION1( EX_FUNC_IMPL_METH_ITER_DOESNT_EXIST, m_strName + "( ... )", m_mapPositions[ LID_FEATURE_NAME ] ) ); 01867 return false; 01868 } 01869 01870 OclMeta::Object FunctionNode::Evaluate( ObjectContext& context ) 01871 { 01872 if ( m_pMethod ) 01873 return m_pMethod->Evaluate( context ); 01874 01875 int iLineFeatureName = m_mapPositions[ LID_FEATURE_NAME ].iLine; 01876 StringVector vecTypes; 01877 unsigned int i; 01878 for ( i = 0 ; i < m_vecArguments.size() ; i++ ) 01879 vecTypes.push_back( m_vecArguments[ i ]->m_vecType[ 0 ] ); 01880 OclSignature::Function signature( m_strName, vecTypes ); 01881 01882 OclMeta::ObjectVector vecArguments; 01883 for ( i = 0 ; i < m_vecArguments.size() ; i++ ) 01884 vecArguments.push_back( m_vecArguments[ i ]->Evaluate( context ) ); 01885 01886 for ( i = 0 ; i < vecArguments.size() ; i++ ) 01887 if ( vecArguments[ i ].IsUndefined() ) 01888 return OclMeta::Object::UNDEFINED; 01889 01890 EVALTRY { 01891 OclMeta::Function* pFunction = GetTreeManager()->GetTypeManager()->GetFunction( signature ); 01892 OclImplementation::Function* pIFunction = pFunction->GetImplementation(); 01893 if ( ! pIFunction ) 01894 THROWOCL0( ET_RUNTIME, EX_FUNCTION_NOT_IMPLEMENTED ); 01895 01896 pIFunction->Initialize(); 01897 pIFunction->SetArguments( vecArguments ); 01898 01899 (*pIFunction)(); 01900 01901 OclMeta::Object spResult = EvaluateCast( context, pIFunction->GetResult(), iLineFeatureName, signature.Print() ); 01902 pIFunction->Finalize(); 01903 01904 return CheckFalseResult( context, spResult, iLineFeatureName, signature.Print() ); 01905 } EVALCATCH( iLineFeatureName, signature.Print() ); 01906 return OclMeta::Object::UNDEFINED; 01907 } 01908 01909 //############################################################################################################################################## 01910 // 01911 // C L A S S : OclTree::AssociationNode <<< + OclTree::TreeNode 01912 // 01913 //############################################################################################################################################## 01914 01915 AssociationNode::AssociationNode( TreeManager* pManager ) 01916 : TreeNode( pManager, TreeNode::NK_ASSOCIATION), m_strName( "" ), m_strAcceptable( "" ), m_pThisNode( NULL ) 01917 { 01918 } 01919 01920 AssociationNode::~AssociationNode() 01921 { 01922 if ( ! m_bTester ) 01923 if ( m_pThisNode ) 01924 delete m_pThisNode; 01925 } 01926 01927 std::string AssociationNode::Print( const std::string& strTabs ) const 01928 { 01929 std::string strOut = strTabs + "<Association name=\"" + m_strName + "\" class=\"" + m_strAcceptable + "\">\r\n"; 01930 01931 strOut += strTabs + TABSTR + "<This>\r\n"; 01932 if ( m_pThisNode ) 01933 strOut += m_pThisNode->Print( strTabs + TABSTR + TABSTR ); 01934 strOut += strTabs + TABSTR + "</This>\r\n"; 01935 01936 strOut += strTabs + "</Association>\r\n"; 01937 return strOut; 01938 } 01939 01940 void AssociationNode::CheckInitialize() 01941 { 01942 if ( m_bSelfTester && ! m_bTester && m_pThisNode ) { 01943 delete m_pThisNode; 01944 m_pThisNode = NULL; 01945 } 01946 TreeNode::CheckInitialize(); 01947 } 01948 01949 bool AssociationNode::CheckImplementation( TypeContext& context ) 01950 { 01951 // Association cannot be called by -> 01952 01953 if ( m_strCallOperator == "->" ) 01954 ADDEX( EXCEPTION1( EX_INVALID_CALL, m_strCallOperator, m_mapPositions[ LID_CALL_OPERATOR ] ) ); 01955 01956 // If This exists 01957 01958 if ( m_pThisNode ) { 01959 bool bThisValid = m_bTester || m_pThisNode->Check( context ); 01960 if ( bThisValid ) 01961 return CheckAssociation( context ); 01962 return false; 01963 } 01964 01965 // If This does not exist 01966 01967 m_bSelfTester = true; 01968 01969 // Check Implicits variables 01970 01971 for ( int i = context.m_vecImplicits.size() - 1 ; i >= 0 ; i-- ) { 01972 01973 TypeContext contextAssociation( context.m_namespace); 01974 CheckInitialize(); 01975 m_pThisNode = CreateThis( context, i ); 01976 if ( CheckAssociation( contextAssociation ) ) 01977 return true; 01978 else { 01979 delete m_pThisNode; 01980 m_pThisNode = NULL; 01981 int iLastCode = GetLastExceptionCode( contextAssociation ); 01982 if ( iLastCode != EX_ASSOCIATION_DOESNT_EXIST ) { 01983 ADDEXP( contextAssociation.m_poolExceptions ); 01984 return false; 01985 } 01986 } 01987 } 01988 ADDEX( EXCEPTION1( EX_IMPL_ASSOC_DOESNT_EXIST, OclSignature::Association( m_strName, "", m_strAcceptable ).Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 01989 return false; 01990 } 01991 01992 bool AssociationNode::CheckAssociation( TypeContext& context ) 01993 { 01994 OclMeta::Type* pType = GetTreeManager()->GetTypeManager()->GetType( m_pThisNode->m_vecType[ 0 ], context.m_namespace ).get(); 01995 01996 // Check static object can be called 01997 01998 if ( m_pThisNode->GetKind() == TreeNode::NK_OBJECT && ! m_bTester ) { 01999 ObjectNode* pONode = (ObjectNode*) m_pThisNode; 02000 if ( ! pONode->m_bCallable ) 02001 ADDEX( EXCEPTION1( EX_OBJECT_CALL_PROHIBITED, m_pThisNode->m_vecType[ 0 ], m_mapPositions[ LID_CALL_OPERATOR ] ) ); 02002 } 02003 02004 // Compound Type cannot have associations 02005 02006 if ( pType->IsCompound() ) { 02007 ADDEX( EXCEPTION1( EX_TYPE_COMPOUND_ASSOCIATION, pType->GetName(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 02008 return false; 02009 } 02010 02011 // Check Association Exists 02012 02013 try { 02014 OclMeta::Association* pAssociation = pType->GetAssociation( OclSignature::Association( m_strName, m_pThisNode->m_vecType[ 0 ], m_strAcceptable ) ); 02015 m_vecType = pAssociation->GetReturnTypeSeq(); 02016 return true; 02017 } 02018 catch ( OclCommon::Exception ex ) { 02019 SETEXPOS( ex, m_mapPositions[ LID_FEATURE_NAME ] ); 02020 ADDEX( ex ); 02021 return false; 02022 } 02023 } 02024 02025 OclMeta::Object AssociationNode::Evaluate( ObjectContext& context ) 02026 { 02027 int iLineFeatureName = m_mapPositions[ LID_FEATURE_NAME ].iLine; 02028 OclSignature::Association signature( m_strName, m_pThisNode->m_vecType[ 0 ], m_strAcceptable ); 02029 02030 OclMeta::Object objectThis = m_pThisNode->Evaluate( context ); 02031 if ( objectThis.IsUndefined() ) 02032 return objectThis; 02033 02034 EVALTRY { 02035 OclMeta::Type* pType = GetTreeManager()->GetTypeManager()->GetType( objectThis.GetStaticTypeName(), NILNAMESPACE ).get(); 02036 OclMeta::Association* pAssociation = pType->GetAssociation( signature ); 02037 OclImplementation::Association* pIAssociation = pAssociation->GetImplementation(); 02038 if ( ! pIAssociation ) 02039 THROWOCL0( ET_RUNTIME, EX_ASSOCIATION_NOT_IMPLEMENTED ); 02040 02041 pIAssociation->Initialize(); 02042 pIAssociation->SetThis( objectThis ); 02043 02044 (*pIAssociation)(); 02045 02046 OclMeta::Object spResult = EvaluateCast( context, pIAssociation->GetResult(), iLineFeatureName, signature.Print() ); 02047 pIAssociation->Finalize(); 02048 02049 return CheckFalseResult( context, spResult, iLineFeatureName, signature.Print() ); 02050 } EVALCATCH( iLineFeatureName, signature.Print() ); 02051 return OclMeta::Object::UNDEFINED; 02052 } 02053 02054 //############################################################################################################################################## 02055 // 02056 // C L A S S : OclTree::AttributeNode <<< + OclTree::TreeNode 02057 // 02058 //############################################################################################################################################## 02059 02060 AttributeNode::AttributeNode( TreeManager* pManager ) 02061 : TreeNode( pManager, TreeNode::NK_ATTRIBUTE ), m_strName( "" ), m_pThisNode( NULL ), m_pAssociation( NULL ), m_pCollector( NULL ) 02062 { 02063 } 02064 02065 AttributeNode::~AttributeNode() 02066 { 02067 if ( ! m_bTester && ! m_bSelfTester ) 02068 if ( m_pThisNode ) 02069 delete m_pThisNode; 02070 if ( m_pAssociation ) { 02071 delete m_pAssociation; 02072 m_pAssociation = NULL; 02073 } 02074 if ( m_pCollector ) { 02075 delete m_pCollector; 02076 m_pCollector = NULL; 02077 } 02078 } 02079 02080 std::string AttributeNode::Print( const std::string& strTabs ) const 02081 { 02082 if ( m_pAssociation ) 02083 return m_pAssociation->Print( strTabs ); 02084 if ( m_pCollector ) 02085 return m_pCollector->Print( strTabs ); 02086 02087 std::string strOut = strTabs + "<Attribute name=\"" + m_strName + "\">\r\n"; 02088 02089 strOut += strTabs + TABSTR + "<This>\r\n"; 02090 strOut += m_pThisNode->Print( strTabs + TABSTR + TABSTR ); 02091 strOut += strTabs + TABSTR + "</This>\r\n"; 02092 02093 strOut += strTabs + "</Attribute>\r\n"; 02094 return strOut; 02095 } 02096 02097 void AttributeNode::CheckInitialize() 02098 { 02099 TreeNode::CheckInitialize(); 02100 if ( m_pAssociation ) { 02101 m_pAssociation->m_bTester = true; 02102 delete m_pAssociation; 02103 m_pAssociation = NULL; 02104 } 02105 if ( m_pCollector ) { 02106 m_pCollector->m_bTester = true; 02107 delete m_pCollector->m_pArgumentNode; 02108 m_pCollector->m_pArgumentNode = NULL; 02109 delete m_pCollector; 02110 m_pCollector = NULL; 02111 } 02112 } 02113 02114 bool AttributeNode::CheckImplementation( TypeContext& context ) 02115 { 02116 // Check Self 02117 02118 bool bThisValid = m_bTester || m_pThisNode->Check( context ); 02119 02120 if ( bThisValid ) { 02121 02122 OclMeta::Type* pType = GetTreeManager()->GetTypeManager()->GetType( m_pThisNode->m_vecType[ 0 ], context.m_namespace ).get(); 02123 02124 // Type is not compound 02125 02126 if ( ! pType->IsCompound() ) { 02127 02128 // Check static object can be called 02129 02130 if ( m_pThisNode->GetKind() == TreeNode::NK_OBJECT ) { 02131 ObjectNode* pONode = (ObjectNode*) m_pThisNode; 02132 if ( ! pONode->m_bCallable ) 02133 ADDEX( EXCEPTION1( EX_OBJECT_CALL_PROHIBITED, m_pThisNode->m_vecType[ 0 ], m_mapPositions[ LID_CALL_OPERATOR ] ) ); 02134 } 02135 02136 // Check member selection operator 02137 02138 if ( m_strCallOperator == "->" ) 02139 ADDEX( EXCEPTION1( EX_INVALID_CALL, m_strCallOperator, m_mapPositions[ LID_CALL_OPERATOR ] ) ); 02140 02141 // Create Feature Call Check 02142 02143 std::vector<OclMeta::Type*> vecTypes( 2, pType ); 02144 02145 OclSignature::Attribute sigAttribute( m_strName, pType->GetName() ); 02146 OclSignature::Association sigAssociation( m_strName, pType->GetName(), "" ); 02147 std::vector<OclSignature::Feature*> vecSignatures( 2, &sigAttribute ); vecSignatures[ 1 ] = &sigAssociation; 02148 02149 std::vector<int> vecCodes( 3, EX_ATTRIBUTE_AMBIGUOUS ); vecCodes[ 1 ] = EX_ASSOCIATION_AMBIGUOUS; vecCodes[ 2 ] = EX_ATTRIBUTE_ASSOCIATION_AMBIGUOUS; 02150 02151 OclCommon::ExceptionPool poolResult; 02152 02153 int iPrecedence = 0; 02154 02155 // Get Feature 02156 02157 OclMeta::Feature* pFeature = CheckAmbiguity( vecTypes, vecSignatures, vecCodes, iPrecedence, poolResult ); 02158 if ( ! pFeature ) { 02159 ADDEXP( poolResult ); 02160 return false; 02161 } 02162 else { 02163 if ( iPrecedence == -1 ) { 02164 m_vecType = pFeature->GetReturnTypeSeq(); 02165 if ( pFeature->IsDependence() ) 02166 context.m_setDependencies.insert( OclMeta::Dependency( sigAttribute.Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 02167 } 02168 else { 02169 m_pAssociation = GetTreeManager()->CreateAssociation(); 02170 m_pAssociation->m_bTester = true; 02171 m_pAssociation->m_pThisNode = m_pThisNode; 02172 m_pAssociation->m_strCallOperator = "."; 02173 m_pAssociation->m_strName = m_strName; 02174 m_pAssociation->m_strAcceptable = ""; 02175 02176 m_pAssociation->Check( context ); 02177 m_pAssociation->m_bTester = false; 02178 m_bSelfTester = true; 02179 m_vecType = m_pAssociation->m_vecType; 02180 } 02181 return true; 02182 } 02183 } 02184 else { 02185 02186 // Type is compound 02187 02188 // Create Feature Call Check 02189 02190 OclMeta::Type* pTypeInner = GetTreeManager()->GetTypeManager()->GetType( m_pThisNode->m_vecType[ 1 ], context.m_namespace ).get(); 02191 02192 std::vector<OclMeta::Type*> vecTypes( 2, pType ); vecTypes[ 1 ] = pTypeInner; 02193 02194 OclSignature::Attribute sigAttribute( m_strName, pType->GetName() ); 02195 OclSignature::Attribute sigAttributeInner( m_strName, pTypeInner->GetName() ); 02196 std::vector<OclSignature::Feature*> vecSignatures( 2, &sigAttribute ); vecSignatures[ 1 ] = &sigAttributeInner; 02197 02198 std::vector<int> vecCodes( 3, EX_ATTRIBUTE_AMBIGUOUS ); vecCodes[ 2 ] = EX_ATTRIBUTE_INNERATTRIBUTE_AMBIGUOUS; 02199 02200 OclCommon::ExceptionPool poolResult; 02201 02202 int iPrecedence = ( m_strCallOperator.empty() ) ? 0 : ( m_strCallOperator == "->" ) ? -1 : 1; 02203 02204 // Get Feature 02205 02206 OclMeta::Feature* pFeature = CheckAmbiguity( vecTypes, vecSignatures, vecCodes, iPrecedence, poolResult ); 02207 if ( ! pFeature ) { 02208 ADDEXP( poolResult ); 02209 return false; 02210 } 02211 else { 02212 if ( iPrecedence == -1 ) { 02213 m_vecType = pFeature->GetReturnTypeSeq(); 02214 if ( pFeature->IsDependence() ) 02215 context.m_setDependencies.insert( OclMeta::Dependency( sigAttribute.Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 02216 } 02217 else { 02218 if ( pFeature->IsDependence() ) 02219 context.m_setDependencies.insert( OclMeta::Dependency( sigAttributeInner.Print(), m_mapPositions[ LID_FEATURE_NAME ] ) ); 02220 int iPiece = 0; char chBuffer[ 500 ]; 02221 std::string strDeclarator = "-" + m_strName; 02222 sprintf_s( chBuffer, sizeof(chBuffer), "%ld", iPiece ); 02223 while ( context.m_ctxTypes.ExistsVariable( strDeclarator + std::string( chBuffer ) ) ) 02224 sprintf_s( chBuffer, sizeof(chBuffer), "%ld", ++iPiece ); 02225 02226 VariableNode* pVariableNode = GetTreeManager()->CreateVariable(); 02227 pVariableNode->m_strName = strDeclarator + std::string( chBuffer ); 02228 pVariableNode->m_vecType = TypeSeq( 1, pTypeInner->GetName() ); 02229 02230 AttributeNode* pAttributeNode = GetTreeManager()->CreateAttribute(); 02231 pAttributeNode->m_pThisNode = pVariableNode; 02232 pAttributeNode->m_strCallOperator = ( pTypeInner->IsCompound() ) ? "->" : "."; 02233 pAttributeNode->m_strName = m_strName; 02234 pAttributeNode->m_vecType = pFeature->GetReturnTypeSeq(); 02235 02236 m_pCollector = GetTreeManager()->CreateIterator(); 02237 m_pCollector->m_bTester = true; 02238 m_pCollector->m_pThisNode = m_pThisNode; 02239 m_pCollector->m_strCallOperator = "->"; 02240 m_pCollector->m_strName = "collect"; 02241 m_pCollector->m_vecDeclarators = StringVector( 1, std::string( chBuffer ) ); 02242 m_pCollector->m_mapPositions = m_mapPositions; 02243 m_pCollector->m_pArgumentNode = pAttributeNode; 02244 02245 m_pCollector->Check( context ); 02246 m_pCollector->m_bTester = false; 02247 m_bSelfTester = true; 02248 m_vecType = m_pCollector->m_vecType; 02249 } 02250 return true; 02251 } 02252 } 02253 } 02254 return false; 02255 } 02256 02257 OclMeta::Object AttributeNode::Evaluate( ObjectContext& context ) 02258 { 02259 if ( m_pAssociation ) 02260 return m_pAssociation->Evaluate( context ); 02261 if ( m_pCollector ) 02262 return m_pCollector->Evaluate( context ); 02263 02264 int iLineFeatureName = m_mapPositions[ LID_FEATURE_NAME ].iLine; 02265 OclSignature::Attribute signature( m_strName, m_pThisNode->m_vecType[ 0 ] ); 02266 02267 OclMeta::Object objectThis = m_pThisNode->Evaluate( context ); 02268 if ( objectThis.IsUndefined() ) 02269 return objectThis; 02270 02271 EVALTRY { 02272 OclMeta::Type* pType = GetTreeManager()->GetTypeManager()->GetType( objectThis.GetStaticTypeName(), NILNAMESPACE ).get(); 02273 OclMeta::Attribute* pAttribute = pType->GetAttribute( signature ); 02274 OclImplementation::Attribute* pIAttribute = pAttribute->GetImplementation(); 02275 if ( ! pIAttribute ) 02276 THROWOCL0( ET_RUNTIME, EX_ATTRIBUTE_NOT_IMPLEMENTED ); 02277 02278 pIAttribute->Initialize(); 02279 pIAttribute->SetThis( objectThis ); 02280 02281 (*pIAttribute)(); 02282 02283 OclMeta::Object spResult = EvaluateCast( context, pIAttribute->GetResult(), iLineFeatureName, signature.Print() ); 02284 pIAttribute->Finalize(); 02285 02286 return CheckFalseResult( context, spResult, iLineFeatureName, signature.Print() ); 02287 } EVALCATCH( iLineFeatureName, signature.Print() ); 02288 return OclMeta::Object::UNDEFINED; 02289 } 02290 02291 //############################################################################################################################################## 02292 // 02293 // C L A S S : OclTree::VariableNode <<< + OclTree::TreeNode 02294 // 02295 //############################################################################################################################################## 02296 02297 VariableNode::VariableNode( TreeManager* pManager ) 02298 : TreeNode( pManager, TreeNode::NK_VARIABLE ), m_strName( "" ), m_pAttribute( NULL ), m_pType( NULL ) 02299 { 02300 } 02301 02302 VariableNode::~VariableNode() 02303 { 02304 CheckInitialize(); 02305 } 02306 02307 std::string VariableNode::Print( const std::string& strTabs ) const 02308 { 02309 if ( m_pAttribute ) 02310 return m_pAttribute->Print( strTabs ); 02311 02312 std::string strOut = strTabs + "<Variable name=\"" + m_strName + "\">\r\n"; 02313 strOut += strTabs + "</Variable>\r\n"; 02314 return strOut; 02315 } 02316 02317 void VariableNode::CheckInitialize() 02318 { 02319 TreeNode::CheckInitialize(); 02320 if ( m_pAttribute ) { 02321 m_pAttribute->m_bTester = true; 02322 m_pAttribute->CheckInitialize(); 02323 delete m_pAttribute->m_pThisNode; 02324 m_pAttribute->m_pThisNode = NULL; 02325 delete m_pAttribute; 02326 m_pAttribute = NULL; 02327 } 02328 if ( m_pType ) { 02329 delete m_pType; 02330 m_pType = NULL; 02331 } 02332 } 02333 02334 bool VariableNode::CheckImplementation( TypeContext& context ) 02335 { 02336 // Check if Type exists 02337 02338 TypeContext contextType( context.m_namespace); 02339 m_pType = GetTreeManager()->CreateObject(); 02340 m_pType->m_bTester = true; 02341 m_pType->m_strType = "ocl::Type"; 02342 m_pType->m_strValue = m_strName; 02343 m_pType->m_bCallable = false; 02344 m_pType->m_mapPositions = m_mapPositions; 02345 if ( m_pType->Check( contextType ) ) { 02346 m_pType->m_bTester = false; 02347 m_bSelfTester = true; 02348 m_vecType = m_pType->m_vecType; 02349 return true; 02350 } 02351 else { 02352 delete m_pType; 02353 m_pType = NULL; 02354 if ( m_strName.find( ":" ) != std::string::npos ) { 02355 ADDEXP( contextType.m_poolExceptions ); 02356 return false; 02357 } 02358 } 02359 02360 // Check if Variable exists 02361 02362 OclCommon::Exception exVariable = EXCEPTION1( EX_VARIABLE_DOESNT_EXIST, m_strName, m_mapPositions[ LID_NODE_START ] ); 02363 if ( context.m_ctxTypes.GetVariable( m_strName, m_vecType ) ) 02364 return true; 02365 else 02366 if ( m_strName == "self" || m_strName.substr( 0, 1 ) == "!" || m_strName.substr( 0, 1 ) == "-" ) { 02367 ADDEX( exVariable ); 02368 return false; 02369 } 02370 02371 // Check Self 02372 02373 for ( int i = context.m_vecImplicits.size() - 1 ; i >= 0 ; i-- ) { 02374 02375 TypeContext contextAttribute = context; 02376 contextAttribute.m_poolExceptions.Clear(); 02377 02378 m_pAttribute = GetTreeManager()->CreateAttribute(); 02379 m_pAttribute->m_bTester = true; 02380 m_pAttribute->m_pThisNode = CreateThis( context, i ); 02381 m_pAttribute->m_strCallOperator = ""; 02382 m_pAttribute->m_strName = m_strName; 02383 02384 if ( m_pAttribute->Check( contextAttribute ) ) { 02385 m_pAttribute->m_bTester = false; 02386 m_bSelfTester = true; 02387 m_vecType = m_pAttribute->m_vecType; 02388 return true; 02389 } 02390 else { 02391 delete m_pAttribute->m_pThisNode; 02392 m_pAttribute->m_pThisNode = NULL; 02393 delete m_pAttribute; 02394 m_pAttribute = NULL; 02395 int iLastCode = GetLastExceptionCode( contextAttribute ); 02396 if ( iLastCode != EX_ATTRIBUTE_DOESNT_EXIST && iLastCode != EX_ASSOCIATION_DOESNT_EXIST ) { 02397 ADDEXP( contextAttribute.m_poolExceptions ); 02398 return false; 02399 } 02400 } 02401 } 02402 ADDEX( EXCEPTION1( EX_VAR_IMPL_ATTRIB_ASSOC_DOESNT_EXIST, m_strName, m_mapPositions[ LID_NODE_START ] ) ); 02403 return false; 02404 } 02405 02406 OclMeta::Object VariableNode::Evaluate( ObjectContext& context ) 02407 { 02408 if ( m_pType ) 02409 return m_pType->Evaluate( context ); 02410 if ( m_pAttribute ) 02411 return m_pAttribute->Evaluate( context ); 02412 02413 OclMeta::Object spObject; 02414 context.oCtx.GetVariable( m_strName, spObject ); 02415 return spObject; 02416 } 02417 02418 //############################################################################################################################################## 02419 // 02420 // C L A S S : OclTree::ContextNode <<< + OclTree::TreeNode 02421 // 02422 //############################################################################################################################################## 02423 02424 ContextNode::ContextNode( TreeManager* pManager ) 02425 : TreeNode( pManager, TreeNode::NK_CONTEXT ), m_strName( "" ), m_strType( "" ), m_bClassifier( false ), m_strStereotype( "" ), m_strReturnType( "" ) 02426 { 02427 } 02428 02429 std::string ContextNode::Print( const std::string& strTabs ) const 02430 { 02431 std::string strOut = strTabs + "<Context type=\"" +( ( m_bClassifier ) ? "Classifier" : "Operation" ) + "\" stereotype=\"" + m_strStereotype + "\">\r\n"; 02432 if ( m_bClassifier ) 02433 strOut += strTabs + TABSTR + ( ( ! m_strName.empty() ) ? m_strName : "self" ) + " : " + m_strType + "\r\n"; 02434 else { 02435 strOut += strTabs + TABSTR + m_strType + "::" + m_strName + "( "; 02436 for ( unsigned int i = 0 ; i < m_vecParameters.size() ; i++ ) { 02437 strOut += m_vecParameters[ i ].GetName() + " : " + m_vecParameters[ i ].GetTypeName(); 02438 if ( i != m_vecParameters.size() - 1 ) 02439 strOut += ", "; 02440 } 02441 strOut += " )" + ( ( ! m_strReturnType.empty() ) ? " : " + m_strReturnType : "" ) + "\r\n"; 02442 } 02443 strOut += strTabs + "</Context>\r\n"; 02444 return strOut; 02445 } 02446 02447 void ContextNode::CheckInitialize() 02448 { 02449 TreeNode::CheckInitialize(); 02450 m_setDependencies.clear(); 02451 m_vecTypeReturn.clear(); 02452 } 02453 02454 bool ContextNode::CheckImplementation( TypeContext& context ) 02455 { 02456 context.m_strStereotype = m_strStereotype; 02457 02458 // C L A S S I F I E R C O N T E X T 02459 02460 // Check type of "self" and Add "self" 02461 02462 if ( m_strStereotype == "inv" ) { 02463 if ( ! ParseTypeSeq( context, m_mapPositions[ LID_CONTEXT_TYPE ], m_strType, m_vecType ) ) 02464 return false; 02465 context.m_ctxTypes.AddVariable( ( m_strName == "" ) ? "self" : m_strName, m_vecType ); 02466 context.m_vecImplicits.push_back( ( m_strName == "" ) ? "self" : m_strName ); 02467 m_vecTypeReturn.push_back( "ocl::Boolean" ); 02468 return true; 02469 } 02470 02471 // O P E R A T I O N C O N T E X T 02472 02473 // Check type of "self" and Add "self" 02474 02475 if ( ParseTypeSeq( context, m_mapPositions[ LID_CONTEXT_TYPE ], m_strType, m_vecType ) ) { 02476 context.m_ctxTypes.AddVariable( "self", m_vecType ); 02477 context.m_vecImplicits.push_back( "self" ); 02478 } 02479 02480 // Check Parameters 02481 02482 TypeSeq vecType; 02483 for ( unsigned int i = 0 ; i < m_vecParameters.size() ; i++ ) { 02484 vecType.clear(); 02485 std::string strType = m_vecParameters[ i ].GetTypeName(); 02486 std::string strName = m_vecParameters[ i ].GetName(); 02487 if ( ParseTypeSeq( context, m_mapPositions[ LID_PARAMETER_TYPE + i ], strType, vecType ) ) 02488 m_vecParameters[ i ] = OclCommon::FormalParameter( strName, strType, m_vecParameters[ i ].IsRequired() ); 02489 if ( context.m_ctxTypes.ExistsVariable( strName ) ) 02490 ADDEX( EXCEPTION1( EX_VARIABLE_ALREADY_EXISTS, strName, m_mapPositions[ LID_PARAMETER_NAME + i ] ) ) 02491 else 02492 if ( ! vecType.empty() ) 02493 context.m_ctxTypes.AddVariable( strName, vecType ); 02494 } 02495 02496 // Check Return Type if exists 02497 02498 if ( ! m_strReturnType.empty() ) 02499 ParseTypeSeq( context, m_mapPositions[ LID_CONTEXT_RETURNTYPE ], m_strReturnType, m_vecTypeReturn ); 02500 if ( m_strStereotype == "defattribute" || m_strStereotype == "defmethod" ) { 02501 if ( m_strReturnType.empty() ) 02502 ADDEX( EXCEPTION0( EX_CONSTRAINT_DEF_RETURN_MISSING, m_mapPositions[ LID_NODE_START ] ) ); 02503 } 02504 else 02505 m_vecTypeReturn.push_back( "ocl::Boolean" ); 02506 if ( ! m_vecTypeReturn.empty() ) 02507 context.m_ctxTypes.AddVariable( "result", m_vecTypeReturn, m_strStereotype == "defattribute" || m_strStereotype == "defmethod" ); 02508 02509 return ! m_vecType.empty(); 02510 } 02511 02512 OclMeta::Object ContextNode::Evaluate( ObjectContext& context ) 02513 { 02514 OclMeta::Object spResult; 02515 context.oCtx.GetVariable( ( m_strName == "" ) ? "self" : m_strName, spResult ); 02516 return spResult; 02517 } 02518 02519 //############################################################################################################################################## 02520 // 02521 // C L A S S : OclTree::Constraint <<< + OclTree::TreeNode 02522 // 02523 //############################################################################################################################################## 02524 02525 Constraint::Constraint( TreeManager* pManager ) 02526 : TreeNode( pManager, TreeNode::NK_CONSTRAINT ), m_strName( "" ), m_pContext( NULL ), m_pExpression( NULL ) 02527 { 02528 } 02529 02530 Constraint::~Constraint() 02531 { 02532 if ( m_pContext ) 02533 delete m_pContext; 02534 if ( m_pExpression ) 02535 delete m_pExpression; 02536 } 02537 02538 std::string Constraint::Print( const std::string& strTabs ) const 02539 { 02540 std::string strOut = strTabs + strTabs + "<Constraint name=\"" + m_strName + "\">\r\n"; 02541 02542 strOut += strTabs + TABSTR + "<Context>\r\n"; 02543 strOut += m_pContext->Print( strTabs + TABSTR + TABSTR ); 02544 strOut += strTabs + TABSTR + "</Context>\r\n"; 02545 02546 strOut += strTabs + TABSTR + "<Expression>\r\n"; 02547 strOut += m_pExpression->Print( strTabs + TABSTR + TABSTR ); 02548 strOut += strTabs + TABSTR + "</Expression>\r\n"; 02549 02550 strOut += "</Constraint>\r\n"; 02551 return strOut; 02552 } 02553 02554 bool Constraint::CheckImplementation( TypeContext& context ) 02555 { 02556 m_pContext->Check( context ); 02557 bool bValidC = context.m_poolExceptions.IsEmpty(); 02558 bool bValidE = true; 02559 if ( m_pExpression ) { 02560 bValidE = m_pExpression->Check( context ); 02561 if ( bValidE && bValidC ) { 02562 m_pContext->m_setDependencies = context.m_setDependencies; 02563 if ( ! GetTreeManager()->GetTypeManager()->IsTypeA( m_pExpression->m_vecType, m_pContext->m_vecTypeReturn ) ) { 02564 if ( m_pContext->m_strStereotype == "defattribute" || m_pContext->m_strStereotype == "defmethod" ) { 02565 std::string strEType, strDType; 02566 OclCommon::Convert( m_pExpression->m_vecType, strEType ); 02567 OclCommon::Convert( m_pContext->m_vecTypeReturn, strDType ); 02568 ADDEX( EXCEPTION2( EX_CONSTRAINT_DEF_RETURN_MISMATCH, strDType, strEType, m_pExpression->m_mapPositions[ LID_NODE_START ] ) ); 02569 } 02570 else 02571 ADDEX( EXCEPTION0( EX_BOOLEAN_REQUIRED, m_pExpression->m_mapPositions[ LID_NODE_START ] ) ); 02572 bValidE = false; 02573 } 02574 else 02575 m_vecType = m_pExpression->m_vecType; 02576 } 02577 } 02578 return bValidC && bValidE; 02579 } 02580 02581 OclMeta::Object Constraint::Evaluate( ObjectContext& context ) 02582 { 02583 int iLineNodeStart = m_mapPositions[ LID_NODE_START ].iLine; 02584 EVALTRY { 02585 OclMeta::Object spResult = EvaluateCast( context, m_pExpression->Evaluate( context ), iLineNodeStart, "At root expression" ); 02586 context.m_bEnableTracking = true; 02587 if ( spResult.IsUndefined() ) { 02588 std::string strMyself = ( m_pContext->m_strStereotype == "defattribute" || m_pContext->m_strStereotype == "defmethod" ) ? "Definition " : "Constraint "; 02589 AddViolation( context, iLineNodeStart, "At root expression", strMyself + "evaluated to undefined object." ); 02590 } 02591 02592 return CheckFalseResult( context, spResult, iLineNodeStart, "At root expression" ); 02593 } EVALCATCH( iLineNodeStart, "At root expression" ); 02594 return OclMeta::Object::UNDEFINED; 02595 } 02596 02597 //############################################################################################################################################## 02598 // 02599 // C L A S S : OclTree::ObjectNodeAdaptor 02600 // 02601 //############################################################################################################################################## 02602 02603 std::string ObjectNodeAdaptor::Print( const std::string& strTabs, ObjectNode* pNode ) const 02604 { 02605 std::string strOut = strTabs + "<Object type=\"" + pNode->m_strType + "\">\r\n"; 02606 02607 strOut += strTabs + TABSTR + "<Value>\r\n"; 02608 strOut += strTabs + TABSTR + TABSTR; 02609 if ( pNode->m_strType == "ocl::String" ) 02610 strOut += "\"" + pNode->m_strValue + "\"\r\n"; 02611 else 02612 if ( pNode->m_strType == "ocl::Enumeration" ) 02613 strOut += "#" + pNode->m_strValue + "\r\n"; 02614 else 02615 strOut += pNode->m_strValue + "\r\n"; 02616 strOut += strTabs + TABSTR + "</Value>\r\n"; 02617 02618 strOut += strTabs + "</Object>\r\n"; 02619 return strOut; 02620 } 02621 02622 bool ObjectNodeAdaptor::Check( TypeContext& context, ObjectNode* pNode ) const 02623 { 02624 if ( pNode->ParseTypeSeq( context, pNode->m_mapPositions[ LID_NODE_START ], pNode->m_strType, pNode->m_vecType ) ) { 02625 02626 // Check whether this adaptor is able to create object 02627 02628 if ( pNode->m_strType == "ocl::String" || pNode->m_strType == "ocl::Enumeration" || pNode->m_strType == "ocl::Real" || pNode->m_strType == "ocl::Integer" || pNode->m_strType == "ocl::Boolean" ) 02629 return true; 02630 else { 02631 if ( pNode->m_strType == "ocl::Type" ) { 02632 std::string strValue = pNode->m_strValue; 02633 TypeSeq vecType; 02634 bool bIsType = pNode->ParseTypeSeq( context, pNode->m_mapPositions[ LID_NODE_START ], strValue, vecType ); 02635 if ( ! bIsType ) 02636 pNode->m_vecType.clear(); 02637 else 02638 pNode->m_strValue = strValue; 02639 return bIsType; 02640 } 02641 ADDEX( EXCEPTION2( EX_CANNOT_CREATE_OBJECT, pNode->m_strType, pNode->m_strValue, pNode->m_mapPositions[ LID_NODE_START ] ) ); 02642 pNode->m_vecType.clear(); 02643 } 02644 } 02645 return false; 02646 } 02647 02648 OclMeta::Object ObjectNodeAdaptor::Evaluate( ObjectContext& context, ObjectNode* pNode ) const 02649 { 02650 if ( pNode->m_strType == "ocl::String" ) 02651 return CREATE_STRING( pNode->GetTreeManager()->GetTypeManager(), pNode->m_strValue ); 02652 if ( pNode->m_strType == "ocl::Enumeration" ) 02653 return CREATE_ENUMERATION( pNode->GetTreeManager()->GetTypeManager(), pNode->m_strValue ); 02654 if ( pNode->m_strType == "ocl::Boolean" ) { 02655 return CREATE_BOOLEAN( pNode->GetTreeManager()->GetTypeManager(), pNode->m_strValue == "true" ); 02656 } 02657 if ( pNode->m_strType == "ocl::Real" ) { 02658 char* pchStop; 02659 double dValue = strtod( pNode->m_strValue.c_str(), &pchStop ); 02660 return CREATE_REAL( pNode->GetTreeManager()->GetTypeManager(), dValue ); 02661 } 02662 if ( pNode->m_strType == "ocl::Integer" ) { 02663 long lValue = atol( pNode->m_strValue.c_str() ); 02664 return CREATE_INTEGER( pNode->GetTreeManager()->GetTypeManager(), lValue ); 02665 } 02666 if ( pNode->m_strType == "ocl::Type" ) 02667 return CREATE_TYPE( pNode->GetTreeManager()->GetTypeManager(), pNode->m_strValue ); 02668 return OclMeta::Object::UNDEFINED; 02669 } 02670 02671 //############################################################################################################################################## 02672 // 02673 // C L A S S : OclTree::CollectionNodeAdaptor 02674 // 02675 //############################################################################################################################################## 02676 02677 std::string CollectionNodeAdaptor::Print( const std::string& strTabs, CollectionNode* pNode ) const 02678 { 02679 std::string strOut = strTabs + "<Collection type=\"" + pNode->m_strType + "\">\r\n"; 02680 02681 for ( unsigned int i = 0 ; i < pNode->m_vecNodes.size() ; i++ ) { 02682 char chNum[ 100 ]; 02683 sprintf_s( chNum, sizeof(chNum), "%lu", i ); 02684 strOut += strTabs + TABSTR + "<Element_" + std::string( chNum ) + ">\r\n"; 02685 strOut += pNode->m_vecNodes[ i ]->Print( strTabs + TABSTR + TABSTR ); 02686 strOut += strTabs + TABSTR + "</Element_" + std::string( chNum ) + ">\r\n"; 02687 } 02688 02689 strOut += strTabs + "</Collection>\r\n"; 02690 return strOut; 02691 } 02692 02693 bool CollectionNodeAdaptor::Check( TypeContext& context, CollectionNode* pNode ) const 02694 { 02695 if ( pNode->m_strType == "Set" || pNode->m_strType == "Sequence" || pNode->m_strType == "Bag" || pNode->m_strType == "OrderedSet" ) 02696 pNode->m_strType = "ocl::" + pNode->m_strType; 02697 02698 bool bValid = pNode->ParseTypeSeq( context, pNode->m_mapPositions[ LID_NODE_START ], pNode->m_strType, pNode->m_vecType ); 02699 02700 // Check if this object is Compound 02701 02702 if ( bValid ) { 02703 OclMeta::Type* pType = pNode->GetTreeManager()->GetTypeManager()->GetType( pNode->m_vecType[ 0 ], context.m_namespace ).get(); 02704 if ( ! pType->IsCompound() ) { 02705 ADDEX( EXCEPTION1( EX_TYPE_ISNT_COMPOUND, pNode->m_vecType[ 0 ], pNode->m_mapPositions[ LID_NODE_START ] ) ); 02706 bValid = false; 02707 } 02708 02709 // Check if this adaptor can create Compound Object 02710 02711 if ( ! ( pNode->m_vecType[ 0 ] == "ocl::Set" || pNode->m_vecType[ 0 ] == "ocl::Sequence" || pNode->m_vecType[ 0 ] == "ocl::Bag" || pNode->m_vecType[ 0 ] == "ocl::OrderedSet" ) ) { 02712 ADDEX( EXCEPTION1( EX_CANNOT_CREATE_COLLECTION, pNode->m_strType, pNode->m_mapPositions[ LID_NODE_START ] ) ); 02713 bValid = false; 02714 } 02715 } 02716 02717 // Determine the base of consisted Objects 02718 02719 bool bArgumentsValid = true; 02720 TypeSeq vecAggregatedType; 02721 for ( unsigned int i = 0 ; i < pNode->m_vecNodes.size() ; i++ ) { 02722 bArgumentsValid = pNode->m_vecNodes[ i ]->Check( context ) && bArgumentsValid; 02723 if ( bArgumentsValid ) { 02724 TypeSeq vecType = pNode->m_vecNodes[ i ]->m_vecType; 02725 if ( vecAggregatedType.empty() ) 02726 vecAggregatedType = vecType; 02727 else 02728 vecAggregatedType = pNode->GetTreeManager()->GetTypeManager()->GetTypeBase( vecAggregatedType, vecType ); 02729 } 02730 } 02731 02732 // Set return type 02733 02734 if ( bValid && bArgumentsValid ) { 02735 if ( vecAggregatedType.empty() ) 02736 vecAggregatedType.push_back( "ocl::Any" ); 02737 vecAggregatedType.insert( vecAggregatedType.begin(), pNode->m_vecType[ 0 ] ); 02738 pNode->m_vecType = vecAggregatedType; 02739 } 02740 return bValid && bArgumentsValid; 02741 } 02742 02743 OclMeta::Object CollectionNodeAdaptor::Evaluate( ObjectContext& context, CollectionNode* pNode ) const 02744 { 02745 OclMeta::ObjectVector vecObjects; 02746 for ( unsigned int i = 0 ; i < pNode->m_vecNodes.size() ; i++ ) 02747 vecObjects.push_back( pNode->m_vecNodes[ i ]->Evaluate( context ) ); 02748 02749 if ( pNode->m_vecType[ 0 ] == "ocl::Set" ) 02750 return CREATE_SET( pNode->GetTreeManager()->GetTypeManager(), vecObjects ); 02751 if ( pNode->m_vecType[ 0 ] == "ocl::Bag" ) 02752 return CREATE_BAG( pNode->GetTreeManager()->GetTypeManager(), vecObjects ); 02753 if ( pNode->m_vecType[ 0 ] == "ocl::Sequence" ) 02754 return CREATE_SEQUENCE( pNode->GetTreeManager()->GetTypeManager(), vecObjects ); 02755 if ( pNode->m_vecType[ 0 ] == "ocl::OrderedSet" ) 02756 return CREATE_ORDEREDSET( pNode->GetTreeManager()->GetTypeManager(), vecObjects ); 02757 02758 return OclMeta::Object::UNDEFINED; 02759 } 02760 02761 //############################################################################################################################################## 02762 // 02763 // C L A S S : OclTree::TreeManager 02764 // 02765 //############################################################################################################################################## 02766 02767 TreeManager::TreeManager( OclMeta::TypeManager* pTypeManager, ObjectNodeAdaptor* pOAdaptor, CollectionNodeAdaptor* pCAdaptor ) 02768 : m_pTypeManager( pTypeManager ), m_pOAdaptor( pOAdaptor ), m_pCAdaptor( pCAdaptor ) 02769 { 02770 } 02771 02772 TreeManager::~TreeManager() 02773 { 02774 delete m_pTypeManager; 02775 delete m_pOAdaptor; 02776 delete m_pCAdaptor; 02777 } 02778 02779 OclMeta::TypeManager* TreeManager::GetTypeManager() const 02780 { 02781 return m_pTypeManager; 02782 } 02783 02784 ObjectNode* TreeManager::CreateObject() const 02785 { 02786 return new ObjectNode( (TreeManager*) this ); 02787 } 02788 02789 CollectionNode* TreeManager::CreateCollection() const 02790 { 02791 return new CollectionNode( (TreeManager*) this ); 02792 } 02793 02794 DeclarationNode* TreeManager::CreateDeclaration() const 02795 { 02796 return new DeclarationNode( (TreeManager*) this ); 02797 } 02798 02799 IteratorNode* TreeManager::CreateIterator() const 02800 { 02801 return new IteratorNode( (TreeManager*) this ); 02802 } 02803 02804 MethodNode* TreeManager::CreateMethod() const 02805 { 02806 return new MethodNode( (TreeManager*) this ); 02807 } 02808 02809 FunctionNode* TreeManager::CreateFunction() const 02810 { 02811 return new FunctionNode( (TreeManager*) this ); 02812 } 02813 02814 AssociationNode* TreeManager::CreateAssociation() const 02815 { 02816 return new AssociationNode( (TreeManager*) this ); 02817 } 02818 02819 AttributeNode* TreeManager::CreateAttribute() const 02820 { 02821 return new AttributeNode( (TreeManager*) this ); 02822 } 02823 02824 VariableNode* TreeManager::CreateVariable() const 02825 { 02826 return new VariableNode( (TreeManager*) this ); 02827 } 02828 02829 ContextNode* TreeManager::CreateContext() const 02830 { 02831 return new ContextNode( (TreeManager*) this ); 02832 } 02833 02834 TypeCastNode* TreeManager::CreateTypeCast() const 02835 { 02836 return new TypeCastNode( (TreeManager*) this ); 02837 } 02838 02839 IfThenElseNode* TreeManager::CreateIfThenElse() const 02840 { 02841 return new IfThenElseNode( (TreeManager*) this ); 02842 } 02843 02844 OperatorNode* TreeManager::CreateOperator() const 02845 { 02846 return new OperatorNode( (TreeManager*) this ); 02847 } 02848 02849 Constraint* TreeManager::CreateConstraint() const 02850 { 02851 return new Constraint( (TreeManager*) this ); 02852 } 02853 02854 //udmoclpat_ocltree_cpp_1 __please do not remove or change this line__ 02855 02856 }; // namespace OclTree