Increase the strictness of our requiring explicit types (#7585)

...now that we have generic methods, their types need to be specified too.
This commit is contained in:
Ian Hickson 2017-01-23 01:04:31 -08:00 committed by GitHub
parent 99822088a7
commit 63aa1397a3
63 changed files with 134 additions and 127 deletions

View file

@ -16,7 +16,8 @@ analyzer:
language: language:
enableStrictCallChecks: true enableStrictCallChecks: true
enableSuperMixins: true enableSuperMixins: true
strong-mode: true strong-mode:
implicit-dynamic: false
errors: errors:
# allow overriding fields (if they use super, ideally...) # allow overriding fields (if they use super, ideally...)
strong_mode_invalid_field_override: ignore strong_mode_invalid_field_override: ignore

View file

@ -17,7 +17,8 @@ analyzer:
language: language:
enableStrictCallChecks: true enableStrictCallChecks: true
enableSuperMixins: true enableSuperMixins: true
strong-mode: true strong-mode:
implicit-dynamic: false
errors: errors:
# allow overriding fields (if they use super, ideally...) # allow overriding fields (if they use super, ideally...)
strong_mode_invalid_field_override: ignore strong_mode_invalid_field_override: ignore

View file

@ -37,7 +37,7 @@ Future<Map<String, dynamic>> runTask(String taskName, { bool silent: false }) as
bool runnerFinished = false; bool runnerFinished = false;
runner.exitCode.then((_) { runner.exitCode.whenComplete(() {
runnerFinished = true; runnerFinished = true;
}); });

View file

@ -166,7 +166,7 @@ Future<Process> startProcess(String executable, List<String> arguments,
ProcessInfo procInfo = new ProcessInfo(command, proc); ProcessInfo procInfo = new ProcessInfo(command, proc);
_runningProcesses.add(procInfo); _runningProcesses.add(procInfo);
proc.exitCode.then((_) { proc.exitCode.whenComplete(() {
_runningProcesses.remove(procInfo); _runningProcesses.remove(procInfo);
}); });

View file

@ -70,7 +70,7 @@ class DialogDemoState extends State<DialogDemo> {
context: context, context: context,
child: child child: child
) )
.then((T value) { // The value passed to Navigator.pop() or null. .then<Null>((T value) { // The value passed to Navigator.pop() or null.
if (value != null) { if (value != null) {
_scaffoldKey.currentState.showSnackBar(new SnackBar( _scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text('You selected: $value') content: new Text('You selected: $value')
@ -178,7 +178,7 @@ class DialogDemoState extends State<DialogDemo> {
context: context, context: context,
initialTime: _selectedTime initialTime: _selectedTime
) )
.then((TimeOfDay value) { .then<Null>((TimeOfDay value) {
if (value != null && value != _selectedTime) { if (value != null && value != _selectedTime) {
_selectedTime = value; _selectedTime = value;
_scaffoldKey.currentState.showSnackBar(new SnackBar( _scaffoldKey.currentState.showSnackBar(new SnackBar(

View file

@ -48,7 +48,7 @@ class DateTimeItem extends StatelessWidget {
firstDate: date.subtract(const Duration(days: 30)), firstDate: date.subtract(const Duration(days: 30)),
lastDate: date.add(const Duration(days: 30)) lastDate: date.add(const Duration(days: 30))
) )
.then((DateTime value) { .then<Null>((DateTime value) {
onChanged(new DateTime(value.year, value.month, value.day, time.hour, time.minute)); onChanged(new DateTime(value.year, value.month, value.day, time.hour, time.minute));
}); });
}, },
@ -74,7 +74,7 @@ class DateTimeItem extends StatelessWidget {
context: context, context: context,
initialTime: time initialTime: time
) )
.then((TimeOfDay value) { .then<Null>((TimeOfDay value) {
onChanged(new DateTime(date.year, date.month, date.day, value.hour, value.minute)); onChanged(new DateTime(date.year, date.month, date.day, value.hour, value.minute));
}); });
}, },
@ -112,7 +112,7 @@ class FullScreenDialogDemoState extends State<FullScreenDialogDemo> {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final TextStyle dialogTextStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color); final TextStyle dialogTextStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color);
showDialog( showDialog<DismissDialogAction>(
context: context, context: context,
child: new AlertDialog( child: new AlertDialog(
content: new Text( content: new Text(

View file

@ -22,7 +22,6 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
_showBottomSheetCallback = _showBottomSheet; _showBottomSheetCallback = _showBottomSheet;
} }
void _showBottomSheet() { void _showBottomSheet() {
setState(() { // disable the button setState(() { // disable the button
_showBottomSheetCallback = null; _showBottomSheetCallback = null;
@ -45,15 +44,17 @@ class _PersistentBottomSheetDemoState extends State<PersistentBottomSheetDemo> {
) )
); );
}) })
.closed.then((_) { .closed.whenComplete(() {
setState(() { // re-enable the button if (mounted) {
_showBottomSheetCallback = _showBottomSheet; setState(() { // re-enable the button
}); _showBottomSheetCallback = _showBottomSheet;
});
}
}); });
} }
void _showMessage() { void _showMessage() {
showDialog( showDialog<Null>(
context: context, context: context,
child: new AlertDialog( child: new AlertDialog(
content: new Text('You tapped the floating action button.'), content: new Text('You tapped the floating action button.'),

View file

@ -66,7 +66,7 @@ class _TabsFabDemoState extends State<TabsFabDemo> with SingleTickerProviderStat
} }
void _showExplanatoryText() { void _showExplanatoryText() {
_scaffoldKey.currentState.showBottomSheet((BuildContext context) { _scaffoldKey.currentState.showBottomSheet<Null>((BuildContext context) {
return new Container( return new Container(
decoration: new BoxDecoration( decoration: new BoxDecoration(
border: new Border(top: new BorderSide(color: Theme.of(context).dividerColor)) border: new Border(top: new BorderSide(color: Theme.of(context).dividerColor))

View file

@ -110,10 +110,12 @@ class FullScreenCodeDialogState extends State<FullScreenCodeDialog> {
@override @override
void dependenciesChanged() { void dependenciesChanged() {
getExampleCode(config.exampleCodeTag, DefaultAssetBundle.of(context)).then((String code) { getExampleCode(config.exampleCodeTag, DefaultAssetBundle.of(context)).then<Null>((String code) {
setState(() { if (mounted) {
_exampleCode = code; setState(() {
}); _exampleCode = code;
});
}
}); });
super.dependenciesChanged(); super.dependenciesChanged();
} }

View file

@ -46,7 +46,7 @@ class TestAssetBundle extends AssetBundle {
} }
@override @override
Future<dynamic> loadStructuredData(String key, Future<dynamic> parser(String value)) async { Future<dynamic> loadStructuredData<T>(String key, Future<T> parser(String value)) async {
return parser(await loadString(key)); return parser(await loadString(key));
} }

View file

@ -167,7 +167,7 @@ void main() {
if (!unsynchedDemoTitles.contains(demoTitle)) { if (!unsynchedDemoTitles.contains(demoTitle)) {
await driver.tap(find.byTooltip('Back')); await driver.tap(find.byTooltip('Back'));
} else { } else {
await driver.runUnsynchronized(() async { await driver.runUnsynchronized<Future<Null>>(() async {
await new Future<Null>.delayed(kWaitBetweenActions); await new Future<Null>.delayed(kWaitBetweenActions);
await driver.tap(find.byTooltip('Back')); await driver.tap(find.byTooltip('Back'));
}); });

View file

@ -137,12 +137,12 @@ class CalculationManager {
// the root bundle (see https://github.com/flutter/flutter/issues/3294). // the root bundle (see https://github.com/flutter/flutter/issues/3294).
// However, the loading process is asynchronous, so the UI will not block // However, the loading process is asynchronous, so the UI will not block
// while the file is loaded. // while the file is loaded.
rootBundle.loadString('services/data.json').then((String data) { rootBundle.loadString('services/data.json').then<Null>((String data) {
if (isRunning) { if (isRunning) {
CalculationMessage message = new CalculationMessage(data, _receivePort.sendPort); final CalculationMessage message = new CalculationMessage(data, _receivePort.sendPort);
// Spawn an isolate to JSON-parse the file contents. The JSON parsing // Spawn an isolate to JSON-parse the file contents. The JSON parsing
// is synchronous, so if done in the main isolate, the UI would block. // is synchronous, so if done in the main isolate, the UI would block.
Isolate.spawn(_calculate, message).then((Isolate isolate) { Isolate.spawn(_calculate, message).then<Null>((Isolate isolate) {
if (!isRunning) { if (!isRunning) {
isolate.kill(priority: Isolate.IMMEDIATE); isolate.kill(priority: Isolate.IMMEDIATE);
} else { } else {

View file

@ -4,7 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
typedef Widget TextTransformer(String name, String text); typedef Widget _TextTransformer(String name, String text);
// From https://en.wikiquote.org/wiki/2001:_A_Space_Odyssey_(film) // From https://en.wikiquote.org/wiki/2001:_A_Space_Odyssey_(film)
const String _kDialogText = ''' const String _kDialogText = '''
@ -84,7 +84,7 @@ class _StyledTextDemoState extends State<StyledTextDemo> {
_toText = toStyledText; _toText = toStyledText;
} }
TextTransformer _toText; _TextTransformer _toText;
void _handleTap() { void _handleTap() {
setState(() { setState(() {
@ -95,7 +95,7 @@ class _StyledTextDemoState extends State<StyledTextDemo> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<Widget> lines = _kNameLines List<Widget> lines = _kNameLines
.map((List<String> nameAndText) => Function.apply(_toText, nameAndText)) .map<Widget>((List<String> nameAndText) => _toText(nameAndText[0], nameAndText[1]))
.toList(); .toList();
List<Widget> children = <Widget>[]; List<Widget> children = <Widget>[];

View file

@ -72,7 +72,7 @@ class StockDataFetcher {
void _fetchNextChunk() { void _fetchNextChunk() {
if (!actuallyFetchData) if (!actuallyFetchData)
return; return;
http.get(_urlToFetch(_nextChunk++)).then((http.Response response) { http.get(_urlToFetch(_nextChunk++)).then<Null>((http.Response response) {
String json = response.body; String json = response.body;
if (json == null) { if (json == null) {
print("Failed to load stock data chunk ${_nextChunk - 1}"); print("Failed to load stock data chunk ${_nextChunk - 1}");

View file

@ -105,7 +105,7 @@ class StockHomeState extends State<StockHome> {
}); });
break; break;
case _StockMenuItem.refresh: case _StockMenuItem.refresh:
showDialog( showDialog<Null>(
context: context, context: context,
child: new _NotImplementedDialog() child: new _NotImplementedDialog()
); );
@ -267,7 +267,7 @@ class StockHomeState extends State<StockHome> {
Navigator.pushNamed(context, '/stock/${stock.symbol}'); Navigator.pushNamed(context, '/stock/${stock.symbol}');
}, },
onShow: (Stock stock) { onShow: (Stock stock) {
_scaffoldKey.currentState.showBottomSheet((BuildContext context) => new StockSymbolBottomSheet(stock: stock)); _scaffoldKey.currentState.showBottomSheet<Null>((BuildContext context) => new StockSymbolBottomSheet(stock: stock));
} }
); );
} }

View file

@ -65,7 +65,7 @@ class StockSettingsState extends State<StockSettings> {
_handleOptimismChanged(false); _handleOptimismChanged(false);
break; break;
case StockMode.pessimistic: case StockMode.pessimistic:
showDialog( showDialog<bool>(
context: context, context: context,
child: new AlertDialog( child: new AlertDialog(
title: new Text("Change mode?"), title: new Text("Change mode?"),
@ -85,7 +85,7 @@ class StockSettingsState extends State<StockSettings> {
), ),
] ]
) )
).then(_handleOptimismChanged); ).then<Null>(_handleOptimismChanged);
break; break;
} }
} }

View file

@ -51,7 +51,7 @@ class SynchronousFuture<T> implements Future<T> {
try { try {
dynamic result = action(); dynamic result = action();
if (result is Future) if (result is Future)
return result.then((_) => _value); return result.then<T>((dynamic value) => _value);
return this; return this;
} catch (e, stack) { } catch (e, stack) {
return new Future<T>.error(e, stack); return new Future<T>.error(e, stack);

View file

@ -515,7 +515,7 @@ class _DropdownButtonState<T> extends State<DropdownButton<T>> {
elevation: config.elevation, elevation: config.elevation,
theme: Theme.of(context, shadowThemeOnly: true), theme: Theme.of(context, shadowThemeOnly: true),
style: _textStyle, style: _textStyle,
)).then((_DropdownRouteResult<T> newValue) { )).then<Null>((_DropdownRouteResult<T> newValue) {
if (!mounted || newValue == null) if (!mounted || newValue == null)
return; return;
if (config.onChanged != null) if (config.onChanged != null)

View file

@ -535,7 +535,7 @@ class _PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
0.0, 0.0 0.0, 0.0
) )
) )
.then((T newValue) { .then<Null>((T newValue) {
if (!mounted || newValue == null) if (!mounted || newValue == null)
return; return;
if (config.onSelected != null) if (config.onSelected != null)

View file

@ -57,7 +57,7 @@ class TabController extends ChangeNotifier {
if (duration != null) { if (duration != null) {
_indexIsChangingCount += 1; _indexIsChangingCount += 1;
_animationController _animationController
..animateTo(_index.toDouble(), duration: duration, curve: curve).then((_) { ..animateTo(_index.toDouble(), duration: duration, curve: curve).whenComplete(() {
_indexIsChangingCount -= 1; _indexIsChangingCount -= 1;
notifyListeners(); notifyListeners();
}); });

View file

@ -56,7 +56,7 @@ abstract class AssetBundle {
/// ///
/// Implementations may cache the result, so a particular key should only be /// Implementations may cache the result, so a particular key should only be
/// used with one parser for the lifetime of the asset bundle. /// used with one parser for the lifetime of the asset bundle.
Future<dynamic> loadStructuredData(String key, Future<dynamic> parser(String value)); Future<dynamic> loadStructuredData<T>(String key, Future<T> parser(String value));
/// If this is a caching asset bundle, and the given key describes a cached /// If this is a caching asset bundle, and the given key describes a cached
/// asset, then evict the asset from the cache so that the next time it is /// asset, then evict the asset from the cache so that the next time it is
@ -100,7 +100,7 @@ class NetworkAssetBundle extends AssetBundle {
/// The result is not cached. The parser is run each time the resource is /// The result is not cached. The parser is run each time the resource is
/// fetched. /// fetched.
@override @override
Future<dynamic> loadStructuredData(String key, Future<dynamic> parser(String value)) async { Future<dynamic> loadStructuredData<T>(String key, Future<T> parser(String value)) async {
assert(key != null); assert(key != null);
assert(parser != null); assert(parser != null);
return parser(await loadString(key)); return parser(await loadString(key));
@ -149,14 +149,14 @@ abstract class CachingAssetBundle extends AssetBundle {
/// subsequent calls will be a [SynchronousFuture], which resolves its /// subsequent calls will be a [SynchronousFuture], which resolves its
/// callback synchronously. /// callback synchronously.
@override @override
Future<dynamic> loadStructuredData(String key, Future<dynamic> parser(String value)) { Future<dynamic> loadStructuredData<T>(String key, Future<T> parser(String value)) {
assert(key != null); assert(key != null);
assert(parser != null); assert(parser != null);
if (_structuredDataCache.containsKey(key)) if (_structuredDataCache.containsKey(key))
return _structuredDataCache[key]; return _structuredDataCache[key];
Completer<dynamic> completer; Completer<dynamic> completer;
Future<dynamic> result; Future<dynamic> result;
loadString(key, cache: false).then(parser).then((dynamic value) { loadString(key, cache: false).then<T>(parser).then<Null>((T value) {
result = new SynchronousFuture<dynamic>(value); result = new SynchronousFuture<dynamic>(value);
_structuredDataCache[key] = result; _structuredDataCache[key] = result;
if (completer != null) { if (completer != null) {

View file

@ -163,7 +163,7 @@ abstract class ImageProvider<T> {
assert(configuration != null); assert(configuration != null);
final ImageStream stream = new ImageStream(); final ImageStream stream = new ImageStream();
T obtainedKey; T obtainedKey;
obtainKey(configuration).then((T key) { obtainKey(configuration).then<Null>((T key) {
obtainedKey = key; obtainedKey = key;
stream.setCompleter(imageCache.putIfAbsent(key, () => load(key))); stream.setCompleter(imageCache.putIfAbsent(key, () => load(key)));
}).catchError( }).catchError(

View file

@ -94,7 +94,7 @@ class AssetImage extends AssetBundleImageProvider {
final AssetBundle chosenBundle = bundle ?? configuration.bundle ?? rootBundle; final AssetBundle chosenBundle = bundle ?? configuration.bundle ?? rootBundle;
Completer<AssetBundleImageKey> completer; Completer<AssetBundleImageKey> completer;
Future<AssetBundleImageKey> result; Future<AssetBundleImageKey> result;
chosenBundle.loadStructuredData(_kAssetManifestFileName, _manifestParser).then( chosenBundle.loadStructuredData<Map<String, List<String>>>(_kAssetManifestFileName, _manifestParser).then<Null>(
(Map<String, List<String>> manifest) { (Map<String, List<String>> manifest) {
final String chosenName = _chooseVariant( final String chosenName = _chooseVariant(
name, name,

View file

@ -239,7 +239,7 @@ class OneFrameImageStreamCompleter extends ImageStreamCompleter {
/// FlutterErrorDetails]). /// FlutterErrorDetails]).
OneFrameImageStreamCompleter(Future<ImageInfo> image, { InformationCollector informationCollector }) { OneFrameImageStreamCompleter(Future<ImageInfo> image, { InformationCollector informationCollector }) {
assert(image != null); assert(image != null);
image.then(setImage, onError: (dynamic error, StackTrace stack) { image.then<Null>(setImage, onError: (dynamic error, StackTrace stack) {
FlutterError.reportError(new FlutterErrorDetails( FlutterError.reportError(new FlutterErrorDetails(
exception: error, exception: error,
stack: stack, stack: stack,

View file

@ -163,7 +163,7 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
@override @override
void didChangeLocale(Locale locale) { void didChangeLocale(Locale locale) {
if (config.onLocaleChanged != null) { if (config.onLocaleChanged != null) {
config.onLocaleChanged(locale).then((LocaleQueryData data) { config.onLocaleChanged(locale).then<Null>((LocaleQueryData data) {
if (mounted) if (mounted)
setState(() { _localeData = data; }); setState(() { _localeData = data; });
}); });

View file

@ -423,7 +423,7 @@ class _DragTargetState<T> extends State<DragTarget<T>> {
return new MetaData( return new MetaData(
metaData: this, metaData: this,
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
child: config.builder(context, _mapAvatarsToData<T>(_candidateAvatars), _mapAvatarsToData(_rejectedAvatars)) child: config.builder(context, _mapAvatarsToData<T>(_candidateAvatars), _mapAvatarsToData<dynamic>(_rejectedAvatars))
); );
} }
} }

View file

@ -338,7 +338,7 @@ abstract class PageableState<T extends Pageable> extends ScrollableState<T> {
.then(_notifyPageChanged); .then(_notifyPageChanged);
} }
void _notifyPageChanged(_) { void _notifyPageChanged(Null value) {
if (config.onPageChanged != null) if (config.onPageChanged != null)
config.onPageChanged(_scrollOffsetToPageIndex(scrollOffset)); config.onPageChanged(_scrollOffsetToPageIndex(scrollOffset));
} }

View file

@ -557,7 +557,7 @@ class AbsoluteBallisticScrollActivity extends ScrollActivity {
) )
..addListener(_tick) ..addListener(_tick)
..animateWith(simulation) ..animateWith(simulation)
.then(_end); .whenComplete(_end);
} }
@override @override
@ -587,7 +587,7 @@ class AbsoluteBallisticScrollActivity extends ScrollActivity {
position.beginIdleActivity(); position.beginIdleActivity();
} }
void _end(Null value) { void _end() {
position.beginIdleActivity(); position.beginIdleActivity();
} }
@ -636,7 +636,7 @@ class AbsoluteDrivenScrollActivity extends ScrollActivity {
) )
..addListener(_tick) ..addListener(_tick)
..animateTo(to, duration: duration, curve: curve) ..animateTo(to, duration: duration, curve: curve)
.then(_end); .whenComplete(_end);
} }
@override @override
@ -659,7 +659,7 @@ class AbsoluteDrivenScrollActivity extends ScrollActivity {
position.beginIdleActivity(); position.beginIdleActivity();
} }
void _end(Null value) { void _end() {
position.beginBallisticActivity(velocity); position.beginBallisticActivity(velocity);
} }

View file

@ -1312,7 +1312,7 @@ class ScrollableState<T extends Scrollable> extends State<T> with SingleTickerPr
config.onScroll(_scrollOffset); config.onScroll(_scrollOffset);
} }
void _handleDragDown(_) { void _handleDragDown(DragDownDetails details) {
setState(() { setState(() {
_stop(); _stop();
}); });
@ -1356,7 +1356,7 @@ class ScrollableState<T extends Scrollable> extends State<T> with SingleTickerPr
void _handleDragEnd(DragEndDetails details) { void _handleDragEnd(DragEndDetails details) {
final double scrollVelocity = pixelDeltaToScrollOffset(details.velocity.pixelsPerSecond); final double scrollVelocity = pixelDeltaToScrollOffset(details.velocity.pixelsPerSecond);
fling(scrollVelocity).then((Null _) { fling(scrollVelocity).then<Null>((Null value) {
_endScroll(details: details); _endScroll(details: details);
}); });
} }

View file

@ -17,7 +17,7 @@ void main() {
builder: (BuildContext context) { builder: (BuildContext context) {
return new RaisedButton( return new RaisedButton(
onPressed: () { onPressed: () {
showDialog( showDialog<Null>(
context: context, context: context,
child: new CupertinoAlertDialog( child: new CupertinoAlertDialog(
title: new Text('The title'), title: new Text('The title'),

View file

@ -8,7 +8,7 @@ import 'dart:ui' show VoidCallback;
List<String> captureOutput(VoidCallback fn) { List<String> captureOutput(VoidCallback fn) {
List<String> log = <String>[]; List<String> log = <String>[];
runZoned(fn, zoneSpecification: new ZoneSpecification( runZoned<Null>(fn, zoneSpecification: new ZoneSpecification(
print: (Zone self, print: (Zone self,
ZoneDelegate parent, ZoneDelegate parent,
Zone zone, Zone zone,

View file

@ -12,13 +12,13 @@ void main() {
Future<int> future = new SynchronousFuture<int>(42); Future<int> future = new SynchronousFuture<int>(42);
int result; int result;
future.then((int value) { result = value; }); future.then<Null>((int value) { result = value; });
expect(result, equals(42)); expect(result, equals(42));
result = null; result = null;
Future<int> futureWithTimeout = future.timeout(const Duration(milliseconds: 1)); Future<int> futureWithTimeout = future.timeout(const Duration(milliseconds: 1));
futureWithTimeout.then((int value) { result = value; }); futureWithTimeout.then<Null>((int value) { result = value; });
expect(result, isNull); expect(result, isNull);
await futureWithTimeout; await futureWithTimeout;
expect(result, equals(42)); expect(result, equals(42));

View file

@ -18,7 +18,7 @@ void main() {
child: new RaisedButton( child: new RaisedButton(
child: new Text('X'), child: new Text('X'),
onPressed: () { onPressed: () {
showDialog( showDialog<Null>(
context: context, context: context,
child: new AlertDialog( child: new AlertDialog(
content: new Container( content: new Container(
@ -68,7 +68,7 @@ void main() {
child: new RaisedButton( child: new RaisedButton(
child: new Text('X'), child: new Text('X'),
onPressed: () { onPressed: () {
showDialog( showDialog<Null>(
context: context, context: context,
child: new AlertDialog( child: new AlertDialog(
title: new Text('Title'), title: new Text('Title'),

View file

@ -211,7 +211,7 @@ void main() {
builder: (BuildContext context) { builder: (BuildContext context) {
return new GestureDetector( return new GestureDetector(
onTap: () { onTap: () {
Scaffold.of(context).showBottomSheet((BuildContext context) { Scaffold.of(context).showBottomSheet<Null>((BuildContext context) {
return new Container( return new Container(
key: sheetKey, key: sheetKey,
decoration: new BoxDecoration(backgroundColor: Colors.blue[500]) decoration: new BoxDecoration(backgroundColor: Colors.blue[500])

View file

@ -356,7 +356,7 @@ void main() {
actionPressed = true; actionPressed = true;
} }
), ),
)).closed.then((SnackBarClosedReason reason) { )).closed.then<Null>((SnackBarClosedReason reason) {
closedReason = reason; closedReason = reason;
}); });
}, },

View file

@ -135,7 +135,7 @@ void main() {
builder: (BuildContext context) { builder: (BuildContext context) {
return new RaisedButton( return new RaisedButton(
onPressed: () { onPressed: () {
showModalBottomSheet( showModalBottomSheet<Null>(
context: context, context: context,
builder: (BuildContext context) => new Text('bottomSheet'), builder: (BuildContext context) => new Text('bottomSheet'),
); );
@ -172,7 +172,7 @@ void main() {
builder: (BuildContext context) { builder: (BuildContext context) {
return new RaisedButton( return new RaisedButton(
onPressed: () { onPressed: () {
showDialog( showDialog<Null>(
context: context, context: context,
child: new Text('dialog'), child: new Text('dialog'),
); );
@ -204,7 +204,7 @@ void main() {
builder: (BuildContext context) { builder: (BuildContext context) {
return new GestureDetector( return new GestureDetector(
onTap: () { onTap: () {
showDialog( showDialog<Null>(
context: context, context: context,
child: new Scaffold( child: new Scaffold(
body: const SizedBox( body: const SizedBox(

View file

@ -65,7 +65,7 @@ void main() {
child: new FlatButton( child: new FlatButton(
child: new Text('X'), child: new Text('X'),
onPressed: () { onPressed: () {
showDialog( showDialog<Null>(
context: context, context: context,
child: new SamplePage(), child: new SamplePage(),
); );

View file

@ -26,7 +26,7 @@ void main() {
showModalBottomSheet<Null>( showModalBottomSheet<Null>(
context: savedContext, context: savedContext,
builder: (BuildContext context) => new Text('BottomSheet') builder: (BuildContext context) => new Text('BottomSheet')
).then((Null result) { ).then<Null>((Null result) {
expectSync(result, isNull); expectSync(result, isNull);
showBottomSheetThenCalled = true; showBottomSheetThenCalled = true;
}); });
@ -48,7 +48,7 @@ void main() {
showModalBottomSheet<Null>( showModalBottomSheet<Null>(
context: savedContext, context: savedContext,
builder: (BuildContext context) => new Text('BottomSheet'), builder: (BuildContext context) => new Text('BottomSheet'),
).then((Null result) { ).then<Null>((Null result) {
expectSync(result, isNull); expectSync(result, isNull);
showBottomSheetThenCalled = true; showBottomSheetThenCalled = true;
}); });
@ -80,12 +80,12 @@ void main() {
expect(showBottomSheetThenCalled, isFalse); expect(showBottomSheetThenCalled, isFalse);
expect(find.text('BottomSheet'), findsNothing); expect(find.text('BottomSheet'), findsNothing);
scaffoldKey.currentState.showBottomSheet((BuildContext context) { scaffoldKey.currentState.showBottomSheet<Null>((BuildContext context) {
return new Container( return new Container(
margin: const EdgeInsets.all(40.0), margin: const EdgeInsets.all(40.0),
child: new Text('BottomSheet') child: new Text('BottomSheet')
); );
}).closed.then((_) { }).closed.whenComplete(() {
showBottomSheetThenCalled = true; showBottomSheetThenCalled = true;
}); });
@ -130,7 +130,7 @@ void main() {
) )
)); ));
scaffoldKey.currentState.showBottomSheet((BuildContext context) { scaffoldKey.currentState.showBottomSheet<Null>((BuildContext context) {
return new Container( return new Container(
margin: const EdgeInsets.all(40.0), margin: const EdgeInsets.all(40.0),
child: new Text('BottomSheet') child: new Text('BottomSheet')

View file

@ -87,8 +87,8 @@ class TestAssetImage extends AssetImage {
@override @override
Future<ImageInfo> loadAsync(AssetBundleImageKey key) { Future<ImageInfo> loadAsync(AssetBundleImageKey key) {
ImageInfo result; ImageInfo result;
key.bundle.load(key.name).then((ByteData data) { key.bundle.load(key.name).then<Null>((ByteData data) {
decodeImage(data).then((ui.Image image) { decodeImage(data).then<Null>((ui.Image image) {
result = new ImageInfo(image: image, scale: key.scale); result = new ImageInfo(image: image, scale: key.scale);
}); });
}); });

View file

@ -29,7 +29,7 @@ class PersistentBottomSheetTestState extends State<PersistentBottomSheetTest> {
_scaffoldKey.currentState.showBottomSheet<Null>((BuildContext context) { _scaffoldKey.currentState.showBottomSheet<Null>((BuildContext context) {
return new Text('bottomSheet'); return new Text('bottomSheet');
}) })
.closed.then((_) { .closed.whenComplete(() {
setState(() { setState(() {
setStateCalled = true; setStateCalled = true;
}); });
@ -421,13 +421,13 @@ void main() {
); );
int popCount = 0; int popCount = 0;
route.popped.then((_) { route.popped.whenComplete(() {
++popCount; popCount += 1;
}); });
int completeCount = 0; int completeCount = 0;
route.completed.then((_) { route.completed.whenComplete(() {
++completeCount; completeCount += 1;
}); });
expect(popCount, 0); expect(popCount, 0);

View file

@ -19,7 +19,7 @@ class InsideState extends State<Inside> {
); );
} }
void _handlePointerDown(_) { void _handlePointerDown(PointerDownEvent event) {
setState(() { }); setState(() { });
} }
} }
@ -42,7 +42,7 @@ class MiddleState extends State<Middle> {
); );
} }
void _handlePointerDown(_) { void _handlePointerDown(PointerDownEvent event) {
setState(() { }); setState(() { });
} }
} }

View file

@ -360,7 +360,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
)); ));
assert(_parentZone != null); assert(_parentZone != null);
assert(_pendingExceptionDetails != null); assert(_pendingExceptionDetails != null);
_parentZone.run(_testCompletionHandler); _parentZone.run<Null>(_testCompletionHandler);
} }
); );
_parentZone = Zone.current; _parentZone = Zone.current;

View file

@ -162,7 +162,7 @@ Future<Null> main(List<String> args) async {
else else
stderr.writeln('Oops; flutter has exited unexpectedly.'); stderr.writeln('Oops; flutter has exited unexpectedly.');
_createCrashReport(args, error, chain).then((File file) { _createCrashReport(args, error, chain).then<Null>((File file) {
stderr.writeln( stderr.writeln(
'Crash report written to ${file.path};\n' 'Crash report written to ${file.path};\n'
'please let us know at https://github.com/flutter/flutter/issues.' 'please let us know at https://github.com/flutter/flutter/issues.'

View file

@ -587,12 +587,11 @@ class _AdbLogReader extends DeviceLogReader {
_timeOrigin = _adbTimestampToDateTime(lastTimestamp); _timeOrigin = _adbTimestampToDateTime(lastTimestamp);
else else
_timeOrigin = null; _timeOrigin = null;
runCommand(device.adbCommandForDevice(args)).then((Process process) { runCommand(device.adbCommandForDevice(args)).then<Null>((Process process) {
_process = process; _process = process;
_process.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine); _process.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
_process.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine); _process.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
_process.exitCode.whenComplete(() {
_process.exitCode.then((int code) {
if (_linesController.hasListener) if (_linesController.hasListener)
_linesController.close(); _linesController.close();
}); });

View file

@ -110,7 +110,7 @@ Future<int> runCommandAndStreamOutput(List<String> cmd, {
// Wait for stdout to be fully processed // Wait for stdout to be fully processed
// because process.exitCode may complete first causing flaky tests. // because process.exitCode may complete first causing flaky tests.
await subscription.asFuture(); await subscription.asFuture<Null>();
subscription.cancel(); subscription.cancel();
return await process.exitCode; return await process.exitCode;

View file

@ -410,13 +410,14 @@ class RecordingProcessManager implements ProcessManager {
await files.forEach((FileSystemEntity entity) { await files.forEach((FileSystemEntity entity) {
File file = entity; File file = entity;
Future<dynamic> readAsBytes = file.readAsBytes(); Future<dynamic> readAsBytes = file.readAsBytes();
addAllFilesToArchive.add(readAsBytes.then((List<int> data) { addAllFilesToArchive.add(readAsBytes.then<Null>((List<int> data) {
archive.addFile(new ArchiveFile.noCompress( archive.addFile(new ArchiveFile.noCompress(
path.basename(file.path), data.length, data)); path.basename(file.path), data.length, data)
);
})); }));
}); });
await Future.wait(addAllFilesToArchive); await Future.wait<dynamic>(addAllFilesToArchive);
return new ZipEncoder().encode(archive); return new ZipEncoder().encode(archive);
} }
} }

View file

@ -232,7 +232,7 @@ class MaterialFonts {
return Cache._downloadFileToCache( return Cache._downloadFileToCache(
Uri.parse(cache.getVersionFor(kName)), fontsDir, true Uri.parse(cache.getVersionFor(kName)), fontsDir, true
).then((_) { ).then<Null>((Null value) {
cache.setStampFor(kName, cache.getVersionFor(kName)); cache.setStampFor(kName, cache.getVersionFor(kName));
status.stop(); status.stop();
}).whenComplete(() { }).whenComplete(() {
@ -401,7 +401,7 @@ class FlutterEngine {
Future<Null> _downloadItem(String message, String url, Directory dest) { Future<Null> _downloadItem(String message, String url, Directory dest) {
Status status = logger.startProgress(message); Status status = logger.startProgress(message);
return Cache._downloadFileToCache(Uri.parse(url), dest, true).then((_) { return Cache._downloadFileToCache(Uri.parse(url), dest, true).then<Null>((Null value) {
status.stop(); status.stop();
}).whenComplete(() { }).whenComplete(() {
status.cancel(); status.cancel();

View file

@ -120,7 +120,7 @@ class AnalyzeContinuously extends AnalyzeBase {
if (firstAnalysis && isBenchmarking) { if (firstAnalysis && isBenchmarking) {
writeBenchmark(analysisTimer, issueCount, -1); // TODO(ianh): track members missing dartdocs instead of saying -1 writeBenchmark(analysisTimer, issueCount, -1); // TODO(ianh): track members missing dartdocs instead of saying -1
server.dispose().then((_) => exit(issueCount > 0 ? 1 : 0)); server.dispose().whenComplete(() { exit(issueCount > 0 ? 1 : 0); });
} }
firstAnalysis = false; firstAnalysis = false;

View file

@ -171,7 +171,7 @@ abstract class Domain {
if (_handlers.containsKey(command)) if (_handlers.containsKey(command))
return _handlers[command](args); return _handlers[command](args);
throw 'command not understood: $name.$command'; throw 'command not understood: $name.$command';
}).then((dynamic result) { }).then<Null>((dynamic result) {
if (result == null) { if (result == null) {
_send(<String, dynamic>{'id': id}); _send(<String, dynamic>{'id': id});
} else { } else {
@ -386,7 +386,7 @@ class AppDomain extends Domain {
if (options.debuggingEnabled) { if (options.debuggingEnabled) {
connectionInfoCompleter = new Completer<DebugConnectionInfo>(); connectionInfoCompleter = new Completer<DebugConnectionInfo>();
connectionInfoCompleter.future.then((DebugConnectionInfo info) { connectionInfoCompleter.future.then<Null>((DebugConnectionInfo info) {
Map<String, dynamic> params = <String, dynamic>{ Map<String, dynamic> params = <String, dynamic>{
'port': info.httpUri.port, 'port': info.httpUri.port,
'wsUri': info.wsUri.toString(), 'wsUri': info.wsUri.toString(),
@ -397,7 +397,7 @@ class AppDomain extends Domain {
}); });
} }
Completer<Null> appStartedCompleter = new Completer<Null>(); Completer<Null> appStartedCompleter = new Completer<Null>();
appStartedCompleter.future.then((_) { appStartedCompleter.future.then<Null>((Null value) {
_sendAppEvent(app, 'started'); _sendAppEvent(app, 'started');
}); });

View file

@ -266,7 +266,7 @@ class _DevFSHttpWriter {
Stream<List<int>> contents = content.contentsAsCompressedStream(); Stream<List<int>> contents = content.contentsAsCompressedStream();
await request.addStream(contents); await request.addStream(contents);
HttpClientResponse response = await request.close(); HttpClientResponse response = await request.close();
await response.drain(); await response.drain<Null>();
} catch (e) { } catch (e) {
printError('Error writing "$devicePath" to DevFS: $e'); printError('Error writing "$devicePath" to DevFS: $e');
} }
@ -417,7 +417,10 @@ class DevFS {
if (progressReporter != null) { if (progressReporter != null) {
final int max = _pendingOperations.length; final int max = _pendingOperations.length;
int complete = 0; int complete = 0;
_pendingOperations.forEach((Future<dynamic> f) => f.then((dynamic v) { _pendingOperations.forEach((Future<dynamic> f) => f.whenComplete(() {
// TODO(ianh): If one of the pending operations fail, we'll keep
// calling progressReporter long after update() has completed its
// future, assuming that doesn't crash the app.
complete += 1; complete += 1;
progressReporter(complete, max); progressReporter(complete, max);
})); }));

View file

@ -402,12 +402,11 @@ class _IOSDeviceLogReader extends DeviceLogReader {
String get name => device.name; String get name => device.name;
void _start() { void _start() {
runCommand(<String>[device.loggerPath]).then((Process process) { runCommand(<String>[device.loggerPath]).then<Null>((Process process) {
_process = process; _process = process;
_process.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine); _process.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
_process.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine); _process.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onLine);
_process.exitCode.whenComplete(() {
_process.exitCode.then((int code) {
if (_linesController.hasListener) if (_linesController.hasListener)
_linesController.close(); _linesController.close();
}); });

View file

@ -663,7 +663,7 @@ class _IOSSimulatorLogReader extends DeviceLogReader {
_systemProcess.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onSystemLine); _systemProcess.stdout.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onSystemLine);
_systemProcess.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onSystemLine); _systemProcess.stderr.transform(UTF8.decoder).transform(const LineSplitter()).listen(_onSystemLine);
_deviceProcess.exitCode.then((int code) { _deviceProcess.exitCode.whenComplete(() {
if (_linesController.hasListener) if (_linesController.hasListener)
_linesController.close(); _linesController.close();
}); });

View file

@ -35,7 +35,7 @@ class CoverageCollector {
int pid = process.pid; int pid = process.pid;
int exitCode; int exitCode;
process.exitCode.then((int code) { process.exitCode.then<Null>((int code) {
exitCode = code; exitCode = code;
}); });

View file

@ -124,7 +124,7 @@ class FlutterPlatform extends PlatformPlugin {
bool subprocessActive = false; bool subprocessActive = false;
bool controllerSinkClosed = false; bool controllerSinkClosed = false;
try { try {
controller.sink.done.then((_) { controllerSinkClosed = true; }); controller.sink.done.whenComplete(() { controllerSinkClosed = true; });
// Prepare our WebSocket server to talk to the engine subproces. // Prepare our WebSocket server to talk to the engine subproces.
HttpServer server = await HttpServer.bind(_kHost, 0); HttpServer server = await HttpServer.bind(_kHost, 0);
@ -524,10 +524,10 @@ class _FlutterPlatformStreamSinkWrapper<S> implements StreamSink<S> {
@override @override
Future<dynamic> close() { Future<dynamic> close() {
Future.wait(<Future<dynamic>>[ Future.wait<dynamic>(<Future<dynamic>>[
_parent.close(), _parent.close(),
_shellProcessClosed, _shellProcessClosed,
]).then( ]).then<Null>(
(List<dynamic> value) { (List<dynamic> value) {
_done.complete(); _done.complete();
}, },

View file

@ -561,7 +561,7 @@ class VM extends ServiceObjectOwner {
Future<Isolate> getIsolate(String isolateId) { Future<Isolate> getIsolate(String isolateId) {
if (!loaded) { if (!loaded) {
// Trigger a VM load, then get the isolate. Ignore any errors. // Trigger a VM load, then get the isolate. Ignore any errors.
return load().then((_) => getIsolate(isolateId)).catchError((_) => null); return load().then<Isolate>((ServiceObject serviceObject) => getIsolate(isolateId)).catchError((dynamic error) => null);
} }
return new Future<Isolate>.value(_isolateCache[isolateId]); return new Future<Isolate>.value(_isolateCache[isolateId]);
} }

View file

@ -37,9 +37,9 @@ class _ArchiveZipBuilder extends ZipBuilder {
final Completer<Null> finished = new Completer<Null>(); final Completer<Null> finished = new Completer<Null>();
int count = entries.length; int count = entries.length;
entries.forEach((String archivePath, DevFSContent content) { entries.forEach((String archivePath, DevFSContent content) {
content.contentsAsBytes().then((List<int> data) { content.contentsAsBytes().then<Null>((List<int> data) {
archive.addFile(new ArchiveFile.noCompress(archivePath, data.length, data)); archive.addFile(new ArchiveFile.noCompress(archivePath, data.length, data));
--count; count -= 1;
if (count == 0) if (count == 0)
finished.complete(); finished.complete();
}); });
@ -73,11 +73,11 @@ class _ZipToolBuilder extends ZipBuilder {
final Completer<Null> finished = new Completer<Null>(); final Completer<Null> finished = new Completer<Null>();
int count = entries.length; int count = entries.length;
entries.forEach((String archivePath, DevFSContent content) { entries.forEach((String archivePath, DevFSContent content) {
content.contentsAsBytes().then((List<int> data) { content.contentsAsBytes().then<Null>((List<int> data) {
File file = fs.file(path.join(zipBuildDir.path, archivePath)); File file = fs.file(path.join(zipBuildDir.path, archivePath));
file.parent.createSync(recursive: true); file.parent.createSync(recursive: true);
file.writeAsBytes(data).then((_) { file.writeAsBytes(data).then<Null>((File value) {
--count; count -= 1;
if (count == 0) if (count == 0)
finished.complete(); finished.complete();
}); });

View file

@ -34,7 +34,7 @@ void main() {
applyMocksToCommand(command); applyMocksToCommand(command);
return createTestCommandRunner(command).run( return createTestCommandRunner(command).run(
<String>['analyze', '--no-current-package', '--no-current-directory', dartFileA.path, dartFileB.path] <String>['analyze', '--no-current-package', '--no-current-directory', dartFileA.path, dartFileB.path]
).then((_) { ).then<Null>((Null value) {
expect(testLogger.statusText, startsWith('Analyzing 2 files...\nNo analyzer warnings!')); expect(testLogger.statusText, startsWith('Analyzing 2 files...\nNo analyzer warnings!'));
}); });

View file

@ -118,7 +118,7 @@ void main() {
notifyingLogger: notifyingLogger notifyingLogger: notifyingLogger
); );
commands.add(<String, dynamic>{'id': 0, 'method': 'daemon.shutdown'}); commands.add(<String, dynamic>{'id': 0, 'method': 'daemon.shutdown'});
return daemon.onExit.then((int code) { return daemon.onExit.then<Null>((int code) {
responses.close(); responses.close();
commands.close(); commands.close();
expect(code, 0); expect(code, 0);

View file

@ -1,3 +1,3 @@
analyzer: analyzer:
exclude: exclude:
- '**' - '**'

View file

@ -1,3 +1,3 @@
analyzer: analyzer:
exclude: exclude:
- '**' - '**'

View file

@ -268,7 +268,7 @@ class MockVMService extends BasicMock implements VMService {
String fsName = request.headers.value('dev_fs_name'); String fsName = request.headers.value('dev_fs_name');
String devicePath = UTF8.decode(BASE64.decode(request.headers.value('dev_fs_path_b64'))); String devicePath = UTF8.decode(BASE64.decode(request.headers.value('dev_fs_path_b64')));
messages.add('writeFile $fsName $devicePath'); messages.add('writeFile $fsName $devicePath');
request.drain().then((_) { request.drain<List<int>>().then<Null>((List<int> value) {
request.response request.response
..write('Got it') ..write('Got it')
..close(); ..close();

View file

@ -47,13 +47,13 @@ void main() {
targetDeviceFinder = () { targetDeviceFinder = () {
throw 'Unexpected call to targetDeviceFinder'; throw 'Unexpected call to targetDeviceFinder';
}; };
appStarter = (_) { appStarter = (DriveCommand command) {
throw 'Unexpected call to appStarter'; throw 'Unexpected call to appStarter';
}; };
testRunner = (_) { testRunner = (List<String> testArgs) {
throw 'Unexpected call to testRunner'; throw 'Unexpected call to testRunner';
}; };
appStopper = (_) { appStopper = (DriveCommand command) {
throw 'Unexpected call to appStopper'; throw 'Unexpected call to appStopper';
}; };
}); });
@ -86,14 +86,14 @@ void main() {
testUsingContext('returns 1 when app fails to run', () async { testUsingContext('returns 1 when app fails to run', () async {
withMockDevice(); withMockDevice();
appStarter = expectAsync((_) async => 1); appStarter = expectAsync((DriveCommand command) async => 1);
String testApp = '/some/app/test_driver/e2e.dart'; String testApp = '/some/app/test_driver/e2e.dart';
String testFile = '/some/app/test_driver/e2e_test.dart'; String testFile = '/some/app/test_driver/e2e_test.dart';
MemoryFileSystem memFs = memoryFileSystem; MemoryFileSystem memFs = memoryFileSystem;
await memFs.file(testApp).writeAsString('main() {}'); await memFs.file(testApp).writeAsString('main() { }');
await memFs.file(testFile).writeAsString('main() {}'); await memFs.file(testFile).writeAsString('main() { }');
List<String> args = <String>[ List<String> args = <String>[
'drive', 'drive',
@ -155,14 +155,14 @@ void main() {
String testApp = '/some/app/test/e2e.dart'; String testApp = '/some/app/test/e2e.dart';
String testFile = '/some/app/test_driver/e2e_test.dart'; String testFile = '/some/app/test_driver/e2e_test.dart';
appStarter = expectAsync((_) { appStarter = expectAsync((DriveCommand command) {
return new Future<int>.value(0); return new Future<int>.value(0);
}); });
testRunner = expectAsync((List<String> testArgs) { testRunner = expectAsync((List<String> testArgs) {
expect(testArgs, <String>[testFile]); expect(testArgs, <String>[testFile]);
return new Future<int>.value(0); return new Future<int>.value(0);
}); });
appStopper = expectAsync((_) { appStopper = expectAsync((DriveCommand command) {
return new Future<int>.value(0); return new Future<int>.value(0);
}); });
@ -186,13 +186,13 @@ void main() {
String testApp = '/some/app/test/e2e.dart'; String testApp = '/some/app/test/e2e.dart';
String testFile = '/some/app/test_driver/e2e_test.dart'; String testFile = '/some/app/test_driver/e2e_test.dart';
appStarter = expectAsync((_) { appStarter = expectAsync((DriveCommand command) {
return new Future<int>.value(0); return new Future<int>.value(0);
}); });
testRunner = (_) { testRunner = (List<String> testArgs) {
throwToolExit(null, exitCode: 123); throwToolExit(null, exitCode: 123);
}; };
appStopper = expectAsync((_) { appStopper = expectAsync((DriveCommand command) {
return new Future<int>.value(0); return new Future<int>.value(0);
}); });

View file

@ -70,7 +70,7 @@ Future<Null> main() async {
stdout.write('> '); stdout.write('> ');
}); });
daemon.exitCode.then((int code) { daemon.exitCode.then<Null>((int code) {
print('daemon exiting ($code)'); print('daemon exiting ($code)');
exit(code); exit(code);
}); });