refactor: replace private access hacks with accessor pattern#315
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: zccrs The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Pull request overview
This PR removes the #define private/protected public access hack in the platform theme plugin and replaces it with a “private accessor” pattern based on explicit template instantiation ([temp.explicit]/12), and adds CI workflows to build in Deepin/Arch container environments.
Changes:
- Introduce
dprivateaccessor_p.hmacros to access private/static Qt internals without preprocessor access hacks. - Update
qdeepintheme.cppto use the new accessor macros forQHighDpiScalingprivate statics across Qt versions. - Add GitHub Actions workflows for Deepin crimson and Arch Linux container builds.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
platformthemeplugin/qdeepintheme.cpp |
Replaces direct private static access with D_PRIVATE_STATIC_MEMBER(...) accessor usage. |
platformthemeplugin/dprivateaccessor_p.h |
Adds the explicit-instantiation-based private member accessor infrastructure. |
platformthemeplugin/CMakeLists.txt |
Registers the new private accessor header in the plugin headers list. |
.github/workflows/qt5integration-deepin-build.yml |
Adds a Deepin crimson container build workflow producing .deb artifacts. |
.github/workflows/qt5integration-archlinux-build.yml |
Adds an Arch container build workflow producing an installation zip artifact. |
Comments suppressed due to low confidence (2)
platformthemeplugin/dprivateaccessor_p.h:53
dtk_private_detail::access()is declaredconstexprbut callsget(t), which is notconstexprhere. With C++17 this typically makes the function ill-formed (aconstexprfunction can’t call a non-constexprfunction). Either removeconstexprfromaccess()or make the friendget(Tag)declaration/definitionconstexpras well.
namespace dtk_private_detail {
template<typename Tag>
inline constexpr typename Tag::MemberPtr access(Tag t) noexcept { return get(t); }
}
.github/workflows/qt5integration-deepin-build.yml:51
apt-get install -y --allow-unauthenticated wlr-protocols || trueboth bypasses package authentication and masks installation failures. If the package is optional, prefer checking availability explicitly and keep signature verification enabled; otherwise, remove--allow-unauthenticatedand the unconditional|| trueso failures are actionable.
set -euxo pipefail
apt-get install -y --allow-unauthenticated wlr-protocols || true
cd /tmp
git clone --depth=1 https://github.com/linuxdeepin/treeland-protocols.git
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // function is findable via ADL when calling get(TagName{}). | ||
|
|
||
| QT_WARNING_PUSH | ||
| QT_WARNING_DISABLE_GCC("-Wnon-template-friend") | ||
|
|
||
| template<typename Tag> | ||
| struct Qt5IntegrationPrivateAccessor |
| set -euxo pipefail | ||
| echo "deb [trusted=yes] http://mirrors.kernel.org/deepin/beige/ crimson main commercial community" > /etc/apt/sources.list | ||
| echo "deb-src [trusted=yes] http://mirrors.kernel.org/deepin/beige/ crimson main commercial community" >> /etc/apt/sources.list | ||
| rm -rf /etc/apt/sources.list.d |
| jobs: | ||
| container: | ||
| runs-on: ubuntu-latest | ||
| container: archlinux:latest |
2a98271 to
0808fb2
Compare
Use C++ [temp.explicit]/12 explicit instantiation to bypass access control instead of #define private/protected public hacks.
tar is always available in base system, no pacman install needed Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
deepin pr auto review你好!我是CodeGeeX。我已经仔细审查了你提供的Git Diff,本次修改主要包含三个部分:新增两个CI构建工作流、引入一个用于安全访问私有成员的宏工具集 总体来说,这次修改的方向非常好,特别是移除 1. 代码逻辑与正确性1.1 显式模板实例化在头文件中的多重定义风险 (高优先级)
1.2
1.3 D_DECLARE_PRIVATE_STATIC_MEMBER(QHighDpiScaling_m_logicalDpi_tag, QHighDpiScaling, m_logicalDpi, QHighDpiScaling_m_logicalDpi_type);
2. 代码性能2.1 CI 工作流中的冗余包安装 (中优先级)
2.2 宏展开带来的运行时开销 (低优先级)
3. 代码安全3.1 恭喜移除 3.2 Deepin CI 工作流中的 apt-get install -y --allow-unauthenticated wlr-protocols || true使用
3.3 CI 工作流中缺少权限限制 (中优先级)
4. 其他改进建议 (格式规范与健壮性)4.1 宏的安全性增强 (中优先级)
4.2 SPDX 版权年份的自动更新 (低优先级) -# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
+# SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.写死未来的年份(2026)在开源合规中通常不推荐,因为无法预知代码是否会在 2026 年仍被维护修改。
4.3 Deepin CI 中的 总结代码修改示例针对 // dprivateaccessor_p.h
template<typename Tag>
struct Qt5IntegrationPrivateAccessor {
using MemberPtr = typename Tag::MemberPtr;
// 使用静态成员函数代替友元函数,无需 ADL,无需显式模板实例化
static MemberPtr get() noexcept;
};
template<typename Tag, typename Tag::MemberPtr Ptr>
struct Qt5IntegrationPrivateAccessorImpl : Qt5IntegrationPrivateAccessor<Tag> {
// 特化静态成员函数
friend typename Tag::MemberPtr Qt5IntegrationPrivateAccessor<Tag>::get() noexcept { return Ptr; }
};
namespace dtk_private_detail {
template<typename Tag>
inline typename Tag::MemberPtr access() noexcept { return Qt5IntegrationPrivateAccessor<Tag>::get(); }
}
// 宏定义:不再需要 template struct 显式实例化,头文件包含安全
#define D_DECLARE_PRIVATE_STATIC_MEMBER(TagName, ClassName, MemberName, MemberType) \
struct TagName { \
using MemberPtr = MemberType*; \
}; \
template <> \
typename TagName::MemberPtr Qt5IntegrationPrivateAccessor<TagName>::get() noexcept; \
inline typename TagName::MemberPtr Qt5IntegrationPrivateAccessorImpl<TagName, &ClassName::MemberName>::Qt5IntegrationPrivateAccessor<TagName>::get() noexcept { return &ClassName::MemberName; }
#define D_PRIVATE_STATIC_MEMBER(tag) (*dtk_private_detail::access<decltype(tag)>())(注:上述代码利用内联特化取代了显式模板实例化,彻底解决了多编译单元链接冲突问题,并去除了对 ADL 的依赖。) 希望这些审查意见对你有所帮助!如果有任何疑问,欢迎随时讨论。 |
Use C++ [temp.explicit]/12 explicit instantiation to bypass access control instead of #define private/protected public hacks.