@@ -20,52 +20,148 @@ export 'package:analyzer/src/dart/analysis/experiments_impl.dart'
20
20
21
21
part 'experiments.g.dart' ;
22
22
23
- /// Gets access to the private list of boolean flags in an [Experiments] object.
24
- /// For testing use only.
23
+ /// Gets access to the private list of boolean flags in an [ExperimentStatus]
24
+ /// object. For testing use only.
25
25
@visibleForTesting
26
26
List <bool > getExperimentalFlags_forTesting (ExperimentStatus status) =>
27
- status._enableFlags;
27
+ status._flags;
28
+
29
+ /// Gets access to the private SDK language version in an [ExperimentStatus]
30
+ /// object. For testing use only.
31
+ @visibleForTesting
32
+ Version getSdkLanguageVersion_forTesting (ExperimentStatus status) =>
33
+ status._sdkLanguageVersion;
28
34
29
35
/// A representation of the set of experiments that are active and whether they
30
36
/// are enabled.
31
37
class ExperimentStatus with _CurrentState implements FeatureSet {
32
38
/// The current language version.
33
39
static final Version currentVersion = Version .parse (_currentVersion);
34
40
41
+ /// The language version to use in tests.
42
+ static final Version testingSdkLanguageVersion = Version .parse ('2.10.0' );
43
+
44
+ /// The latest known language version.
45
+ static final Version latestSdkLanguageVersion = Version .parse ('2.10.0' );
46
+
47
+ static final FeatureSet latestWithNullSafety = ExperimentStatus .fromStrings2 (
48
+ sdkLanguageVersion: latestSdkLanguageVersion,
49
+ flags: [EnableString .non_nullable],
50
+ );
51
+
35
52
/// A map containing information about all known experimental flags.
36
53
static final Map <String , ExperimentalFeature > knownFeatures = _knownFeatures;
37
54
38
- final List <bool > _enableFlags;
55
+ final Version _sdkLanguageVersion;
56
+ final List <bool > _explicitEnabledFlags;
57
+ final List <bool > _explicitDisabledFlags;
58
+ final List <bool > _flags;
39
59
40
- /// Initializes a newly created set of experiments based on optional
41
- /// arguments.
42
- ExperimentStatus () : _enableFlags = _buildExperimentalFlagsArray ();
60
+ factory ExperimentStatus () {
61
+ return ExperimentStatus . latestLanguageVersion ();
62
+ }
43
63
44
64
/// Computes a set of features for use in a unit test. Computes the set of
45
65
/// features enabled in [sdkVersion] , plus any specified [additionalFeatures] .
46
66
///
47
67
/// If [sdkVersion] is not supplied (or is `null` ), then the current set of
48
68
/// enabled features is used as the starting point.
49
69
@visibleForTesting
50
- ExperimentStatus .forTesting (
51
- {String sdkVersion, List <Feature > additionalFeatures = const []})
52
- : this ._(enableFlagsForTesting (
53
- sdkVersion: sdkVersion, additionalFeatures: additionalFeatures));
70
+ factory ExperimentStatus .forTesting (
71
+ // ignore:avoid_unused_constructor_parameters
72
+ {String sdkVersion,
73
+ List <Feature > additionalFeatures = const []}) {
74
+ var explicitFlags = decodeExplicitFlags ([]);
75
+ for (ExperimentalFeature feature in additionalFeatures) {
76
+ explicitFlags.enabled[feature.index] = true ;
77
+ }
78
+
79
+ var sdkLanguageVersion = latestSdkLanguageVersion;
80
+ var flags = restrictEnableFlagsToVersion (
81
+ sdkLanguageVersion: sdkLanguageVersion,
82
+ explicitEnabledFlags: explicitFlags.enabled,
83
+ explicitDisabledFlags: explicitFlags.disabled,
84
+ version: sdkLanguageVersion,
85
+ );
86
+
87
+ return ExperimentStatus ._(
88
+ sdkLanguageVersion,
89
+ explicitFlags.enabled,
90
+ explicitFlags.disabled,
91
+ flags,
92
+ );
93
+ }
94
+
95
+ factory ExperimentStatus .fromStorage (List <int > encoded) {
96
+ var allFlags = encoded.skip (2 ).map ((e) => e != 0 ).toList ();
97
+ var featureCount = allFlags.length ~ / 3 ;
98
+ return ExperimentStatus ._(
99
+ Version (encoded[0 ], encoded[1 ], 0 ),
100
+ allFlags.sublist (0 , featureCount),
101
+ allFlags.sublist (featureCount, featureCount * 2 ),
102
+ allFlags.sublist (featureCount * 2 , featureCount * 3 ),
103
+ );
104
+ }
105
+
106
+ /// Decodes the strings given in [flags] into a representation of the set of
107
+ /// experiments that should be enabled.
108
+ ///
109
+ /// Always succeeds, even if the input flags are invalid. Expired and
110
+ /// unrecognized flags are ignored, conflicting flags are resolved in favor of
111
+ /// the flag appearing last.
112
+ factory ExperimentStatus .fromStrings (List <String > flags) {
113
+ return ExperimentStatus .fromStrings2 (
114
+ sdkLanguageVersion: latestSdkLanguageVersion,
115
+ flags: flags,
116
+ );
117
+ }
54
118
55
119
/// Decodes the strings given in [flags] into a representation of the set of
56
120
/// experiments that should be enabled.
57
121
///
58
122
/// Always succeeds, even if the input flags are invalid. Expired and
59
123
/// unrecognized flags are ignored, conflicting flags are resolved in favor of
60
124
/// the flag appearing last.
61
- ExperimentStatus .fromStrings (List <String > flags) : this ._(decodeFlags (flags));
125
+ factory ExperimentStatus .fromStrings2 ({
126
+ @required Version sdkLanguageVersion,
127
+ @required List <String > flags,
128
+ // TODO(scheglov) use restrictEnableFlagsToVersion
129
+ }) {
130
+ var explicitFlags = decodeExplicitFlags (flags);
131
+
132
+ var decodedFlags = restrictEnableFlagsToVersion (
133
+ sdkLanguageVersion: sdkLanguageVersion,
134
+ explicitEnabledFlags: explicitFlags.enabled,
135
+ explicitDisabledFlags: explicitFlags.disabled,
136
+ version: sdkLanguageVersion,
137
+ );
138
+
139
+ return ExperimentStatus ._(
140
+ sdkLanguageVersion,
141
+ explicitFlags.enabled,
142
+ explicitFlags.disabled,
143
+ decodedFlags,
144
+ );
145
+ }
146
+
147
+ factory ExperimentStatus .latestLanguageVersion () {
148
+ return ExperimentStatus .fromStrings2 (
149
+ sdkLanguageVersion: latestSdkLanguageVersion,
150
+ flags: [],
151
+ );
152
+ }
62
153
63
- ExperimentStatus ._(this ._enableFlags);
154
+ ExperimentStatus ._(
155
+ this ._sdkLanguageVersion,
156
+ this ._explicitEnabledFlags,
157
+ this ._explicitDisabledFlags,
158
+ this ._flags,
159
+ );
64
160
65
161
@override
66
162
int get hashCode {
67
163
int hash = 0 ;
68
- for (var flag in _enableFlags ) {
164
+ for (var flag in _flags ) {
69
165
hash = JenkinsSmiHash .combine (hash, flag.hashCode);
70
166
}
71
167
return JenkinsSmiHash .finish (hash);
@@ -74,9 +170,19 @@ class ExperimentStatus with _CurrentState implements FeatureSet {
74
170
@override
75
171
bool operator == (Object other) {
76
172
if (other is ExperimentStatus ) {
77
- if (_enableFlags.length != other._enableFlags.length) return false ;
78
- for (int i = 0 ; i < _enableFlags.length; i++ ) {
79
- if (_enableFlags[i] != other._enableFlags[i]) return false ;
173
+ if (_sdkLanguageVersion != other._sdkLanguageVersion) {
174
+ return false ;
175
+ }
176
+ if (! _equalListOfBool (
177
+ _explicitEnabledFlags, other._explicitEnabledFlags)) {
178
+ return false ;
179
+ }
180
+ if (! _equalListOfBool (
181
+ _explicitDisabledFlags, other._explicitDisabledFlags)) {
182
+ return false ;
183
+ }
184
+ if (! _equalListOfBool (_flags, other._flags)) {
185
+ return false ;
80
186
}
81
187
return true ;
82
188
}
@@ -86,16 +192,42 @@ class ExperimentStatus with _CurrentState implements FeatureSet {
86
192
/// Queries whether the given [feature] is enabled or disabled.
87
193
@override
88
194
bool isEnabled (covariant ExperimentalFeature feature) =>
89
- _enableFlags [feature.index];
195
+ _flags [feature.index];
90
196
91
197
@override
92
- FeatureSet restrictToVersion (Version version) =>
93
- ExperimentStatus ._(restrictEnableFlagsToVersion (_enableFlags, version));
198
+ FeatureSet restrictToVersion (Version version) {
199
+ return ExperimentStatus ._(
200
+ _sdkLanguageVersion,
201
+ _explicitEnabledFlags,
202
+ _explicitDisabledFlags,
203
+ restrictEnableFlagsToVersion (
204
+ sdkLanguageVersion: _sdkLanguageVersion,
205
+ explicitEnabledFlags: _explicitEnabledFlags,
206
+ explicitDisabledFlags: _explicitDisabledFlags,
207
+ version: version,
208
+ ),
209
+ );
210
+ }
211
+
212
+ /// Encode into the format suitable for [ExperimentStatus.fromStorage] .
213
+ List <int > toStorage () {
214
+ return [
215
+ _sdkLanguageVersion.major,
216
+ _sdkLanguageVersion.minor,
217
+ ..._explicitEnabledFlags.map ((e) => e ? 1 : 0 ),
218
+ ..._explicitDisabledFlags.map ((e) => e ? 1 : 0 ),
219
+ ..._flags.map ((e) => e ? 1 : 0 ),
220
+ ];
221
+ }
94
222
95
223
@override
96
- String toString () => experimentStatusToString (_enableFlags );
224
+ String toString () => experimentStatusToString (_flags );
97
225
98
- /// Returns a list of strings suitable for passing to
99
- /// [ExperimentStatus.fromStrings] .
100
- List <String > toStringList () => experimentStatusToStringList (this );
226
+ static bool _equalListOfBool (List <bool > first, List <bool > second) {
227
+ if (first.length != second.length) return false ;
228
+ for (var i = 0 ; i < first.length; i++ ) {
229
+ if (first[i] != second[i]) return false ;
230
+ }
231
+ return true ;
232
+ }
101
233
}
0 commit comments