-
Notifications
You must be signed in to change notification settings - Fork 214
/
platform_selector.dart
121 lines (104 loc) · 3.83 KB
/
platform_selector.dart
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
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:boolean_selector/boolean_selector.dart';
import 'package:source_span/source_span.dart';
import 'operating_system.dart';
import 'runtime.dart';
import 'suite_platform.dart';
/// The set of variable names that are valid for all platform selectors.
final _universalValidVariables = {
'posix',
'dart-vm',
'browser',
'js',
'blink',
'google',
for (var runtime in Runtime.builtIn) runtime.identifier,
for (var os in OperatingSystem.all) os.identifier,
};
/// An expression for selecting certain platforms, including operating systems
/// and browsers.
///
/// This uses the [boolean selector][] syntax.
///
/// [boolean selector]: https://pub.dev/packages/boolean_selector
class PlatformSelector {
/// A selector that declares that a test can be run on all platforms.
static const all = PlatformSelector._(BooleanSelector.all);
/// The boolean selector used to implement this selector.
final BooleanSelector _inner;
/// The source span from which this selector was parsed.
final SourceSpan _span;
/// Parses [selector].
///
/// If [span] is passed, it indicates the location of the text for [selector]
/// in a larger document. It's used for error reporting.
PlatformSelector.parse(String selector, [SourceSpan span])
: _inner =
_wrapFormatException(() => BooleanSelector.parse(selector), span),
_span = span;
const PlatformSelector._(this._inner) : _span = null;
/// Runs [body] and wraps any [FormatException] it throws in a
/// [SourceSpanFormatException] using [span].
///
/// If [span] is `null`, runs [body] as-is.
static T _wrapFormatException<T>(T Function() body, SourceSpan span) {
if (span == null) return body();
try {
return body();
} on FormatException catch (error) {
throw SourceSpanFormatException(error.message, span);
}
}
/// Throws a [FormatException] if this selector uses any variables that don't
/// appear either in [validVariables] or in the set of variables that are
/// known to be valid for all selectors.
void validate(Set<String> validVariables) {
if (identical(this, all)) return;
_wrapFormatException(
() => _inner.validate((name) =>
_universalValidVariables.contains(name) ||
validVariables.contains(name)),
_span);
}
/// Returns whether the selector matches the given [platform].
///
/// [os] defaults to [OperatingSystem.none].
bool evaluate(SuitePlatform platform) {
return _inner.evaluate((String variable) {
if (variable == platform.runtime.identifier) return true;
if (variable == platform.runtime.parent?.identifier) return true;
if (variable == platform.os.identifier) return true;
switch (variable) {
case 'dart-vm':
return platform.runtime.isDartVM;
case 'browser':
return platform.runtime.isBrowser;
case 'js':
return platform.runtime.isJS;
case 'blink':
return platform.runtime.isBlink;
case 'posix':
return platform.os.isPosix;
case 'google':
return platform.inGoogle;
default:
return false;
}
});
}
/// Returns a new [PlatformSelector] that matches only platforms matched by
/// both [this] and [other].
PlatformSelector intersection(PlatformSelector other) {
if (other == PlatformSelector.all) return this;
return PlatformSelector._(_inner.intersection(other._inner));
}
@override
String toString() => _inner.toString();
@override
bool operator ==(other) =>
other is PlatformSelector && _inner == other._inner;
@override
int get hashCode => _inner.hashCode;
}