summaryrefslogtreecommitdiff
path: root/basic/source/classes/sb.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'basic/source/classes/sb.cxx')
-rwxr-xr-xbasic/source/classes/sb.cxx130
1 files changed, 127 insertions, 3 deletions
diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx
index df5bd58e90..f8aef3d6d2 100755
--- a/basic/source/classes/sb.cxx
+++ b/basic/source/classes/sb.cxx
@@ -57,6 +57,7 @@
#include <vos/mutex.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include "errobject.hxx"
+#include <hash_map>
#include <com/sun/star/script/ModuleType.hpp>
#include <com/sun/star/script/ModuleInfo.hpp>
@@ -552,6 +553,39 @@ SbClassModuleObject::SbClassModuleObject( SbModule* pClassModule )
USHORT nFlags_ = pProp->GetFlags();
pProp->SetFlag( SBX_NO_BROADCAST );
SbxProperty* pNewProp = new SbxProperty( *pProp );
+
+ // Special handling for modules instances and collections, they need
+ // to be instantiated, otherwise all refer to the same base object
+ SbxDataType eVarType = pProp->GetType();
+ if( eVarType == SbxOBJECT )
+ {
+ SbxBase* pObjBase = pProp->GetObject();
+ SbxObject* pObj = PTR_CAST(SbxObject,pObjBase);
+ if( pObj != NULL )
+ {
+ String aObjClass = pObj->GetClassName();
+ (void)aObjClass;
+
+ SbClassModuleObject* pClassModuleObj = PTR_CAST(SbClassModuleObject,pObjBase);
+ if( pClassModuleObj != NULL )
+ {
+ SbModule* pLclClassModule = pClassModuleObj->getClassModule();
+ SbClassModuleObject* pNewObj = new SbClassModuleObject( pLclClassModule );
+ pNewObj->SetName( pProp->GetName() );
+ pNewObj->SetParent( pLclClassModule->pParent );
+ pNewProp->PutObject( pNewObj );
+ }
+ else if( aObjClass.EqualsIgnoreCaseAscii( "Collection" ) )
+ {
+ String aCollectionName( RTL_CONSTASCII_USTRINGPARAM("Collection") );
+ BasicCollection* pNewCollection = new BasicCollection( aCollectionName );
+ pNewCollection->SetName( pProp->GetName() );
+ pNewCollection->SetParent( pClassModule->pParent );
+ pNewProp->PutObject( pNewCollection );
+ }
+ }
+ }
+
pNewProp->ResetFlag( SBX_NO_BROADCAST );
pNewProp->SetParent( this );
pProps->PutDirect( pNewProp, i );
@@ -726,6 +760,7 @@ SbClassData::SbClassData( void )
void SbClassData::clear( void )
{
mxIfaces->Clear();
+ maRequiredTypes.clear();
}
SbClassFactory::SbClassFactory( void )
@@ -981,6 +1016,72 @@ SbModule* StarBASIC::FindModule( const String& rName )
return NULL;
}
+
+struct ClassModuleRunInitItem
+{
+ SbModule* m_pModule;
+ bool m_bProcessing;
+ bool m_bRunInitDone;
+ //ModuleVector m_vModulesDependingOnThisModule;
+
+ ClassModuleRunInitItem( void )
+ : m_pModule( NULL )
+ , m_bProcessing( false )
+ , m_bRunInitDone( false )
+ {}
+ ClassModuleRunInitItem( SbModule* pModule )
+ : m_pModule( pModule )
+ , m_bProcessing( false )
+ , m_bRunInitDone( false )
+ {}
+};
+
+typedef std::hash_map< ::rtl::OUString, ClassModuleRunInitItem,
+ ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ModuleInitDependencyMap;
+
+static ModuleInitDependencyMap* GpMIDMap = NULL;
+
+void SbModule::implProcessModuleRunInit( ClassModuleRunInitItem& rItem )
+{
+ ModuleInitDependencyMap& rMIDMap = *GpMIDMap;
+
+ rItem.m_bProcessing = true;
+
+ //bool bAnyDependencies = true;
+ SbModule* pModule = rItem.m_pModule;
+ if( pModule->pClassData != NULL )
+ {
+ StringVector& rReqTypes = pModule->pClassData->maRequiredTypes;
+ if( rReqTypes.size() > 0 )
+ {
+ for( StringVector::iterator it = rReqTypes.begin() ; it != rReqTypes.end() ; ++it )
+ {
+ String& rStr = *it;
+
+ // Is required type a class module?
+ ModuleInitDependencyMap::iterator itFind = rMIDMap.find( rStr );
+ if( itFind != rMIDMap.end() )
+ {
+ ClassModuleRunInitItem& rParentItem = itFind->second;
+ if( rParentItem.m_bProcessing )
+ {
+ // TODO: raise error?
+ DBG_ERROR( "Cyclic module dependency detected" );
+ continue;
+ }
+
+ if( !rParentItem.m_bRunInitDone )
+ implProcessModuleRunInit( rParentItem );
+ }
+ }
+ }
+ }
+
+ pModule->RunInit();
+ rItem.m_bRunInitDone = true;
+ rItem.m_bProcessing = false;
+}
+
// Run Init-Code of all modules (including inserted libraries)
void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit )
{
@@ -994,10 +1095,33 @@ void StarBASIC::InitAllModules( StarBASIC* pBasicNotToInit )
// compile modules first then RunInit ( otherwise there is
// can be order dependency, e.g. classmodule A has a member
// of of type classmodule B and classmodule B hasn't been compiled yet )
+
+ // Consider required types to init in right order. Class modules
+ // that are required by other modules have to be initialized first.
+ ModuleInitDependencyMap aMIDMap;
+ GpMIDMap = &aMIDMap;
for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
{
SbModule* pModule = (SbModule*)pModules->Get( nMod );
- pModule->RunInit();
+ String aModuleName = pModule->GetName();
+ if( pModule->isProxyModule() )
+ aMIDMap[aModuleName] = ClassModuleRunInitItem( pModule );
+ }
+
+ ModuleInitDependencyMap::iterator it;
+ for( it = aMIDMap.begin() ; it != aMIDMap.end(); ++it )
+ {
+ ClassModuleRunInitItem& rItem = it->second;
+ SbModule::implProcessModuleRunInit( rItem );
+ }
+ GpMIDMap = NULL;
+
+ // Call RunInit on standard modules
+ for ( USHORT nMod = 0; nMod < pModules->Count(); nMod++ )
+ {
+ SbModule* pModule = (SbModule*)pModules->Get( nMod );
+ if( !pModule->isProxyModule() )
+ pModule->RunInit();
}
// Check all objects if they are BASIC,
@@ -1962,7 +2086,7 @@ void BasicCollection::CollItem( SbxArray* pPar_ )
if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() )
pRes = xItemArray->Get32( nIndex );
if( !pRes )
- SetError( SbxERR_BAD_INDEX );
+ SetError( SbERR_BAD_ARGUMENT );
else
*(pPar_->Get(0)) = *pRes;
}
@@ -1980,6 +2104,6 @@ void BasicCollection::CollRemove( SbxArray* pPar_ )
if( nIndex >= 0 && nIndex < (INT32)xItemArray->Count32() )
xItemArray->Remove32( nIndex );
else
- SetError( SbxERR_BAD_INDEX );
+ SetError( SbERR_BAD_ARGUMENT );
}