basctl/Library_basctl.mk                          |    4 
 basctl/source/basicide/idecodecompletiontypes.cxx |   55 ++++++
 basctl/source/basicide/idedataprovider.cxx        |   20 ++
 basctl/source/basicide/idetimer.cxx               |   42 +++++
 basctl/source/basicide/idetimer.hxx               |   37 ++++
 basctl/source/basicide/objectbrowser.cxx          |   36 ++++
 basctl/source/inc/idedataprovider.hxx             |   32 ++++
 basctl/source/inc/objectbrowser.hxx               |   39 ++++
 include/basctl/idecodecompletiontypes.hxx         |  174 ++++++++++++++++++++++
 9 files changed, 439 insertions(+)

New commits:
commit dadddf3861f10bf3a869f85afff612732d50f518
Author:     Devansh Varshney <varshney.devansh...@gmail.com>
AuthorDate: Tue Aug 19 23:53:16 2025 +0530
Commit:     Jonathan Clark <jonat...@libreoffice.org>
CommitDate: Fri Sep 26 20:53:40 2025 +0200

    tdf#165785: basctl: Core Data Structures for Object Browser
    
    This commit introduces the core data structures and minimal C++ class
    definitions for the new BASIC IDE Object Browser. It establishes the
    necessary foundation for the feature, allowing the code to build cleanly.
    
    The actual logic for the UI, data fetching, and other features
    will be implemented in subsequent, focused patches.
    
    (GSoC 2025 - Object Browser: Core Data Structures)
    
    Change-Id: Ibd9bb6be0adf579d156662bf33565de497187a55
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189934
    Reviewed-by: Jonathan Clark <jonat...@libreoffice.org>
    Tested-by: Jenkins

