diff options
author | Philip Chimento <philip.chimento@gmail.com> | 2018-08-19 22:17:28 -0400 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2018-08-19 22:54:21 -0400 |
commit | f55c0123ad9be959d133c9c94292525e70b768f9 (patch) | |
tree | 81b0ddaed61a62fde905794f681c2269d31c6379 | |
parent | 3276e0c1b4cfce44d3d69dc02dd4285e9a9bd733 (diff) | |
download | gjs-f55c0123ad9be959d133c9c94292525e70b768f9.tar.gz |
deprecation: Add deprecation warning framework
This adds a framework for deprecation warnings. It consists of an enum of
deprecated features, and the API _gjs_warn_deprecated_once_per_callsite()
which warns only once in each place the feature is used, even if that
code is executed more than once.
This is meant to be joined in the future by _gjs_warn_deprecated_once()
and _gjs_warn_deprecated_once_per_file(), since we have unconditional
deprecation warnings elsewhere in GJS that could very well use those
APIs.
-rw-r--r-- | gjs-srcs.mk | 2 | ||||
-rw-r--r-- | gjs/deprecation.cpp | 91 | ||||
-rw-r--r-- | gjs/deprecation.h | 36 |
3 files changed, 129 insertions, 0 deletions
diff --git a/gjs-srcs.mk b/gjs-srcs.mk index dadfa0ed..6e172b45 100644 --- a/gjs-srcs.mk +++ b/gjs-srcs.mk @@ -59,6 +59,8 @@ gjs_srcs = \ gjs/context-private.h \ gjs/coverage.cpp \ gjs/debugger.cpp \ + gjs/deprecation.cpp \ + gjs/deprecation.h \ gjs/engine.cpp \ gjs/engine.h \ gjs/global.cpp \ diff --git a/gjs/deprecation.cpp b/gjs/deprecation.cpp new file mode 100644 index 00000000..9faf0c02 --- /dev/null +++ b/gjs/deprecation.cpp @@ -0,0 +1,91 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* + * Copyright (c) 2018 Philip Chimento <philip.chimento@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <string> +#include <unordered_set> + +#include "gjs/context-private.h" +#include "gjs/deprecation.h" +#include "gjs/jsapi-util.h" +#include "gjs/jsapi-wrapper.h" + +const char* messages[] = { + // None: + "(invalid message)", +}; + +struct DeprecationEntry { + GjsDeprecationMessageId id; + std::string loc; + + DeprecationEntry(GjsDeprecationMessageId an_id, const char* a_loc) + : id(an_id), loc(a_loc) {} + + bool operator==(const DeprecationEntry& other) const { + return id == other.id && loc == other.loc; + } +}; + +namespace std { +template <> +struct hash<DeprecationEntry> { + size_t operator()(const DeprecationEntry& key) const { + return hash<int>()(key.id) ^ hash<std::string>()(key.loc); + } +}; +}; // namespace std + +static std::unordered_set<DeprecationEntry> logged_messages; + +static char* get_callsite(JSContext* cx) { + JS::RootedObject stack_frame(cx); + if (!JS::CaptureCurrentStack(cx, &stack_frame, + JS::StackCapture(JS::MaxFrames(1))) || + !stack_frame) + return nullptr; + + JS::RootedValue v_frame(cx, JS::ObjectValue(*stack_frame)); + JS::RootedString frame_string(cx, JS::ToString(cx, v_frame)); + if (!frame_string) + return nullptr; + + GjsAutoJSChar frame_utf8; + if (!gjs_string_to_utf8(cx, JS::StringValue(frame_string), &frame_utf8)) + return nullptr; + return frame_utf8.release(); +} + +/* Note, this can only be called from the JS thread because it uses the full + * stack dump API and not the "safe" gjs_dumpstack() which can only print to + * stdout or stderr. Do not use this function during GC, for example. */ +void _gjs_warn_deprecated_once_per_callsite(JSContext* cx, + const GjsDeprecationMessageId id) { + GjsAutoJSChar callsite = get_callsite(cx); + DeprecationEntry entry(id, callsite); + if (!logged_messages.count(entry)) { + JS::UniqueChars stack_dump = JS::FormatStackDump(cx, nullptr, false, + false, false); + g_warning("%s\n%s", messages[id], stack_dump.get()); + logged_messages.insert(std::move(entry)); + } +} diff --git a/gjs/deprecation.h b/gjs/deprecation.h new file mode 100644 index 00000000..7353388f --- /dev/null +++ b/gjs/deprecation.h @@ -0,0 +1,36 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* + * Copyright (c) 2018 Philip Chimento <philip.chimento@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef GJS_DEPRECATION_H_ +#define GJS_DEPRECATION_H_ + +#include "gjs/jsapi-wrapper.h" + +enum GjsDeprecationMessageId { + None, +}; + +void _gjs_warn_deprecated_once_per_callsite(JSContext* cx, + GjsDeprecationMessageId message); + +#endif /* GJS_DEPRECATION_H_ */ |