summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basic/inc/basic/sbmod.hxx4
-rwxr-xr-xbasic/source/classes/sb.cxx93
-rw-r--r--basic/source/comp/codegen.cxx8
-rw-r--r--basic/source/comp/dim.cxx3
-rw-r--r--basic/source/inc/parser.hxx5
-rw-r--r--basic/source/inc/sbintern.hxx6
-rw-r--r--basic/source/runtime/methods1.cxx2
7 files changed, 112 insertions, 9 deletions
diff --git a/basic/inc/basic/sbmod.hxx b/basic/inc/basic/sbmod.hxx
index bccf8212f10e..abb482f7bfe5 100644
--- a/basic/inc/basic/sbmod.hxx
+++ b/basic/inc/basic/sbmod.hxx
@@ -44,6 +44,7 @@ class SbProcedureProperty;
class SbIfaceMapperMethod;
class SbClassModuleObject;
+struct ClassModuleRunInitItem;
struct SbClassData;
class SbModuleImpl;
@@ -71,6 +72,7 @@ protected:
SbxObjectRef pDocObject; // an impl object ( used by Document Modules )
bool bIsProxyModule;
+ static void implProcessModuleRunInit( ClassModuleRunInitItem& rItem );
void StartDefinitions();
SbMethod* GetMethod( const String&, SbxDataType );
SbProperty* GetProperty( const String&, SbxDataType );
@@ -134,7 +136,7 @@ public:
void SetVBACompat( BOOL bCompat );
INT32 GetModuleType() { return mnType; }
void SetModuleType( INT32 nType ) { mnType = nType; }
- bool GetIsProxyModule() { return bIsProxyModule; }
+ bool isProxyModule() { return bIsProxyModule; }
void AddVarName( const String& aName );
void RemoveVars();
::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > GetUnoModule();
diff --git a/basic/source/classes/sb.cxx b/basic/source/classes/sb.cxx
index e28b0a304f28..d4520025953e 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>
@@ -726,6 +727,7 @@ SbClassData::SbClassData( void )
void SbClassData::clear( void )
{
mxIfaces->Clear();
+ maRequiredTypes.clear();
}
SbClassFactory::SbClassFactory( void )
@@ -981,6 +983,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 +1062,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 );
+ 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 );
- pModule->RunInit();
+ if( !pModule->isProxyModule() )
+ pModule->RunInit();
}
// Check all objects if they are BASIC,
diff --git a/basic/source/comp/codegen.cxx b/basic/source/comp/codegen.cxx
index 46f829b382e8..e0f23c15d224 100644
--- a/basic/source/comp/codegen.cxx
+++ b/basic/source/comp/codegen.cxx
@@ -138,11 +138,10 @@ void SbiCodeGen::Save()
pCLASSFAC->AddClassModule( &rMod );
nIfaceCount = pParser->aIfaceVector.size();
+ if( !rMod.pClassData )
+ rMod.pClassData = new SbClassData;
if( nIfaceCount )
{
- if( !rMod.pClassData )
- rMod.pClassData = new SbClassData;
-
for( int i = 0 ; i < nIfaceCount ; i++ )
{
const String& rIfaceName = pParser->aIfaceVector[i];
@@ -152,6 +151,8 @@ void SbiCodeGen::Save()
pIfaces->Insert( pIfaceVar, pIfaces->Count() );
}
}
+
+ rMod.pClassData->maRequiredTypes = pParser->aRequiredTypes;
}
else
{
@@ -161,6 +162,7 @@ void SbiCodeGen::Save()
rMod.mnType = com::sun::star::script::ModuleType::NORMAL;
rMod.bIsProxyModule = false;
}
+
if( pParser->bText )
p->SetFlag( SBIMG_COMPARETEXT );
// GlobalCode-Flag
diff --git a/basic/source/comp/dim.cxx b/basic/source/comp/dim.cxx
index bff3d22dd9b0..b8fa3c089fd8 100644
--- a/basic/source/comp/dim.cxx
+++ b/basic/source/comp/dim.cxx
@@ -161,6 +161,9 @@ void SbiParser::TypeDecl( SbiSymDef& rDef, BOOL bAsNewAlreadyParsed )
// In den String-Pool uebernehmen
rDef.SetTypeId( aGblStrings.Add( aCompleteName ) );
+
+ if( rDef.IsNew() && pProc == NULL )
+ aRequiredTypes.push_back( aCompleteName );
}
eType = SbxOBJECT;
break;
diff --git a/basic/source/inc/parser.hxx b/basic/source/inc/parser.hxx
index 1161c4ed259d..733a65db7f61 100644
--- a/basic/source/inc/parser.hxx
+++ b/basic/source/inc/parser.hxx
@@ -34,7 +34,7 @@
#include <vector>
-typedef ::std::vector< String > IfaceVector;
+typedef ::std::vector< String > StringVector;
struct SbiParseStack;
@@ -81,7 +81,8 @@ public:
BOOL bText; // OPTION COMPARE TEXT
BOOL bExplicit; // TRUE: OPTION EXPLICIT
BOOL bClassModule; // TRUE: OPTION ClassModule
- IfaceVector aIfaceVector; // Holds all interfaces implemented by a class module
+ StringVector aIfaceVector; // Holds all interfaces implemented by a class module
+ StringVector aRequiredTypes; // Types used in Dim As New <type> outside subs
SbxDataType eDefTypes[26]; // DEFxxx-Datentypen
SbiParser( StarBASIC*, SbModule* );
diff --git a/basic/source/inc/sbintern.hxx b/basic/source/inc/sbintern.hxx
index 59cfe21d25a8..4c54e2301bd5 100644
--- a/basic/source/inc/sbintern.hxx
+++ b/basic/source/inc/sbintern.hxx
@@ -50,10 +50,16 @@ public:
virtual SbxObject* CreateObject( const String& );
};
+typedef ::std::vector< String > StringVector;
+
struct SbClassData
{
SbxArrayRef mxIfaces;
+ // types this module depends on because of use in Dim As New <type>
+ // needed for initialization order of class modules
+ StringVector maRequiredTypes;
+
SbClassData( void );
~SbClassData( void )
{ clear(); }
diff --git a/basic/source/runtime/methods1.cxx b/basic/source/runtime/methods1.cxx
index 8c7da2403705..9d806cac933a 100644
--- a/basic/source/runtime/methods1.cxx
+++ b/basic/source/runtime/methods1.cxx
@@ -1586,8 +1586,6 @@ RTLFUNC(Join)
}
-typedef ::std::vector< String > StringVector;
-
RTLFUNC(Split)
{
(void)pBasic;