Related tdf#171441 idedataprovider: Lazily load libraries on demand

Instead of loading all of the scripting libraries when IdeDataProvider
is initialised, it now only loads them when the children are requested.
This is probably a good idea for efficiency anyway, but it also
partially fixes the problem described in tdf#171441. Loading a library
ends up making the members of the library accessible in the global
namespace of a running script. That meant that just openining the macro
editor would cause the IdeDataProvider to make all members of all
libraries available to the current script. If we lazily load them then
they are instead only available if the object browser is manipulated.
This is still a problem, but it’s no worse than the existing object
catalog and macro dialogs which also have the same problem (see comments
4&5 of the bug).

Change-Id: I43ccd06cee45e53e6575f768fa24fe4befeefc20
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206473
Tested-by: Jenkins
Reviewed-by: Neil Roberts <nroberts@libreoffice.org>
(cherry picked from commit 8fa45b9f69)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207094
This commit is contained in:
Neil Roberts
2026-06-22 11:17:09 +02:00
parent ebebf57585
commit 8d69ce7f59
+2 -75
View File
@@ -335,6 +335,8 @@ void ImplGetChildrenOfBasicLibrary(SymbolInfoList& rChildren, const IdeSymbolInf
BasicManager* pBasMgr = aDoc.getBasicManager();
if (aDoc.hasLibrary(E_SCRIPTS, rParent.sName))
{
aDoc.loadLibraryIfExists(E_SCRIPTS, rParent.sName);
StarBASIC* pLib = pBasMgr->GetLib(rParent.sName);
if (pLib)
{
@@ -374,81 +376,6 @@ void IdeDataProvider::Initialize()
SAL_INFO("basctl", "Performing full synchronous UNO scan...");
performFullUnoScan();
// Preload all BASIC Libraries
IdeTimer aBasicTimer(u"IdeDataProvider::Initialize (Basic Library Preload)"_ustr);
SAL_INFO("basctl", "Starting BASIC library preload...");
try
{
ScriptDocument aAppDoc = ScriptDocument::getApplicationScriptDocument();
if (aAppDoc.isAlive())
{
Reference<css::script::XLibraryContainer> xLibContainer
= aAppDoc.getLibraryContainer(E_SCRIPTS);
if (xLibContainer.is())
{
for (const OUString& rLibName : xLibContainer->getElementNames())
{
try
{
if (xLibContainer->hasByName(rLibName)
&& !xLibContainer->isLibraryLoaded(rLibName))
{
xLibContainer->loadLibrary(rLibName);
}
}
catch (const Exception& e)
{
SAL_WARN("basctl", "Exception while preloading application library '"
<< rLibName << "': " << e.Message);
}
}
}
}
}
catch (const Exception& e)
{
SAL_WARN("basctl", "Could not retrieve Application library container: " << e.Message);
}
// Preload from any open documents
try
{
for (const auto& rDoc :
ScriptDocument::getAllScriptDocuments(ScriptDocument::DocumentsSorted))
{
if (rDoc.isAlive())
{
auto xDocLibContainer = rDoc.getLibraryContainer(E_SCRIPTS);
if (xDocLibContainer.is())
{
for (const OUString& rLibName : xDocLibContainer->getElementNames())
{
try
{
if (xDocLibContainer->hasByName(rLibName)
&& !xDocLibContainer->isLibraryLoaded(rLibName))
{
xDocLibContainer->loadLibrary(rLibName);
}
}
catch (const Exception& e)
{
SAL_WARN("basctl", "Exception while preloading document library '"
<< rLibName << "' in document '"
<< rDoc.getTitle() << "': " << e.Message);
}
}
}
}
}
}
catch (const Exception& e)
{
SAL_WARN("basctl", "Could not iterate through document libraries: " << e.Message);
}
SAL_INFO("basctl", "BASIC library preload finished.");
m_aAllTopLevelNodes.clear();
m_aAllTopLevelNodes.push_back(
std::make_shared<IdeSymbolInfo>(u"UNO APIs", IdeSymbolKind::ROOT_UNO_APIS, u"root"));