Skip to content

Commit e41640d

Browse files
srawlinsCommit Queue
authored andcommitted
Core libs: Introduce 5 new forms of the Deprecated annotation.
Change-Id: I102662244eec205775d5adbed8fa33ffcf702cbd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/449582 Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Martin Kustermann <[email protected]> Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Lasse Nielsen <[email protected]> Reviewed-by: Stephen Adams <[email protected]>
1 parent 522e611 commit e41640d

File tree

7 files changed

+164
-38
lines changed

7 files changed

+164
-38
lines changed

pkg/analyzer/lib/src/test_utilities/mock_sdk.dart

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -313,20 +313,16 @@ class DateTime extends Object {
313313
}
314314
315315
class Deprecated extends Object {
316-
final String message;
316+
final String? message;
317317
final _DeprecationKind _kind;
318-
const Deprecated(this.message)
319-
: _kind = _DeprecationKind.use;
320-
const Deprecated.implement([this.message = "next release"])
321-
: _kind = _DeprecationKind.implement;
322-
const Deprecated.extend([this.message = "next release"])
323-
: _kind = _DeprecationKind.extend;
324-
const Deprecated.subclass([this.message = "next release"])
325-
: _kind = _DeprecationKind.subclass;
326-
const Deprecated.instantiate([this.message = "next release"])
327-
: _kind = _DeprecationKind.instantiate;
328-
const Deprecated.mixin([this.message = "next release"])
329-
: _kind = _DeprecationKind.mixin;
318+
const Deprecated(this.message) : _kind = _DeprecationKind.use;
319+
const Deprecated.implement([this.message])
320+
: _kind = _DeprecationKind.implement;
321+
const Deprecated.extend([this.message]) : _kind = _DeprecationKind.extend;
322+
const Deprecated.subclass([this.message]) : _kind = _DeprecationKind.subclass;
323+
const Deprecated.instantiate([this.message])
324+
: _kind = _DeprecationKind.instantiate;
325+
const Deprecated.mixin([this.message]) : _kind = _DeprecationKind.mixin;
330326
}
331327
332328
enum _DeprecationKind {

pkg/compiler/test/model/cfe_constant_evaluation_common.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const List<TestData> DATA = [
7575
ConstantData('true ? 0 : 1', 'IntConstant(0)'),
7676
ConstantData(
7777
'deprecated',
78-
'ConstructedConstant(Deprecated(message=StringConstant("next release")))',
78+
'ConstructedConstant(Deprecated(_kind=ConstructedConstant(_DeprecationKind(_name=StringConstant("use"),index=IntConstant(0))),message=StringConstant("next release")))',
7979
),
8080
ConstantData('const [] == null', 'BoolConstant(false)'),
8181
ConstantData('deprecated == null', 'BoolConstant(false)'),

pkg/front_end/testcases/extension_types/annotations.dart.strong.expect

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ library;
22
import self as self;
33
import "dart:core" as core;
44

5-
@#C2
5+
@#C5
66
extension type A(core::int i) {
77
abstract extension-type-member representation-field get i() → core::int;
88
method m = self::A|m;
@@ -12,27 +12,30 @@ extension type A(core::int i) {
1212
constructor constructor = self::A|constructor#constructor;
1313
constructor tearoff constructor = self::A|constructor#_#constructor#tearOff;
1414
}
15-
static extension-type-member method A|constructor#(@#C2 core::int i) → self::A% /* erasure=core::int, declared=! */ {
15+
static extension-type-member method A|constructor#(@#C5 core::int i) → self::A% /* erasure=core::int, declared=! */ {
1616
lowered final self::A% /* erasure=core::int, declared=! */ #this = i;
1717
return #this;
1818
}
1919
static extension-type-member synthetic method A|constructor#_#new#tearOff(core::int i) → self::A% /* erasure=core::int, declared=! */
2020
return self::A|constructor#(i);
21-
@#C2
21+
@#C5
2222
static extension-type-member method A|constructor#constructor(core::int i) → self::A% /* erasure=core::int, declared=! */ {
2323
lowered final self::A% /* erasure=core::int, declared=! */ #this = i;
2424
return #this;
2525
}
2626
static extension-type-member synthetic method A|constructor#_#constructor#tearOff(core::int i) → self::A% /* erasure=core::int, declared=! */
2727
return self::A|constructor#constructor(i);
28-
@#C2
28+
@#C5
2929
static extension-type-member method A|m(lowered final self::A% /* erasure=core::int, declared=! */ #this) → void {}
3030
static extension-type-member method A|get#m(lowered final self::A% /* erasure=core::int, declared=! */ #this) → () → void
3131
return () → void => self::A|m(#this);
3232

3333
constants {
3434
#C1 = ""
35-
#C2 = core::Deprecated {message:#C1}
35+
#C2 = 0
36+
#C3 = "use"
37+
#C4 = core::_DeprecationKind {index:#C2, _name:#C3}
38+
#C5 = core::Deprecated {message:#C1, _kind:#C4}
3639
}
3740

3841

pkg/front_end/testcases/extension_types/annotations.dart.strong.modular.expect

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ library;
22
import self as self;
33
import "dart:core" as core;
44

5-
@#C2
5+
@#C5
66
extension type A(core::int i) {
77
abstract extension-type-member representation-field get i() → core::int;
88
method m = self::A|m;
@@ -12,27 +12,30 @@ extension type A(core::int i) {
1212
constructor constructor = self::A|constructor#constructor;
1313
constructor tearoff constructor = self::A|constructor#_#constructor#tearOff;
1414
}
15-
static extension-type-member method A|constructor#(@#C2 core::int i) → self::A% /* erasure=core::int, declared=! */ {
15+
static extension-type-member method A|constructor#(@#C5 core::int i) → self::A% /* erasure=core::int, declared=! */ {
1616
lowered final self::A% /* erasure=core::int, declared=! */ #this = i;
1717
return #this;
1818
}
1919
static extension-type-member synthetic method A|constructor#_#new#tearOff(core::int i) → self::A% /* erasure=core::int, declared=! */
2020
return self::A|constructor#(i);
21-
@#C2
21+
@#C5
2222
static extension-type-member method A|constructor#constructor(core::int i) → self::A% /* erasure=core::int, declared=! */ {
2323
lowered final self::A% /* erasure=core::int, declared=! */ #this = i;
2424
return #this;
2525
}
2626
static extension-type-member synthetic method A|constructor#_#constructor#tearOff(core::int i) → self::A% /* erasure=core::int, declared=! */
2727
return self::A|constructor#constructor(i);
28-
@#C2
28+
@#C5
2929
static extension-type-member method A|m(lowered final self::A% /* erasure=core::int, declared=! */ #this) → void {}
3030
static extension-type-member method A|get#m(lowered final self::A% /* erasure=core::int, declared=! */ #this) → () → void
3131
return () → void => self::A|m(#this);
3232

3333
constants {
3434
#C1 = ""
35-
#C2 = core::Deprecated {message:#C1}
35+
#C2 = 0
36+
#C3 = "use"
37+
#C4 = core::_DeprecationKind {index:#C2, _name:#C3}
38+
#C5 = core::Deprecated {message:#C1, _kind:#C4}
3639
}
3740

3841

pkg/front_end/testcases/extension_types/annotations.dart.strong.outline.expect

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static extension-type-member method A|get#m(lowered final self::A% /* erasure=co
2929

3030

3131
Extra constant evaluation status:
32-
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotations.dart:5:2 -> InstanceConstant(const Deprecated{Deprecated.message: ""})
33-
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotations.dart:7:4 -> InstanceConstant(const Deprecated{Deprecated.message: ""})
34-
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotations.dart:10:4 -> InstanceConstant(const Deprecated{Deprecated.message: ""})
32+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotations.dart:5:2 -> InstanceConstant(const Deprecated{Deprecated.message: "", Deprecated._kind: const _DeprecationKind{_Enum.index: 0, _Enum._name: "use"}})
33+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotations.dart:7:4 -> InstanceConstant(const Deprecated{Deprecated.message: "", Deprecated._kind: const _DeprecationKind{_Enum.index: 0, _Enum._name: "use"}})
34+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///annotations.dart:10:4 -> InstanceConstant(const Deprecated{Deprecated.message: "", Deprecated._kind: const _DeprecationKind{_Enum.index: 0, _Enum._name: "use"}})
3535
Extra constant evaluation: evaluated: 10, effectively constant: 3

pkg/front_end/testcases/extension_types/annotations.dart.strong.transformed.expect

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ library;
22
import self as self;
33
import "dart:core" as core;
44

5-
@#C2
5+
@#C5
66
extension type A(core::int i) {
77
abstract extension-type-member representation-field get i() → core::int;
88
method m = self::A|m;
@@ -12,27 +12,30 @@ extension type A(core::int i) {
1212
constructor constructor = self::A|constructor#constructor;
1313
constructor tearoff constructor = self::A|constructor#_#constructor#tearOff;
1414
}
15-
static extension-type-member method A|constructor#(@#C2 core::int i) → self::A% /* erasure=core::int, declared=! */ {
15+
static extension-type-member method A|constructor#(@#C5 core::int i) → self::A% /* erasure=core::int, declared=! */ {
1616
lowered final self::A% /* erasure=core::int, declared=! */ #this = i;
1717
return #this;
1818
}
1919
static extension-type-member synthetic method A|constructor#_#new#tearOff(core::int i) → self::A% /* erasure=core::int, declared=! */
2020
return self::A|constructor#(i);
21-
@#C2
21+
@#C5
2222
static extension-type-member method A|constructor#constructor(core::int i) → self::A% /* erasure=core::int, declared=! */ {
2323
lowered final self::A% /* erasure=core::int, declared=! */ #this = i;
2424
return #this;
2525
}
2626
static extension-type-member synthetic method A|constructor#_#constructor#tearOff(core::int i) → self::A% /* erasure=core::int, declared=! */
2727
return self::A|constructor#constructor(i);
28-
@#C2
28+
@#C5
2929
static extension-type-member method A|m(lowered final self::A% /* erasure=core::int, declared=! */ #this) → void {}
3030
static extension-type-member method A|get#m(lowered final self::A% /* erasure=core::int, declared=! */ #this) → () → void
3131
return () → void => self::A|m(#this);
3232

3333
constants {
3434
#C1 = ""
35-
#C2 = core::Deprecated {message:#C1}
35+
#C2 = 0
36+
#C3 = "use"
37+
#C4 = core::_DeprecationKind {index:#C2, _name:#C3}
38+
#C5 = core::Deprecated {message:#C1, _kind:#C4}
3639
}
3740

3841

sdk/lib/core/annotations.dart

Lines changed: 127 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,143 @@ class Deprecated {
6666
/// The message should explain how to migrate away from the feature if an
6767
/// alternative is available, and when the deprecated feature is expected to be
6868
/// removed.
69-
final String message;
69+
final String? message;
7070

71-
/// Create a deprecation annotation which specifies the migration path and
71+
final _DeprecationKind _kind;
72+
73+
/// Creates a deprecation annotation which specifies the migration path and
7274
/// expiration of the annotated feature.
7375
///
74-
/// The [message] argument should be readable by programmers, and should state
75-
/// an alternative feature (if available) as well as when an annotated feature
76-
/// is expected to be removed.
77-
const Deprecated(this.message);
76+
/// The [message] is displayed as part of the warning. The message should be
77+
/// aimed at the programmer who owns the extending class, and should
78+
/// recommend an alternative (if available), and say when this functionality
79+
/// is expected to be removed if that is sooner or later than the next major
80+
/// version.
81+
const Deprecated(this.message) : _kind = _DeprecationKind.use;
82+
83+
/// Creates an annotation which deprecates implementing a class or mixin.
84+
///
85+
/// The annotation can be used on `class` or `mixin` declarations whose
86+
/// interface can currently be implemented, so they are not marked `final`,
87+
/// `sealed`, or `base`, but where the ability to implement will be removed
88+
/// in a later release.
89+
///
90+
/// Any existing class, mixin or enum declaration which `implements` the
91+
/// interface will cause a warning that such use is deprecated. Does not
92+
/// affect classes which extend or mix in the annotated class or mixin (see
93+
/// [Deprecated.extend], [Deprecated.mixin], and [Deprecated.subclass]).
94+
///
95+
/// The annotation is not inherited by subclasses. If a public subclass will
96+
/// also become unimplementable, which it will if the annotated declaration
97+
/// becomes `final` or `base`, but not if it becomes `sealed`, then the
98+
/// subclass should deprecate implementation as well.
99+
///
100+
/// The [message], if given, is displayed as part of the warning. The message
101+
/// should be aimed at the programmer who owns the implementing class, and
102+
/// should recommend an alternative (if available), and say when this
103+
/// functionality is expected to be removed if that is sooner or later than
104+
/// the next major version.
105+
const Deprecated.implement([this.message])
106+
: _kind = _DeprecationKind.implement;
107+
108+
/// Creates an annotation which deprecates extending a class.
109+
///
110+
/// The annotation can be used on `class` declarations which can currently be
111+
/// extended, so they are not marked `final`, `sealed`, or `interface`, but
112+
/// where the ability to extend will be removed in a later release.
113+
///
114+
/// Any existing class declaration which `extends` the class will cause a
115+
/// warning that such use is deprecated. Does not affect classes which
116+
/// implement or mix in the annotated class (see [Deprecated.implement],
117+
/// [Deprecated.mixin], and [Deprecated.subclass]).
118+
///
119+
/// The annotation is not inherited by subclasses. If a public subclass will
120+
/// also become unextendable, which it will if the annotated declaration
121+
/// becomes `final` or `interface`, but not if it becomes `sealed`, then the
122+
/// subclass should deprecate extendability as well.
123+
///
124+
/// The [message], if given, is displayed as part of the warning. The message
125+
/// should be aimed at the programmer who owns the extending class, and
126+
/// should recommend an alternative (if available), and say when this
127+
/// functionality is expected to be removed if that is sooner or later than
128+
/// the next major version.
129+
const Deprecated.extend([this.message]) : _kind = _DeprecationKind.extend;
130+
131+
/// Creates an annotation which deprecates subclassing (implementing or
132+
/// extending) a class.
133+
///
134+
/// The annotation can be used on `class` and `mixin` declarations which can
135+
/// currently be subclassed, so they are not marked `final`, or `sealed`, but
136+
/// where the ability to subclass will be removed in a later release.
137+
///
138+
/// Any existing class declaration which `extends` or `implements` the
139+
/// annotated class or mixin will cause a warning that such use is
140+
/// deprecated. Does not affect classes which mix in the annotated class (see
141+
/// [Deprecated.extend], [Deprecated.implement] and [Deprecated.mixin]).
142+
///
143+
/// The annotation is not inherited by subclasses. If a public subclass will
144+
/// also become unsubclassable, which it will if the annotated declaration
145+
/// becomes `final`, but not if it becomes `sealed`, then the subclass should
146+
/// deprecate subclassability as well.
147+
///
148+
/// The [message], if given, is displayed as part of the warning. The message
149+
/// should be aimed at the programmer who owns the subclassing class, and
150+
/// should recommend an alternative (if available), and say when this
151+
/// functionality is expected to be removed if that is sooner or later than
152+
/// the next major version.
153+
const Deprecated.subclass([this.message]) : _kind = _DeprecationKind.subclass;
154+
155+
/// Creates an annotation which deprecates instantiating a class.
156+
///
157+
/// The annotation can be used on `class` declarations which can currently be
158+
/// instantiated, so they are not marked `abstract` or `sealed`, but where
159+
/// the ability to instantiate will be removed in a later release.
160+
///
161+
/// Any existing code which instantiates the annotated class will cause a
162+
/// warning that such use is deprecated.
163+
///
164+
/// The [message], if given, is displayed as part of the warning. The message
165+
/// should be aimed at the programmer who owns the instantiating code, and
166+
/// should recommend an alternative (if available), and say when this
167+
/// functionality is expected to be removed if that is sooner or later than
168+
/// the next major version.
169+
const Deprecated.instantiate([this.message])
170+
: _kind = _DeprecationKind.instantiate;
171+
172+
/// Creates an annotation which deprecates mixing in a class.
173+
///
174+
/// The annotation can be used on `class` declarations which can currently be
175+
/// mixed in, so they are marked `mixin`, but where the ability to mix in
176+
/// will be removed in a later release.
177+
///
178+
/// Any existing class declaration which mixes in the annotated class will
179+
/// cause a warning that such use is deprecated. Does not affect classes
180+
/// which extend or implement the annotated class (see [Deprecated.extend],
181+
/// [Deprecated.implement] and [Deprecated.subclass]).
182+
///
183+
/// The [message], if given, is displayed as part of the warning. The message
184+
/// should be aimed at the programmer who owns the class which mixes in the
185+
/// annotated class, and should recommend an alternative (if available), and
186+
/// say when this functionality is expected to be removed if that is sooner
187+
/// or later than the next major version.
188+
const Deprecated.mixin([this.message]) : _kind = _DeprecationKind.mixin;
78189

79190
String toString() => "Deprecated feature: $message";
80191
}
81192

82193
/// Marks a feature as [Deprecated] until the next release.
83194
const Deprecated deprecated = Deprecated("next release");
84195

196+
/// The various kinds of deprecations with which a feature can be annotated.
197+
///
198+
/// Each deprecation kind is paired directly with a [Deprecated] constructor.
199+
/// [_DeprecationKind.use] is used by the unnamed [Deprecated.new] constructor
200+
/// and the [deprecated] constant.
201+
///
202+
/// This enum can be private because the information is only intended for
203+
/// static tooling, such as the analyzer. Values may be added.
204+
enum _DeprecationKind { use, implement, extend, subclass, instantiate, mixin }
205+
85206
class _Override {
86207
const _Override();
87208
}

0 commit comments

Comments
 (0)