diff --git a/basctl/Library_basctl.mk b/basctl/Library_basctl.mk
index 3dfb2f2522f4..37c94edd089a 100644
--- a/basctl/Library_basctl.mk
+++ b/basctl/Library_basctl.mk
@@ -94,6 +94,9 @@ $(eval $(call gb_Library_add_exception_objects,basctl,\
        basctl/source/basicide/doceventnotifier \
        basctl/source/basicide/docsignature \
        basctl/source/basicide/documentenumeration \
+       basctl/source/basicide/idecodecompletiontypes \
+       basctl/source/basicide/idedataprovider \
+       basctl/source/basicide/idetimer \
        basctl/source/basicide/iderdll \
        basctl/source/basicide/layout \
        basctl/source/basicide/linenumberwindow \
@@ -104,6 +107,7 @@ $(eval $(call gb_Library_add_exception_objects,basctl,\
        basctl/source/basicide/moduldlg \
        basctl/source/basicide/BasicColorConfig \
        basctl/source/basicide/ColorSchemeDialog \
+       basctl/source/basicide/objectbrowser \
        basctl/source/basicide/ObjectCatalog \
        basctl/source/basicide/sbxitem \
        basctl/source/basicide/scriptdocument \
diff --git a/basctl/source/basicide/idecodecompletiontypes.cxx 
b/basctl/source/basicide/idecodecompletiontypes.cxx
new file mode 100644
index 000000000000..3d9d87756c0a
--- /dev/null
+++ b/basctl/source/basicide/idecodecompletiontypes.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <basctl/idecodecompletiontypes.hxx>
+
+namespace basctl
+{
+IdeParamInfo::IdeParamInfo(OUString sName_, OUString sTypeName_, bool bOut, 
bool bIn)
+    : sName(std::move(sName_))
+    , sTypeName(std::move(sTypeName_))
+    , bIsOut(bOut)
+    , bIsIn(bIn)
+{
+}
+
+IdeDimensionInfo::IdeDimensionInfo(sal_Int32 lower, sal_Int32 upper, bool 
dynamic)
+    : nLowerBound(lower)
+    , nUpperBound(upper)
+    , bIsDynamic(dynamic)
+{
+}
+
+IdeSymbolInfo::IdeSymbolInfo(std::u16string_view rName, IdeSymbolKind eTheKind,
+                             std::u16string_view rParentIdentifier)
+    : sName(rName)
+    , eKind(eTheKind)
+{
+    if (rParentIdentifier.empty())
+    {
+        sIdentifier = OUString::Concat(OUStringLiteral(u"root:")) + rName;
+    }
+    else
+    {
+        // Child ID = Parent's Full ID + ":" + Child's Name
+        sIdentifier = OUString::Concat(rParentIdentifier) + u":" + rName;
+    }
+}
+
+void IdeSymbolInfo::AddMember(std::shared_ptr<IdeSymbolInfo> pMember)
+{
+    if (!pMember)
+        return;
+
+    mapMembers.insert_or_assign(pMember->sName, std::move(pMember));
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/basicide/idedataprovider.cxx 
b/basctl/source/basicide/idedataprovider.cxx
new file mode 100644
index 000000000000..3c094c751426
--- /dev/null
+++ b/basctl/source/basicide/idedataprovider.cxx
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <idedataprovider.hxx>
+
+namespace basctl
+{
+IdeDataProvider::IdeDataProvider() {}
+
+IdeDataProvider::~IdeDataProvider() = default;
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/basicide/idetimer.cxx 
b/basctl/source/basicide/idetimer.cxx
new file mode 100644
index 000000000000..2818890e1999
--- /dev/null
+++ b/basctl/source/basicide/idetimer.cxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL.2.0/.
+ */
+
+#include "idetimer.hxx"
+#include <sal/log.hxx>
+#include <rtl/string.hxx>
+
+#define PERF_LOG_CHANNEL "basctl"
+
+namespace basctl
+{
+IdeTimer::IdeTimer(const rtl::OUString& operationName)
+    : m_sOperationName(operationName)
+{
+    osl_getSystemTime(&m_aStart);
+}
+
+IdeTimer::~IdeTimer()
+{
+    TimeValue aEnd;
+    osl_getSystemTime(&aEnd);
+
+    sal_uInt32 seconds = aEnd.Seconds - m_aStart.Seconds;
+    sal_Int32 nanos = aEnd.Nanosec - m_aStart.Nanosec;
+
+    double fElapsedSeconds = static_cast<double>(seconds) + 
static_cast<double>(nanos) / 1e9;
+
+    // Log the result.
+    SAL_INFO(PERF_LOG_CHANNEL, "Operation '"
+                                   << OUStringToOString(m_sOperationName, 
RTL_TEXTENCODING_UTF8)
+                                   << "' took " << fElapsedSeconds << " 
seconds.");
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/basicide/idetimer.hxx 
b/basctl/source/basicide/idetimer.hxx
new file mode 100644
index 000000000000..58f4c0bda589
--- /dev/null
+++ b/basctl/source/basicide/idetimer.hxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <osl/time.h>
+#include <rtl/ustring.hxx>
+
+namespace basctl
+{
+/**
+     * A simple RAII timer to measure the duration of an operation and log it.
+     * Starts timing upon construction, logs the elapsed time upon destruction.
+     */
+class IdeTimer
+{
+public:
+    explicit IdeTimer(const rtl::OUString& operationName);
+    ~IdeTimer();
+
+private:
+    IdeTimer(const IdeTimer&) = delete;
+    IdeTimer& operator=(const IdeTimer&) = delete;
+
+    rtl::OUString m_sOperationName;
+    TimeValue m_aStart;
+};
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/basicide/objectbrowser.cxx 
b/basctl/source/basicide/objectbrowser.cxx
new file mode 100644
index 000000000000..ec4d8a811394
--- /dev/null
+++ b/basctl/source/basicide/objectbrowser.cxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <iderid.hxx>
+#include "idetimer.hxx"
+#include <objectbrowser.hxx>
+
+#include <strings.hrc>
+
+namespace basctl
+{
+ObjectBrowser::ObjectBrowser(vcl::Window* pParent)
+    : basctl::DockingWindow(pParent, u""_ustr, u"ObjectBrowser"_ustr)
+    , m_pDataProvider(std::make_unique<IdeDataProvider>())
+{
+}
+
+ObjectBrowser::~ObjectBrowser() {}
+
+void ObjectBrowser::Initialize() { m_pDataProvider = 
std::make_unique<IdeDataProvider>(); }
+
+void ObjectBrowser::dispose()
+{
+    m_pDataProvider.reset();
+    DockingWindow::dispose();
+}
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/inc/idedataprovider.hxx 
b/basctl/source/inc/idedataprovider.hxx
new file mode 100644
index 000000000000..21294f2015bc
--- /dev/null
+++ b/basctl/source/inc/idedataprovider.hxx
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <memory>
+#include <basctl/idecodecompletiontypes.hxx>
+
+namespace basctl
+{
+class IdeDataProviderInterface
+{
+public:
+    virtual ~IdeDataProviderInterface() = default;
+};
+
+class IdeDataProvider : public IdeDataProviderInterface
+{
+public:
+    IdeDataProvider();
+    ~IdeDataProvider() override;
+};
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/basctl/source/inc/objectbrowser.hxx 
b/basctl/source/inc/objectbrowser.hxx
new file mode 100644
index 000000000000..b5c01e2833e2
--- /dev/null
+++ b/basctl/source/inc/objectbrowser.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include "bastypes.hxx"
+#include "idedataprovider.hxx"
+
+#include <basctl/idecodecompletiontypes.hxx>
+#include <memory>
+
+namespace basctl
+{
+class Shell;
+class IdeDataProviderInterface;
+
+class ObjectBrowser : public basctl::DockingWindow
+{
+public:
+    ObjectBrowser(vcl::Window* pParent);
+    ~ObjectBrowser() override;
+
+    void Initialize();
+    void dispose() override;
+
+private:
+    // Data Provider
+    std::unique_ptr<IdeDataProviderInterface> m_pDataProvider;
+};
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/basctl/idecodecompletiontypes.hxx 
b/include/basctl/idecodecompletiontypes.hxx
new file mode 100644
index 000000000000..45ab8785fbae
--- /dev/null
+++ b/include/basctl/idecodecompletiontypes.hxx
@@ -0,0 +1,174 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vector>
+#include <map>
+#include <optional>
+#include <memory>
+#include <string_view>
+
+#include <rtl/ustring.hxx>
+#include <basic/sbxdef.hxx>
+
+namespace basctl
+{
+enum class IdeSymbolKind
+{
+    UNKNOWN,
+    VARIABLE,
+    CONSTANT,
+    PARAMETER,
+    FUNCTION,
+    SUB,
+    PROPERTY_GET,
+    PROPERTY_LET,
+    PROPERTY_SET,
+    UDT, // User Defined Type (Struct)
+    UDT_MEMBER,
+    ENUM,
+    ENUM_MEMBER,
+    MODULE,
+    NAMESPACE,
+    LIBRARY,
+    CLASS_MODULE, // BASIC Class Module
+    // UNO specific kinds
+    UNO_SERVICE,
+    UNO_INTERFACE,
+    UNO_STRUCT,
+    UNO_ENUM,
+    UNO_CONSTANTS, // A constants group
+    UNO_EXCEPTION,
+    UNO_TYPE, // Generic UNO type
+    UNO_TYPEDEF,
+    UNO_METHOD,
+    UNO_PROPERTY,
+    UNO_FIELD, // For struct/exception members
+    // Built-in specific kinds
+    BUILTIN_FUNCTION,
+    BUILTIN_PROPERTY,
+    GLOBAL_CONSTANT_UNO, // e.g. StarDesktop
+    // Logical groupings for the browser UI
+    ROOT_APPLICATION_LIBS,
+    ROOT_DOCUMENT_LIBS,
+    ROOT_UNO_APIS,
+    ROOT_BASIC_BUILTINS,
+    UNO_NAMESPACE,
+    PLACEHOLDER // For temporary UI nodes like "[Loading...]"
+};
+
+enum class IdeScopeKind
+{
+    UNKNOWN,
+    GLOBAL_APPLICATION,
+    GLOBAL_DOCUMENT,
+    LIBRARY_PUBLIC,
+    MODULE_PUBLIC,
+    MODULE_PRIVATE,
+    CLASS_MEMBER_PUBLIC,
+    CLASS_MEMBER_PRIVATE,
+    PROCEDURE_LOCAL,
+    BLOCK_LOCAL,
+    WITH_BLOCK_MEMBER
+};
+
+enum class IdeAccessModifier
+{
+    NOT_APPLICABLE,
+    PUBLIC,
+    PRIVATE
+};
+
+struct IdeParamInfo
+{
+    OUString sName;
+    OUString sTypeName;
+    OUString sQualifiedTypeName;
+    SbxDataType eBasicType = SbxDataType::SbxEMPTY;
+    bool bIsByVal = true;
+    bool bIsOptional = false;
+    bool bIsUnoTypeOrigin = false;
+    std::optional<OUString> osDefaultValueExpression;
+    bool bIsParamArray = false;
+    // For UNO parameters
+    bool bIsOut = false;
+    bool bIsIn = true;
+
+    IdeParamInfo() = default;
+    IdeParamInfo(OUString sName_, OUString sTypeName_, bool bOut, bool bIn);
+};
+
+/**
+ * @struct IdeDimensionInfo
+ * @brief Represents array dimension bounds.
+ */
+struct IdeDimensionInfo
+{
+    sal_Int32 nLowerBound = 0;
+    sal_Int32 nUpperBound = 0;
+    bool bIsDynamic = true;
+
+    IdeDimensionInfo() = default;
+    IdeDimensionInfo(sal_Int32 lower, sal_Int32 upper, bool dynamic = false);
+};
+
+/**
+ * @struct IdeSymbolInfo
+ * @brief Comprehensive structure for storing metadata about any program 
symbol.
+ * @comment For mapMembers, the IdeSymbolInfo objects pointed to are owned.
+ *          Direct cycles through mapMembers are not expected from BASIC 
language constructs.
+ *          UNO type cycles are handled by name resolution against a global 
UNO type cache.
+ */
+struct IdeSymbolInfo
+{
+    bool bSelectable = true;
+    OUString sIdentifier;
+    OUString sName;
+    OUString sQualifiedName;
+    IdeSymbolKind eKind = IdeSymbolKind::UNKNOWN;
+    OUString sTypeName;
+    OUString sQualifiedTypeName;
+    SbxDataType eBasicType = SbxDataType::SbxEMPTY;
+    bool bIsUnoTypeOrigin = false;
+    IdeScopeKind eScope = IdeScopeKind::UNKNOWN;
+    OUString sOriginLibrary;
+    OUString sOriginLocation;
+    OUString sOriginModule;
+    OUString sOriginUnoContainer;
+    OUString sParentName;
+    sal_Int32 nSourceLine = -1;
+    sal_Int32 nSourceColumn = -1;
+    std::vector<IdeParamInfo> aParameters;
+    OUString sReturnTypeName;
+    OUString sQualifiedReturnTypeName;
+    bool bIsArray = false;
+    std::vector<IdeDimensionInfo> aArrayDimensions;
+    IdeAccessModifier eAccessModifier = IdeAccessModifier::NOT_APPLICABLE;
+    bool bIsResolved = true;
+    bool bHasParseErrors = false;
+    std::optional<OUString> osConstantValue;
+    std::optional<OUString> osBriefDescription;
+    std::optional<OUString> osFullSignatureForDisplay;
+    std::optional<OUString> osHelpURL;
+    std::map<OUString, std::shared_ptr<IdeSymbolInfo>> mapMembers;
+
+    IdeSymbolInfo() = default;
+    IdeSymbolInfo(std::u16string_view rName, IdeSymbolKind eTheKind,
+                  std::u16string_view rParentIdentifier);
+
+    void AddMember(std::shared_ptr<IdeSymbolInfo> pMember);
+};
+
+using SymbolInfoList = std::vector<std::shared_ptr<IdeSymbolInfo>>;
+using ParamInfoList = std::vector<IdeParamInfo>;
+
+} // namespace basctl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */

Reply via email to