/
bsls_deprecatefeature.h
288 lines (276 loc) · 12.7 KB
/
bsls_deprecatefeature.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// bsls_deprecatefeature.h -*-C++-*-
#ifndef INCLUDED_BSLS_DEPRECATEFEATURE
#define INCLUDED_BSLS_DEPRECATEFEATURE
//@PURPOSE: Provide machinery to deprecate entities in C++ code.
//
//@MACROS:
// BSLS_DEPRECATE_FEATURE: mark a C++ entity as deprecated
//
//@DESCRIPTION: This component provides facilities to identify deprecated C++
// entities. The deprecation annotations supplied by this component may,
// depending on the build configuration, instantiate as C++ '[[deprecated]]'
// annotations for which the compiler will emit a warning. Each deprecated
// entity annotated by the macros in this component is identified by a 'UOR'
// and 'FEATURE', allowing the use of that deprecated entity to be more easily
// uniquely identified and tracked over time via tooling. Here "UOR" means
// Unit-Of-Release, which is typically a package, package-group or library.
//
// **WARNING**: The build configuration flag,
// 'BB_DEPRECATE_ENABLE_ALL_DEPRECATIONS_FOR_TESTING', that enables compiler
// warnings for 'BSLS_DEPRECATE_FEATURE' should not be used in
// cross-organizational integration builds such as a production 'unstable'
// dpkg build.
//
///Concerns with Compiler Warnings
///- - - - - - - - - - - - - - - -
// In large development organization, where many teams may enable "warnings as
// errors", enabling deprecation warnings in a cross-organizational integration
// build will frequently prevent lower-level software from applying the
// deprecation annotation to any newly deprecated code.
//
// Instead this component is designed to support static analysis tools that
// identify deprecated entities, and allow them to be tracked and reported by
// systems outside of the normal compilation process. The expectation is that
// developers would use configuration options that generate compiler warnings
// in local builds when they are actively working to remove the use of
// deprecated code.
//
///Macro Reference
///---------------
// This section documents the preprocessor macros defined in this component.
//
//: 'BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)':
//: This macro is used to annotate code to indicate that a name or entity
//: has been deprecated, and is associated with the specified 'UOR'
//: (Unit-Of-Release), deprecated 'FEATURE', and 'MESSAGE'. This macro can
//: be used as if it were the C++ standard attribute '[[deprecated]]', and
//: in appropriate build configurations will instantiate as a C++
//: '[[deprecated]]' annotation. 'UOR' and 'FEATURE' are character strings
//: intended to uniquely identify one or more related entities that have
//: been deprecated. 'MESSAGE' is a descriptive text intended for the a
//: user of the deprecated feature (for example informing them of a
//: replacement feature). For example, if several of the date and time
//: types in the 'bde' library were deprecated they might be marked with the
//: annotation:
//: 'BSLS_DEPRECATE_FEATURE("bde", "date-and-time", "Use bdlt instead")'.
//: 'UOR' and 'FEATURE' are meant to help uniquely identify a deprecation in
//: external systems (e.g., a dashboard monitoring the state of a
//: deprecation) so the supplied strings should start with a letter, and
//: contain only letters, numbers, underscore, and dash characters (i.e.,
//: matching the regular expression "[a-zA-Z][\w\-]*").
//:
//: 'BSLS_DEPRECATE_FEATURE_IS_SUPPORTED': This macro is defined if the
//: current platform supports instantiating the deprecation annotation
//: macros into annotation understood by the compiler.
//:
//: 'BSLS_DEPRECATE_FEATURE_ANNOTATION_IS_ACTIVE': This macro is defined if
//: deprecation annotation macros defined in this component *will* be
//: instantiated into annotations understood by the compiler (i.e., this
//: will be defined if 'BSLS_DEPRECATE_FEATURE_SUPPORTED_PLATFORM' is
//: defined and the build configuration macros are configured in a way
//: that the annotations will instantiate as the '[[deprecated]]'
//: attribute).
//
///Configuration Reference
///-----------------------
// There are a set of macros, not defined by this component, that users may
// supply (e.g., to their build system) to configure the behavior of the
// deprecation annotation macros provided by this component.
//
// The available configuration macros are described below:
//..
// * 'BB_DEPRECATE_ENABLE_ALL_DEPRECATIONS_FOR_TESTING': This macro, when
// defined, enables the instantiation of every deprecation macro as a C++
// '[[deprecated]]' annotation. This *MUST* *NOT* be defined as part of
// cross-organization integration build such as an 'unstable' dpkg build
// (see {Concerns with Compiler Warnings}).
//
// * 'BB_DEPRECATE_ENABLE_JSON_MESSAGE': Changes the messages reported by
// compiler deprecation annotations to be a JSON document intended to
// be useful for tools looking to identify and categorize deprecations.
//
// * 'BSLS_DEPRECATE_FEATURE_ENABLE_ALL_DEPRECATIONS_FOR_TESTING': This macro
// is a synonym for 'BB_DEPRECATE_ENABLE_ALL_DEPRECATIONS_FOR_TESTING'.
//
// * 'BSLS_DEPRECATE_FEATURE_ENABLE_JSON_MESSAGE': This macro is a synonym for
// 'BB_DEPRECATE_ENABLE_JSON_MESSAGE'.
//..
//
///Usage
///-----
// In this section we show intended usage of this component.
//
///Example 1: Deprecating a Feature
/// - - - - - - - - - - - - - - - -
// The following example demonstrates using the 'BSLS_DEPRECATE_FEATURE' macro
// to deprecate several C++ entities.
//
// The 'BSLS_DEPRECATE_FEATURE' macro can be applied in the same way as the C++
// '[[deprecated]]' annotation. For example, imagine we are deprecating a
// function 'oldFunction' in the 'bsl' library as part of migrating software to
// the linux platform, we might write:
//..
// BSLS_DEPRECATE_FEATURE("bsl", "oldFunction", "Use newFunction instead")
// void oldFunction();
//..
// Here the string "bsl" refers to the library or Unit-Of-Release (UOR) that
// the deprecation occurs in. "oldFunction" is an arbitrary identifier for
// the feature being deprecated. Together the 'UOR' and 'FEATURE' are
// intended to form a unique enterprise-wide identifier for the feature being
// deprecated. Finally the string "Use newFunction instead" is a message for
// users of the deprecated feature.
//
// Marking 'oldFunction' in this way makes the deprecation of 'oldFunction'
// visible to code analysis tools. In addition, in a local build, warnings
// for uses of the deprecated entity can be enabled using a build macro
// 'BB_DEPRECATE_ENABLE_ALL_DEPRECATIONS_FOR_TESTING' (this macro *MUST* *NOT*
// be used as part of a cross-organization integration build such as a
// 'unstable' dpkg build, see {Concerns with Compiler Warnings}).
//
// Similarly, if we were deprecating a class 'OldType' we might write:
//..
//
// class BSLS_DEPRECATE_FEATURE("bsl", "OldType", "Use NewType instead")
// OldType {
// // ...
// };
//..
// Frequently, more than one C++ related entity may be associated with a
// deprecated feature. In that case we would want to use the same identifier
// for each entity we mark deprecated. To simplify this we might create a
// deprecation macro that is local to the component. For example, if we were
// deprecating a queue and its iterator in the 'bde' library we might write:
//..
// #define BDEC_QUEUE_DEPRECATE \.
// BSLS_DEPRECATE_FEATURE("bde", "bdec_queue", "Use bsl::queue instead")
//
// class BDEC_QUEUE_DEPRECATE bdec_Queue {
// //...
// };
//
// class BDEC_QUEUE_DEPRECATE bdec_QueueIterator {
// //...
// };
//..
// Sometimes several entities are deprecated as part of the same feature where
// separate messages are appropriate. For example, imagine we had a component
// 'bsls_measurementutil' that we were converting from imperial to metric
// units:
//..
// #define BSLS_MEASUREMEANTUTIL_DEPRECATE_IMPERIAL(MESSAGE) \.
// BSLS_DEPRECATE_FEATURE("bsl", "deprecate-imperial-units", MESSAGE)
//
// struct MeasurementUtil {
//
// BSLS_MEASUREMEANTUTIL_DEPRECATE_IMPERIAL("Use getKilometers instead")
// static double getMiles();
//
// BSLS_MEASUREMEANTUTIL_DEPRECATE_IMPERIAL("Use getKilograms instead")
// static double getPounds();
// };
//..
//
///Deprecating a Feature Across Multiple Headers
///- - - - - - - - - - - - - - - - - - - - - - -
// Frequently a feature being deprecated may span multiple components. For
// example, we may want to deprecate all the date and time types in the 'bde'
// library. In those instances one may define a macro in the lowest level
// component (e.g., define 'BDET_DATE_DEPRECATE_DATE_AND_TIME' in 'bdet_date').
// Alternatively, one might create a component specifically for the deprecation
// (e.g., define 'BDET_DEPRECATE_DATE_AND_TIME' in a newly created
// 'bdet_deprecate' component). The following code shows the latter, creating
// a new component, 'bdet_deprecate' in which to provide macros to deprecate
// code across 'bdet'.
//
// First, we create a new component, 'bdet_deprecate` and define the following
// macro:
//..
// // bdet_deprecate.h
//
// #define BDET_DEPRECATE_DATE_AND_TIME(MESSAGE) \.
// BSLS_DEPRECATE_FEATURE("bde", "date-and-time", MESSAGE)
//..
// We can use that macro to mark various components deprecated. Next, we mark
// an old type name as deprecated:
//..
// // bdet_date.h
//
// BDET_DEPRECATE_DATE_AND_TIME("Use bdlt::Date") typedef bdlt::Date Date;
//..
// Then we mark a class declaration as deprecated:
//..
// // bdet_calendar.h
//
// class BDET_DEPRECATE_DATE_AND_TIME("Use bdlt::PackedCalendar") Calendar {
// // ...
// };
//..
// Finally we mark a function as deprecated:
//..
// // bdet_dateimputil.h
//
// struct DateUtil {
//
// BDET_DEPRECATE_DATE_AND_TIME("Use bdlt::DateUtil instead")
// static bool isValidYYYYMMDD(int yyyymmddValue);
//
// // ...
// };
//..
// ==============================
// Component Configuration Macros
// ==============================
// This could be replaced with BSLS_COMPILERFEATURES_CPLUSPLUS, but for the
// moment, this header has 0 dependencies, which may be a useful feature to
// maintain.
#if (defined(__cplusplus) && (__cplusplus >= 201703L)) || \
(defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))
#define BSLS_DEPRECATE_FEATURE_IS_SUPPORTED
#endif
#if defined(BSLS_DEPRECATE_FEATURE_IS_SUPPORTED) && \
(defined(BB_DEPRECATE_ENABLE_ALL_DEPRECATIONS_FOR_TESTING) || \
defined(BSLS_DEPRECATE_FEATURE_ENABLE_ALL_DEPRECATIONS_FOR_TESTING))
#define BSLS_DEPRECATE_FEATURE_ANNOTATION_IS_ACTIVE
#else
#undef BSLS_DEPRECATE_FEATURE_ANNOTATION_IS_ACTIVE
#endif
// ====================================
// Implementation Details: Do *NOT* Use
// ====================================
#ifndef BSLS_DEPRECATE_FEATURE_ANNOTATION_IS_ACTIVE
#define BSLS_DEPRECATE_FEATURE_IMP(UOR, FEATURE, MESSAGE)
#else
#if defined(BB_DEPRECATE_ENABLE_JSON_MESSAGE) || \
defined(BSLS_DEPRECATE_FEATURE_ENABLE_JSON_MESSAGE)
#define BSLS_DEPRECATE_FEATURE_IMP(UOR, FEATURE, MESSAGE) \
[[deprecated("{\"library\": \"" UOR "\", \"feature\": \"" FEATURE \
"\", \"message\": \"" MESSAGE "\"}")]]
#else
#define BSLS_DEPRECATE_FEATURE_IMP(UOR, FEATURE, MESSAGE) \
[[deprecated(MESSAGE)]]
#endif // BB_DEPRECATE_ENABLE_JSON_MESSAGE
#endif
// If the number of arguments needs to be expanded, commit
// abd14c70a7c9fb38d9bf3fe225eb0966cb036c9f contains a variadic implementation
// similar to 'BSLIM_TESTUTIL_ASSERTV'.
// =================
// Annotation Macros
// =================
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE) \
BSLS_DEPRECATE_FEATURE_IMP(UOR, FEATURE, MESSAGE)
#endif // INCLUDED_BSLS_DEPRECATEFEATURE
// ----------------------------------------------------------------------------
// Copyright 2022 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------