-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecation handling - better error messages + compile-time error when time to deprecate #4912
Conversation
…pile-time error when it's time to remove deprecated
…model) cd developer/ruby && ruby DeprecatedMethods.rb
…for better message
@@ -206,7 +206,7 @@ set(ENERGYPLUS_REPO "NREL") | |||
set(RADIANCE_VERSION "5.0.a.12") | |||
|
|||
# configure file with version information | |||
configure_file(${PROJECT_SOURCE_DIR}/OpenStudio.in ${PROJECT_BINARY_DIR}/src/OpenStudio.hxx) | |||
configure_file(${PROJECT_SOURCE_DIR}/OpenStudio.hxx.in ${PROJECT_BINARY_DIR}/src/OpenStudio.hxx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was annoyed this wasn't hxx.in so I changed it
namespace openstudio { | ||
namespace detail { | ||
|
||
inline constexpr int cx_openStudioVersionMajor() { | ||
return ${PROJECT_VERSION_MAJOR}; | ||
} | ||
inline constexpr int cx_openStudioVersionMinor() { | ||
return ${PROJECT_VERSION_MINOR}; | ||
} | ||
inline constexpr int cx_openStudioVersionPatch() { | ||
return ${PROJECT_VERSION_PATCH}; | ||
} | ||
inline constexpr std::string_view cx_openStudioVersion() { | ||
return "${OPENSTUDIO_VERSION}"; | ||
} | ||
|
||
} // namespace detail | ||
} // namespace openstudio |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nobody responded when I asked if we could change inline std::string openStudioVersionMajor()
to return int or not, so I added this constexpr int version in a detail namespace
#define OS_DEPRECATED(__deprecatedAtVersionMajor__, __deprecatedAtVersionMinor__, __deprecatedAtVersionPatch__) \ | ||
[[deprecated("Deprecated at " #__deprecatedAtVersionMajor__ "." #__deprecatedAtVersionMinor__ "." #__deprecatedAtVersionPatch__ \ | ||
". It will be removed after three releases.")]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OS_DEPRECATED changed here
#ifndef UTILITIES_CORE_DEPRECATEDHELPERS_HPP | ||
#define UTILITIES_CORE_DEPRECATEDHELPERS_HPP | ||
|
||
#include "Compare.hpp" | ||
#include "Exception.hpp" | ||
#include "Logger.hpp" | ||
|
||
#include <OpenStudio.hxx> | ||
|
||
#include <boost/current_function.hpp> | ||
#include <fmt/core.h> | ||
#include <fmt/compile.h> | ||
|
||
#include <string> | ||
|
||
namespace openstudio { | ||
|
||
struct cx_VersionString | ||
{ | ||
constexpr cx_VersionString(int t_major, int t_minor, int t_patch) : major(t_major), minor(t_minor), patch(t_patch) {} | ||
|
||
constexpr cx_VersionString() = default; | ||
|
||
constexpr bool isGreaterThan(const cx_VersionString& other, int numMinors = 3) const { | ||
return (major > other.major) || (minor >= other.minor + numMinors); | ||
} | ||
|
||
std::string str() const { | ||
return fmt::format("{}.{}.{}", major, minor, patch); | ||
} | ||
|
||
int major = openstudio::detail::cx_openStudioVersionMajor(); | ||
int minor = openstudio::detail::cx_openStudioVersionMinor(); | ||
int patch = openstudio::detail::cx_openStudioVersionPatch(); | ||
}; | ||
|
||
// static inline constexpr cx_VersionString cx_currentVersion{}; | ||
|
||
namespace detail { | ||
inline void log_deprecation_and_throw_if_time_to_remove(const std::string& deprecatedAt, const std::string& logChannel, | ||
const std::string& methodName, const std::string& extraMessage = "") { | ||
if (extraMessage.empty()) { | ||
LOG_FREE(Warn, logChannel, "As of " << deprecatedAt << ", " << methodName << " is deprecated."); | ||
} else { | ||
LOG_FREE(Warn, logChannel, "As of " << deprecatedAt << ", " << methodName << " is deprecated. " << extraMessage); | ||
} | ||
} | ||
} // namespace detail | ||
} // namespace openstudio | ||
|
||
#define DEPRECATED_AT(__deprecatedAtVersionMajor__, __deprecatedAtVersionMinor__, __deprecatedAtVersionPatch__) \ | ||
DEPRECATED_AT_MSG(__deprecatedAtVersionMajor__, __deprecatedAtVersionMinor__, __deprecatedAtVersionPatch__, "") | ||
|
||
#define DEPRECATED_AT_MSG(__deprecatedAtVersionMajor__, __deprecatedAtVersionMinor__, __deprecatedAtVersionPatch__, __message__) \ | ||
constexpr openstudio::cx_VersionString deprecatedAt(__deprecatedAtVersionMajor__, __deprecatedAtVersionMinor__, __deprecatedAtVersionPatch__); \ | ||
static_assert(true || !openstudio::cx_VersionString{}.isGreaterThan(deprecatedAt), \ | ||
"Time to remove, deprecated at " #__deprecatedAtVersionMajor__ "." #__deprecatedAtVersionMinor__ "." #__deprecatedAtVersionPatch__); \ | ||
openstudio::detail::log_deprecation_and_throw_if_time_to_remove(deprecatedAt.str(), logChannel(), BOOST_CURRENT_FUNCTION, __message__) | ||
|
||
#endif // UTILITIES_CORE_DEPRECATEDHELPERS_HPP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeprecatedHelpers for the CPP files. I didn't want to pollute the headers of the files that have deprecated methods with the deps, so I made it a separate file from Deprecated.hpp.
The rest is a mix of constexpr/consteval and macro hell.
|
||
#define DEPRECATED_AT_MSG(__deprecatedAtVersionMajor__, __deprecatedAtVersionMinor__, __deprecatedAtVersionPatch__, __message__) \ | ||
constexpr openstudio::cx_VersionString deprecatedAt(__deprecatedAtVersionMajor__, __deprecatedAtVersionMinor__, __deprecatedAtVersionPatch__); \ | ||
static_assert(true || !openstudio::cx_VersionString{}.isGreaterThan(deprecatedAt), \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've disabled the static_assert for now, because there are tons of methods that due to deprecate and I wanted this to be reviewed before I remove them.
- TODO: remove the disabling part
static_assert(true || !openstudio::cx_VersionString{}.isGreaterThan(deprecatedAt), \ | |
static_assert(!openstudio::cx_VersionString{}.isGreaterThan(deprecatedAt), \ |
@@ -825,7 +826,7 @@ namespace model { | |||
} | |||
|
|||
std::string AirTerminalSingleDuctVAVReheat::zoneMinimumAirFlowMethod() { | |||
LOG(Warn, "zoneMinimumAirFlowMethod is deprecated, please use zoneMinimumAirFlowInputMethod"); | |||
DEPRECATED_AT_MSG(3, 0, 1, "Use zoneMinimumAirFlowInputMethod instead."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example usage in the CPP file
@@ -90,14 +90,14 @@ namespace model { | |||
/** Returns the value of the MaximumAirFlowRate field. */ | |||
std::string zoneMinimumAirFlowInputMethod(); | |||
/** deprecated **/ | |||
OS_DEPRECATED std::string zoneMinimumAirFlowMethod(); | |||
OS_DEPRECATED(3, 0, 1) std::string zoneMinimumAirFlowMethod(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example usage in the HPP file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the deprecated_methods.csv while I was at it.
constexpr bool isGreaterThan(const cx_VersionString& other, int numMinors = 3) const { | ||
return (major > other.major) || (minor >= other.minor + numMinors); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the logic I'm using to determine whether it's time to remove the deprecated method.
I have another way in mind that could capture the patch (if that's what we want), but it involves keeping a version history up to date, so not a fan.
As a free function:
consteval std::size_t numVersionsPassed(
openstudio::cx_VersionString deprecatedAt) {
std::array<openstudio::cx_VersionString, 3> versionHistory{{
{3, 5, 0},
{3, 6, 0},
{3, 6, 1},
}};
auto curVersion = openstudio::cx_VersionString{};
auto it =
std::find(versionHistory.begin(), versionHistory.end(), deprecatedAt);
auto itCur =
std::find(versionHistory.begin(), versionHistory.end(), curVersion);
if (it == versionHistory.end()) {
// static_assert(false, "deprecatedAt not found in versionHistory");
}
std::size_t offset = 0;
if (itCur == versionHistory.end()) {
offset = 1;
}
return std::distance(it, versionHistory.end()) - 1 + offset;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the key thing that that needs to be maintained right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we wanted to capture patch, yeah; would have to keep updating versionHistory
. Otherwise the maintenance is nil, just removing deprecated functions when we get the compile time error.
CI Results for a1a3eef:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is cool. I still hope we deprecate sparingly.
Pull request overview
It's been really annoying tracking the deprecated methods. This PR aims to provide facilities to make it easier.
A new DEPRECATED_AT_MSG macro is added in
core/DeprecatedHelpers.cpp
for the CPP filesOS_DEPRECATED (for the hpp files) now takes (major, minor, patch) at which it was deprecated so if you try to use that method in C++ you get a better deprecation warning such as
'void deprecatedFun()' is deprecated: Deprecated at 3.2.0. It will be removed after three releases
. This also makes use of the[[deprecated()]]
attribute instead of using attribute and __declspecGiven this test program:
While we're still within the same major version, and less than 3 minor versions from deprecation, this is the log message
After that, a compile-time error is issued:
The deprecation warning when you try to use it from C++
Pull Request Author
src/model/test
)src/energyplus/Test
)src/osversion/VersionTranslator.cpp
)Labels:
IDDChange
APIChange
Pull Request - Ready for CI
so that CI builds your PRReview Checklist
This will not be exhaustively relevant to every PR.